从qt线程制作一个ros节点
making a ros node from a qt thread
我的应用程序中有一个 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
基本上,你包含main()
函数的可执行文件必须同时是你的ros节点和你的QT应用程序。在你的 "main.cpp"
你打电话给 ros::init(...)
并订阅你想听的话题。您的订阅者回调函数可能会将 ros 图像转换为 Mat
并在每次调用时发出 ImgSignal
。为此,我将创建一个 RosImageProvider class,类似于 ..
class RosImageProvider: public QObject
{
Q_OBJECT
public:
void ImageSubscriberCallback(const sensor_msgs::Image::ConstPtr& img);
...
signals:
void ImgSignal(Mat*);
};
我在处理来自 Qt 中 ROS 节点的 TCP/IP 连接时遇到了同样的问题,我的解决方案是直接从 QThread 对象继承,因此在初始化 class 时,你初始化ROS 节点并在回调和线程 运行() 函数中实现工作 TODO。
最后,我的代码看起来像这样:
#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 节点的模板,因为我不知道您的具体需求。随意构建您自己的!
干杯,
我的应用程序中有一个 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
基本上,你包含main()
函数的可执行文件必须同时是你的ros节点和你的QT应用程序。在你的 "main.cpp"
你打电话给 ros::init(...)
并订阅你想听的话题。您的订阅者回调函数可能会将 ros 图像转换为 Mat
并在每次调用时发出 ImgSignal
。为此,我将创建一个 RosImageProvider class,类似于 ..
class RosImageProvider: public QObject
{
Q_OBJECT
public:
void ImageSubscriberCallback(const sensor_msgs::Image::ConstPtr& img);
...
signals:
void ImgSignal(Mat*);
};
我在处理来自 Qt 中 ROS 节点的 TCP/IP 连接时遇到了同样的问题,我的解决方案是直接从 QThread 对象继承,因此在初始化 class 时,你初始化ROS 节点并在回调和线程 运行() 函数中实现工作 TODO。
最后,我的代码看起来像这样:
#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 节点的模板,因为我不知道您的具体需求。随意构建您自己的!
干杯,