前言

在大致了解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源码中添加自己的程序

PX4代码解析(2)相关推荐

  1. PX4代码解析(5)

    一.前言 我所讨论的PX4代码是基于v1.11版本,该版本与之前的版本有不少不同,其中一个比较大的区别在于新版本大部分用到了C++中模板,使得代码没有以前那么容易理解,因此我在后面介绍PX4的姿态估计 ...

  2. PX4代码解析(6)

    一.前言 上一节介绍了PX4姿态估计调用函数的流程,这一节分享一下我对PX4姿态解算的解读.首先,要理解PX4姿态解算的程序,要先从传感器的特性入手,这里主要介绍的传感器有加速度计,磁力计,陀螺仪. ...

  3. px4代码解析(3)

    前言 在使用PX4飞控时,我们难免要对其进行二次开发,例如修改控制算法,添加新的传感器,这时需要在代码中定义属于自己的消息.本节主要分享一下如何在PX4代码中添加自己的消息 一.消息添加与配置 从代码 ...

  4. PX4代码解析(1)

    前言 做pixhawk飞控有一段时间了,但在学习过程中遇到许多困难,目前网上找不到比较完整的PX4学习笔记,我打算结合自己理解,写写自己对PX4源码的理解,不一定对,只是希望与各位大佬交流交流,同时梳 ...

  5. PX4代码解析(4)

    一.引言 PX4程序是基于实时操作系统(Real-time operating system, RTOS)的上层应用程序,PX4飞控程序的很多重要模块都是在Nuttx操作系统的调度下运行的.因此,想要 ...

  6. PX4代码解析:振动分析

    本篇文章首发于公众号:无人机系统技术.更多无人机技术相关文章请关注此公众号 一.前言 前面的文章主要都是一些理论知识为主,很多读者朋友看了之后可能会有点枯燥,里面很多公式看起来也比较晦涩,今天起给大家 ...

  7. px4代码jlink调试

    之前看了许多介绍px4环境搭建的文章有介绍windows下eclipse和ubuntu下eclipse阅读px4源码的文章,但是没有看到对px4进行代码调试的文章,后来查看px官网发现可以通过visu ...

  8. PX4代码学习系列博客(6)——offboard模式位置控制代码分析(之前转载过,这是第二次转载了)

    我刚刚发现这篇文章去年八月份的时候转载过一次了 https://blog.csdn.net/sinat_16643223/article/details/107874349 转载自:https://b ...

  9. matrix_multiply代码解析

    matrix_multiply代码解析 关于matrix_multiply 程序执行代码里两个矩阵的乘法,并将相乘结果打印在屏幕上. 示例的主要目的是展现怎么实现一个自定义CPU计算任务. 参考:ht ...

最新文章

  1. pandas数据转换时遇到不能转换的数据转为NaN的参数设置errors='coerce'
  2. js 的 math 函数
  3. matlab宏参赛,MATLAB杯无人机大赛 | 决赛通知!
  4. Web笔记-使用jsonp解决跨域请求(CROS)问题
  5. 深度学习自学(三十七):基于用户自定义要求3D房间自动设计研究
  6. java实现数据的Excel导出(合并单元格、样式等)
  7. Hyper-V 2016 系列教程40 使用 PowerShell 实现虚拟机自动化和管理虚拟机
  8. 探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页...
  9. Windows-Server-2012-如何实现多个用户远程桌面登陆
  10. Navicat Premium 15 工具自动被杀毒防护软件删除解决方法
  11. 怎么获取jquery版本_获取jQuery版本
  12. Java生成csv文件设置文本格式
  13. 计算机科学导论二分法实验报告,二分法上机实验报告.doc
  14. NYOJ 62 笨小熊
  15. 磨金石教育学剪辑是正规的教育机构吗?小白学剪辑怎么样?有什么学习方法?
  16. caj打印PDF提示打印超范围应该怎么办?
  17. 【HAN】代码逐句理解三
  18. 抑制细胞代谢紊乱的抑制剂
  19. 大数据(052)Oozie【Oozie介绍 CDH安装Oozie】
  20. 改善Unity编辑器对Lua文件的支持

热门文章

  1. GridView批量删除页面最后N条数据时自动翻到上一页问题
  2. Exchaneg 2013 集成OWAS
  3. KeyMob具有手机广告优化的管理平台
  4. Linux学习命令总结个人及个人心得
  5. 如何从一个吊丝男成为一个合格的高级程序员
  6. 团队项目:过山车游戏的设想
  7. 程序员,该注意下啦!
  8. React native 第三方组件 React native swiper
  9. 关于c3样式在浏览器上的兼容问题
  10. 集群负载均衡之lvs和keepalived