PX4二次开发——uorb订阅

2023-05-16

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文件
  • 在子编译脚本中加入自己模块名字等,在总编译加入自己的模块名字
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4二次开发——uorb订阅 的相关文章

  • PX4/Pixhawk---uORB深入理解和应用

    The Instructions of uORB PX4 Pixhawk 软件体系结构 uORB 主题发布 主题订阅 1 简介 1 1 PX4 Pixhawk的软件体系结构 PX4 Pixhawk的软件体系结构主要被分为四个层次 xff0c
  • RealSense二次开发

    转载 xff1a librealsense2查看相机设备信息 JavaShuo 文章目录 1 librealsense2设备信息读取 xff12 xff0e realsense 投影函数和反投影函数3 深度相机与彩色相机的坐标变换 1 li
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • 初学PX4之环境搭建

    文章转自 xff1a http www jianshu com p 36dac548106b 前言 前段时间linux崩溃了 xff0c 桌面进去后只有背景 xff0c 折腾好久没搞定 xff0c 为了节省时间索性重装了系统 xff0c 同
  • 从Simulink到PX4——Simulink-PX4插件安装与环境搭建

    从Simulink到PX4 Simulink PX4插件安装与环境搭建 前言0 准备工作1 安装WSL2 Setting up the PX4 Toolchain on Windows3 Setting up the PX4 Tool Ch
  • PX4 ---- Mixer

    文章目录 Mixer 混合控制 作用输入输出装载混控文件MAVROS代码解析总结示例MAINAUX Mixer 混合控制 作用 经过位置控制和姿态控制后 xff0c 控制量通过 actuator controls发布 xff0c 其中 co
  • PX4模块设计之一:SITL & HITL模拟框架

    PX4模块设计之一 xff1a SITL amp HITL模拟框架 1 模拟框架1 1 SITL模拟框架1 2 HITL模拟框架 2 模拟器类型3 MAVLink API4 总结 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分
  • PX4模块设计之十一:Built-In框架

    PX4模块设计之十一 xff1a Built In框架 1 Nuttx Built In框架2 PX4 Built In框架2 1 NSH Built In关联文件2 2 NSH Built In关联文件生成2 3 NSH Built In
  • PX4模块设计之二十一:uORB消息管理模块

    PX4模块设计之二十一 xff1a uORB消息管理模块 1 uORB模块构建模式2 uORB消息管理函数2 1 状态查询2 2 资源利用2 3 模块启动2 4 模块停止3 uORB消息接口3 1 消息主题注册3 2 消息主题去注册3 3
  • PX4模块设计之二十四:内部ADC模块

    PX4模块设计之二十四 xff1a 内部ADC模块 1 内部ADC模块简介2 模块入口函数2 1 主入口board adc main2 2 自定义子命令custom command 3 内部ADC模块重要函数3 1 task spawn3
  • PX4模块设计之三十:Hysteresis类

    PX4模块设计之三十 xff1a Hysteresis类 1 Hysteresis类简介2 Hysteresis类成员变量介绍3 Hysteresis类迟滞逻辑4 Hysteresis类重要方法4 1 Hysteresis bool ini
  • PX4模块设计之三十三:Sensors模块

    PX4模块设计之三十三 xff1a Sensors模块 1 Sensors模块简介2 模块入口函数2 1 主入口sensors main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 Se
  • vue-element-admin 二次开发 报错修改

    安装 GitHub git clone https github com PanJiaChen vue element admin git Gitee https gitee com panjiachen vue element admin
  • mavros连接px4失败的usb-ttl原因

    问题描述 xff1a 最近在搞mavros xff0c 以方便协处理器和pixhawk通讯 xff0c 在按照官网教程安装mavros xff0c 设置px4 xff0c 连接硬件之后发现mavros卡在中间下不去 xff1a MAVROS
  • uORB和MAVLink通讯例程

    uORB uORB 是一种异步 publish subscribe 的消息传递 API xff0c 用于进程或者线程间通信 IPC 添加新的Topic xff08 主题 xff09 在msg 目录下创建一个新的 msg文件 xff0c 并将
  • pixhawk px4 commander.cpp

    对于复杂的函数 xff0c 要做的就是看函数的输入是什么 来自哪里 xff0c 经过处理后得到什么 给谁用 xff0c 这样就可以把程序逻辑理清 中间的分析就是看函数如何处理的 span class hljs keyword extern
  • PX4飞控之自主返航(RTL)控制逻辑

    本文基于PX4飞控1 5 5版本 xff0c 分析导航模块中自护返航模式的控制逻辑和算法 自主返航模式和导航中的其他模式一样 xff0c 在Navigator main函数中一旦触发case vehicle status s NAVIGAT
  • PX4飞控的PPM接收机

    xff08 一 xff09 原理图 xff1a PX4飞控的PPM输入捕获由协处理器完成 xff0c 接在A8引脚 xff0c 对应Timer1的通道1 xff08 二 xff09 PPM协议 xff1a PPM的每一帧数据间隔为20ms
  • 步骤三:PX4,Mavros的下载安装及代码测试

    1 安装Mavros sudo apt install ros melodic mavros ros melodic mavros extras 2 安装Mavros相关的 geographiclib dataset 此处已经加了ghpro
  • 四、无人机知识笔记(初级:基本运动原理)

    笔记来源于 沈阳无距科技 工业级无人机的中国名片 编程外星人 目录 一 多旋翼直升机 二 基本飞行姿态 三 多旋翼飞行原理 四 反扭力与偏航运动 五 螺旋桨 六 有刷电机和无刷电机 七 电调与PWM信号 八 动力电池 九 遥控器 十 机架设

