Mavlink协议理解Pixhawk APM(三)
来源:互联网 发布:破解美国加密软件 编辑:程序博客网 时间:2024/05/17 09:16
有问题请回复评论,然后邮箱提醒我回复,550746284@qq.com 私信不回。。。
本文在上两篇博客的基础上,介绍mavlink代码的结构和编解码流程。mavlink有很多的版本,虽然都是mavlink v1.0,但还是有很多不一样的地方,不同飞控,不同时间的mavlink文件都会不一样,笔者讲的mavlink是在这里下载的<a target=_blank href="https://github.com/mavlink/c_library">https://github.com/mavlink/c_library</a>。mavlink代码全部由头文件组成,可以很方便的添加到你自己的代码中。
可以看到,里面有多个文件夹和几个头文件。pixhawk,ardupilotmega(apm),matrixpilot这类的文件夹里都是各个飞控自己定义的mavlink消息类型,原始的mavlink消息放在common文件夹里面(大部分消息都在common文件夹中)。checksum.h中存放的是计算校验码的代码。 mavlink_helper.h里面是将各个消息包补充完整(调用checksum.h中的函数计算校验码并补上消息帧的头,比如sysid和compid等)成为mavlink消息帧再发送。最主要的功能集中在这两个文件夹中。mavlink_conversions.h里是dcm,欧拉角,四元数三种姿态表示方法之间的转换代码。
下面以发送心跳包(heartbeat)为例,说明下如何使用mavlink头文件来发送心跳包。首先打开common文件夹中的 mavlink_msg_heartbeat.h 头文件。这个头文件可以分为两部分,一部分用来打包、发送heartbeat消息,另一部分用来接收到heartbeat消息时解码消息。heartbeat.h定义了heartbeat消息对应的数据类型:
typedef struct __mavlink_heartbeat_t{ uint32_t custom_mode; ///< A bitfield for use for autopilot-specific flags. uint8_t type; ///< Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) uint8_t autopilot; ///< Autopilot type / class. defined in MAV_AUTOPILOT ENUM uint8_t base_mode; ///< System mode bitfield, see MAV_MODE_FLAG ENUM in mavlink/include/mavlink_types.h uint8_t system_status; ///< System status flag, see MAV_STATE ENUM uint8_t mavlink_version; ///< MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version} mavlink_heartbeat_t;
static inline void mavlink_msg_heartbeat_send(mavlink_channel_t chan, uint8_t type, uint8_t autopilot, uint8_t base_mode, uint32_t custom_mode, uint8_t system_status)
其中的chan是channel的缩写,用于选择发送的串口或者usb口。type就是飞行器类型,其余参数不明的可以看看本博客的第一篇文章。
该函数功能是将传入的各个参数按照对应的格式放到heartbeat消息包中(即打包)
这个函数内部有一句预处理:
#if MAVLINK_CRC_EXTRA
是说是否使用额外的crc校验字符(默认使用),详情请看第一篇博客中对于两个校验字节的说明。
函数中会调用函数【2】
_mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HEARTBEAT, buf, MAVLINK_MSG_ID_HEARTBEAT_LEN, MAVLINK_MSG_ID_HEARTBEAT_CRC);
MAVLINK_MSG_ID_HEARTBEAT//这个是心跳包消息对应的编号 这里=0
MAVLINK_MSG_ID_HEARTBEAT_LEN//这个是心跳包的长度 注意这个长度仅仅是payload的长度,不包括帧的头尾。
MAVLINK_MSG_ID_HEARTBEAT_CRC//这个是heartbeat消息对应的额外的crc校验码 这里=50这个函数位于mavlink_helper.h中,用于更新消息帧的编号(seq 每发送一帧加1)并将消息帧的头和计算校验码,使得成为完整的一个mavlink消息帧。最后调用串口发送函数进行消息帧的发送。
如果只是想将对应的心跳包参数按照心跳包的格式存放好,则可以只调用
static inline uint16_t mavlink_msg_heartbeat_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, uint8_t type, uint8_t autopilot, uint8_t base_mode, uint32_t custom_mode, uint8_t system_status)将参数打包为heartbeat消息帧,待之后使用。
解码消息帧时可以调用mavlink_helper.h中的
MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
它会将收到的字符一个个进行解码,会检验收到的校验码是否正确;有效载荷的长度小于最大长度并且和该消息的长度一致。如果一切顺利,将会得到解码到的消息,放在解码得到的消息帧类型中
typedef struct __mavlink_message {uint16_t checksum; ///< sent at end of packetuint8_t magic; ///< protocol magic markeruint8_t len; ///< Length of payloaduint8_t seq; ///< Sequence of packetuint8_t sysid; ///< ID of message sender system/aircraftuint8_t compid; ///< ID of the message sender componentuint8_t msgid; ///< ID of message in payloaduint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];} mavlink_message_t;其中的magic是一帧的起始标志(FE=254),就是mavlink_stx的值。
其余的mavlink消息也是类似的,旧的mavlink代码中有些类型的消息类型可能会找不到,使用时要注意接受和发送方使用的mavlink版本是否兼容。common文件夹中的common.h里面包含了要用到的数据类型和所有消息的头文件,使用时直接包含进来即可。
mavlink系列博客到此告一段落,请多指正。有错误欢迎回复评论,或联系我。
- Mavlink协议理解Pixhawk APM(三)
- Mavlink协议理解Pixhawk APM(一)
- Mavlink协议理解Pixhawk APM(二)
- STM32控制APM飞控(四)MAVLINK协议深入理解之数据结构
- MAVLINK协议理解
- pixhawk-----mavlink
- STM32控制APM飞控(三)MAVLINK整合并适配stm32串口的收发
- Pixhawk原生固件PX4之MAVLink协议解析
- MAVLink协议通信分析——(三)消息解析
- pixhawk学习笔记-----mavlink
- pixhawk学习笔记-----mavlink
- STM32控制APM飞控(五)MAVLINK的C源码的解释及MAVLINK心跳包
- APM 、PX4, PIXHAWK
- 开源飞控APM与PIXHAWK
- Mavlink协议
- STM32控制APM飞控(二)MAVLINK源码集成到stm32工程中
- APM代码中MAVLINK的初步分析。
- MAVLink C# APM 控制输出方法
- 武汉大学GNSS中心给IGS提供的数据产品下载地址
- 第五周上机实践项目3——用多文件组织多个类的程序
- 通知控件的使用步骤
- Path Sum--LeetCode
- WEP
- Mavlink协议理解Pixhawk APM(三)
- jsp超链接<a href="../servlet/DeleteProject?pid=<%=rs.getInt("pid")%>">删除</a>传参数到servlet时出现404错误
- 经典递归问题
- AndroidStudio参考资料整理
- zoj 3329 One Person Game(概率(期望)+dp)经典
- linux内存管理学习笔记
- 我的24小时-Intel Galileo Gen 2入门
- 坚持ACM!!!
- Linux - 系统文件结构