ROS开发--Qt接收摇杆话题

2 篇文章 0 订阅

我需要做一个Qt界面用来接收摇杆信息等,需要用到ROS和Qt相结合。进行开发需要两点,首先是需要将Qt界面作为节点加入到ROS中;然后,由于话题接收需要ros::spin()进行不断的循环接收,需要把话题订阅节点放入到一个单独线程中。首先实现对摇杆话题的接收,之后对其他话题接收也就同理了。
我的环境是:
操作系统:ubuntu16.04
ROS:kinetic
Qt:5.12.5

将Qt界面加入到ROS节点

这个网上有很多帖子,我主要参考基于ROS的QT界面开发史上最强教程三种方法在ROS中加载Qt库进行GUI设计这两篇文章。
虽然上面两篇文章讲的很详细了,我还是讲一下我最后配置编程的过程。

1.ROS添加Qt界面节点

不用插件直接用Qt库来建立

$ mkdir -p ~/catkin_qt/src
$ cd ~catkin_qt/src
$ catkin_create_pkg qt_ui std_msgs rospy roscpp

然后打开qt,新建界面,在这里插入图片描述
将创建的界面放到src/qt_ui/src下,会产生MainWindow.cpp,MainWindow.h,MainWindow.ui三个文件,还需要手动创建一个main.cpp文件,具体代码后面说,将qt界面加入到ROS中关键是对CMakeLists.txt的修改,如下:

cmake_minimum_required(VERSION 2.8.3)
project(qt_ui)

## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)

find_package(Qt5 REQUIRED COMPONENTS Widgets)

###################################
## qt5                           ##
###################################
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

qt5_wrap_cpp(MOC src/mainwindow.h)
qt5_wrap_ui(UIC src/mainwindow.ui)

###################################
## catkin specific configuration ##
###################################
catkin_package(
   INCLUDE_DIRS include
   CATKIN_DEPENDS roscpp rospy std_msgs
)

###########
## Build ##
###########
include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  INCLUDE_DIRS include
  ${CMAKE_CURRENT_BINARY_DIR}/..
)

add_executable(${PROJECT_NAME}_node 
	src/mainwindow.cpp
	src/main.cpp
	src/StatusNode.cpp
	src/mainwindow.ui
)

add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES} Qt5::Widgets)

然后就配置完成了,之后有要添加的文件或者库再在这个基础上对CMakeLists.txt进行修改。
在main.cpp中写入如下:

#include"mainwindow.h"
#include<QApplication>

int main(int argc, char *argv[])
{
        QApplication a(argc,argv);
        MainWindow w;
        w.show();
        return a.exec();
}

返回到目录~/catkin_qt/,在终端打开

$ catkin_make

还有就是通过Qt来运行程序,打开qt然后打开项目,选择catkin_qt/src/CMakeLists.txt,
在这里插入图片描述
然后点击“项目”,将构件目录改到工程下的“build”目录。
在这里插入图片描述
然后在终端打开roscore,最后运行程序,qt界面就出来了

2.界面接收摇杆信息

首先要安装ros-joy包,
界面要在每次接收到话题都要进行处理,所以需要将消息的订阅放在一个单独的线程里面,参考ros_qtc_plugin插件自带的一个例子进行改写。
ros_qtc_plugin插件安装:

$ sudo apt-get install ros-kinetic-qt-ros

其中的kinetic根据所用ros版本不同进行更换即可
插件创建界面节点语句为

$ catkin_create _qt_pkg 

这个plugin_test小例子这里就不贴了,可自行查看

然后写一个节点多线程类用于接收摇杆信息
StatusNode.h

#include <ros/ros.h>
#include <QThread>
#include<sensor_msgs/Joy.h>
#include <std_msgs/String.h>
#include<QString>
namespace Status_Node{

class StatusNode :public QThread{
    Q_OBJECT
signals:
    //void joystatus(const QString& str);
    void joystatus(const QString& angluar, const QString& linear);

public:
    StatusNode(int argc, char** argv);
    virtual ~StatusNode();
    bool init();
    void run();
private:
        int init_argc;
        char** init_argv;
        void chatterCallback(const sensor_msgs::Joy::ConstPtr &joy);
        ros::Subscriber sub;
        ros::Publisher pub;


};
}

StatusNode.cpp

#include"StatusNode.h"

namespace Status_Node{

StatusNode::StatusNode(int argc, char** argv):
    init_argc(argc),
    init_argv(argv){
}

StatusNode::~StatusNode(){
    if(ros::isStarted()){
        ros::shutdown();
        ros::waitForShutdown();
    }
    wait();
}

bool StatusNode::init(){
    ros::init(init_argc,init_argv,"status_node");
    if(!ros::master::check()){
        return false;
    }
    ros::start();
    ros::NodeHandle n;
    pub = n.advertise<std_msgs::String>("zx", 1000);
    sub = n.subscribe<sensor_msgs::Joy>("joy",1000,&StatusNode::chatterCallback,this);
    start();
    return true;

}

void StatusNode::chatterCallback(const sensor_msgs::Joy::ConstPtr &joy){
    double angular;
    angular = joy->axes[0];
    double linear;
    linear =joy->axes[1];
    emit joystatus(QString::number(angular,'g',6),QString::number(linear,'g',6));

}

void StatusNode::run(){


    ros::spin();

}

}

这里StatusNode类有两个参数,因此需要对main.cpp和mainwindow.h、mainwindow.cpp进行修改
main.cpp修改:

int main(int argc, char *argv[])
{
        QApplication a(argc,argv);
        MainWindow w(argc,argv);//修改
        w.show();
        return a.exec();
}

mainwindow.h修改:

#include <QMainWindow>
#include"StatusNode.h"
#include<QMessageBox>
#include<QString>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(int argc, char** argv,QWidget *parent = nullptr);//修改
    ~MainWindow();
    void showNoMasterMessage();

public slots:
    void joystatus(const QString& angluar, const QString& linear);

private:
    Ui::MainWindow *ui;
    Status_Node::StatusNode node;

};

mainwindow.cpp修改:

MainWindow::MainWindow(int argc, char** argv,QWidget *parent) : //修改
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    node(argc,argv)
{
    ui->setupUi(this);

    ui->joy_speed->setText("0");
    if(!node.init()){
        showNoMasterMessage();
    }
    connect(&node,&Status_Node::StatusNode::joystatus,this,&MainWindow::joystatus);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::joystatus(const QString& angluar, const QString& linear){
    ui->joy_angluar->setText(angluar);
    ui->joy_speed->setText(linear);
}

void MainWindow::showNoMasterMessage(){
    QMessageBox msgBox;
    msgBox.setText("Couldn't find the ros master.");
    msgBox.exec();
    close();
}

这样就可以在qt界面中通过QLabel控件显示摇杆信息了,
首先打开master,

$ roscore

然后打开joy节点

$ rosrun joy joy_node

最后再通过qt运行程序就ok了
在这里插入图片描述
记得修改代码需要 caktin_make 从新编译。
话题接收实现后,就剩下话题的发布了。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值