【ROS界面开发】【1-3:编写一个简单的ROS2 Qt Demo】

系列文章目录

【ROS界面开发】【1-1:创建及编译功能包】
【ROS界面开发】【1-2:开发工具的使用】



前言

本文

一、ros通信介绍

可以参考如下博客
ros2通信介绍

二、代码编写

学习了ros之后就理解了ros的数据类型,节点,发布订阅等概念,ros有rclcpp等c++库来对这些概念或规范做具体实现,但是仍需要自己编写一个通信的具体实现。

1.ros通信类

rclcomm.h代码如下(示例):

#ifndef RCLCOMM_H
#define RCLCOMM_H
#include <QObject>
#include <QThread>
#include <iostream>
#include <rclcpp/rclcpp.hpp>
#include "std_msgs/msg/int32.hpp"
class rclcomm:public QThread
{
	//qobjec宏
    Q_OBJECT
public:
    rclcomm();
    void publish_topic(int count);
    void recv_callback(const std_msgs::msg::Int32::SharedPtr msg);
protected:
    void run();
private:
    rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr _publisher;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr _subscription;
    std::shared_ptr<rclcpp::Node> node;
signals:
    void emitTopicData(QString);
};
#endif // RCLCOMM_H

rclcomm.c

#include "rclcomm.h"
rclcomm::rclcomm()  {
	//初始化参数
    int argc=0;
    char **argv=NULL;
    //初始化
    rclcpp::init(argc,argv);
    //节点创建
    node=rclcpp::Node::make_shared("ros2_qt_demo");
    //发布者创建
    _publisher = node->create_publisher<std_msgs::msg::Int32>("ros2_qt_demo_publish", 10);
    //订阅者创建
    _subscription = node->create_subscription<std_msgs::msg::Int32>("ros2_qt_demo_publish", 10,std::bind(&rclcomm::recv_callback,this,std::placeholders::_1));
    this->start();
  }
  //发布者运行
void rclcomm::run(){
    //20HZ
    std_msgs::msg::Int32 pub_msg;
    pub_msg.data=0;
    rclcpp::WallRate loop_rate(1);
    while (rclcpp::ok())
    {
        pub_msg.data++;
        _publisher->publish(pub_msg);
        rclcpp::spin_some(node);
        loop_rate.sleep();
    }
    rclcpp::shutdown();
}
//回调函数
void rclcomm::recv_callback(const std_msgs::msg::Int32::SharedPtr msg){
    //  RCLCPP_INFO(node->get_logger(), "I heard: '%d'", msg->data);
    emitTopicData("I head from ros2_qt_demo_publish:"+QString::fromStdString(std::to_string(msg->data)));
}

2.窗口

窗口类头文件其实可以根据ui文件自动生成,这是qtuic等qt工具的功劳。

ui_mainwindow.h

/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.12.8
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralwidget;
    QLabel *label;
    QLabel *label_2;
    QLabel *label_3;
    QMenuBar *menubar;
    QStatusBar *statusbar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(800, 600);
        centralwidget = new QWidget(MainWindow);
        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
        label = new QLabel(centralwidget);
        label->setObjectName(QString::fromUtf8("label"));
        label->setGeometry(QRect(10, 10, 341, 291));
        label_2 = new QLabel(centralwidget);
        label_2->setObjectName(QString::fromUtf8("label_2"));
        label_2->setGeometry(QRect(10, 320, 291, 21));
        label_3 = new QLabel(centralwidget);
        label_3->setObjectName(QString::fromUtf8("label_3"));
        label_3->setGeometry(QRect(10, 360, 291, 21));
        MainWindow->setCentralWidget(centralwidget);
        menubar = new QMenuBar(MainWindow);
        menubar->setObjectName(QString::fromUtf8("menubar"));
        menubar->setGeometry(QRect(0, 0, 800, 28));
        MainWindow->setMenuBar(menubar);
        statusbar = new QStatusBar(MainWindow);
        statusbar->setObjectName(QString::fromUtf8("statusbar"));
        MainWindow->setStatusBar(statusbar);

        retranslateUi(MainWindow);

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr));
        label->setText(QString());
        label_2->setText(QApplication::translate("MainWindow", "Hello ROS2!", nullptr));
        label_3->setText(QApplication::translate("MainWindow", "This is a demo for ROS2 Qt App", nullptr));
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

ui_mainwinodw.c


#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QImage img;
    img.load(":/icon/images/foxy.jpg");
    img.scaled(ui->label->width(),ui->label->height());
    ui->label->setPixmap(QPixmap::fromImage(img).scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
    commNode=new rclcomm();
    connect(commNode,SIGNAL(emitTopicData(QString)),this,SLOT(updateTopicInfo(QString)));
}
void MainWindow::updateTopicInfo(QString data){
    ui->label_4->clear();
    ui->label_4->setText(data);
}
MainWindow::~MainWindow()
{
    delete ui;
}


编写mainwindow的时候难免需要展示图片,这个时候加载图片可以使用qt的qrc文件来导入图片
这里讲一下怎么使用资源文件
在ros2_qt_demo文件夹右键add new添加资源文件
按下图方式选中 Qt Resource File
在这里插入图片描述
将资源文件命名为image
然后讲生成路径放在resource目录下
重新cmake后就会出现
在这里插入图片描述
在resource文件右键add with打开编辑窗口
在这里插入图片描述
在resource文件夹下再新建一个存放图片的文件夹,然后再这个编辑器选择add files将其添加进去
此处Add Prefix是添加前缀,上图添加了icon前缀用来跟其他类型图片做区分.qrc文件能够将其他格式图片转化为二进制格式跟源码一起打包使用时直接复制资源路径即可。


总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文简单讲解了rosqtdemo各个软件模块的作用和写法,经过三节课的学习应该可以自行搭建一个demo工程。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值