Development Guide

Create Custom MAVLink Messages

This tutorial assumes you have a custom uORB ca_trajectory message in msg/ca_trajectory.msg and a custom mavlink ca_trajectory message in mavlink/include/mavlink/v1.0/custom_messages/mavlink_msg_ca_trajectory.h (see here how to create a custom mavlink message and header).

Sending Custom MAVLink Messages

This section explains how to use a custom uORB message and send it as a mavlink message.

Add the headers of the mavlink and uorb messages to mavlink_messages.cpp

#include <uORB/topics/ca_trajectory.h>
#include <v1.0/custom_messages/mavlink_msg_ca_trajectory.h>

Create a new class in mavlink_messages.cpp

class MavlinkStreamCaTrajectory : public MavlinkStream
    const char *get_name() const
        return MavlinkStreamCaTrajectory::get_name_static();
    static const char *get_name_static()
        return "CA_TRAJECTORY";
    uint8_t get_id()
    static MavlinkStream *new_instance(Mavlink *mavlink)
        return new MavlinkStreamCaTrajectory(mavlink);
    unsigned get_size()

    MavlinkOrbSubscription *_sub;
    uint64_t _ca_traj_time;

    /* do not allow top copying this class */
    MavlinkStreamCaTrajectory(MavlinkStreamCaTrajectory &);
    MavlinkStreamCaTrajectory& operator = (const MavlinkStreamCaTrajectory &);

    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

    void send(const hrt_abstime t)
        struct ca_traj_struct_s _ca_trajectory;    //make sure ca_traj_struct_s is the definition of your uorb topic

        if (_sub->update(&_ca_traj_time, &_ca_trajectory)) {
            mavlink_ca_trajectory_t _msg_ca_trajectory;  //make sure mavlink_ca_trajectory_t is the definition of your custom mavlink message 

            _msg_ca_trajectory.timestamp = _ca_trajectory.timestamp;
            _msg_ca_trajectory.time_start_usec = _ca_trajectory.time_start_usec;
            _msg_ca_trajectory.time_stop_usec  = _ca_trajectory.time_stop_usec;
            _msg_ca_trajectory.coefficients =_ca_trajectory.coefficients;
            _msg_ca_trajectory.seq_id = _ca_trajectory.seq_id;

            _mavlink->send_message(MAVLINK_MSG_ID_CA_TRAJECTORY, &_msg_ca_trajectory);

Finally append the stream class to the streams_list at the bottom of mavlink_messages.cpp

StreamListItem *streams_list[] = {
new StreamListItem(&MavlinkStreamCaTrajectory::new_instance, &MavlinkStreamCaTrajectory::get_name_static),

Receiving Custom MAVLink Messages

This section explains how to receive a message over mavlink and publish it to uORB.

Add a function that handles the incoming mavlink message in mavlink_receiver.h

#include <uORB/topics/ca_trajectory.h>
#include <v1.0/custom_messages/mavlink_msg_ca_trajectory.h>

Add a function that handles the incoming mavlink message in the MavlinkReceiver class in mavlink_receiver.h

void handle_message_ca_trajectory_msg(mavlink_message_t *msg);

Add an uORB publisher in the MavlinkReceiver class in mavlink_receiver.h

orb_advert_t _ca_traj_msg_pub;

Implement the handle_message_ca_trajectory_msg function in mavlink_receiver.cpp

MavlinkReceiver::handle_message_ca_trajectory_msg(mavlink_message_t *msg)
    mavlink_ca_trajectory_t traj;
    mavlink_msg_ca_trajectory_decode(msg, &traj);

    struct ca_traj_struct_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;
    for(int i=0;i<28;i++)
        f.coefficients[i] = traj.coefficients[i];

    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);

and finally make sure it is called in MavlinkReceiver::handle_message()

MavlinkReceiver::handle_message(mavlink_message_t *msg)
     switch (msg->msgid) {