PX4代码解析(2)

article/2025/10/8 11:05:01

前言

在大致了解PX4代码架构后,我们需要了解PX4的通信机制。在PX4代码架构中,每通信总线主要分为两个部分,一是内部通信总线uORB,即PX4内部进程通信采用的协议,例如PX4内部姿态控制需要获取飞行器姿态,而飞行器姿态是由姿态解算产生,它们之间便是由uorb通信
二是外部通信总线Mavlink,它主要负责飞控端与地面站系统的通信协议,后续会详细讲解,本章主要先了解uorb。本章分为三个部分,先介绍uorb基础,然后结合源码讲解怎么使用uorb,最后实际操作练手

一、uorb基础

关于这一部分,CSDN上有很多大佬对uorb进行了详细的讲解,我写的不一定有他们好,就不献丑了,推荐阅读
1、http://shequ.dimianzhan.com/articles/315
2、https://blog.csdn.net/freeape/article/details/46880637
看完之后,你就会对uorb有一定的了解,说简单点,在uorb中,发送者只管发送消息到消息池中,不管谁去调用,接收者只管去消息池中获得需要的消息,不管消息是谁发布的,示意图如下
在这里插入图片描述
在了解uorb后 ,下面以官方例程开始讲解怎么使用uorb

二、uorb代码讲解

在官方提供的px4代码中,有一个历程就是讲解uorb使用的,首先进入PX4目录下src/example目录,找到px4_simple_app,如下图所示
在这里插入图片描述在px4_simple_app下有一个c文件,直接打开

