[pixhawk笔记]7-MAVLink添加自定义消息
前一篇学习了uORB,用于px4中各个模块的进程间通信,下来学习MAVLink,用于飞控和地面站之间的通信。教程中主要给出了使用MAVLink的发送和接收消息的方法。
完整的MAVLink消息列表见该网页。
- 创建一个自定义MAVLink消息
假设存在/msg/ca_trajectory.msg定义了ca_trajectory的uORB主题。(笔者下载到的代码中没有自定义的ca_trajectory主题)
如果没有,自行在/msg文件夹下面添加ca_trajectory.msg,笔者添加内容如下(该内容来自于Fantasy大神的博客):uint64_t time_start_usec
uint64_t time_stop_usec
uint32_t coefficients
uint16_t seq_id #TOPICS ca_trajectory同时在mavlink/include/mavlink/v2.0/custom_message/mavlink_msg_ca_trajectory.h中存在ca_trajectory的自定义mavlink消息。(笔者下载的代码中也没有该部分)
没有的话可以自己添加自定义mavlink消息,教程见官方文档。
先自定义在mavlink/include/mavlink/v2.0/message_definitions/下创建自定义消息custom_message.xml文件,与ca_trajectory中结构一致,内容如下:<?xml version="1.0"?>
<mavlink>
<include>common.xml</include>
<!-- NOTE: If the included file already contains a version tag, remove the version tag here, else uncomment to enable. -->
<!--<version>3</version>-->
<enums>
</enums>
<messages>
<message id="166" name="CA_TRAJECTORY">
<description>This message encodes all of the raw rudder sensor data from the USV.</description>
<field type="uint64_t" name="timestamp">Timestamp in milliseconds since system boot</field>
<field type="uint64_t" name="time_start_usec">start time, unit usec.</field>
<field type="uint64_t" name="time_stop_usec">stop time, unit usec.</field>
<field type="uint32_t" name="coefficients">as it says.</field>
<field type="uint16_t" name="seq_id">can not cheat any more.</field>
</message>
</messages>
</mavlink>注意需要添加一个timestamp的成员,因为在编译时为了记录,会增加一个timestamp的成员。然后使用mavlink generator生成c语言源文件。
没有mavlink generator的同学可以用git下载并使用:git clone https://github.com/mavlink/mavlink mavlink-generator
cd mavlink-generator
python mavgenerate.pyXML文件定位可以直接定位到mavlink/include/mavlink/v2.0/message_definitions/custom_message.xml,Out目录定位到mavlink/include/mavlink/v2.0/,注意语言选择C,协议选择2.0,如下图所示:

