当前位置:   article > 正文

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_ros qt gui

ros qt gui

    本篇博客主要介绍怎么使用qt对ros进行gui设计与调试,包括使用列表视图显示ROS话题发布与接收的消息,点击QT按钮按钮进行ros消息的发布

在阅读本文之前没有安装QT与配置环境可以参考博文:如何用Qt的对ROS项目进行调试及创建GUI界面

最近有个项目需要对ROS进行GUI设计,而ROS在这方面开发教程实在是很少,去师兄那里取经之后就开始干活了,现将自己的详细经验分享。

 

一,ROS下创建QT_GUI文件

    (1)安装catkin_create_qt_pkg ROS包,打开终端输入以下命令:

$ sudo apt-get install ros- <distro> -qt-ros // distro是ros版本,例如LZ的就是ros-hydro-qt-ros

    (2)进入工作空间使用如下命令创建基于QT的ros_gui文件:

  1. $ cd catkin_ws / src //进入自己的工作空间
  2. $ catkin_create_qt_pkg ros_gui //创建ros_gui包
$ catkin_create_qt_pkg ros_gui //创建ros_gui包

    (3)如下图,在终端输入qtcreator打开QT(或者在桌面配置了QT-ROS启动快捷方式的直接点击启打开),选择打开项目进入ros_gui文件下选择CMakeList.txt文件打开:

    (4)进入的CMake向导构建路径步骤点击下一步:

    (5)在执行Cmake步骤中,参数选项输入:-DCMAKE_BUILD_TYPE = DEBUG,然后点击执行CMake,最后点击完成:

    (6)如下图,可以看到打开的ros_gui项目(吐槽下这里居然不显示头文件目录,导致编辑头文件代码不方便,建议将头文件与CPP文件放在一起再导入,导入后修改的cpp中头文件路径):

 

