PX4二次开发——uorb订阅

2023-11-05 01:59
文章标签 二次开发 订阅 px4 uorb

本文主要是介绍PX4二次开发——uorb订阅,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PX4二次开发——uorb订阅

一、写在前面

​ 我们写了一个一个功能的模块,这些模块并不是独立的。模块之间是有数据传递的,这样才能组合到一起实现飞行控制的目的。那么解决模块之间的数据传递的方式就是通过uorb订阅的方式。

​ 下面举一个例子,包含了飞控串口读取外部传感器数据,飞控开启一个进程读取外部传感器发布一个 UORB 主题,另一个进程订阅前一个进程发布的主题,还有就是订阅到的主题通过 mavlink 消息发送到地面站。走了一个完整的飞控数据链路(UORB 链路和 MAVLINK 链路)。

二、新增一个自定义UORB主题

​ 下面是源码的msg文件夹下面是飞控所有的UORB主题,这里展示的就是你所能够从现有系统订阅发布的主题,当然你还可以自定义自己需要的主题消息。

在这里插入图片描述

可以看到 vehicle_global_position.msg 载具全球位置,vehicle_attitude_setpoint.msg 载具姿态消息,这 个姿态消息很重要如下所示::

在这里插入图片描述

我们可以看到姿态的成员变量,包括横滚 roll, 俯仰 pitch,偏航 yaw, 横滚速度,俯仰速度等 等相关姿态的数据。相关的加速度计,磁力计,陀螺仪经过算法滤波整合之后会发布姿态数 据,而姿态控制进程会订阅这个 vehicle_attitude_setpoint.msg 主题。这个模式很像 linux 的消息队列, 或者进程间通信的手段。

1.1 自己定义一个主题

​ 我们在 msg 文件夹下面添加添加一个具体的消息,比如我们的消息是

在这里插入图片描述

Laser_gun.msg 和 laser_gun_shoot.msg 消息。消息的成员函数可以参照其他原有的消息来写。Msg 文件里面的成员如下:

在这里插入图片描述

注意:新版本后每个msg都需要建立一个时间辍uint64 timestamp

​ 这个结构体成员是自己定义的。修改 cmakelist 脚本可以让这个消息生成相应的 uorb 头文件。这个 Cmakelinst 和 msg消息是同目录的,然后我们需要cmakelsit能够把我们写的被编译路径包括,点开该文件下的cmakelist,我们修改如下:

在这里插入图片描述

​ 当于把消息名字添加到这个 Cmakelist 里面,在编译源码的是就把这个消息主题相应的.h头文件自动写好了,不要我们自己写。到这里我们 make px4_fmu-v3_default 一把。结果如下:

在这里插入图片描述

​ 然后在源码的~/src/Firmware/build_px4_fmu-v3_default/uORB/topics 这个文件夹下面可以看到我们自定义消息的头文件。结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-在这里插入图片描述

​ 我们可以看到和我们在msg文件夹里面定义成员的一样。而这个结构体名为laser_gun_shoot_s,我们在以后的订阅发布进程里面,包含这个头文件就可以顺利使用了。

在这里插入图片描述

三、使用UORB

3.1 发布一个自定义消息

这里路径一定要修改对!

在这里插入图片描述

