欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3 ROS人机交互界面的搭建

程序员文章站 2022-03-04 21:10:52
...

3.1 Qt安装和配置

前提条件,虚拟机运行ROS-melodic和Qt5.9.9。其他版本很容易报错。
安装----- 在http://download.qt.io/archive/qt/下载Qt5(linux对于.run文件这里下载的是Qt5.9.9) ,下载完后在改文件夹打开终端,输入sudo chmod a+x /给安装包赋予权限,之后双击安装,安装时,没有Qt账户的需要注册,然后在安装组件那一步勾选gcc,其他都按照默认的安装(即安装在home目录下)。安装完Qt后设置快捷方式,sudo gedit /usr/bin/qtcreator 打开后输入

#!/bin/sh 
export QT_HOME=/home/用户名xxx/Qt5.9.9/Tools/QtCreator/bin 
$QT_HOME/qtcreator $* 

最后再chmod a+x /usr/bin/qtcreator赋予权限。安装完Qt后再给ROS安装Qt依赖项,输入命令sudo apt-get install ros-melodic-qt-createsudo apt-get install ros-melodic-qt-bulid
配置----- 配置的前题,最好是melodic和Qt5.9.9,其他版本容易失败。在ROS工作空间的src目录下(/catkin_ws/src),新建Qt包catkin_create_qt_pkg qt_demo功能包名 roscpp rospy 个依赖项。创建完成后再工作空间的目录下(/catkin_ws)进行编译,编译无误则无需后面的配置文件更改,编译出现问题的话可以在qt包的CMakeLists.txt文件(/catkin_ws/src/qt_demo/CMakeLists.txt)进行下面的修改:①添加当前目录set(CMAKE_INCLUDE_CURRENT_DIR ON) ②添加Qt库find_package(Qt5 REQUIRED Core Widgets)和set(QT_LIBRARIES Qt5::Widgets) ③注释掉rosbuild_prepare_qt4(QtCore QtGui) ④将相应的QT4的变量改成QT5 ⑤打开include文件下的mainwindows.hpp将头文件QtGUI改成QtWidgets ⑥打开src文件下的mainwindows.cpp把QtGUI换成QtWidgets。
设置完成后,首先打开ROS的工作空间(举例catkin_ws),执行catkin_make先进行编译,没有问题之后,就在这个终端后面输入qtcreator打开Qt,再导入文件,选择工作空间的源文件(/catkin_ws/src/CMakeLists.txt)下的CMakeLists.txt文件,打开时注意build的指向必须指向工作空间的build目录。
个人理解的Qt界面与ROS的关系:
3 ROS人机交互界面的搭建

3.2 Qt-UI的基本操作

在新建项目,选择qt widegets application项目,确定好项目的存放位置一切,其余全部默认即可。
3 ROS人机交互界面的搭建
在ui界面设置的文本其中①处文本可以被源文件的代码给替换掉,②和③处的文本是同一个内容,是对按钮这个参数的命名,在源文件中对这个按钮所要执行的所有操作,都用这个变量名来调用。3 ROS人机交互界面的搭建
3 ROS人机交互界面的搭建

// Headers/mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
//---------------------------------------------
//**************---START---*********************
//---------------------------------------------
public slots:
        void but1_fun(bool);
        void ckb_fun(int);
        void hts_fun(int);
//---------------------------------------------
//**************---END---*********************
//---------------------------------------------
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

// Sources/mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
//---------------------------------------------
//**************---START---*********************
//---------------------------------------------
#include "QDebug"
#include "qtreewidget.h"
#include "qcombobox.h"
//---------------------------------------------
//**************---END---*********************
//---------------------------------------------
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
//---------------------------------------------
//**************---START---*********************
//---------------------------------------------
        //对按键but1进行连接,通过点击的信号,进行回调函数操作
        connect(ui->but1,SIGNAL(clicked(bool)),this,SLOT(but1_fun(bool)));

        //对选项框ckb进行连接,通过状态字的改变,进行回调函数操作
        connect(ui->ckb,SIGNAL(stateChanged(int)),this,SLOT(ckb_fun(int)));

        //对拖拉条hts进行连接,通过值的改变,进行回调函数操作
        ui->hts->setRange(0,100);
        ui->hts->setValue(25);
        ui->lab3->setText("25");
        ui->pgb->setValue(25);
        connect(ui->hts,SIGNAL(valueChanged(int)),this,SLOT(hts_fun(int)));

