uORB: (Micro Object Request Broker )
[PX4进程间的通讯机制:多对多的信息发布与订阅方式]
发布消息:
1. 公告 advertise:
相当于初始化,在发布消息之前需要对主题(topic)进行公告,一个topic只公告一次
创建一个主题(uORB上创建一个消息源)
驱动程序通过以下接口公告一个主题:
orb_advert_t orb_advertise( const struct orb_metadata *meta, const void *data )
meta:为发布数据的ID
data:为发布数据的初始内容
2. 发布 publish:
当消息源产生一个新数据时,可通过已公告的主题向uORB发布消息
消息源通过以下接口发布消息:
int orb_publish(const struct orb_metadata * meta, orb_advert_t handle, const void *data)
{ return uORB::Manager::get_instance()->orb_publish(meta, handle, deta ); }
meta:为发布数据的ID
handle:为发布数据的句柄(文件描述符),初始化为null
data:为发布数据的内容
订阅消息:
1. 订阅 2. 检查更新 3. 拷贝数据
1.订阅 subscribe:
订阅主题,当主题发生更新后,会收到来自uORB的通知
应用程序可通过以下接口来订阅主题:
int orb_subscribe(const struct orb_metadata *meta)
{ return uORB::Manager::get_instance()->orb_subscribe(meta); }
meta:订阅发布数据的ID
返回一个int型的句柄
2. 1检查更新:方式一【非关键数据】
每隔一段时间,检测主题数据是否更新
int orb_check(int handle, bool *updated)
{ return uORB::Manager::get_instance()->orb_check(handle, updated); }
检测handle句柄是否更新,若更新,updated会被设置为true。
一旦调用orb_copy来接受处理后,update会被自动设置为false,因此该方式下数据仅能被一个用户检测到。
2.2 检查更新:方式二【数据很重要】
阻塞等待数据更新,设置等待时间上限,等待数据更新。
int poll( struct pollfd *fds, nfds_t nfds, int timeout);
fds:已经订阅的主题数据
timeout:最大阻塞时间 ms
返回值: >0[ 阻塞时间内拿到了数据 ]
-1[ 函数调用失败]
==0[ 时间用完还没拿到数据 ]
3. 拷贝数据
通过以上方式检测到数据更新之后,将数据拷贝到buffer中
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer);
meta:要拷贝数据的ID
handle:要拷贝数据数据的句柄
buffer:储存位置
如何订阅一个数据
int sensor_sub_fd = orb_subscribe( ORB_ID( sensor_combine )) ;
orb_set_interval(sensor_sub_fd, 200);
struct fds[ ] = { {.fd = sensor_sub_fd, .event = POLLIN }, };
if( 循环条件 ){
int poll_ret = poll ( fds, 1 ,1000 );
if( poll_ret == 0)
PX4_ERR("Got no data within a second");
else if ( poll_ret < 0 )
{
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]);
}
}
}
如何发布一个数据
struct vehicle_attitude_s att;
memset(&att, 0, sizeof(att));
orb_advert_t att_pub = orb_advertise(ORB_ID(vehicle_attitude), &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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)