【问题标题】:making a ros node from a qt thread从 qt 线程创建一个 ros 节点
【发布时间】:2016-12-12 22:49:42
【问题描述】:

我的应用程序中有一个 qt 线程,它发出一个 Mat 类型的图像,以便其他线程可以使用它。通过使用 opencv 库的 VideoCapture 对象,图像来自相机。现在我打算做的是从 rostopic 中获取此图像,而不是直接从相机中获取。为了做到这一点,我必须在我的线程中创建一个 ros 节点,在这里我被卡住了。有没有人有集成ros node和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

【问题讨论】:

    标签: qt ros


    【解决方案1】:

    基本上,您的包含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*);
    };
    

    【讨论】:

      【解决方案2】:

      我在 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 线程 ROS 节点的模板,因为我不知道您的具体需求。随意构建自己的!

      干杯,

      【讨论】:

        猜你喜欢
        • 2016-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-13
        • 1970-01-01
        • 2022-06-29
        相关资源
        最近更新 更多