随机推荐

  • [通俗易懂]无线通信读书笔记05(统计多径信道模型)

    通俗易懂 无线通信读书笔记05 xff08 统计多径信道模型 xff09 基本概念通用的时变信道的冲激响应模型窄带衰落模型 本文讨论一类能够描述信道中多径相互叠加产生干涉情形的衰落模型 xff0c 虽然在先前介绍的射线跟踪模型中 xff08
  • IMX6ULL学习笔记(18)——GPIO中断

    一 中断简介 相比 STM32 的 NVIC xff0c IMX6ULL 的中断控制系统更复杂 xff0c 它的中断管理器使用的是 GIC V2 xff0c GIC V2 的实现方式与我们熟知的 NVIC 差别较大 1 1 GIC GIC
  • 解决方法:编译IMX6ULL裸机中断程序提示错误selected processor does not support `cpsid i‘ in ARM mode

    一 问题 编译IMX6ULL野火裸机中断程序出现错误 xff1a arm span class token operator span none span class token operator span eabi span class
  • IMX6ULL学习笔记(19)——时钟系统

    一 时钟系统简介 I MX6U 的系统主频为 528MHz xff0c 有些型号可以跑到 696MHz xff0c 但是默认情况下内部 boot rom 会将 I MX6U 的主频设置为 396MHz 我们在使用 I MX6U 的时候肯定是
  • IMX6ULL学习笔记(20)——UART串口使用

    一 UART简介 i MX6U 芯片具有多达 8 个 UART 外设用于串口通讯 xff0c UART 是在 USART 基础上裁剪掉了同步通信功能 xff0c 只支持异步通信 简单区分同步和异步就是看通信时需不需要对外提供时钟输出 xff
  • 解决方法:编译IMX6ULL裸机串口程序提示错误arm-none-eabi-ld: cannot find -lgcc: 没有那个文件或目录

    一 问题 编译IMX6ULL野火裸机串口程序出现错误 xff1a make span class token punctuation span span class token number 1 span span class token
  • IMX6ULL学习笔记(21)——MMDC接口使用(DDR3测试)

    一 MMDC简介 MMDC 接口与 STM32 的 FSMC 接口类似 xff0c 只不过 MMDC 接口专用于外接 DDR xff0c 并且 MMDC 外部引脚不复用 MMDC 是一个多模的 DDR 控制器 xff0c 可以连接 16 位
  • IMX6ULL学习笔记(22)——eLCDIF接口使用(TFT-LCD屏显示)

    一 TFT LCD简介 TFT LCD xff08 Thin Film Transistor Liquid Crystal Display xff09 即薄膜晶体管液晶显示器 TFT LCD 与无源 TN LCD STN LCD 的简单矩阵
  • STM32 ROS控制器底层代码讲解

    本文主要对控制器底层代码的整天架构进行讲解 控制器由两部分组成一部分是BootLoader 另一部分是APP xff1b BootLoader主要用于固件升级 xff0c APP则作为应用程序 BootLoader的地址为 0x800000
  • STM32 使用microros与ROS2通信

    本文主要介绍如何在STM32中使用microros与ROS2进行通信 xff0c 在ROS1中标准的库是rosserial 在ROS2中则是microros 目前网上的资料也有一部分了 xff0c 但是都没有提供完整可验证的demo xff
  • 用ROS自带的gazebo仿真器搭建自己的环境

    近期需要搭建一个室内仿真环境 xff0c 用于实验调试 xff0c 所以想把相关技巧记录下来 xff0c 如有错误 xff0c 还请批评指正 xff0c 谢谢 参考网页 xff1a 使用gazebo中的building editor创建一个
  • docker如何删除容器里的文件

    问题起因 为什么会有这个问题呢 xff1f 起因是要从一个es搜索引擎从另一个es搜索引擎中拷贝数据 图方便没用软件导致重启es的时候拷贝的数据 xff0c 引发了es的启动异常 解决方案 docker inspect docker ins
  • 从程序中学习EKF-SLAM(一)

    在一次课程的结课作业上 xff0c 作业要求复写一个EKF SLAM系统 xff0c 我从中学到了好多知识 作为一个典型轻量级slam系统 xff0c 这个小项目应该特别适合于slam系统入门 xff0c 可以了解到经典卡尔曼滤波器在sla
  • numpy和tensorflow的一些用法与联系

    tensorflow和numpy值的差别 在numpy中生成的np array可以直接在 debug中看到产生的具体数字 xff1b 而在tensorflow中却只是一个tensor类型 xff0c 需要调用tf Session run X
  • ubuntu18.04 安装librealsense并验证

    安装环境 OS Ubuntu 18 04 bionic Kernel x86 64 Linux 4 15 0 20 generic 安装Realsense SDK 参考https github com IntelRealSense libr
  • YOLOV3只显示一类检测结果,并输出位置信息

    YOLOV3批量检测图片 xff0c 只显示一类检测结果 xff0c 并输出位置信息保存到txt 第一步 xff1a 首先修改YOLOV3中src imge c中的void draw detections函数 这里的修改实现了保存检测类别的
  • 搭建PX4开发环境

    搭建PX4开发环境 官方网站PX4 IO xff0c 我使用的是ubuntu20 04 一 官方环境搭建 1 下载PX4固件 span class token function git span clone https github com
  • PX4二次开发——程序运行过程

    PX4二次开发 程序运行过程 一 写在前面 px4固件程序与最开始我们所学习的对单片机外设开发不同 xff0c 是因为飞行器控制系统是一个复杂的系统 xff0c 要求实时性好 xff0c 完成复杂的控制任务 xff0c 简简单单的按照之前所
  • PX4二次开发——编译与启动脚本的修改

    PX4二次开发 编译和启动脚本的修改 一 在修改之前我们先了解一下目录结构 1 1 总目录结构 上图 xff0c 是源码目录 Src xff1a 目录是源码目录存放所有的源码 xff0c 源码的查看都应该在这里 Mavlink xff1a
  • PX4二次开发——uorb订阅

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