二,在QT视图中显示ROS话题发布与接收的消息

    (1)打开终端roscore启动ros_Master,在QT上直接编译运行ros_gui项目,填写自己的ROS信息(ROS_MASTER_Url可直接在终端中查看,ROS_IP可以在终端输入的ifconfig命令查看),点击连接,如下图可以看到程序内置了一个文本视图与ROS发送节点,视图上显示节点发送的信息:

    (2)下面在窗口空间中添加一个文本视图使其显示接收到的消息,打开main_window.ui文件,拖入一个列表视图控件并将其对象名更改为view_logging_sub,然后拖入两个Label控件到对应的视图空间上改为pub与sub:

    (3)打开qnode.hpp(项目列表不显示的直接打开项目包括文件夹拖入qt)与qnode.cpp,在其添加代码(添加部分代码标记为//添加):

<qnode.hpp>:

  1. #include <QStringListModel>
  2. #include <std_msgs / String.h> //add
  3. / ******************* ****************************
  4. **
  5. ************************************************** *************************** /
  6. class QNodepublic QThread {
  7.     Q_OBJECT
  8. public
  9.     QStringListModel * loggingModel_sub(){return&logging_model_sub; } //add
  10.     void log_sub(const LogLevel&level,const std :: string&msg); //add
  11.     void Callback(const std_msgs :: StringConstPtr&submsg); //add
  12. Q_SIGNALS:
  13.     void loggingUpdated_sub(); //add
private:
  1.     ros :: Subscriber chatter_subscriber; //add
  2.     QStringListModel logging_model_sub; //add
  3. };

<qnode.cpp>:

 

  1. / ******************* ****************************
  2. **
  3. ************************************************** *************************** /
  4. bool QNode :: init(){
  5. //在这里添加你的ros通讯。
  6. chatter_publisher = n.advertise <std_msgs :: String>(“chatter”,1000);
  7. chatter_subscriber = n.subscribe( “chatter”,1000,&QNode ::Callback,this); //加
  8. }
  9. bool QNode :: init(const std :: string&master_url,const std :: string&host_url){
  10. //在这里添加你的ros通讯。
  11. chatter_publisher = n.advertise <std_msgs :: String>(“chatter”,1000);
  12. chatter_subscriber = n.subscribe( “chatter”,1000,&QNode ::Callback,this); //add
  13. }
  14. void QNode :: log_sub(const LogLevel&level,const std :: string&msg){// add
  15.     logging_model_sub.insertRows(logging_model_sub.rowCount(),1);
  16.     std :: stringstream logging_model_msg;
  17.     开关(级别){
  18.         case(Debug):{
  19.                 ROS_DEBUG_STREAM(MSG);
  20.                 logging_model_msg <<“[DEBUG] [”<< ros :: Time :: now()<<“]:”<< msg;
  21.                 break;
  22.         }
  23.         case(Info):{
  24.                 ROS_INFO_STREAM(MSG);
  25.                 logging_model_msg <<“[INFO] [”<< ros :: Time :: now()<<“]:”<< msg;
  26.                 break;
  27.         }
  28.         case(Warn):{
  29.                 ROS_WARN_STREAM(MSG);
  30.                 logging_model_msg <<“[INFO] [”<< ros :: Time :: now()<<“]:”<< msg;
  31.                 break;
  32.         }
  33.         case(Error):{
  34.                 ROS_ERROR_STREAM(MSG);
  35.                 logging_model_msg <<“[ERROR] [”<< ros :: Time :: now()<<“]:”<< msg;
  36.                 break;
  37.         }
  38.         case(Fatal):{
  39.                 ROS_FATAL_STREAM(MSG);
  40.                 logging_model_msg <<“[FATAL] [”<< ros :: Time :: now()<<“]:”<< msg;
  41.                 break;
  42.         }
  43.     }
  44.     QVariant new_row(QString(logging_model_msg.str().c_str()));
  45.     logging_model_sub.setData(logging_model_sub.index(logging_model_sub.rowCount() - 1),NEW_ROW);
  46.     Q_EMIT loggingUpdated_sub(); //用于重新调整滚动条
  47. }
  48. void QNode :: Callback(const std_msgs :: StringConstPtr&submsg)// add
  49. {
  50.     log_sub(Info,std :: string(“Success sub:”)+ submsg-> data.c_str());
  51. }

    (4)再打开main_window.hpp(项目列表不显示的直接打开项目包括文件夹拖入qt)与main_window.cpp,其中添加代码(添加部分代码标记为// add):

 

<main_window.hpp>:

  1. pubilc Q_SLOTS:
  2. / ******************************************
  3. **
  4. ********* /
  5.     void updateLoggingView_sub(); //add

<main_window.cpp>:

  1. / *********************
  2. **
  3. ********************** /
  4. ui.view_logging_sub->setModel(qnode.loggingModel_sub()); //add
  5. QObject :: connect(&qnode,SIGNAL(loggingUpdated_sub()),this,SLOT(updateLoggingView_sub())); //add
  6. / ******************* ****************************
  7. **
  8. ************************************************** *************************** /
  9. void MainWindow :: updateLoggingView_sub(){// add
  10.         ui.view_logging_sub-> scrollToBottom();
  11. }

    (5)如下图,保存修改后的文件并且编译运行可以实现在GUI显示消息的接收与发送:

 

三,使用QT按钮进行消息的发布

下面实现通过点击按钮进行ROS消息的发送:

    (1)如下图打开main_window.ui,拖入一个按钮控件,将对象名改为sent_cmd

    (2)打开qnode.hpp(项目列表不显示的直接打开项目包含文件夹拖入qt)与qnode.cpp,在其中添加代码(添加部分代码标记为红色//添加):

<qnode.hpp>:

  1. class QNodepublic QThread {
  2.     Q_OBJECT
  3. pubilc:
  4. / *********************
  5. **
  6. ********************** /
  7. void sent_cmd(); //add

<qnode.cpp>:

  1. / ******************* ****************************
  2. **实施
  3. **********************************
  4. void QNode :: sent_cmd()// add
  5. {
  6.  if(ros :: ok()){
  7.       std_msgs :: String msg;
  8.       std :: stringstream ss;
  9.       ss <<“clicked the button”;
  10.       msg.data = ss.str();
  11.        chatter_publisher.publish(MSG);
  12.        log(Info,std :: string(“I sent:”)+ msg.data);
  13.        ROS :: spinOnce();
  14. }

(4)再打开main_window.hpp(项目列表不显示的直接打开项目包括文件夹拖入qt)与main_window.cpp,其中添加代码(添加部分代码标记为红色// add):

<main_window.hpp>:

  1. pubilc Q_SLOTS:
  2. / ******************************************
  3. **
  4. ********* /
  5. void pub_cmd(); //add

<main_window.cpp>:

  1. / *********************
  2. **
  3. ********************** /
  4. QObject ::connect(ui.sent_cmd,SIGNAL(clicked()),this,SLOT(pub_cmd())); //add
  5. / *********************
  6. **
  7. ********************** /
  8. void MainWindow :: pub_cmd(){// add
  9. qnode.sent_cmd();
  10. }

      (5)最后编译运行,如下图,点击sent_cmd按钮可以看到发送的消息:

下一篇博客会详细讲解怎么在GUI中显示rviz,怎么使用按钮运行ROS启动文件启动。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/477372
推荐阅读
相关标签
  

闽ICP备14008679号