APM data over telemetry

Hi Folks,

 

I'm looking for a way to integrate telemetry data into a custom software project, for use in ground station processing of aerial images. Specifically, I need GPS coordinates and body angles of the aircraft in as close to real time as possible. I'm just getting started in programming with the serial port on the ground station computer, and I'm wondering if anyone can offer me any guidance as to how to proceed. Here's what I have so far:

 

- I can open the serial port and display data at intervals received over the serial port

- I can do this with the APM attached directly, or with the telemetry radio, but don't see any data, just blank characters.

 

So, I'm guessing now that I need to configure the APM to send me the data I'm looking for. I know it's capable of doing this because both the mission planner and QGroundControl get this data from the telemetry radio while in flight. My next step is to probably dive into the source code of QGroundControl and look at its implementation of the MAVLink protocol. I'm just wondering if maybe there's some documentation already written regarding this, or if anyone has done it before, before I jump straight into reading source code. 

As always, your thoughts and musings are appreciated. Thanks!

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • Hi Jake,

    I would like to know if i need to configure the APM to send the data. As from what I observe, the code given below is for the receiving end. Does that mean that the APM sends the data by default and we just have to receive and decode it?As I am quite new to the telemetry, so i really hope that you could somehow guide me through.

    • Goh,


      By default your APM is going to transmit some barebones messages over a telem link whenever one is installed. You can always configure exactly what data is transmitted every so often through the APM parameters. 

      To get started, I would just power up an APM with a telemetry unit installed, default configuration, and then attach your other telem unit to your computer with this code running. See if you get any results!

  • So, I have found my own answer after much experimentation. After examining the QGroundControl source code (no easy task, even though their code is beautifully organized and encapsulated), I found that the message handling functions employ a simple switch-case branch which operates on the messageID field of each message. 

    In the MAVLink library code, there are a great deal of helper functions for the messages. The basic process is to receive the message a byte array, and pass it to mavlink_parse_char(). This will create a message struct, with the sysid, gid, msgid properties. Then, you switch msgid and look for the values you're interested in. Find one, and use the corresponding MAVLink helper function to read that particular type of message. I've included a code snippet from my test project for anyone interested in this particular subject. 

    Also, I have attached the entire source code for this simple console app that talks to APM over the serial port. Built with Qt 4.8.4, using QtSerialPort for the hardware interface. Enjoy!

    [code]

    void parse_message(QByteArray inArray)
    {
    mavlink_message_t msg;
    mavlink_status_t status;

    for (int i = 0; i < inArray.size(); ++i)
    {
    if (mavlink_parse_char(MAVLINK_COMM_0, inArray[i], &msg, &status))
    {
    //qDebug() "\nReceived packet: SYS: " msg.sysid ", COMP: " msg.compid ", LEN: " msg.len ", MSG ID: " msg.msgid "\n";
    }
    }

    readMessage(msg,msg.msgid);
    //return msg;

    }

    void readMessage(mavlink_message_t msg, uint8_t msgid) {
    /*cout.precision(3);
    cout " omegaIx: " scientific mavlink_msg_ahrs_get_omegaIx(&msg);
    cout " omegaIy: " mavlink_msg_ahrs_get_omegaIy(&msg);
    cout " omegaIz: " mavlink_msg_ahrs_get_omegaIz(&msg);*/

    switch(msgid) {
    case MAVLINK_MSG_ID_ATTITUDE:
    mavlink_attitude_t attitude_struct;
    mavlink_msg_attitude_decode(&msg, &attitude_struct);
    qDebug() "Received Attitude Message";

    cout.precision(2);
    cout "\nRoll: " fixed attitude_struct.roll;
    cout "\nPitch: " fixed attitude_struct.pitch;
    cout "\nYaw: " fixed attitude_struct.yaw endl;

    break;

    case MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN:
    mavlink_gps_global_origin_t gps_global_origin_struct;
    mavlink_msg_gps_global_origin_decode(&msg, &gps_global_origin_struct);
    qDebug() "Received GPS Message";

    cout.precision(2);
    cout "\nLattitude: " fixed gps_global_origin_struct.latitude;
    cout "\nLongitude: " fixed gps_global_origin_struct.longitude;
    cout "\nAltitude: " fixed gps_global_origin_struct.altitude endl;
    break;

    case MAVLINK_MSG_ID_AHRS:
    mavlink_ahrs_t ahrs_struct;
    mavlink_msg_ahrs_decode(&msg, &ahrs_struct);
    qDebug() "Received AHRS Message\n";
    break;

    case MAVLINK_MSG_ID_GPS_RAW_INT:
    mavlink_gps_raw_int_t gps_raw_int_struct;
    mavlink_msg_gps_raw_int_decode(&msg, &gps_raw_int_struct);
    qDebug() "Received Raw GPS Struct";

    cout.precision(2);
    cout "\nLattitude: " fixed (float)gps_raw_int_struct.lat/(1E7);
    cout "\nLongitude: " fixed (float)gps_raw_int_struct.lon/(1E7);
    cout "\nAltitude: " fixed (float)gps_raw_int_struct.alt/1000 endl;
    break;

    default :
    break;
    };


    }

    [/code]

    main.cpp

    https://storage.ning.com/topology/rest/1.0/file/get/3692675416?profile=original
  • I should mention that I've opened the link with PuTTY, and was able to use the CLI just like in the mission planner. When I tell it to reboot and resume flight mode, though, I don't see any readable data, just garbled characters that I imagine are binary MAVLink data. 

This reply was deleted.

Activity