本文参考官网:RTPS/DDS Interface: PX4-Fast RTPS(DDS) Bridge | PX4 User Guide
版本说明:
PX4固件版本: 1.13.0d
自驾仪:PIXHAWK 4
宿主机操作系统:Ubuntu 20.04
1. 什么是Fast DDS中间件 ?
Fast DDS是eProsima公司(一个位于马德里的西班牙公司)的一个开源的中间件产品( Apache License),是OMG组织制定的数据分发服务规范(DDS)和实时发布订阅(RTPS)协议的C++实现。
Fast DDS以前叫Fast RTPS,RTPS是Realtime Publish Subscribe的缩写 。
在PX4系统中,Fast DDS为自动驾驶仪建立了实时的发布订阅接口,可以使各种自动驾驶仪内部组件与offboard计算机(或者与offboard计算机有连接的计算机)中的 Fast DDS应用程序之间实时交换PX4中的uORB消息。
2. MicroRPTS Bridge (桥)
micrortps_bridge在PX4与DDS应用程序之间交换信息。如图所示,uORB消息在PX4这一端,DDS消息在offboard计算机这一端。这个桥将PX4中内置的订阅发布机制-uORB与offboard计算机中运行的DDS订阅发布机制连接起来。
在PX4系统中,micrortps_bridge由micrortps_client、micrortps_agent以及一组代码生成工具组成;桥的两端,一端是自驾仪中的PX4,另一端是offboard计算机中的DDS应用程序,DDS应用程序可以通过这个桥控制安装有PX4的自驾仪。
PX4传统上,offboard计算机通过mavlink通讯协议+mavlink命令与PX4自驾仪交互,有了这个桥,offboard计算机就可以通过micrortps_bridge+PX4话题与PX4自驾仪进行交互。代替mavlink?PX4官网否认,不过通过Fast DDS与PX4自驾仪通讯确实不需要mavlink。
2.1 MicroRTPS Client(客户端)
micrortps_client作为一个后台进程驻留在PX4系统中。它订阅PX4组件发布的uORB话题,通过串口或者UDP口将由此话题更新而产生的信息发送给micrortps_agent,另外它也接收micrortps_agent发送给它的消息,并转换成uORB消息发布给PX4系统。
2.2 MicroRTPS Agent(代理)
micrortps_agent作为一个后台进程运行在offboard计算机中。micrortps_agent监视来自micrortps_client的uORB更新消息,然后把这些消息通过RTPS协议再发布给DDS应用程序,另外,micrortps_agent订阅来自其他DDS应用程序的DDS消息,并且转送给micrortps_client。
2.3 MicroRTPS代理/客户端之间的通讯
micrortps_agent和micrortps_client之间通过串行线或者UDP网络相连,uORB消息在被传输之前被CDR序列化编码(CDR serialization提供了一种在不同平台之间传送数据的通用格式)。
micrortps_agent与任何DDS应用之间通过UDP连接,有可能在一台机器上,也有可能在不同机器之间。典型的配置是micrortps_agent与DDS应用在同一个系统中(比如:一个开发计算机,Linux协同计算机,或者是一个计算机单板机),这个系统与micrortps_client相连,可以通过Wifi或者USB串口。
2.4 核心库和代码生成工具
这节请参考官网文章。
注:以下描述的安装编译过程是在Raspberry Pi 3B+(32G)上进行的,是源代码级安装。根据以前在x86笔记本上的安装经验,应该没什么区别。
PX4的microRTPS桥相关的客户端(micrortps_client)、代理(micrortps_agent)的源代码都在构建PX4目标代码时自动生成了,然后需要把micrortps_agent(代理)的源代码拿到offboard计算机中编译运行。在此之前,必须安装两种软件:Fast DDS和Fast-RTPS-Gen。Fast DDS包含了microRTPS桥相关代码需要链接的核心库以及相关的工具软件,Fast-RTPS-Gen是IDL代码生成工具。
2.4.1 安装Fast DDS
Fast DDS包含两种核心库,fastrtps和fastcdr,前者是microRTPS桥的核心功能代码的链接库,生成的microRTPS_agent和microRTPS_client源代码,在编译后需要与这个库链接。后者也是一个核心库,这个库实现了microRTPS_agent和microRTPS_client之间数据传输之前和之后编码与解码的过程,Fast DDS还包含实用程序fastdds,提供了Fast DDS的命令行接口,用于Fast DDS相关的维护和配置任务。在编译安装Fast DDS之前,必须先安装Foonathan memory软件包,Foonathan memory是一个C++基于对象的内存管理软件。
先克隆源代码:
git clone https://github.com/eProsima/foonathan_memory_vendor.git
cd foonathan_memory_vendor
mkdir build && cd build
再编译
cmake ..
sudo
cmake --build . --target install
(慢啊,中间过程需要克隆
foo-mem-ext
)
注:最后一步,需要
sudo cmake
,因为
cmake
在安装过程的操作
/
usr/local/
bin
目录的环节需要特权。
先克隆源代码
$ git clone --recursive https://github.com/eProsima/Fast-DDS.git -b v2.0.2 ~/FastDDS-2.0.2
$ cd ~/FastDDS-2.0.2
$ mkdir build && cd build
再编译
$ cmake -DTHIRDPARTY=ON -DSECURITY=ON ..
$ make -j$(nproc --all)
$ sudo make install
make编译比较慢,耐心等待,可能需要10分钟以上。
编译好的FastDDS核心库位于/usr/local/lib目录中,相关的实用程序被放在/usr/local/bin目录中,目前Fast DDS的版本是2.0.2。
2.4.2 安装Fast-RTPS-Gen
Fast-RTPS-Gen是一个java程序,它根据IDL定义的数据类型生成Fast RTPS(DDS)相关的代码,程序名:fastrtpsgen。
在编译安装fastrtpsgen之前,需要先安装Gradle构建工具和java,jdk 11(要求版本要大于等于11)的安装不在此赘述。
Gradle是一个构建工具,官网说不要安装7.0以上版本,最好是6.3,用sdkman安装最方便。sdkman是java开发工具的管理软件,安装sdkman时,要保证计算机联网。
需要先安装
unzip
和
zip:
sudo apt
install unzip
sudo apt
install zip
然后执行安装sdkman的命令:
curl -s "https://get.sdkman.io" | bash
这样就安装好
sdkman
了。
打开另外一个终端:
source "/home/fengwj/.sdkman/bin/sdkman-init.sh"
现在可以用
sdkman
安装
gradle
了,注意要的是
6.3
版。
sdk install gradle
6
.
3
这个过程也挺长。
下载、编译、安装,一气呵成。
git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git -b v1.0.4 ~/Fast-RTPS-Gen \
&& cd ~/Fast-RTPS-Gen \
&& gradle assemble \
&& sudo env "PATH=$PATH" gradle install
编译好的
Fast-RTPS-Gen
被放在
/
usr/local/bin
目录下,程序名:
fastrtpsgen
。目前的版本是
1.0.4
。
3
.
构建并运行一个
Fast DDS
应用程序
3
.1
构建
micrortps_bridge
在构建具备
Fast DDS
中间件的
PX4
的目标程序时,如果是真实硬件
Pixhawk 4
,则构建命令是
make px4_fmu-v5_rtps
,如果是仿真环境,构建命令是
make px4_sitl_rtps
。
在构建
PX4
的目标程序的过程中生成了
micrortps_client
以及
micrortps_agent
的源程序。源程序分别放在
build/<target-platform>/src/modules/micrortps_bridge
目录下的
micrortps_
client
和
micrortps_agent
子目录下。其中,<target-platform>可以是px4_sitl_rtps(软件仿真环境),也可以是px4_fmu-v5_rtps(pixhawk的固件)。
另外,msg/tools/
urtps_bridge_topics.yaml文件定义了micrortps_bridge需要处理哪些PX4 uorb话题,编译过程根据这个文件生成了对应这些PX4 uorb话题的idl接口定义文件,这些idl文件被保存在micrortps_agent/idl子目录下,每个PX4 uorb话题对应一个idl文件。
3.1.1. 运行micrortps_client
mi
crortps client
不需要用手工构建
,
PX4
在编译生成目标程序时就已经生成了它的
二进制程序
px
4_micrortps_client
,并保存在
build/bin
中
,这个程序可以
在
PX
4
的
真实硬件环境中的
Nuttx Shell
中运行
,
也可以在仿真环境中的
pxh Shell
中运行。比如:
pxh>micrortps_client start -t UDP
。
注意:运行
gazebo
或者
jmavsim
仿真程序时
(比如:
make px4_sitl_rtps gazebo)
,micrortps_client在
PX4 1.13版固件下
是自动启动,
1.12
版固件下则需要手工启动。
3.1.2 编译并运行micrortps_agent
micrortps_agent
的源代码虽然在构建
PX
4
的目标程序时是自动生成出来的
,但是
没有生成它的二进制
,因为
micrortps_
agent
通常是运行在
offboard
计算机中的,需要把源程序拿到
offboard
计算机中编译
。
micrortps_agent
与
仿真环境运行在同一台计算机
(宿主机,比如我的x86笔记本计算机)时
,编译命令如下
:
cd build/<target-platform>/src/modules/micrortps_bridge/micrortps_agent
mkdir build && cd build
cmake ..
make
运行命令:
$micrortps_agent -t UDP
这个程序在屏幕上列出了所有Fast DDS应用程序可以向PX4发布的话题(因为micrortps_agent中有subscriber在等待发布)以及能够从PX4订阅的话题(因为micrortps_agent中有publisher在等待订阅)。
3
.2
构建并运行
Fast DDS
应用程序
一旦
micrortps_
client
和
micrortps_agent
运行起来,并连接正常,
F
ast DDS
的应用程序就可以通过
RTPS
协议订阅和发布
PX
4
的
uorb
话题相关的数据。
Fast DDS
应用程序可以用
fastrtpsgen
生成
,生成出的程序可以订阅或发布某个PX4的话题。
以下是生成、编译、运行订阅并打印输出
sensor_combined
话题相关数据的过程
:
cd /path/to/PX4/PX4-Autopilot
cd build/px4_sitl_rtps/src/modules/micrortps_bridge
mkdir micrortps_listener
cd micrortps_listener
fastrtpsgen -example x64Linux2.6gcc ../micrortps_agent/idl/sensor_combined.idl
生成出的程序需要在sensor_combinedSubscriber.cxx中增加打印输出sensor_combined话题数据的语句:
// Print your structure data here.
++n_msg;
std::cout << "Sample received, count=" << n_msg << std::endl;
// gyro_rad
std::cout << "gyro_rad: " << st.gyro_rad().at(0);
std::cout << ", " << st.gyro_rad().at(1);
std::cout << ", " << st.gyro_rad().at(2) << std::endl;
std::cout << "gyro_integral_dt: " << st.gyro_integral_dt_() << std::endl;
// accelerometer
std::cout << "accelerometer_timestamp_relative: " << st.accelerometer_timestamp_relative_() << std::endl;
std::cout << "accelerometer_m_s2: " << st.accelerometer_m_s2().at(0);
std::cout << ", " << st.accelerometer_m_s2().at(1);
std::cout << ", " << st.accelerometer_m_s2().at(2) << std::endl;
std::cout << "accelerometer_integral_dt: " << st.accelerometer_integral_dt_() << std::endl;
然后用以下命令编译
,执行:
make -f makefile_x64Linux2.6gcc
bin/*/sensor_combinedPublisherSubscriber subscriber
至此,sensor_combined话题的数据应该打印在屏幕上。
3.3.
关于
yaml
文件
micrortps_
client
和
micrortps_agent
,一个是客户端一个是服务器端,
两边交换的信息是依据
PX4
的
uorb
话题而定义的,在编译
PX
4
的
RTPS
目标程序时,
RTPS
能处理的
uorb
话题在
yaml文件
中定义,通过yaml产生一组对应的
IDL
接口文件
(
被保存在目录
build/px4_sitl_rtps/src/modules/micrortps_bridge/micrortps_agent/idl
下
)
,然后编译过程再根据这组
IDL
接口文件生成
micro
rtps_client以及micrortps_agent
的源代码。
在
micrortps
环境下
,
哪些话题可以交换?是接收还是发送?在PX4的1.12版本的uorb_rtps_message_ids.yaml()中定义
,而1.13版本的文件名改为urtps_bridge_topics.yaml。名字改了,格式也稍有变化,比如
相对于1.12
版本格式,
1.13
版本没有
id这个域了,下面是1.13版本的格式
示例1
msg: sensor_combined
send: true
代表
sensor_combined
这个话题需要有一个
idl
定义,另外需要生成
Publish
这个话题的代码,这样Fast DDS应用程序就可以从PX4订阅这个话题的数据了。
示例2
msg: vehicle_command
receive: true
代表vehicle_command这个话题需要一个
idl
定义,另外需要生成
Subscribe
这个话题的代码,这样Fast DDS应用程序就可以向PX4发布这个话题的数据。
比较一下PX4 msg话题和urtps_bridge_topics.yaml列出的话题,可以看出,PX
4
处理的uORB话题有
200
多个,而
RTPS
处理的话题是
31
个。
注:
1.13.0d
的
yaml
文件格式已经与
1.12.0d
不一样了,取消了
id
这个域,yaml的文件名改成了urtps_bridge_topics.yaml,
yaml文件
只存放
RTPS
中间件处理的
uORB
消息
,没有需要接收或发送的
uORB话题
就不放在这个
yaml
文件中了。
id
在程序内部还是有的,但是id的值由
uorb_rtps_classifier.py
根据
msg
在
yaml
中的顺序产生。
-------来自1.13.0d版本中msg/tools/urtps_bridge_topics.yaml文件的注释:
该文件映射了microRTPS桥上要使用的所有话题。如果想要添加一个新话题时,应该将其添加到这个文件中,并将其标记出“send”或“receive”。也可以添加alias(别名)/多话题消息(即在uORB消息的“#TOPICS”上找到的消息),但是需要额外的条目(“base”)来定义基本消息。
重要提示:microRTPS桥上发送的消息的ID是根据该文件中消息的顺序生成的。为了保持一致性和向后兼容性,建议将希望在microRTPS桥中传输的任何新消息添加到列表末尾。处于列表中间的任何更改(添加、删除、替换)也会更改当前的消息ID,这可能会导致与以前的PX4版本(引入或存在此格式的列表)兼容。
当与ROS2一起使用时,对该文件的任何更新都应该镜像到microRTPS桥的两侧(即PX4和PX4_ros_com)。这可以通过“msg/tools/uorb_to_ros_urtps_topics.py轻松实现。py脚本重新生成的文件可以放在ROS2的“px4_ros_com/templates/”目录下。
如果不与ROS2一起使用,而是“裸”着使用microRTPS中间件时,就不存在“镜像”这个动作,因为micrortps_agent(生成在build/<px4_target>/src/modules/micrortps_bridge/目录下)会直接使用msg/tools/下的yaml文件。
-------------
可以用以下命令重新生成具有PascalCase的yaml话题文件:
uorb_to_ros_urtps_topics.py -i urtps_bridge_topics.yaml -o a.yaml
然后把a.yaml拷贝到ROS2的目录中(px4_ros_com/templates)。用个临时名a.yaml是因为在安装ROS2的时候,ROS2的templates目录中已经有一个urtps_bridge_topics.yaml文件,你需要斟酌是不是覆盖它。覆盖它就可以使microRTPS桥两端具有相同的话题处理能力。
3.4.
官网上的几个小问题
bin/*/sensor_combined_PublisherSubscriber subscriber
,名字不对了
,应该是
bin/*/sensor_combinedPublisherSubscriber subscriber
。
官网上贴出的源程序
,
init
()函数中
订阅话题名字是“
fmu/sensor_combined/out
”
,但是
1.12.0d
版,生成程序中
init
()函数中订阅话题名字
是
“
sensor_combinedPubSubTopic“
。
官网上贴出的源程序
void sensor_combinedSubscriber::SubListener::onNewDataMessage(Subscriber* sub)
函数打印话题
sensor_combined
中的内容
,但是
这个话题与实际
1.12.0d
版本固件中提供的话题不太一样了,
1.12
中的
sensor_combined
只有
gyro
(
罗盘
)
和
accelerometer
(
加速度
)
计的内容
,但
不包括:
magnetometer
(地磁计)
和
baro
(气压计)
相关内容
。参见文件
PX4-Autopilot/msg/sensor_combined.msg
对话题的定义。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)