文章目录
- 前言
- 一、创建自定义进程
- 二、自定义UORB消息
- 三、UORB消息的订阅与发布
前言
一个人可以走的更快,一群人才能走的更远,交流学习加qq:2096723956
更多保姆级PX4+ROS学习视频:https://b23.tv/ZeUDKqy
分享知识,传递正能量,如有疏漏或不当之处,恳请指出.
固件版本:PX4 1.11.3
本文主要介绍利用PX4进行二次开发所需的基础知识,磨刀不误砍柴工,掌握这些知识是进行二次开发的前提.
一、创建自定义进程
创建代码文件夹
在src/modules文件夹下创建存放代码的文件夹(也可以在其他文件夹下创建,不同的文件夹下写CMakeLists.txt文件时要区分)
我这里创建了一个01text文件夹
具体内容如下,包含一个头文件,一个cpp文件和一个CMakeLists.txt文件.
我这里直接用的是PX4中自带的模板文件
复制到src/modules文件夹下
编写CMakeLists.txt文件
PX4采用跨平台的编译工具CMake编译固件,CMakeList文件是CMake的配置文件,分别配置了文件名、主函数名、源文件名等信息。文件内容如下:
px4_add_module(
添加文件夹名字为01test
MODULE modules__01test
添加主函数名字为module,主函数名不能和其他主函数名重名
MAIN module
添加文件夹中的.cpp文件
SRCS
module.cpp
添加依赖
DEPENDS
modules__uORB
)
为了让新添加的应用程序编译进固件中,还要修改编译脚本,编译脚本在boards文件夹下,以PX4 fmu-v5为例,打开default.cmake
在MODULES下面添加需要编译的文件夹名01test.
添加完后即可将创建的应用程序软件编译到PX4固件中,在Firmware目录下打开终端,执行make px4_fmu-v5_default upload即可将固件编译并通过USB下载到飞控中。下载完成后将飞控连接到地面站,在MAVLink Console页面的终端中,输入help,可以找到module,说明代码已经编译到固件中.
二、自定义UORB消息
1.创建msg文件
PX4中所有的UORB消息都有一个msg文件,该文件存放在msg文件夹下,如果要添加自定义UORB消息,首先需要在msg文件夹下创建msg文件,这里手动创建一个a01_test.msg,如下:
msg文件中包含一个时间戳(时间戳不可省略)以及消息成员的定义,具体内容如下
uint64 timestamp # time since system start (microseconds)
uint32 a
bool b
2.将msg文件添加到CMakeLists.txt文件中
创建完msg文件后,还要将文件名添加到msg/CMakeLists.txt文件中。这样才能自动生成所需的C/C++代码。
文件位置:
添加如下:
添加完后编译固件,可以看到生成了消息头文件(执行不同的编译脚本,头文件的位置也不一样).
头文件内容如下:
三、UORB消息的订阅与发布
在编写订阅发布程序之前,先简单介绍一下module.cpp的程序执行流程,首先在执行module_main
函数,在该函数中调用了main
函数.
在main
函数中,如果执行start,也就是是执行module start
时,会进入到start_command_base
中执行.
在start_command_base
中执行了task_spawn
在task_spawn中创建了一个任务,任务从run_trampoline
开始执行.
在run_trampoline
中调用了instantiate接口的run()函数.
而instantiate指向Module类
所以调用了如下函数
该函数中有一个While大循环,我们后面就在这个循环里面实现订阅发布就可以了.
第一步:添加头文件
主要是UORB消息头文件和订阅发布接口的头文件
第二步:在头文件中定义订阅发布接口
定义为私有类型
a01_test_s _sub{};
a01_test_s _pub{};
// Subscriptions
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
uORB::Subscription _a01_test_sub{ORB_ID(a01_test)};
// Publications
uORB::Publication<a01_test_s> _a01_test_pub{ORB_ID(a01_test)};
第三步:订阅发布
在run函数中编写如下代码:
void Module::run()
{
while大循环
while (!should_exit()) {
发布递增数据
_pub.a++;
_a01_test_pub.publish(_pub);
打印发布数据
PX4_INFO("pub=%d",_pub.a);
订阅发布数据
_a01_test_sub.copy(&_sub);
打印订阅数据
PX4_INFO("sub=%d",_sub.a);
睡眠0.1秒
usleep(100000);
}
}
我这里是在同一个进程中进行发布订阅的,在不同的进程中发布订阅是一样的.
测试
将程序编译下载到飞控,在地面站终端中输入
module start
可以看到能正确打印发布订阅的数据.