一、话题通信最佳实践
完成工程架构设计
1、需求:
1)通过这个小工具可以看到系统的实时状态信息,包括记录信息的时间、主机名称、CPU使用率、内存使用率、内存总大小、剩余内存、网络接收数据量和网络发送数据量;
2)要有一个简单的界面,可以将系统信息显示出来;
3)要能在局域网内其他主机上查看数据。
2、分析:
1)要能获取系统状态信息;python库psutils;
2)要有一个展示界面;Qt;
3)要能共享数据,ros2话题;
4)分工合作:
C++负责显示节点(/sys_status_display)
python负责系统状态信息的发布节点(/sys_status_pub)
通过话题来发布(/sys_status),C++来订阅,订阅到话题之后显示到界面。
每个话题都有对应的接口类型,ros2已有的接口并没有满足这个需求的,所以我们需要自己来定义一个新的接口。
3、自定义通信接口
没有完全符合需求的接口,自己定义一个。
确定了系统中,每个节点的功能及节点的关系之后,整个工程结构就算确定下来了。每个话题都会有自己对应的接口类型。
二、自定义通信接口
1、创建工作空间
2、创建功能包
1)创建C++功能包:
ros2 pkg create status_interfaces --dependencies builtin_interfaces rosidl_default_generators --license Apache-2.0
c++功能包的创建默认是类型是CMake,因此创建时可以不添加类型属性。
builtin_interfaces:时间戳;
rosidl_default_generators :将自定义的信息文件转换成C++、python的源码;
3、编写接口
1)SystemStatus.msg
状态信息接口(消息接口定义),话题消息接口的后缀是.msg,和自己的文件夹的名字msg保持一致。
根据需求,确定我们SystemStatus.msg需要记录的内容
A、时间戳
builtin_interfaces/Time stamp #记录时间戳
终端查看命令:ros2 interface list | grep Time
注意:如果你的依赖地址,里面有和你的包重名的,可以在引入依赖的时候,去掉重名包(这是规定,没有为什么)。比如这里,我的消息接口包名是"msg",而我的里面的文件SystemStatus.msg里面要用的是Time这个依赖,我们查到他的包是builtin_interfaces/msg/Time,因此在引用Time的时候可以直接builtin_interfaces/Time。
B、系统名称
string:ros2系统自带的基础数据类型;bool、byte、char、float32、float64、int8、unit8、int32、unit32、int64、unit64、string;
C、CPU使用率
D、内存使用率
E、内存总量
F、剩余有效内存
G、网络发送数据总量
H、网络接收数据总量
2)转换SystemStatus.msg
A、修改CMakeLists.txt
在CMakeLists.txt中有 rosidl_default_generators 依赖,主要是用于添加一些CMake指令,CMake指令就是用于产生功能包的这样的CMake指令。
# cmake函数rosidl_generator_interface(),来自依赖rosidl_default_generators,用于将msg等消息接口定义文件转换成库或者头文件类
#两个参数,${PROJECT_NAME}-工程名,"msg/SystemStatus.msg"消息接口文件相对路径,多个接口直接后面拼;DEPENDENCIES-依赖,就是你消息接口,用到哪些依赖,就添加对应的依赖信息。
B、修改package.xml
添加命令,告诉大家,我当前的这个功能包是包含消息接口的功能包。
<member_of_group>rosidl_interface_packages</member_of_group>
C、
3)
4、构建
记得切换目录再build。
5、查看接口信息
ros2 interface show status_interfaces/msg/SystemStatus
三、系统信息获取与发布
1、系统信息获取与发布
2、实现
1)创建功能包
ros2 pkg create status_publisher --build-type ament_python --dependencies rclpy status_interfaces --license Apache-2.0
2)编写sys_status_pub.py
上一步我们自定义了消息接口,我们可以直接导入使用。
3)启动
A、配置可执行文件
B、启动三部曲
4)查看信息
ros2 topic echo /sys_status
此时查看话题 sys_status ,会发现他说我们自定义的 status_interfaces/msg/SystemStatus 消息接口是无效的。当我们使用ros2 topic list -t去查看话题的时候,你会发现我们的话题‘sys_status ’对应的消息接口就是‘status_interfaces/msg/SystemStatus’,那为什么会这样呢?
因为我们这个终端没有source,默认目录是/opt/ros/humble,即ros2的安装目录。而这个‘status_interfaces/msg/SystemStatus’接口目录在‘topic_ws’目录下‘install’下的‘status_publisher’。因此要改变下环境变量,再去查看。
四、在功能包中使用QT
1、Qt:
Qt:是跨平台的软件设计与开发工具,ros2中大量的工具都使用Qt作为界面的设计工具。
2、实现
1)创建功能包
status_interfaces:自定义的话题接口。
ros2 pkg create status_display --dependencies rclcpp status_interfaces --license Apache-2.0
2)编写
A、编写hello_qt.cpp
3)修改CMakeLists.txt
A、hello_qt.cpp中相关修改
4)启动
A、hello_qt.cpp启动
五、订阅数据并用QT显示
1、订阅数据并用Qt显示
2、修改工作空间配置
在报错的地方,点击黄色小灯,然后选择“includePath”,在弹出的窗口,可以看到c_cpp_properties.json 文件,这个就是我们要修改的配置文件,如果找不到,可以手动编写。
添加后,记得保存,可以看到hello_qt.cpp里面就不会再报错了,后续使用时,会有代码提示了。
ros2相关成员路径:"/opt/ros/humble/include/**"
qt5路径:"/usr/include/x86_64-linux-gnu/qt5/**"
3、实现:
1)编写:
2)main函数讲解:
在main函数中,当我们运行sys_status_display节点的时候,会阻塞我们当前的线程,因此我们的app.exec();是无法继续执行的。同样,先执行QApplication也会阻塞当前线程,因此我们要开线程,分开运行。
3)修改CMakeLists.txt
4)启动:
5)关于中文出不来
我用的是本地的WSL,因为Linux默认只有英文字体,遇到中文字符时找不到对应的字形,这时给ubuntu安装中文字体即可。
步骤:
打开自己的ubuntu,在终端输入
sudo apt update
然后:
sudo apt install fonts-wqy-zenhei fonts-wqy-microhei -y
记得刷新:fc-cache -fv
然后重启节点: