uORB通信机制和添加⾃⼰的topics学习笔记
本⽂参考进⾏操作,结合⽹上⼀篇uROB的介绍进⾏深⼊的了解。
1.简介
uORB(Micro Object Request Broker,微对象请求代理器)是PX4/Pixhawk系统中⾮常重要且关键的⼀个模块,它肩负了整个系统的数据传输任务,所有的传感器数据、GPS、PPM信号等都要从芯⽚获取后通过uORB进⾏传输到各个模块进⾏计算处理。实际上uORB是⼀套跨「进程」的IPC通讯模块。在Pixhawk中,所有的功能被独⽴以进程模块为单位进⾏实现并⼯作。⽽进程间的数据交互就由为重要,必须要能够符合实时、有序的特点。
Pixhawk使⽤的是NuttX实时ARM系统,uORB实际上是多个进程打开同⼀个设备⽂件,进程间通过此⽂件节点进⾏数据交互和共享。进程通过命名的「总线」交换的消息称之为「主题」(topic),在Pixhawk 中,⼀个主题仅包含⼀种消息类型,通俗点就是数据类型。每个进程可以「订阅」或者「发布」主题,可以存在多个发布者,或者⼀个进程可以订阅多个主题,但是⼀条总线上始终只有⼀条消息。
uROB通信机制介绍uORB的通信机制从下图可以看得很清楚,就是在数据管道上每个模块都可以给数据给这个通道(publish),也可以在这个通道获得数据(subscribe),每个模块就是⼀个进程,它们可
以彼此独⽴,它们不需要知道把数据给哪个模块,也不需要知道从哪个模块获取数据,有uORB作为桥梁,这也防⽌了程序的死锁问题。下⾯具体演⽰如何添加⾃⼰的topics:
bleep
汉语学习2.添加⾃⼰的topics
2.1添加⾃⼰的msg
在Firmware/msg下新建uROB成员变量:lulu.msg
uint8 lulu1
# TOPICS lulu lulu_x lulu_y //这⼀步⽣成三个主题ID,注意#号和TOPICS之间有空格
2.2在Firmware/中添加话题的xxx.msg,作为cmake的索引
bore的用法>名词语法time_offt.msg
netac
transponder_report.msg
uavcan_parameter_request.msg
uavcan_parameter_value.msg
ulog_stream.msg
ulog_stream_ack.msg
vehicle_attitude.msg
vehicle_attitude_tpoint.msg
vehicle_command.msg
vehicle_command_ack.msg
vehicle_control_mode.msg
vehicle_force_tpoint.msg
vehicle_global_position.msg
vehicle_gps_position.msg
vehicle_land_detected.msg
vehicle_local_position.msg
vehicle_local_position_tpoint.msg
vehicle_rates_tpoint.msg
风眼
vehicle_roi.msg
vehicle_status.msg
片断教学vehicle_status_flags.msg
vtol_vehicle_status.msg
wind_estimate.msg
lulu.msg
)
2.3 编译⼯程
cd ~/src/Firmware
make px4fmu-v2_default
现在在src/Firmware/build_px4fmu-v2_default/src/modules/uROB/topics⽬录下会产⽣相应的头⽂件
打开该⽂件后,我们看到⾥⾯定义了⼀个结构体,⽤到了我们写msg中的lulu1变量,这个结构体我们⾃⼰定义发布和订阅要⽤到心疼的英文
#pragma once
#include <stdint.h>
#ifdef __cplusplus
#include <cstring>
#el
#include <string.h>
#endif
#include <uORB/uORB.h>
#ifndef __cplusplus
#endif
struct microCDR;
#ifdef __cplusplus
adderstruct __EXPORT lulu_s {
#el
struct lulu_s {
#endif
uint64_t timestamp; // required for logger
uint8_t lulu1;
uint8_t _padding0[7]; // required for logger
#ifdef __cplusplus
#endif
};
void rialize_lulu(const struct lulu_s *input, char *output, uint32_t *length, struct microCDR *microCDRWriter);
void derialize_lulu(struct lulu_s *output, char *input, struct microCDR *microCDRReader);
/* register this as object request broker structure */
ORB_DECLARE(lulu);
ORB_DECLARE(lulu_x);
ORB_DECLARE(lulu_y);
下⾯可以开始进⾏⾃⼰数据的发布和订阅,我为了不更改原本的⽂件,在Firmware/src/examples下新建了⽂件夹取名为
px4_simple_app1,在这个⽂件夹⾥添加将px4_simple_app⽂件中的⽂件名稍微改下就⾏。新建⽂件px4_simple_app1.c内容如下:
#include <px4_config.h>
羚羊的英文#include <px4_tasks.h>
#include <px4_posix.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <math.h>
#include <uORB/uORB.h>
#include <uORB/topics/nsor_combined.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/lulu.h>
//添加⾃⼰的头⽂件
__EXPORT int px4_simple_app1_main(int argc, char *argv[]); //主函数声明,必须要写
int px4_simple_app1_main(int argc, char *argv[])
{
PX4_INFO("Hello lulu!");//PX4_INFO为打印函数,printf也可以
/*定义话题结构*/
struct lulu_s test; //这个结构体就是lulu.h⽂件中定义的
/*初始化数据*/
memt(&test, 0, sizeof(test));
/*公告主题*/
/
*test_pub 为handle指针*/
orb_advert_t test_pub = orb_adverti(ORB_ID(lulu), &test);
/*test数据赋值*/
test.lulu1 = 200;
/*发布测试数据*/
orb_publish(ORB_ID(lulu), test_pub, &test);
/*订阅数据,在copy之前,必须要订阅*/
/*test_sub_fd为handle*/
int test_sub_fd = orb_subscribe(ORB_ID(lulu));
struct lulu_s data_copy;
/*copy数据*/
orb_copy(ORB_ID(lulu), test_sub_fd, &data_copy);
/*打印*/
PX4_WARN("[px4_simple_app1] GanTA:\t%8.4f",
(double)data_copy.lulu1
);
return0;
}
具体的发布和订阅函数可以参考博客:
2.4配置启动脚本,进⼊nsh系统
在默认的脚本中px4_simple_app1并不会被编译执⾏,需要到Firmware/cmake/configs/nuttx_ake下将px4_simple_app1的⽂件添加进去,就是把注释去掉:
此时我们连接飞控到计算机,编译并刷固件:
makepx4fmu-v2_default upload
ls /dev/tty*