然后点击Generate即可生成c代码源文件。
- 发送自定义MAVLink消息
自定义信息的发送主要通过修改src/modules/mavlink/下的mavlink_messsages.cpp文件来实现。- 添加自定义消息的头文件
#include <uORB/topics/ca_trajectory.h>
#include <v2.0/custom_messages/mavlink_msg_ca_trajectory.h>注意添加到已有包含文件的尾部,否则编译时可能会出现类型为定义的错误。
创建自定义消息对应的类
class MavlinkStreamCaTrajectory : public MavlinkStream
{
public:
const char *get_name() const
{
return MavlinkStreamCaTrajectory::get_name_static();
} static const char *get_name_static()
{
return "CA_TRAJECTORY";
} static uint16_t get_id_static()
{
return MAVLINK_MSG_ID_CA_TRAJECTORY;
} uint16_t get_id()
{
return get_id_static();
} static MavlinkStream *new_instance(Mavlink *mavlink)
{
return new MavlinkStreamCaTrajectory(mavlink);
} unsigned get_size()
{
return MAVLINK_MSG_ID_CA_TRAJECTORY_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES;
} private:
MavlinkOrbSubscription *_sub;
uint64_t _ca_traj_time; /* do not allow top copying this class */
MavlinkStreamCaTrajectory(MavlinkStreamCaTrajectory &);
MavlinkStreamCaTrajectory& operator = (const MavlinkStreamCaTrajectory &); protected:
explicit MavlinkStreamCaTrajectory(Mavlink *mavlink) : MavlinkStream(mavlink),
_sub(_mavlink->add_orb_subscription(ORB_ID(ca_trajectory))), // make sure you enter the name of your uorb topic here
_ca_traj_time(0)
{} bool send(const hrt_abstime t)
{
struct ca_trajectory_s _ca_trajectory; //make sure ca_trajectory_s is the definition of your uorb topic if (_sub->update(&_ca_traj_time, &_ca_trajectory)) { mavlink_ca_trajectory_t msg;//make sure mavlink_ca_trajectory_t is the definition of your custom mavlink message msg.timestamp = _ca_trajectory.timestamp;
msg.time_start_usec = _ca_trajectory.time_start_usec;
msg.time_stop_usec = _ca_trajectory.time_stop_usec;
msg.coefficients =_ca_trajectory.coefficients;
msg.seq_id = _ca_trajectory.seq_id; mavlink_msg_ca_trajectory_send_struct(_mavlink->get_channel(), &msg);
return true;
}
return false;
}
};注意该类的函数成员返回类型和MAVLink v1.0稍有不同,笔者发现下载到的master分支和stable分支的函数类型都有所不同,具体以下载代码为准,可以参考代码中已有的其他消息例子来编写。
在附加流类中添加该自定义项
StreamListItem *streams_list[] = {
...
new StreamListItem(&MavlinkStreamCaTrajectory::new_instance, &MavlinkStreamCaTrajectory::get_name_static, &MavlinkStreamCaTrajectory::get_id_static),
nullptr
};
- 添加自定义消息的头文件
- 在mavlink_main.cpp中加入自定义消息的更新频率:
configure_stream("CA_TRAJECTORY", 100.0f);
- 在mavlink_main.cpp中加入自定义消息的更新频率:
- 接收自定义MAVLink消息
接收自定义消息主要通过修改mavlink_receiver.h和mavlink_receiver.cpp来实现,加入一个消息处理函数,并调用他。- 在mavlink_receiver.h中加入如下代码:
- 添加自定义消息头文件:
#include <uORB/topics/ca_trajectory.h>
#include <v2.0/custom_messages/mavlink_msg_ca_trajectory.h> - 在类中添加一个uORB消息发布者
orb_advert_t _ca_traj_msg_pub;
在类Mavlink_Receiver中增加一个消息处理函数
void handle_message_ca_trajectory_msg(mavlink_message_t *msg);
- 添加自定义消息头文件:
在mavlink_receiver.cpp中加入如下代码:
- 实现消息处理函数
void
MavlinkReceiver::handle_message_ca_trajectory_msg(mavlink_message_t *msg)
{
mavlink_ca_trajectory_t traj;
mavlink_msg_ca_trajectory_decode(msg, &traj); struct ca_trajectory_s f;
memset(&f, 0, sizeof(f)); f.timestamp = hrt_absolute_time();
f.seq_id = traj.seq_id;
f.time_start_usec = traj.time_start_usec;
f.time_stop_usec = traj.time_stop_usec;
f.coefficients = traj.coefficients; if (_ca_traj_msg_pub == nullptr) {
_ca_traj_msg_pub = orb_advertise(ORB_ID(ca_trajectory), &f); } else {
orb_publish(ORB_ID(ca_trajectory), _ca_traj_msg_pub, &f);
}
}在该函数中实现了对消息的解包及发布。
在MavlinkReceiver::handle_message()中调用消息处理函数
MavlinkReceiver::handle_message(mavlink_message_t *msg)
{
switch (msg->msgid) {
...
case MAVLINK_MSG_ID_CA_TRAJECTORY:
handle_message_ca_trajectory_msg(msg);
break;
...
}
...
}但是,在nsh里面看不到该消息发布的数据,哪位高手能告诉我哪错了……
- 实现消息处理函数
- 在mavlink_receiver.h中加入如下代码:
[pixhawk笔记]7-MAVLink添加自定义消息的更多相关文章
- [pixhawk笔记]4-如何写一个简单的应用程序
本文主要内容来自于:https://dev.px4.io/en/tutorials/tutorial_hello_sky.html,并对文档中的部分问题进行更正. 本文假设已经建立好开发环境并能正确编 ...
- [cocos2dx笔记004] android添加�静态库project
(基于2.2.2版本号) 这步比較麻烦,不像vs2013那样好设置.參考了非常多文章.还是不能解决这个问题.仅仅有慢慢摸索了.在这里贴出来,希望能让大家能少走点弯路. 还是其于前面的文章提到的myli ...
- 笔记-python-动态添加属性
笔记-python-动态添加属性 1. 添加对象/类属性 添加对象属性 class Person(object): def __init__(self, newName, newAge): ...
- [pixhawk笔记]5-uORB消息传递
本文主要内容翻译自官方文档:https://dev.px4.io/en/middleware/uorb.html 在前一篇笔记中使用uORB完成消息传递,实现了一个简单示例程序,本文将对uORB进行系 ...
- MFC添加自定义消息
由于MFC中无法通过类向导来自定义消息,所以需要手动添加,主要过程如下: 本文基于vs2008下通过线程实现数据实时更新的对话框运用程序 1. 定义消息(Resource.h文件中): 由于很多新控件 ...
- MFC开发中添加自定义消息和消息响应函数
(1)在.h或.cpp文件定义一个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗口ctrl.cpp发送消息 //自定义消 ...
- SpringBoot添加自定义消息转换器
首先我们需要明白一个概念:springboot中很多配置都是使用了条件注解进行判断一个配置或者引入的类是否在容器中存在,如果存在会如何,如果不存在会如何. 也就是说,有些配置会在springboot中 ...
- [pixhawk笔记]8-半物理仿真环境
通过半物理仿真,可以在不试飞的情况下对飞控的软硬件进行部分验证,下面结合文档对半物理仿真环境的搭建和运行进行学习.先跑起来再说. Pixhawk支持多轴和固定翼的仿真,多轴用jMavSim,固定翼用X ...
- [pixhawk笔记]2-飞行模式
本文翻译自px4官方开发文档:https://dev.px4.io/en/concept/flight_modes.html ,有不对之处,敬请指正. pixhawk的飞行模式如下: MANUAL( ...
随机推荐
- ORA-01102的解决办法
启动数据库时报错了! SQL> startup mount ORACLE instance started. Total System Global Area 608174080 bytes ...
- PHP 开发环境的搭建和使用02--整合让apache处理php
PHP5.3.5直接下载解压即可.但是怎样才能让apache处理php呢? 1/ 在apache 的conf目录下 的 httpd.conf(用于指定apache的设置)加入如下代码: Load ...
- Python全栈day10(基本数据类型及其常用方法)
一,数字 1,int 将字符串转化成数字 a = '123' b=int(a) b=123 2,以进制方式进行转换 num="a" >>> num = " ...
- java讲讲几种常见的排序算法(二)
java讲讲几种常见的排序算法(二) 目录 java讲讲几种常见的排序算法(一) java讲讲几种常见的排序算法(二) 堆排序 思路:构建一个小顶堆,小顶堆就是棵二叉树,他的左右孩子均大于他的根节点( ...
- 【Python算法】归纳、递归、归简
归简法(reduction) 指的是将某一问题转化成另一个问题,将一个未知问题归简成一个已解决的问题. 归纳法(induction) 首先要证明语句在某一基本情况下是成立的,然后证明他可以由一个对象推 ...
- CentOS 部署openVPN
一.openVPN工作原理 VPN技术通过密钥交换.封装.认证.加密手段在公共网络上建立起私密的隧道,保障传输数据的完整性.私密性和有效性.OpenVPN是近年来新出现的开放源码项目,实现了SSLVP ...
- Spark源码分析 -- TaskScheduler
Spark在设计上将DAGScheduler和TaskScheduler完全解耦合, 所以在资源管理和task调度上可以有更多的方案 现在支持, LocalSheduler, ClusterSched ...
- mysql创建索引时报错1170
MySQL只能将BLOB/TEXT类型字段设置索引为BLOB/TEXT数据的前N个字符. 索引指定下col2的长度就可以了 :alter table foo add index col_2 (col2 ...
- TCP和UDP的区别?
答:TCP提供面向连接的.可靠的数据流传输,而UDP提供的是非面向连接的.不可靠的数据流传输.TCP传输单位称为TCP报文段,UDP传输单位称为用户数据报.TCP注重数据安全性,UDP数据传输快,因为 ...
- Python并行编程(七):线程同步之事件
1.基本概念 事件是线程之间用于通讯的对象.有的线程等待信号,有的线程发出信号.基本上事件对象都会维护一个内部变量,可以通过set方法设置为true,也可以通过clear方法设置为false.wait ...