从qt线程创建一个ros节点

时间:2016-12-08 14:02:29

标签: qt ros

我的应用程序中有一个qt线程,它发出一个Mat类型的图像,以便其他线程可以使用它。通过使用opencv库的VideoCapture对象,图像来自相机。现在我打算做的是从rostopic获取这个图像,而不是直接从相机获取。为了做到这一点,我必须在我的线程中创建一个ros节点,在这里我被卡住了。有谁有经验整合ros节点和qt? 这是我的主题:

#include "../include/Ground_Station/camera.h"
#include <iostream>

using namespace std;

Camera::Camera()
{

}

void Camera::run()
{

    VideoCapture cap;
    cap.open(0);

    while(1){

        Mat image;
        cap >> image;

        cvtColor(image,image,CV_BGR2RGB);

        emit ImgSignal(&image);
        QThread::msleep(30);
    }
}

和Camera.h:

#ifndef CAMERA_H
#define CAMERA_H

#include <QObject>
#include <QThread>
#include <QtCore>
#include <QtGui>

#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <ros/ros.h>

#include <opencv2/opencv.hpp>

using namespace cv;

class Camera: public QThread
{
    Q_OBJECT
public:
    Camera();

    void run();
    bool Stop = false;

signals:
    void ImgSignal(Mat*);

private:                                                                 

public slots:


};

#endif // THREAD_H

2 个答案:

答案 0 :(得分:0)

基本上,包含main()函数的可执行文件必须同时是您的ros节点和QT应用程序。在你的“main.cpp”中 你打电话给ros::init(...)并订阅你想听的主题。您的订阅者回调函数可能会将ros图像转换为Mat,并在每次调用时发出ImgSignal。为了做到这一切,我将创建一个RosImageProvider类,类似于......

class RosImageProvider: public QObject
{
    Q_OBJECT
public:
  void ImageSubscriberCallback(const sensor_msgs::Image::ConstPtr& img);
...
signals:
  void ImgSignal(Mat*);
};

答案 1 :(得分:0)

在处理来自Qt内的ROS节点的TCP / IP连接时,我遇到了同样的问题,我的解决方案是直接从QThread对象继承,因此在初始化类时,初始化ROS节点并实现工作TODO回调和线程run()函数。

最后,我的代码看起来像这样:

#ifndef INCLUDE_TCPHANDLER_HPP_
#define INCLUDE_TCPHANDLER_HPP_

#include <ros/ros.h>

#include <QThread>
#include <string>

class TCP_Handler : public QThread
{
    Q_OBJECT

private:
    int init_argc;
    char** init_argv;

    ros::Publisher cmd_control_publisher;
    ros::Subscriber feedback_subscriber;

public:
    TCP_Handler()
    {}

    virtual ~TCP_Handler(){}

 /**
     * @brief ROS methods
 *
 */
    inline bool init_ros()
    {
        int argc =0; char** argv = new char*();
        ros::init(argc,argv,"tcp_handler");
        ros::NodeHandle n;
        cmd_control_publisher = n.advertise<robot_common::cmd_control>("cmd_control", 1000);
        feedback_subscriber = n.subscribe<robot_common::feedback>("wifibot_pose", 4, &TCP_Handler::FeedbackCallback , this);
        return true;
    }

    void FeedbackCallback(const robot_common::feedback::ConstPtr& pose)
    {
        //.....
    }

 /**
 * @brief Threading methods
 *
 */
    virtual void init(int, std::string ip_addr = "127.0.0.1") = 0;
    virtual void run() = 0;
    virtual void stop() = 0;

/**
 * @brief TCP methods (Server/Client have to implement these folks)
 *
 */

    virtual bool Send_data(char* data, int size) = 0;
    virtual int  Receive_data(char* in_data, int size) = 0;
    virtual bool Open_connection() = 0;
    virtual void Close_connection() = 0;
};

#endif /* INCLUDE_TCPHANDLER_HPP_ */ 

这段代码只是用于TCP连接的Qt-threaded-ROS节点的模板,因为我不知道您的具体需求。随意建立自己的!

干杯,