//对树状条进行连接,先是头标的样式,空格是用来撑住宽度的,也可以换成文字
        ui->tw->setHeaderLabels(QStringList()<<"             "<<"            ");
        //下面两条命令是一组,用来创建下拉菜单,并且命名为top
        QTreeWidgetItem* item=new QTreeWidgetItem(QStringList()<<"top");
        ui->tw->addTopLevelItem(item);
        //下面两条命令是一组,用来创建下拉条top的第一列条目,并命名为next1
        QTreeWidgetItem* item_child1=new QTreeWidgetItem(QStringList()<<"next1");
        item->addChild(item_child1);
        //同理创建了下拉条top下的第二列条目,并命名为next2
        QTreeWidgetItem* item_child2=new QTreeWidgetItem(QStringList()<<"next2");
        item->addChild(item_child2);
        //给第一列条目next1添加了下拉框,并且命名为name,而且是默认选中状态
        QComboBox* box=new QComboBox;
        box->addItem("name");
        box->setEditable(true);
        ui->tw->setItemWidget(item_child1,1,box);
//---------------------------------------------
//**************---END---*********************
//---------------------------------------------

}

//---------------------------------------------
//**************---START---*********************
//---------------------------------------------
void MainWindow::hts_fun(int)
{
    ui->lab3->setText(QString::number(ui->hts->value()));
    ui->pgb->setValue(ui->hts->value());
}


void MainWindow::ckb_fun(int state)
{
    if(state==2)
    {
        ui->lab2->setText("Clicked");
    }
    else
    {
        ui->lab2->setText("NOT CHICKED");
    }
}


void MainWindow::but1_fun(bool)
{
        ui->ckb->setChecked(true);
        ui->lab2->setText("Clicked!");
}
//---------------------------------------------
//**************---END---*********************
//---------------------------------------------
MainWindow::~MainWindow()
{
    delete ui;
}

现在对已经编辑好的qt_demo文件添加跳转窗口的操作。
首先向qt_demo里添加form类文件。并在UI中设计一个pushbutton来执行返回操作。
3 ROS人机交互界面的搭建
在mainwindow.hpp里添加form的头文件,然后定义两个回调函数,来完成qt_demo里的按钮操作,以及相应form里的按钮操作。

// Headers/mainwindow.hpp
…
#include <form.h>public slots:void but2_fun(bool);//qt_demo里的按钮回调操作
        void slot_qt_demo_show();//比较特殊,是给form-ui的按钮的响应函数

在mianwindow.cpp里编写程序。

// mainwindow.cppconnect(ui->but2,SIGNAL(clicked(bool)),this,SLOT(but2_fun(bool)));void MainWindow::but2_fun(bool)
{
    Form* f = new Form;//声明form对象(form是新建的UI class文件名)
    f->show();//显示form的ui界面
    connect(f,SIGNAL(close_and_open()),this,SLOT(slot_qt_demo_show()));//创建连接,如果f收到了close_and_open信号则在this(指代此时的qt_demo)里执行slot_qt_demo_show()的回调操作。
    this->hide();//声明完qt_demo页面隐藏
}

void MainWindow::slot_qt_demo_show()
{
    this->show();
}

在form文件里所要的内容包括一个自定义信号close_and_open()和其按键的回调函数。

// Headers/form.hpppublic slots:
    void slot_pushbutton();
signals:
void close_and_open();
//form.cppconnect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(slot_pushbutton()));void Form::slot_pushbutton()
{
    emit close_and_open();
    this->hide();
}

最终效果:3 ROS人机交互界面的搭建

3.3 Qt与ROS的交互

3.3.1创建节点订阅消息

Step1----- 创建基础的Qt的ros模板(见3.1).
Step2----- 在qnode.hpp文件里添加头文件、订阅者和回调函数。

相关标签: ROS