uORB为PX4系统的数据集散中心,应用程序间的数据共享全部要通过uORB来传递,
而数据传递的载体被称为 topic. 其实,一个topic就是一个事先已经定义好的结构体,用来反映该topic的数据构成.
数据传递的方法是通过几个uORB数据管理中心提供的几个接口函数,这些接口中最重要的4个是:
orb_subscribe(...) , orb_copy(...), orb_advertise(...), orb_publish(...).
topic是一个被生产和被消费的过程.
某个APP要消费一个topic,它首先要使用函数orb_subscribe来订阅该topic,然后才能用rb_copy函数来获取被订阅的数据;
某个APP要发布一个topic,它首先要使用函数orb_advertise来广告这个topic给uORB,然后用orb_publish函数来发布这个topic的数据.
那么,如何自己定义一个topic呢?
自己定义一个新的topic,要做3个步骤,
1.去src/modules/uORB/topics 目录下面定义一个头文件,在文件中以结构体定义的方式声明该topic数据的构成.
2.在上面头文件中声明该topic的名字,通过ORB_DECLARE(topic_name) 来达到该目的.
3.在src/modules/uORB/objects.common.cpp中添加一个字义,从而将topic的名字和结构体的定义关联起来,即ORB_DEFINE(topic_name,tpicc_name_struct);
上面两个宏定义 ORB_DECLARE(topic_name)和ORB_DEFINE(topic_name,tpicc_name_struct)的分析,此处通过一个具体的实现来分析 (airspeed.h):
airspeed结构体的定义:
-
#ifdef __cplusplus
-
struct __EXPORT airspeed_s {
-
#else
-
struct airspeed_s {
-
#endif
-
uint64_t timestamp;
-
float indicated_airspeed_m_s;
-
float true_airspeed_m_s;
-
float true_airspeed_unfiltered_m_s;
-
float air_temperature_celsius;
-
#ifdef __cplusplus
-
-
#endif
-
};
-
#ifdef __cplusplus
-
struct __EXPORT airspeed_s {
-
#else
-
struct airspeed_s {
-
#endif
-
uint64_t timestamp;
-
float indicated_airspeed_m_s;
-
float true_airspeed_m_s;
-
float true_airspeed_unfiltered_m_s;
-
float air_temperature_celsius;
-
#ifdef __cplusplus
-
-
#endif
-
};
ORB_DECLARE(airspeed):
-
# define ORB_DECLARE(_name) extern "C" const struct orb_metadata __orb_##_name __EXPORT
展开后为:
-
extern "C" const struct orb_metadata __orb_airspeed_name __EXPORT;
所以这里是在声明一个新的结构体的定义.
在再objects_common.cpp中,
-
#include "topics/airspeed.h"
-
ORB_DEFINE(airspeed, struct airspeed_s);
-
#define ORB_DEFINE(_name, _struct) \
-
const struct orb_metadata __orb_##_name = { \
-
#_name, \
-
sizeof(_struct) \
-
}; struct hack
从上面可以看出宏展开后的内容为:
-
const struct orb_metadata __orb_airspeed = {
-
.o_name = airspeed,
-
.o_size = sizeof(strcut airspeed_s)
-
};
-
/**
-
* Object metadata.
-
*/
-
struct orb_metadata {
-
const char *o_name; /**< unique object name */
-
const size_t o_size; /**< object size */
-
}
所以,每定义一个topic,都会定义一个以该topic名称命名的类型为 orb_metadata 结构体,并且这个结构体中只记录了topic的名称和该topic的大小.
所以一个topic其实定义了两个东西:
1. 承载具体数据内容的topic结构体 :
struct airspeed_s;
2.记录该topic的uORB结构体;
struct orb_metadata __orb_airspeed;
所以topic头文件中的
ORB_DECLARE(airspeed) 其实是在声名
ORB_DEFINE(airspeed, struct airspeed_s)所定义的结构体变量,名字为:__orb_airspeed.
因此,你在发布或消费一个topic时,必须要知道这个topic的数据构型,即这个topic关联的结构体的定义.
阅读(7171) | 评论(0) | 转发(1) |