Offboard start failed if heartbeat is received before offboard start


I am trying to start offboard by sending one setpoint (Offboard::set_position_ned()), and then immediately requesting offboard start (Offboard::start()).

Sometimes It fails with ‘Offboard start failed’. This happens when a heartbeat is received from the drone, between the first setpoint and the request to switch to offboard.

I see why it happens in the code; There’s a mechanism in OffboardImpl::process_heartbeat that changes the internal mode back to Mode::NotActive when heartbeat indicates that the drone is not in offboard anymore.

However this also applies in my case, where the heartbeat indicates the drone is not in offboard, because it hasn’t yet switched to offboard, but the internal mode is different than Mode::NotActive because of the first setpoint that was sent);
The heartbeat callback calls stop_sending_setpoints(), which changes the internal mode to Mode::NotActive, which in turn prevents Offboard::start() from switching to offboard.

Am I using MAVSDK wrong somehow? Please help.


I think you’re using it correctly but this might indeed be a bit of a race condition. Which MAVSDK version are you using?

I’m using commit c6d2d2e which is 2 commits ahead of v0.28.0 (3 years ago).
Do you think i should try to upgrade?

OK i figured out why this reproduced for me although it should be very rare;

I’ve added a 20ms sleep between sending the first setpoint and the offboard start command. This was to workaround another issue in PX4, in which those two messages arrive too close to each other, so that PX4’s Commander while loop sometimes misses the first setpoint because it’s not atomic.

That is, Commander’s loop looks like:

1 while true:
2   ...
3   set offboard signal available if received a setpoint
4   ....
5   handle vehicle_commands from mavlink (allow switch to offboard only if offboard signal is available)
6   ....

So if both the setpoint and the offboard arrive between lines 3 and 5, Commander will handle the offboard start command first, and will deny it. So the added 20ms made sure that there will be enough time for the first setpoint to be handled first.

This caused the heartbeat issue to be more frequent (heartbeat arrives at 1hz, so it should reproduce in 1 out of 50 flights if it arrives during the sleep).

In order to solve the heartbeat issue, i think that i’ll modify offboard plugin on my drone to mask heartbeats, only for the short period between the first setpoint and the offboard start command.

Let me know if you can think of a better solution.
Also, do you think that it’s something worth pushing to MAVSDK (the masking of the heartbeat)?

Gosh, that version is ancient!

I’m pretty sure we’ve fixed this issue with v0.37.0, see: Various offboard improvements by julianoes · Pull Request #1317 · mavlink/MAVSDK · GitHub