/*** @file px4_uorb_adver_app.c*/#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <systemlib/err.h>
#include <fcntl.h>
#include <systemlib/mavlink_log.h>
#include <uORB/uORB.h>
#include <uORB/topics/test_uorb.h>
#include <px4_platform_common/defines.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/posix.h>
//#include <px4_platform_common/shutdown.h>
#include <px4_platform_common/tasks.h>
#include <px4_time.h>static bool thread_should_exit = false;		/**< daemon exit flag */
static bool thread_running = false;		/**< daemon status flag */
static int px4_uorb_adver_task;				/**< Handle of daemon task / thread *//*** daemon management function.*/
__EXPORT int px4_uorb_adver_main(int argc, char *argv[]);/*** Mainloop of daemon.*/
int px4_uorb_adver_thread_main(int argc, char *argv[]);/*** Print the correct usage.*/
static void usage(const char *reason);static void
usage(const char *reason)
{if (reason) {warnx("%s\n", reason);}warnx("usage: px4_uorb_adver {start|stop|status} [-p <additional params>]\n\n");
}/**
消息发布进程,会不断的发送自定义的消息*/
int px4_uorb_adver_main(int argc, char *argv[])
{if (argc < 2) {usage("missing command");return 1;}if (!strcmp(argv[1], "start")) {if (thread_running) {warnx("daemon already running\n");/* this is not an error */return 0;}thread_should_exit = false;//定义一个守护进程px4_uorb_adver_task = px4_task_spawn_cmd("px4_uorb_adver",SCHED_DEFAULT,SCHED_PRIORITY_DEFAULT,//调度优先级2000,//堆栈分配大小px4_uorb_adver_thread_main,(argv) ? (char *const *)&argv[2] : (char *const *)NULL);return 0;}if (!strcmp(argv[1], "stop")) {thread_should_exit = true;return 0;}if (!strcmp(argv[1], "status")) {if (thread_running) {warnx("\trunning\n");} else {warnx("\tnot started\n");}四、return 0;}usage("unrecognized command");return 1;
}int px4_uorb_adver_thread_main(int argc, char *argv[])//这里的argc表示输入参数个数(中间用空格隔开),argv表示存放的内容。在使用一个模块是会输入参数比如px4_uorb_adver start(stop),存入的就是start.在上面px4_uorb_adver_main中会有对输入指令的判断,并执行进程
{struct test_uorb_s test_uorb_ad;memset(&test_uorb_ad, 0 , sizeof(test_uorb_ad));orb_advert_t test_pub = orb_advertise(ORB_ID(test_uorb), &test_uorb_ad);warnx("[daemon] starting\n");thread_running = true;while (!thread_should_exit) {test_uorb_ad.test1 = 5;test_uorb_ad.test2 = 6;orb_publish(ORB_ID(test_uorb), test_pub, &test_uorb_ad);usleep(1000);}warnx("[daemon] exiting.\n");thread_running = false;return 0;
}

3.2 订阅一个自定义消息

/*** @file px4_uorb_subs.c*/#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <systemlib/err.h>
#include <fcntl.h>
#include <systemlib/mavlink_log.h>
#include <uORB/uORB.h>
#include <uORB/topics/test_uorb.h>
#include <px4_platform_common/defines.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/posix.h>
//#include <px4_platform_common/shutdown.h>
#include <px4_platform_common/tasks.h>
#include <px4_time.h>static bool thread_should_exit = false;		/**< px4_uorb_subs exit flag */
static bool thread_running = false;		/**< px4_uorb_subs status flag */
static int px4_uorb_subs_task;				/**< Handle of px4_uorb_subs task / thread *//*** daemon management function.*/
__EXPORT int px4_uorb_subs_main(int argc, char *argv[]);/*** Mainloop of daemon.*/
int px4_uorb_subs_thread_main(int argc, char *argv[]);/*** Print the correct usage.*/
static void usage(const char *reason);static void
usage(const char *reason)
{if (reason) {warnx("%s\n", reason);}warnx("usage: px4_uorb_adver {start|stop|status} [-p <additional params>]\n\n");
}/**
消息发布进程,会不断的接收自定义消息*/
int px4_uorb_subs_main(int argc, char *argv[])
{if (argc < 2) {usage("missing command");return 1;}if (!strcmp(argv[1], "start")) {if (thread_running) {warnx("px4_uorb_subs already running\n");/* this is not an error */return 0;}thread_should_exit = false;//定义一个守护进程px4_uorb_subs_task = px4_task_spawn_cmd("px4_uorb_subs",SCHED_DEFAULT,SCHED_PRIORITY_DEFAULT,//调度优先级2000,//堆栈分配大小px4_uorb_subs_thread_main,(argv) ? (char *const *)&argv[2] : (char *const *)NULL);return 0;}if (!strcmp(argv[1], "stop")) {thread_should_exit = true;return 0;}if (!strcmp(argv[1], "status")) {if (thread_running) {warnx("\trunning\n");} else {warnx("\tnot started\n");}return 0;}usage("unrecognized command");return 1;
}int px4_uorb_subs_thread_main(int argc, char *argv[])
{warnx("[px4_uorb_subs] starting\n");int test_sub_fd = orb_subscribe(ORB_ID(test_uorb));struct test_uorb_s test_uorb_sub;memset(&test_uorb_sub, 0 , sizeof(test_uorb_sub));int test1 = 0,test2 = 0;thread_running = true;while (!thread_should_exit) {warnx("Hello px4_uorb_subs!\n");bool updated;/* Check if vehicle control mode has changed */orb_check(test_sub_fd, &updated);if (updated){orb_copy(ORB_ID(test_uorb),test_sub_fd,&test_uorb_sub);test1 = test_uorb_sub.test1;test2 = test_uorb_sub.test2;}warnx("test_uorb.test1 = %d, test_uorb.test2 = %d ,test_uorb.test3 = %d\n",test1,test2);usleep(500);}warnx("[px4_uorb_subs] exiting.\n");thread_running = false;return 0;
}

在这里插入图片描述

四、修改编译脚本和启动脚本

​ 参照之前即可,这里启动脚本没有修改,通过mavlink控制进程的开关,如若需要开机启动在机型那个子启动脚本start即可

五、总结

​ 在linux中,万物皆文件。

​ 自制主题注意:

  • 在msg文件夹中创建自己的XXX.msg,新版需要加时间辍
  • 把自己主题加入消息的编译脚本中
  • 编译完成会在build->UORB中生成一个中包含XXX_s结构体头文件
  • 使用这个包含#include <uORB/uORB.h> #include <uORB/topics/test_uorb.h>

​ 订阅发布注意:

  • 新建模块文件夹,新建C文件,新建CMAKELIST文件
  • 在子编译脚本中加入自己模块名字等,在总编译加入自己的模块名字

这篇关于PX4二次开发——uorb订阅的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/346654

相关文章

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

C++编程:ZeroMQ进程间(订阅-发布)通信配置优化

文章目录 0. 概述1. 发布者同步发送(pub)与订阅者异步接收(sub)示例代码可能的副作用: 2. 适度增加缓存和队列示例代码副作用: 3. 动态的IPC通道管理示例代码副作用: 4. 接收消息的超时设置示例代码副作用: 5. 增加I/O线程数量示例代码副作用: 6. 异步消息发送(使用`dontwait`标志)示例代码副作用: 7. 其他可以考虑的优化项7.1 立即发送(ZMQ_IM

Superset二次开发之Select 筛选器源码分析

路径:superset-frontend/src/filters/components/Select  源码文件: 功能点: 作用 交互 功能 index.ts作为模块的入口点,导出其他文件中定义的主要组件和函数。它使其他文件中的导出可以被外部模块使用。 SelectFilterPlugin.tsx 定义主要的插件类 SelectFilterPlugin 和组件 Sele

了解elementUI的底层源码, 进行二次开发

Element UI 是一个基于 Vue.js 的桌面端组件库,广泛用于构建美观、交互友好的用户界面。要深入理解 Element UI 的底层源码并进行二次开发,你需要掌握以下几个关键点: Vue.js 原理 Element UI 是基于 Vue.js 构建的,因此首先需要熟悉 Vue.js 的核心概念和机制,包括: ● 组件系统:Vue.js 的组件化思想,如何定义组件、使用组件、传递属性和事

关于武汉高芯coin417G2红外机芯的二次开发

文章目录 前言一、外观和机芯参数二、SDK的使用1、打开相机2、回调函数中获取全局温度和图像3、关闭相机 前言 最近工作中接触了一款基于武汉高芯科技有限公司开发的红外模组,即coin417g2(测温型)+9.1mm镜头.使用此模组,开发了一套红外热成像检测桌面应用程序.下面简单记录下该模组的使用. 一、外观和机芯参数 如下是该机芯的外观和机芯参数: 二、SDK

NX二次开发—进阶(二)

一、创建圆弧 在NX上通过代码画出圆弧,定义起始和终止位置,还有圆心位置和半径 创建圆弧,需要获取CSYS的矩阵ID,通过UF_CURVE_create_arc函数进行创建 //定义参数UF_CURVE_arc_t arc;arc.start_angle = 0.0;arc.end_angle = 225 * DEGRA;//DEGRA=PI/180//中心坐标arc.arc_center

NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001

由于需要对NFI进行汉化,以及二次开发,首先要下载源码以后编辑通过,NIFI的源码,项目非常多,编译过程中需要编译超过570个jar包,同时编译过程很慢需要30多分钟. 1.首先下载NIFI源码,根据需要下载对应版本: https://github.com/kemixkoo/orchsym-runtime/   首先介绍一下,这个是一个公司根据nifi进行定制开发的,已经汉化,但是不能商

NX二次开发——进阶(一)

一、链表及相关函数的用法 函数说明UF_MODL_create_list创建一个链表,并返回链表的头指针UF_MODL_put_list_item插入元素到链表中,不检验对象是否重复,或者已经存在UF_MODL_ask_list_count获取链表对象数量,从头开始遇到null_tag结束UF_MODL_ask_list_item查询链表对象标识,给个位置返回标识UF_MODL_delete_l

​​NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南002

继续,执行pom.xml引入依赖以后,发现以下几种报错: 可以看到在下载aws-java-sdk-bundle 1.12.710版本的时候报错了 可以看到日志信息,就是在阿里云上下载的,因为阿里云上缺少这个jar包 aws-java-sdk-bundle-1.12.710.jar 这个jar包,我还特意去阿里云上查询了一下 https://developer.aliyun.com/

恋爱相亲交友系统源码原生源码可二次开发APP 小程序 H5,web全适配

直播互动:平台设有专门的直播间,允许房间主人与其他异性用户通过视频连线的方式进行一对一互动。语音视频交流:异性用户可以发起语音或视频通话,以增进了解和交流。群组聊天:用户能够创建群聊,邀请自己关注的异性朋友加入,以便进行多人在线交流。虚拟礼品赠送:平台提供多样化的虚拟礼物,不同礼物有不同的价值,用户可以用来表达好感或支持。私人消息:异性用户之间可以互相发送私人信息,不过平台为了维护用户体验,对