PX4官方examples 发布与订阅 分析

功能:实现 订阅 sensor_combined 消息,将订阅的消息数据 通过发布主题( vehicle_attitude)发布出去
/****************************************************************************
*

  • Copyright © 2012-2019 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.
    1. 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.
    1. 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_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> //引入 需要订阅sensor_combined 消息头文件
#include <uORB/topics/vehicle_attitude.h> //引入 需要发布vehicle_attitude 消息头文件

__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 */ 
//功能:订阅主题(topic)
//说明:通过实例的ID索引来确定是主题的哪个实例;
//可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));

/* limit the update rate to 5 Hz */
//int orb_set_interval(int handle, unsigned interval)
//功能:设置订阅的最小时间间隔;订阅消息间隔200ms一次
//说明:如果设置了,则在这间隔内发布的数据将订阅不到;需要注意的是,设置后,第一次的数据订阅还是由起初设	 //  	置的频率来获取
//参数:handle:orb_subscribe函数返回的句柄;interval:间隔时间,单位ms;
orb_set_interval(sensor_sub_fd, 200);

/* advertise attitude topic */
//生成一个来自vehicle_attitude.h的vehicle_attitude_s类型的结构体
struct vehicle_attitude_s att;
memset(&att, 0, sizeof(att));
//功能:公告发布者的主题;
//说明:在发布主题之前是必须的;否则订阅者虽然能订阅,但是得不到数据;
//参数:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
//	   指向一个已被初始化,发布者要发布的数据存储变量的指针;
//返回值:错误则返回ERROR;成功则返回一个可以发布主题的句柄;如果待发布的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
orb_advert_t att_pub = orb_advertise(ORB_ID(vehicle_attitude), &att);

/* 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;

for (int i = 0; i < 5; i++) {
	/* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */
	//添加等待订阅消息的时间,非阻塞,如果订阅n个消息,②将修改第二个参数n
	int poll_ret = px4_poll(fds, 1, 1000);

	/* 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语句fd[n]...
		if (fds[0].revents & POLLIN) {
		
			/* obtained data for the first file descriptor */
			//创建来自sensor_combined.h的sensor_combined_s结构体实例;注意结构体 *_s
			struct sensor_combined_s raw;
			
			/* copy sensors raw data into local buffer */
			//读取sensor_sub_fd的数据到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]);

			/* set att and publish this information for other apps
			 the following does not have any meaning, it's just an example
			*/
			//只是试验例程,无功能意义;raw数组中的数据赋值给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];
			
			//实现向vehicle_attitude消息中发布数据
			orb_publish(ORB_ID(vehicle_attitude), 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MQTT是一种轻量级的发布/订阅协议,让我们来看看如何使用C语言实现MQTT发布订阅接口。 首先,需要使用MQTT客户端库,例如Eclipse Paho,这是一款流行的跨平台MQTT客户端库,支持C语言。可以通过以下代码行安装Eclipse Paho: ``` git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c make ``` 接下来,让我们看看如何实现MQTT发布订阅接口: ### MQTT发布接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientPub" #define TOPIC "MQTT Examples" #define PAYLOAD "Hello World!" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } pubmsg.payload = PAYLOAD; pubmsg.payloadlen = strlen(PAYLOAD); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); printf("Message with delivery token %d delivered\n", token); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT发布接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,设置MQTT消息的主题、负载、QoS和保留。最后,使用MQTTClient_publishMessage函数将消息发布到MQTT代理,使用MQTTClient_waitForCompletion函数等待发布完成,并使用MQTTClient_disconnect函数断开连接。 ### MQTT订阅接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "MQTT Examples" #define QOS 1 #define TIMEOUT 10000L volatile MQTTClient_deliveryToken deliveredtoken; void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause) { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_token token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } MQTTClient_subscribe(client, TOPIC, QOS); MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); while (1) { // do something } MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT订阅接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,使用MQTTClient_subscribe函数订阅MQTT消息,并设置MQTTClient_setCallbacks回调函数处理MQTT消息。最后,使用while循环等待MQTT消息的到来。 以上就是使用C语言实现MQTT发布订阅接口的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值