//需要使用的头文件
#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>
#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[])
{//在控制台输出Hello SkyPX4_INFO("Hello Sky!");//定义句柄接收名为sensor_combined的消息int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));//定义更新频率orb_set_interval(sensor_sub_fd, 200);//定义结构体变量,并完成初始化struct vehicle_attitude_s att;memset(&att, 0, sizeof(att));//向系统公告自己要发布消息,完成初始化,在系统中创建一个主题,并返回指针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) *///检查1s内是否有数据更新//int poll_ret = px4_poll(fds, 1, 1000);/* handle the poll result *///返回值为0,证明1s内数据没有更新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) {//返回值为-1,证明出错/* 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 {//返回值大于0,说明得到数据后还剩poll_ret时间if (fds[0].revents & POLLIN) {/* obtained data for the first file descriptor *///定义sensor_combined的结构体,接收sensor_combined的消息struct sensor_combined_s raw;/* copy sensors raw data into local buffer *///把消息复制出来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 appsthe 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];//发布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.在代码中我们看到了vehicle_attitude_s,sensor_combined_s的结构体,有人会好奇这些结构体怎么产生的。实际上,这些结构体是由我们之前定义好的msg编译产生,即系统根据你之前定义的消息自动生成。打开PX4目录,进入其中msg文件夹,你会看到许多以.msg结尾的文件,如下图
在这里插入图片描述
我们可以在其中找到sensor_combined.msg文件,打开文件

uint64 timestamp				# time since system start (microseconds)int32 RELATIVE_TIMESTAMP_INVALID = 2147483647	# (0x7fffffff) If one of the relative timestamps is set to this value, it means the associated sensor values are invalid# gyro timstamp is equal to the timestamp of the message
float32[3] gyro_rad			# average angular rate measured in the XYZ body frame in rad/s over the last gyro sampling period
uint32 gyro_integral_dt		# gyro measurement sampling period in usint32 accelerometer_timestamp_relative	# timestamp + accelerometer_timestamp_relative = Accelerometer timestamp
float32[3] accelerometer_m_s2		# average value acceleration measured in the XYZ body frame in m/s/s over the last accelerometer sampling period
uint32 accelerometer_integral_dt	# accelerometer measurement sampling period in usuint8 CLIPPING_X = 1
uint8 CLIPPING_Y = 2
uint8 CLIPPING_Z = 4
uint8 accelerometer_clipping            # bitfield indicating if there was any accelerometer clipping (per axis) during the sampling period

我们可以看到其中定义的消息,结合之前的代码,可以看到px4_simple_app这个例子实际上是取出sensor_combined的加速度数据,并把它以vehicle_attitude话题发布出去,不过这些消息都是系统定义好的,后面会介绍怎么定义和使用自己的消息。
2.代码讲解完毕,但该代码一般情况下不会运行,因为飞控板上的资源非常少,一般是不编译的。控制是否编译的文件在board/px4中(若是V1.11之前的版本可能在cmake文件中),如下
在这里插入图片描述
这些不同文件夹是针对不同硬件的编译配置,打开以fmu开头的文件夹或者sitl,你会发现以.cmake结尾的文件,例如sitl,该文件夹主要主管仿真的相关配置
在这里插入图片描述在这些以.cmake结尾的文件中,我们常用default.cmake,打开文件

px4_add_board(PLATFORM posixVENDOR px4MODEL sitlLABEL defaultTESTINGDRIVERS#barometer # all available barometer drivers#batt_smbuscamera_capturecamera_trigger#differential_pressure # all available differential pressure drivers#distance_sensor # all available distance sensor driversgps#imu # all available imu drivers#magnetometer # all available magnetometer driverspwm_out_sim#telemetry # all available telemetry driverstone_alarm#uavcanMODULESairspeed_selectorattitude_estimator_qcamera_feedbackcommanderdatamanekf2eventsfw_att_controlfw_pos_control_l1land_detectorlanding_target_estimator#load_monlocal_position_estimatorloggermavlinkmc_att_controlmc_hover_thrust_estimatormc_pos_controlmc_rate_controlnavigatorrc_updatereplayrover_pos_controlsensors#sihsimulatortemperature_compensationvmountvtol_att_controluuv_att_controlSYSTEMCMDS#config#dumpfiledynesc_calibled_controlmixermotor_rampmotor_test#mtd#nshtermparamperfpwmrebootsd_benchshutdowntests # tests and test runner#toptopic_listenertune_controlverwork_queueEXAMPLESdyn_hello # dynamically loading modules examplefixedwing_control # Tutorial code from https://px4.io/dev/example_fixedwing_controlhellomy_demoapp#hwtest # Hardware test#matlab_csv_serialpx4_mavlink_debug # Tutorial code from http://dev.px4.io/en/debug/debug_values.htmlpx4_simple_app # Tutorial code from http://dev.px4.io/en/apps/hello_sky.htmlrover_steering_control # Rover example appuuv_example_appwork_item)set(config_sitl_viewer jmavsim CACHE STRING "viewer for sitl")
set_property(CACHE config_sitl_viewer PROPERTY STRINGS "jmavsim;none")set(config_sitl_debugger disable CACHE STRING "debugger for sitl")
set_property(CACHE config_sitl_debugger PROPERTY STRINGS "disable;gdb;lldb")# If the environment variable 'replay' is defined, we are building with replay
# support. In this case, we enable the orb publisher rules.
set(REPLAY_FILE "$ENV{replay}")
if(REPLAY_FILE)message(STATUS "Building with uorb publisher rules support")add_definitions(-DORB_USE_PUBLISHER_RULES)message(STATUS "Building without lockstep for replay")set(ENABLE_LOCKSTEP_SCHEDULER no)
else()set(ENABLE_LOCKSTEP_SCHEDULER yes)
endif()

你会看到一些比较熟悉的字母,例如DRIVERS,MODULES等,这正是我们src目录下的文件,而跟在这些文件夹之后的正是目录下的源代码,其实这份编译文件我已经修改过,在EXAMPLES下有px4_simple_app

三、px4_simple_app代码结果展示

验证代码结果,你可以将代码下载到支持PX4的硬件中,也可以采用jMavSim,gazebo等仿真软件进行半物理仿真,操作步骤如下
1.按上一章的讲解找到boards/px4/sitl文件夹,修改default.camke文件,在EXAMPLES下添加px4_simple_app
2.保存,在PX4目录下输入代码make px4_sitl_default jmavsim,等待编译成功
3.当出现下面界面就说明编译成功
在这里插入图片描述4.这时返回终端窗口,输入help,你会看到可以运行的代码,你会在其中找到px4_simple_app
在这里插入图片描述5.在终端输入px4_simple_app,会有以下结果
在这里插入图片描述
下章介绍如何在msg中添加自己的消息,并在PX4源码中添加自己的程序


http://chatgpt.dhexx.cn/article/AJF9UEeR.shtml

相关文章

Teams Bot App 代码解析

上一篇文章我们讲了如何使用 teams toolkit 来快速弄一个 teams bot&#xff0c;可以看到 toolkit 给我们提供了极大的方便性&#xff0c;让开发人员可以更好的把重心放在 coding 上&#xff0c;而不是各种配置上。 那我们这篇文章主要接着上篇&#xff0c;来解析一下 teams b…

代码分析(一)

2021SCSDUSC 分析前言 对于APIJSON的代码分析首先就是&#xff0c;看一下该项目的作用以及如何进行&#xff0c;看一下原来不部署这个项目的正常流程&#xff1a; 再来看一下部署上APIJSON后项目的流程走向&#xff1a; 接下来开始按照这个流程对相应的代码进行分析。 Abst…

Linux命令之lsusb

一、lsusb命令用于显示本机的USB设备列表&#xff0c;以及USB设备的详细信息。 二、lsusb命令显示的USB设备信息来自“/proc/bus/usb”目录下的对应文件。 三、Linux从/var/lib/usbutils/usb.ids识别USB设备的详细信息。 语法格式 lsusb [参数] 常用参数&#xff1a; -v显…

Linux命令-磁盘管理-lsusb

1 需求 2 语法 C:\>adb shell lsusb --help Toybox 0.8.4-android multicall binary: https://landley.net/toybox (see toybox --help)usage: lsusbList USB hosts/devices. 3 示例 adb shell lsusb 4 参考资料

嵌入式debian没有lsusb命令解决

问题 -bash: lsusb: command not found 解决

linux之lsusb命令和cd -命令使用总结

1、lsusb命令介绍 使用 lsusb 来列出 USB 设备和它的属性,lsusb 会显示驱动和内部连接到你系统的设备。直接在控制台输入 lsusb 即可 2、lsusb简单使用 在控制台输入 lsusb 效果如下 系统中同时使用了 USB 2.0 root hub 驱动和 USB 3.0 root hub 驱动。 bus 002 指明设备…

LSB

知识点 LSB即为最低有效位&#xff08;Least Significant Bit&#xff0c;lsb&#xff09;&#xff0c;这里百度了一下&#xff1a;图片中的图像像素一般是由RGB三原色&#xff08;红绿蓝&#xff09;组成&#xff0c;每一种颜色占用8位&#xff0c;取值范围为0x00~0xFF&#…

lsusb命令-在系统中显示有关USB设备信息

在 中我们使用lsusb 列出USB设备及其属性&#xff0c;lsusb用于显示系统中的USB总线及其连接的设备信息。下面介绍如何安装并使用。 系统环境 7 安装usbutils 默认Centos7系统中没有lsusb &#xff0c;我们需要安装usbutils安装包&#xff0c;才能使用lsusb&#xff1a; […

LSF-bsub命令

文章目录 一、LSF(load sharing facility)二、bsub命令三、 常用命令3.1 bhosts3.2 bqueues3.3 bjobs3.4 bkill3.5 bhist3.6 busers 一、LSF(load sharing facility) 分布资源管理的工具&#xff0c;用来调度、监视、分析联网计算机的负载。 目的&#xff1a;通过集中监控和调…

Linux下的lsusb命令详解

lsusb命令详解 参考&#xff1a; 1、https://zhuanlan.zhihu.com/p/142403866 2、https://blog.csdn.net/phmatthaus/article/details/124198879 简介 ​USB&#xff0c;是英文Universal Serial Bus&#xff08;通用串行总线&#xff09;的缩写&#xff0c;是一个外部总线标…

详解 lsusb命令

USB设备检测的一般过程 USB设备检测也是通过/proc目录下的USB文件系统进行的。为了使一个USB设备能够正常工作&#xff0c;必须要现在系统中插入USB桥接器模块。在检测开始时&#xff0c;一般要先检测是否存在/proc/bus/usb目录&#xff0c;若不存在则尝试插入USB桥接模块。 现…

lsusb

1.lsusb查看系统的USB设备 $ lsusb Bus 001 Device 006: ID 0951:1666 Kingston Technology Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 004: ID 0e0f:0008 VMware, Inc. Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB H…

Linux常用命令——lsusb命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) lsusb 显示本机的USB设备列表信息 补充说明 lsusb命令用于显示本机的USB设备列表&#xff0c;以及USB设备的详细信息。 lsusb命令是一个学习USB驱动开发&#xff0c;认识USB设备的助手&#xff0c;推荐大家使用…

Linux下lsusb命令详解

Linux下lsusb命令详解 参考链接&#xff1a;https://zhuanlan.zhihu.com/p/142403866 ​ USB&#xff0c;是英文Universal Serial Bus&#xff08;通用串行总线&#xff09;的缩写&#xff0c;是一个外部总线标准&#xff0c;早期用于规范电脑与外部设备的连接和通讯。 ​ U…

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署

1、Kong的概述 Kong是一个clould-native、快速的、可扩展的、分布式的微服务抽象层&#xff08;也称为API网关、API中间件或在某些情况下称为服务网格&#xff09;框架。Kong作为开源项目在2015年推出&#xff0c;它的核心价值是高性能和可扩展性。Kong被广泛用于从初创企业到全…

Konga arm64 安装

arm64 平台&#xff1a; 一、源码安装 konga 前提&#xff1a;安装nodejswget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-arm64.tar.xztar -xf node-v12.16.1-linux-arm64.tar.xz 配置node环境变量&#xff1a;vi /etc/profileexport NODE_HOME/home/node-v12.16…

kong/kongA docker部署+汉化

部署完成后界面 一、部署kong/kongA 1、创建一个自定义 Docker 网络以允许容器相互发现和通信&#xff1a; docker network create kong-net 2、启动一个 PostgreSQL 容器&#xff1a; sudo docker run -d --name kong-database \--networkkong-net \-v /opt/pgdata:/var/l…

konga--添加service和rouce详细步骤

注意&#xff1a;先有service后&#xff0c;才能创建rouce(可以有多个),包括删除顺序先删除route&#xff0c;再删除service。次序问题 1.添加service 是抽象层面的服务&#xff0c;他可以直接映射到一个物理服务 (host 指向 ip port)&#xff0c;也可以指向一个 upstream 来…

kong及konga的最新版本安装

1、创建docker网络 docker network create kong-net 2、运行postgresql的数据库 挂载 # docker volume create kong-volume # docker run -d --name kong-database \ --networkkong-net \ -p 5432:5432 \ -v kong-volume:/var…

使用Kong和Konga管理微服务和API

Kong是Mashape开源的高性能高可用API网关和API服务管理层。自2015年在github开源后&#xff0c;广泛受到关注。它基于OpenResty&#xff0c;进行API管理&#xff0c;并提供了插件实现API的AOP。Kong在Mashape 管理了超过15,000 个API&#xff0c;为200,000开发者提供了每月数十…