ROS项目开发实战(三)——使用QT进行ROS的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-  -qt-ros // distro是ros版本,例如LZ的就是ros-hydro-qt-ros

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

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第1张图片

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第2张图片

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第3张图片

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第4张图片

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第5张图片

 

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

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第6张图片

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第7张图片

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

#include 
#include  //add

/ ******************* ****************************
**
************************************************** *************************** /
class QNode:public QThread {
    Q_OBJECT
public:
    QStringListModel * loggingModel_sub(){return&logging_model_sub; } //add
    void log_sub(const LogLevel&level,const std :: string&msg); //add
    void Callback(const std_msgs :: StringConstPtr&submsg); //add

Q_SIGNALS:
    void loggingUpdated_sub(); //add

private:    ros :: Subscriber chatter_subscriber; //add
    QStringListModel logging_model_sub; //add
};

 

/ ******************* ****************************
**
************************************************** *************************** /
bool QNode :: init(){
//在这里添加你的ros通讯。
chatter_publisher = n.advertise (“chatter”,1000);

chatter_subscriber = n.subscribe( “chatter”,1000,&QNode ::Callback,this); //加

}


bool QNode :: init(const std :: string&master_url,const std :: string&host_url){
//在这里添加你的ros通讯。
chatter_publisher = n.advertise (“chatter”,1000);

chatter_subscriber = n.subscribe( “chatter”,1000,&QNode ::Callback,this); //add

}

void QNode :: log_sub(const LogLevel&level,const std :: string&msg){// add
    logging_model_sub.insertRows(logging_model_sub.rowCount(),1);
    std :: stringstream logging_model_msg;
    开关(级别){
        case(Debug):{
                ROS_DEBUG_STREAM(MSG);
                logging_model_msg <<“[DEBUG] [”<< ros :: Time :: now()<<“]:”<< msg;
                break;
        }
        case(Info):{
                ROS_INFO_STREAM(MSG);
                logging_model_msg <<“[INFO] [”<< ros :: Time :: now()<<“]:”<< msg;
                break;
        }
        case(Warn):{
                ROS_WARN_STREAM(MSG);
                logging_model_msg <<“[INFO] [”<< ros :: Time :: now()<<“]:”<< msg;
                break;
        }
        case(Error):{
                ROS_ERROR_STREAM(MSG);
                logging_model_msg <<“[ERROR] [”<< ros :: Time :: now()<<“]:”<< msg;
                break;
        }
        case(Fatal):{
                ROS_FATAL_STREAM(MSG);
                logging_model_msg <<“[FATAL] [”<< ros :: Time :: now()<<“]:”<< msg;
                break;
        }
    }
    QVariant new_row(QString(logging_model_msg.str().c_str()));
    logging_model_sub.setData(logging_model_sub.index(logging_model_sub.rowCount() -  1),NEW_ROW);
    Q_EMIT loggingUpdated_sub(); //用于重新调整滚动条
}


void QNode :: Callback(const std_msgs :: StringConstPtr&submsg)// add
{
    log_sub(Info,std :: string(“Success sub:”)+ submsg-> data.c_str());
}

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

 

pubilc Q_SLOTS:
/ ******************************************
**
********* /
    void updateLoggingView_sub(); //add

/ *********************
**
********************** /
ui.view_logging_sub->setModel(qnode.loggingModel_sub()); //add
QObject :: connect(&qnode,SIGNAL(loggingUpdated_sub()),this,SLOT(updateLoggingView_sub())); //add

/ ******************* ****************************
**
************************************************** *************************** /
void MainWindow :: updateLoggingView_sub(){// add
        ui.view_logging_sub-> scrollToBottom();
}

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第8张图片

 

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

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

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第9张图片

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

class QNode:public QThread {
    Q_OBJECT
pubilc:
/ *********************
**
********************** /
void sent_cmd(); //add

/ ******************* ****************************
**实施
**********************************
void QNode :: sent_cmd()// add
{
 if(ros :: ok()){
      std_msgs :: String msg;
      std :: stringstream ss;
      ss <<“clicked the button”;
      msg.data = ss.str();
       chatter_publisher.publish(MSG);
       log(Info,std :: string(“I sent:”)+ msg.data);
       ROS :: spinOnce();
}

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

pubilc Q_SLOTS:
/ ******************************************
**
********* /
void pub_cmd(); //add

/ *********************
**
********************** /
QObject ::connect(ui.sent_cmd,SIGNAL(clicked()),this,SLOT(pub_cmd())); //add


/ *********************
** 
********************** /
void MainWindow :: pub_cmd(){// add
qnode.sent_cmd();
}

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

ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)_第10张图片

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

你可能感兴趣的:(QT,ROS,qt,ROS,ros-gui)