- 1. 新增自定义uORB消息步骤
- 2. 应用ext_hello_world消息示例
- 3. 编译执行结果
- 4. 参考资料
基于PX4开源软件框架简明简介和PX4模块设计之二:uORB消息代理, 了解了更多关于中间件uORB消息代理作为PX4系统内部消息传递的重要性。
关于新增消息或者消息主题,可以分为PX4代码库内部新增(通常是PX4开源组织在进行维护)和外部新增两种方式。
这里自定义uORB消息主要侧重的是外部新增主题消息,后续将会结合一个示例进行相关应用的Demo。
1. 新增自定义uORB消息步骤- 新增与PX4-Autopilot平行目录PX4-ExternalModule;
- 建立PX4-ExternalModule下相应的msg、src目录;
- 在PX4-ExternalModule的msg目录下新建.msg文件,参考PX4-Autopilot下msg目录下的相关文件;
1 uint64 timestamp # time since system start (microseconds) 2 int8 hello # index of hello variable 3 4 # TOPICS ext_hello_world
- 在PX4-ExternalModule的msg目录下新建CMakeLists.txt文件;
- 在CMakeList.txt文件中添加.msg文件;
34 set(config_msg_list_external 35 ext_hello_world.msg 36 PARENT_SCOPE 37 )
- 在make的时候,框架代码会自动根据上述源文件生成对应的两个C/C++文件;
PX4-Autopilotbuildpx4_sitl_defaultuORBtopicsext_hello_world.h PX4-Autopilotbuildpx4_sitl_defaultmsgtopics_sourcesext_hello_world.cpp
注:自此已经完成新增自定义uORB消息ext_hello_world。
2. 应用ext_hello_world消息示例定义消息的目的主要是为了不同的任务之间进行通信,这里写了一个Demo:两个任务,一个任务publish消息,一个任务subscribe消息;
- 在Demo代码里面包含头文件;
#include
- 使用ORB_ID(ext_hello_world)唯一定位消息主题;
- 使用px4_task_spawn_cmd函数建立两个任务;
- 使用uORB消息处理接口函数Demo应用;
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #define TASK_NAME_CUSTOM_UORB_SUBSCRIBE "orb subscribe" #define TASK_NAME_CUSTOM_UORB_PUBLISH "orb publish" #define TASK_SUBSCRIBE_NUM 8 #define TASK_PUBLISH_NUM 5 __EXPORT int px4_custom_uorb_main(int argc, char *argv[]); int px4_custom_uorb_subscribe(int argc, char *argv[]) { int hello_fd = orb_subscribe(ORB_ID(ext_hello_world)); orb_set_interval(hello_fd, 200); px4_pollfd_struct_t fds[] = { { .fd = hello_fd, .events = POLLIN }, }; int error_counter = 0; for (int i = 0; i < TASK_SUBSCRIBE_NUM; i++) { int poll_ret = px4_poll(fds, 1, 5000); if (poll_ret == 0) { PX4_ERR("Got no data within a second"); } else if (poll_ret < 0) { if (error_counter < 10 || error_counter % 50 == 0) { PX4_ERR("ERROR return value from poll(): %d", poll_ret); } error_counter++; } else { if (fds[0].revents & POLLIN) { struct ext_hello_world_s tmp; orb_copy(ORB_ID(ext_hello_world), hello_fd, &tmp); PX4_INFO("Hello world(subscribe):t%d", tmp.hello); } } } PX4_INFO("px4_custom_uorb_subscribe exiting"); return 0; } int px4_custom_uorb_publish(int argc, char *argv[]) { struct ext_hello_world_s hello_world; memset(&hello_world, 0, sizeof(hello_world)); orb_advert_t hello_world_pub = orb_advertise(ORB_ID(ext_hello_world), &hello_world); for (int i = 0; i < TASK_PUBLISH_NUM; i++) { sleep(5); hello_world.hello = i + 1; PX4_INFO("Hello world(puslish):t%d", hello_world.hello); orb_publish(ORB_ID(ext_hello_world), hello_world_pub, &hello_world); } PX4_INFO("px4_custom_uorb_publish exiting"); return 0; } int px4_custom_uorb_main(int argc, char *argv[]) { int task_subscribe, task_publish; task_publish = px4_task_spawn_cmd(TASK_NAME_CUSTOM_UORB_PUBLISH, SCHED_DEFAULT, SCHED_PRIORITY_DEFAULT, 2000, px4_custom_uorb_publish, argv); PX4_INFO("creating %s task_publish = %d", TASK_NAME_CUSTOM_UORB_PUBLISH, task_publish); sleep(1); task_subscribe = px4_task_spawn_cmd(TASK_NAME_CUSTOM_UORB_SUBSCRIBE, SCHED_DEFAULT, SCHED_PRIORITY_DEFAULT, 2000, px4_custom_uorb_subscribe, argv); PX4_INFO("creating %s task_subscribe = %d", TASK_NAME_CUSTOM_UORB_SUBSCRIBE, task_subscribe); while(px4_task_is_running(TASK_NAME_CUSTOM_UORB_SUBSCRIBE) || px4_task_is_running(TASK_NAME_CUSTOM_UORB_PUBLISH)){ sleep(1); } PX4_INFO("px4_custom_uorb_main exiting"); return 0; }
整个DEMO结构如下所示:
目录结构
├── PX4-Autopilot
│ └── build/px4_sitl_default
│ ├── external_modules
│ │ └── examples
│ │ └── px4_custom_uorb/libexamples__px4_custom_uorb.a
│ ├── uORB
│ │ └── topics/ext_hello_world.h
│ └── msg
│ └── ttopics_sources/ext_hello_world.cpp
└── PX4-ExternalModule
├── msg
│ ├── CMakeLists.txt
│ └── ext_hello_world.msg
└── src
├── CMakeLists.txt
└── examples
└── px4_custom_uorb
├── CMakeLists.txt
├── Kconfig
└── px4_custom_uorb.c
完整的PX4-ExternalModule代码,请链接下载。
3. 编译执行结果基于SITL仿真环境,在PX4-Autopilot目录下,进行编译;
$ make px4_sitl EXTERNAL_MODULES_LOCATION=../PX4-ExternalModule/
然后,执行仿真环境;
$ make px4_sitl jmavsim
最后,测试下效果。
pxh> px4_custom_uorb INFO [px4_custom_uorb] creating orb publish task_publish = 13 INFO [px4_custom_uorb] creating orb subscribe task_subscribe = 14 INFO [px4_custom_uorb] Hello world(subscribe): 0 INFO [px4_custom_uorb] Hello world(puslish): 1 INFO [px4_custom_uorb] Hello world(subscribe): 1 INFO [px4_custom_uorb] Hello world(puslish): 2 INFO [px4_custom_uorb] Hello world(subscribe): 2 INFO [px4_custom_uorb] Hello world(puslish): 3 INFO [px4_custom_uorb] Hello world(subscribe): 3 INFO [px4_custom_uorb] Hello world(puslish): 4 INFO [px4_custom_uorb] Hello world(subscribe): 4 INFO [px4_custom_uorb] Hello world(puslish): 5 INFO [px4_custom_uorb] px4_custom_uorb_publish exiting INFO [px4_custom_uorb] Hello world(subscribe): 5 ERROR [px4_custom_uorb] Got no data within a second ERROR [px4_custom_uorb] Got no data within a second INFO [px4_custom_uorb] px4_custom_uorb_subscribe exiting INFO [px4_custom_uorb] px4_custom_uorb_main exiting4. 参考资料
【1】uorb messaging
【2】out of tree uorb message definitions



