uORB消息的收发 c++中的使用

PX4-Autopilot/msg/

这个目录下定义了所有uORB消息的格式
用于PX4各模块间传递消息

px4开发文档给出的uORB消息的参考资料

https://docs.px4.io/master/en/middleware/uorb.html

如何新增一个uORB消息

1.在PX4-Autopilot/msg/文件夹下新增一个*.msg文件,写法参考其他msg文件
通过在.msg文件中添加类似于以下内容的行,可以将单个消息定义用于多个独立的主题:

# TOPICS mission offboard_mission onboard_mission

然后在代码中,把它们作为主题ID: ORB_ID(offboard_mission)
2. PX4-Autopilot/msg/文件夹中,打开cmakelists.txt文件,加入对应的*.msg,这样才会编译这个消息,如下:

set(msg_files
	actuator_armed.msg
	actuator_controls.msg
	actuator_outputs.msg
	adc_report.msg
	airspeed.msg
	airspeed_validated.msg
	battery_status.msg
	camera_capture.msg
	camera_trigger.msg
	cellular_status.msg
	collision_constraints.msg
	..
    //[查看全部](https://github.com/PX4/PX4-Autopilot/blob/master/msg/CMakeLists.txt)
)

编译后会自动生成一个对应的头文件。
3.只要在一个模块中引用这个叫uORB消息的头文件,便可进行使用了,如:

#include <uORB/topics/sensor_combined.h>
..
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));

该sensor_sub_fd是一个主题手柄,可用于非常有效地进行封锁来等待新的数据。当前线程进入睡眠状态,一旦有新数据可用,调度程序会自动将其唤醒,而在等待时不会占用任何CPU周期。
为此,我们使用poll()
添加poll()到订阅中看起来像:

#include <poll.h>
#include <uORB/topics/sensor_combined.h>
..
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
/* 可以使用此技术等待多个主题,仅在此处使用一次 */
px4_pollfd_struct_t fds[] = {
    { .fd = sensor_sub_fd,   .events = POLLIN },
};
while (true) {
	/* 等待1个文件描述符的传感器更新1000毫秒(1秒) */
	int poll_ret = px4_poll(fds, 1, 1000);
	..
	if (fds[0].revents & POLLIN) {
		/* 获得的第一个文件描述符的数据 */
		struct sensor_combined_s raw;
		/* 将传感器原始数据复制到本地缓冲区 */
		orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
		PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
					(double)raw.accelerometer_m_s2[0],
					(double)raw.accelerometer_m_s2[1],
					(double)raw.accelerometer_m_s2[2]);
	}
}

发布uORB消息

例如:初始化struct要发布的主题并发布主题

#include <uORB/topics/vehicle_attitude.h>
..
/* 广播姿态主题 */
struct vehicle_attitude_s att;
memset(&att, 0, sizeof(att));
orb_advert_t att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);

在主循环中,随时准备发布信息:

orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);

完整的示例代码

#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/tasks.h>
#include <px4_platform_common/posix.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <math.h>
#include <uORB/uORB.h>
#include <uORB/topics/sensor_combined.h>
#include <uORB/topics/vehicle_attitude.h>
__EXPORT int px4_simple_app_main(int argc, char *argv[]);
int px4_simple_app_main(int argc, char *argv[])
{
	PX4_INFO("Hello Sky!");
	/* 订阅传感器组合主题 */
	int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
	/* 限制更新速度5hz */
	orb_set_interval(sensor_sub_fd, 200);
	/* 广播姿态主题 */
	struct vehicle_attitude_s att;
	memset(&att, 0, sizeof(att));
	orb_advert_t att_pub = orb_advertise(ORB_ID(vehicle_attitude), &att);
	/* 可以使用此技术等待多个主题,仅在此处使用一个 */
	px4_pollfd_struct_t fds[] = {
		{ .fd = sensor_sub_fd,   .events = POLLIN },
		/* 可有多个订阅,如: * { .fd = other_sub_fd, .events = POLLIN }, */
	};
	int error_counter = 0;
	for (int i = 0; i < 5; i++) {
		/* 等待1个文件描述符的传感器更新1000毫秒(1秒) */
		int poll_ret = px4_poll(fds, 1, 1000);
		/* 处理poll结果 */
		if (poll_ret == 0) {
			/* 这意味着我们的订阅没有向我们提供数据 */
			PX4_ERR("Got no data within a second");
		} else if (poll_ret < 0) {
			/* this is seriously bad - should be an emergency啊,这.... */
			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 sensor_combined_s raw;
				/* 将传感器原始数据复制到本地缓冲区 */
				orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
				PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
					 (double)raw.accelerometer_m_s2[0],
					 (double)raw.accelerometer_m_s2[1],
					 (double)raw.accelerometer_m_s2[2]);
				/* 设置att并为其他应用发布此信息,以下内容没有任何意义,仅是示例 */
				att.q[0] = raw.accelerometer_m_s2[0];
				att.q[1] = raw.accelerometer_m_s2[1];
				att.q[2] = raw.accelerometer_m_s2[2];
				orb_publish(ORB_ID(vehicle_attitude), att_pub, &att);
			}
			/* 这里可有更多的文件描述符,格式如下: * if (fds[1..n].revents & POLLIN) {} */
		}
	}
	PX4_INFO("exiting");
	return 0;
}

树外uORB消息定义

与任何其他uORB消息定义的格式相同

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值