Incoming MAVLink data handling

I’ve written a local server in C that in a nutshell receives mavlink messages from multiple sources and is designed to relay them to clients that connect to it, including QGC.

However, I can’t seem to be able to reliably receive mavlink data in QGC over the TCP comm link. Some amount of HEARTBEAT and TIMESYNC messages get through, so at least something is meshing.

I’ve seen various posts in the PX4 forums in the past pointing at the feature not being fully developed, or having some bugs/issues. In general, docs and tools always seem to bubble up the UDP comms. Before I spend more time on troubleshooting this, I’d like to make sure that I’m not headed down a dead-end street.

My questions are: what is the status of the TCP connectivity functionality in QGroundControl? If implemented as intended, does it just expect a byte stream of serialized mavlink msgs or is there some additional protocol needed? Anything else I need to be aware of?

Any pointers to “design materials” would be appreciated.

It seems that you are re-inventing mavlink-router/mavlink-router: Route mavlink packets between endpoints (github.com). It supports serial, TCP client, TCP server, and UDP connections. It event contains Mavlink messages filter (although it is not documented).

To answer your question about the QGC’s TCP connectivity - it works really well and reliably. It expects MavLink messages serialized as described in the MavLink standard. No extra bells and whistles needed.

1 Like

Thanks @j_p

I’d seen the mavlink-router repo, I’m prototyping something a bit different. :wink:

Good to know about the TCP comm link - kudos to the QGC team for staying on top of it.

I’m wondering if it’s the delay in data streaming in that has been giving me grief while I’m in the early stages developing this. It appears that when the heartbeat does not arrive within a second, QGC considers the device disconnected and won’t even process the remaining incoming messages, including the response to QGC’s query for parameters. When the params are not processed, the UI is kaput. Then some time later QGC sees heartbeat again and re-connects, but the prior packets are gone.

I didn’t see a configurable option in QGroundControl for said timeout, if it doesn’t exist I’ll just customize the QGC code to give me some breathing room while I work on optimizing the data stream.

I can confirm that the dropped connection is caused by a near miss, due to the prototype system’s latency, by a component’s heartbeat of the expected frequency of 1Hz, arriving just a fraction of second late. QGC disconnects from the vehicle right after.

The MAVLink spec (Heartbeat/Connection Protocol · MAVLink Developer Guide) states the following:

The rate at which the HEARTBEAT message must be broadcast, and how many messages may be “missed” before a system is considered to have timed out/disconnected from the network, depends on the channel (it is not defined by MAVLink). On RF telemetry links, components typically publish their heartbeat at 1 Hz and consider another system to have disconnected if four or five messages are not received.

Is the expected heartbeat arrival rate into QGC hardcoded at 1Hz? I’m curious what the specific reasons are behind QGC being stricter and disconnecting right after the very first missed message when the spec is a bit more lax on this matter?

Circling back to this since I’m done with the prototype.

Indeed, after some issues in the past the TCP conn link works well in QGroundControl for incoming MAVLink data. After optimizing the incoming data stream I no longer have an undue delay, the data stream arrives well within the 1Hz timeout, with no connections dropped. I’ll be closing this.

The “high latency” option in QGC helped somewhat during dev, but because of its raison d’être the message set is different between high latency and low latency so it wasn’t that helpful. I ended up creating a hybrid of both options (“medium latency”) for the duration of the development.

For others curious about the location of the QGC code responsible for kicking vehicle “out” after the 1Hz timeout is reached (“Connection to vehicle x lost”), it’s here.