Pixhawk学习2——uORB微对象请求代理及规则

在Pixhawk中,所有的功能被独立以进程模块为单位进行实现并工作。而每个进程模块都有一个(或多个?)主题信息topic(topic可以在Firmware/msg里查看到所有的可使用的)。所有的进程进行数据交互,其实就是将这些topic扔在一个市场上供大家选取。而uORB(Micro Object Request Broker,微对象请求代理器)就是这个市场。uORB在Pixhawk系统中肩负了整个系统的数据传输任务,所有的传感器信息或者中间计算量得到之后都通过UORB进行传输。

uORB的规则如下:
对应uORB的话题发布者:公告(advertise) + 发布(publish);
对于uORB的话题接收者:订阅(subscribe) + 查询(poll阻塞式等待或check更新) + 复制(copy)。

以Pixhawk中提供的例子为例(src/examples/px4_simple_app),利用对程序的注释,详细说明以上规则。

/****************************************************************************
 *
 *   Copyright (c) 2012-2016 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file px4_simple_app.c
 * Minimal application example for PX4 autopilot
 *
 * @author Example User <mail@example.com>
 */

#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 <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!");

	/* subscribe to sensor_combined topic  */
	/* 订阅 一个sensor_combined (传感器——联合)主题*/
	int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
		/* 
			sensor_combined 为所要订阅信息的ID,所有能够被订阅的信息ID都在Firmware/msg中能看到
		   	sensor_sub_fd 为订阅函数的返回值,有以下几种情况:
		   		1:错误则返回ERROR;
		   		2:成功则返回一个可以读取数据、更新话题的句柄;
		   		3:如果待订阅的主题没有定义或声明则会返回-1
		*/
	/* limit the update rate to 5 Hz*/
	/* 限制更新频率为5HZ */
	orb_set_interval(sensor_sub_fd, 200);

	/* advertise attitude topic*/
	/* 定义结构体,表示广播信息 */
	struct vehicle_attitude_s att;
	memset(&att, 0, sizeof(att));  // 申请内存并初始化
	
	/* 广播(公告)信息*/
	orb_advert_t att_pub = orb_advertise(ORB_ID(vehicle_attitude), &att);
		/*
			 vehicle_attitude为要广播的信息ID;
			 att为实际要广播的信息;
			 att_pub为返回的对象指针,有以下几种情况:
		   		1:错误则返回ERROR;
		   		2:成功则返回一个可以读取数据、更新话题的句柄;
		   		3:如果待广播的主题没有定义或声明则会返回-1
		*/

	/* one could wait for multiple topics with this technique, just using one here */
	px4_pollfd_struct_t fds[] = {
		{ .fd = sensor_sub_fd,   .events = POLLIN },
		/* there could be more file descriptors here, in the form like:
		 * { .fd = other_sub_fd,   .events = POLLIN },
		 */
	};

	int error_counter = 0;

	/*×××××××××××××××××××检测更新 阻塞等待x××××××××××××××××××*/

	for (int i = 0; i < 5; i++) {
		/* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */
		/*阻塞等待函数,时间为1s*/
		int poll_ret = px4_poll(fds, 1, 1000);
			/*
				该函数返回值有几种情况:
					大于0:表示等到数据更新;
					等于0:表示没有等到数据更新,
					小于0则表示发生错误。
			*/

		/* handle the poll result */
		/* 根据返回值进行数据处理*/
		if (poll_ret == 0) {
			/* this means none of our providers is giving us data */
			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) {
				/* use a counter to prevent flooding (and slowing us down) */
				PX4_ERR("ERROR return value from poll(): %d", poll_ret);
			}

			error_counter++;

		} else { // 表示数据有更新

			if (fds[0].revents & POLLIN) {
				/* obtained data for the first file descriptor */
				struct sensor_combined_s raw;
				/* copy sensors raw data into local buffer*/
				/*  复制出原始数据 */
				orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
					/*  
						sensor_combined为所要复制的主题ID;
						sensor_sub_fd文件描述符(订阅返回值);
						raw为需要复制的缓存地址)。
					*/
				PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",  // PX4——INFO类似于C语言的printf 函数
					 (double)raw.accelerometer_m_s2[0],
					 (double)raw.accelerometer_m_s2[1],
					 (double)raw.accelerometer_m_s2[2]);

				/* set att and publish this information for other apps
				 the following does not have any meaning, it's just an example
				*/
				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);
					/*
						vehicle_attitude为需要发布的主题ID,后续可以通过该ID订阅数据att;
						att_pub为广播时返回的对象指针;
						att为需要发布的真实数据。
					*/
			}

			/* there could be more file descriptors here, in the form like:
			 * if (fds[1..n].revents & POLLIN) {}
			 */
		}
	}

	PX4_INFO("exiting");

	return 0;
}

该段代码的流程为:
1、订阅ID为sensor_combined 的信息

2、广播ID为vehicle_attitude的信息

3、采用阻塞等待方式等候sensor_combined 的信息到来

4、等到数据来之后Copy ID为sensor_combined下的数据给raw数据

5、将raw中需要的数据赋值给att

6、发布ID为vehicle_attitude的信息,其中的数据为att

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值