前一篇学习了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.py

    XML文件定位可以直接定位到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消息
    接收自定义消息主要通过修改mavlink_receiver.hmavlink_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里面看不到该消息发布的数据,哪位高手能告诉我哪错了……

          

[pixhawk笔记]7-MAVLink添加自定义消息的更多相关文章

  1. [pixhawk笔记]4-如何写一个简单的应用程序

    本文主要内容来自于:https://dev.px4.io/en/tutorials/tutorial_hello_sky.html,并对文档中的部分问题进行更正. 本文假设已经建立好开发环境并能正确编 ...

  2. [cocos2dx笔记004] android添加�静态库project

    (基于2.2.2版本号) 这步比較麻烦,不像vs2013那样好设置.參考了非常多文章.还是不能解决这个问题.仅仅有慢慢摸索了.在这里贴出来,希望能让大家能少走点弯路. 还是其于前面的文章提到的myli ...

  3. 笔记-python-动态添加属性

    笔记-python-动态添加属性 1.      添加对象/类属性 添加对象属性 class Person(object): def __init__(self, newName, newAge): ...

  4. [pixhawk笔记]5-uORB消息传递

    本文主要内容翻译自官方文档:https://dev.px4.io/en/middleware/uorb.html 在前一篇笔记中使用uORB完成消息传递,实现了一个简单示例程序,本文将对uORB进行系 ...

  5. MFC添加自定义消息

    由于MFC中无法通过类向导来自定义消息,所以需要手动添加,主要过程如下: 本文基于vs2008下通过线程实现数据实时更新的对话框运用程序 1. 定义消息(Resource.h文件中): 由于很多新控件 ...

  6. MFC开发中添加自定义消息和消息响应函数

    (1)在.h或.cpp文件定义一个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗口ctrl.cpp发送消息 //自定义消 ...

  7. SpringBoot添加自定义消息转换器

    首先我们需要明白一个概念:springboot中很多配置都是使用了条件注解进行判断一个配置或者引入的类是否在容器中存在,如果存在会如何,如果不存在会如何. 也就是说,有些配置会在springboot中 ...

  8. [pixhawk笔记]8-半物理仿真环境

    通过半物理仿真,可以在不试飞的情况下对飞控的软硬件进行部分验证,下面结合文档对半物理仿真环境的搭建和运行进行学习.先跑起来再说. Pixhawk支持多轴和固定翼的仿真,多轴用jMavSim,固定翼用X ...

  9. [pixhawk笔记]2-飞行模式

    本文翻译自px4官方开发文档:https://dev.px4.io/en/concept/flight_modes.html  ,有不对之处,敬请指正. pixhawk的飞行模式如下: MANUAL( ...

随机推荐

  1. 1358 棋盘游戏[状压dp]

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 这个游戏在一个有10*10 ...

  2. iOS json解析中包含“\n”等解析出错

    文题算是解决了,把特殊字符替换一下:-(NSString *)JSONString:(NSString *)aString {    NSMutableString *s = [NSMutableSt ...

  3. hibernate配置文件分析

    <!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...

  4. ERR_PTR,PTR_ERR还有IS_ERR函数详解

    内核中的函数常常返回指针,问题是如果出错,也希望能够通过返回的指针体现出来. 总体来说,如果内核返回一个指针,那么有三种情况:合法指针,NULL指针和非法指针. 1)合法指针:内核返回的指针一般是指向 ...

  5. Net Core MVC6 RC2 启动过程分析

    入口程序 如果做过Web之外开发的人,应该记得这个是标准的Console或者Winform的入口.为什么会这样呢?.NET Web Development and Tools Blog ASP.NET ...

  6. new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

    new运算符 - JavaScript | MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operator ...

  7. JPA 入门程序及相关注解

    1. 概述 JPA(Java Persistence API):用于对象持久化的API; JPA本质上是一种ORM规范,不是ORM框架;提供了一些编程的API接口; Hibernate是实现; 1.1 ...

  8. 微信js分享朋友圈(二)

    近期又用到微信分享的功能了.虽然不是第一次用了,依然我又有幸踩到了一个坑,所以分享一下吧. 根据微信sdk写的代码一步步很顺利,但是后面就是获取微信返回的分享结果的回调的时候IOS老是有问题,然后就网 ...

  9. 【我的Android进阶之旅】推荐一款视频转换GIF图片格式的转换工具(Video to GIF)

    一.背景 最近想把一些Android Demo的运行效果图获取下来,但是一直使用真机进行调试,在电脑上不好截取一段gif动画.而之前使用模拟器的时候可以使用 GifCam 工具进行屏幕动画截取.Gif ...

  10. Mybatis框架学习总结-表的关联查询

    一对一关联 创建表和数据:创建一张教师表和班级表,这里假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关系. CREATE TABLE teacher( t_id INT PRIM ...