Я работаю над C ++ Qt GUI для удаленного управления роботом ROS.Я читал, что команда ros::spin()
должна быть выполнена в отдельном потоке, поэтому у меня есть обычное MainWindow, производное от QMainWindow
, конструктор которого устанавливает элементы GUI, заставляет объекты подписчика подписываться на их соответствующие темы (например, * 1003).* для sensor_msgs/Image
тем), а также запускает другую тему.Для этого я извлек класс RosThread из QThread
, который ничего не делает, кроме запуска ros:MultiThreadedSpinner
при вызове RosThread::run()
.
Как вы, вероятно, можете сказать, я не очень разбираюсь в программировании в целом, поэтому мой вопрос в том, имеет ли смысл основная концепция моего проекта для вас?Особенно я должен оставить NodeHandle и объекты подписчика в MainWindow и настроить подписки из конструктора MainWindow?
Соответствующие фрагменты кода:
mainwindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), itLeft(nh), itArm(nh)
{
//subscribe to cameras
imageSubLeft = itLeft.subscribe("/camera_1/image_raw", 1000, &MainWindow::camCallbackLeft, this);
imageSubArm = itArm.subscribe("/camera_2/image_raw", 1000, &MainWindow::camCallbackArm, this);
pagestack = new QStackedWidget;
page1 = new QWidget;
grid = new QGridLayout;
page1->setLayout(grid);
pagestack->addWidget(page1);
labelLeft = new QLabel;
labelMid = new QLabel;
grid->addWidget(labelLeft, 0, 0);
grid->addWidget(labelMid, 0, 1);
this->startSpinThread(); //starts the seperate Thread where run() is executed
this->setCentralWidget(pagestack);
this->setWindowState(Qt::WindowMaximized);
this->setMinimumSize(1024, 768);
}
MainWindow::~MainWindow(){}
void MainWindow::camCallbackLeft(const sensor_msgs::Image::ConstPtr &msg){/*some code*/}
void MainWindow::camCallbackArm(const sensor_msgs::Image::ConstPtr &msg){/*some code*/}
void MainWindow::closeEvent(QCloseEvent *event){/*some code*/}
void MainWindow::startSpinThread()
{
if(rosSpin.isRunning())
{
return;
}
//rosSpin is an Object of the of QThread derived class
rosSpin.start();
}
rosthread.h:
#ifndef ROSTHREAD_H
#define ROSTHREAD_H
#include <ros/ros.h>
#include <QThread>
class RosThread : public QThread
{
Q_OBJECT
public:
RosThread();
protected:
void run();
private:
ros::MultiThreadedSpinner spinner;
};
#endif // ROSTHREAD_H
rosthread.cpp:
#include "rosthread.h"
RosThread::RosThread()
{
}
void RosThread::run() {
spinner.spin();
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
#include <ros/ros.h>
int main(int argc, char **argv)
{
ros::init(argc, argv, "gui_node");
QApplication app (argc, argv);
MainWindow *win = new MainWindow();
win->show();
return app.exec();
}