目录
一.在px4中添加新的Topic
在px4中是通过uorb进行消息的传递,通过根目录下的msg文件可以添加自定义的消息,然后在msg下CmakeLists.txt中加入新添加msg文件名,就可以编译生成新的结构体消息,用于在uorb中进行发布和订阅。
这个在px4官网已经给出了方法:
二、px4生成msg生成的结构体优势
有同学肯定会问,那我为什么还要移植px4的生成消息的功能,自己写消息结构体不就行了。
这个问题,只要研究过uorb消息的同学就会发现这套机制的优势:
一.px4通过msg生成的结构体会对结构体参数进行排序,是经过字节对齐后最节约内存空间的排布(这一块不懂得可以搜索结构体字节对齐补一下知识)。
eg: 原始的结构体:实际数据长度20, 默认占内存大小为32
(timestamp8个字节占满一个最小单元,armed 一个字节又占一个单元, 第三行是4个字节得数组又会新起一个单元,第四行及往下都是一个字节共7个字节凑一个最小单元,这样4*8就32个字节)
px4排序后生成的结构体:占24个字节 后面有4个字节的填充
这样一个自动排序去解决内存空间得工具岂不是省老大劲了,当然又产生了新得问题,那生成多出来得填充不是干扰了赋值。下面就是第二点优势:
二。在生成topic头文件得同时也会生成一个cpp文件
在其中会有一个关于消息结构体描述得meta对象
constexpr char __orb_actuator_armed_fields[] = "uint64_t timestamp;uint32_t armed_time_ms;bool armed;bool prearmed;bool ready_to_arm;bool lockdown;bool manual_lockdown;bool force_failsafe;bool in_esc_calibration_mode;bool soft_stop;uint8_t[4] _padding0;";
ORB_DEFINE(actuator_armed, struct actuator_armed_s, 20, __orb_actuator_armed_fields, static_cast<uint8_t>(ORB_ID::actuator_armed));
原型在uorb.h定义得如下:
struct orb_metadata {
const char *o_name; /**< unique object name */
const uint16_t o_size; /**< object size */
const uint16_t o_size_no_padding; /**< 对象大小,末尾没有填充\0(用于记录器)*/
const char *o_fields; /**<分号分隔的字段列表(带类型)) */
uint8_t o_id; /**< ORB_ID enum */
};
这个对象记录 结构体名称o_name,大小o_size,去掉填充的大小o_size_no_padding,还有结构体内参得字符串描述o_fields,以及msg得id
每个消息对应都有一个这个meta对象,那我们拷贝结构体消息时候只需要获取此消息meta中o_size_no_padding,
并且会生成中会有一个uORBTopic文件,将所有消息的meta放入一个列表
const constexpr struct orb_metadata *const uorb_topics_list[ORB_TOPICS_COUNT] = {
中并提供查询的接口
extern const struct orb_metadata *const *orb_get_topics() __EXPORT;
const struct orb_metadata *get_orb_meta(ORB_ID id);
拿到这些数据就可以实现很多想法。
三、msg生成工具及移植方法
查看msg下的CmakeLists.txt,
就可以看到msg实际调用目录下python工具
其中templates是模板,只要修改模板中样式就会对应将生成.h和.cpp文件内容发生变化,要从px4中移植出来就将px4底层依赖项给屏蔽掉就完成了