PX4-Autopilot: MAVLink over USB fails on battery power over time on 1.9.0

MAVLink over USB fails when the flight controller is on battery power if there’s no receiver running on the PC side during the first 1-2 seconds after the connection.

To Reproduce 1. Make sure no MAVLink receivers (QGroundControl, MAVROS, etc) are running on your PC 2. Connect your flight controller to a PC via USB 3. Wait for the flight controller to boot (let it pass bootloader + wait for 1-2 sec) 4. Try to connect to the flight controller via MAVLink (using QGroundControl/MAVROS/mavlink_shell script). Turns out this was a bug in Ubuntu 16.04

Alternatively,

  1. Provide power to your flight controller through its power port
  2. Wait for the flight controller to boot + 1-2 sec
  3. Connect the flight controller to a PC via USB
  4. Try to connect to the flight controller via MAVLink

Expected behavior MAVLink connection should be established (QGroundControl should display current FCU status, MAVROS should report heartbeats, mavlink_shell should display nsh > prompt)

Actual behavior The underlying serial device (/dev/ttyACM0 on Linux) appears in the system, but MAVLink connection is not established (QGroundControl suggests rebooting the vehicle, mavlink_shell doesn’t go anywhere past Connecting to MAVLINK... message)

I’ve noticed this behavior on a Pixracer.

Additional context This issue was present in v1.8.2, but was harder to notice. In v1.8.2, the “timeout” started after I’ve connected the USB cable to the PC, not straight after FCU boot. Apparently this was enough to let our companion computer finish booting and start MAVROS. This was a bug in Ubuntu 16.04 and is not related to this issue mavlink process doesn’t seem to report any problems in the debug console - in fact, mavlink status shows an instance running over /dev/ttyACM0 on the PX4 side. USB status is shown correctly in the system_power message (running listener system_power shows a message with usb_connected: 1 and usb_valid: 1 when the cable is plugged and usb_connected: 0 and usb_valid: 0 when it isn’t).

This is a showstopper for us, since we’re using USB for our companion computer connection.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (18 by maintainers)

Most upvoted comments

@mcsauder We could use

          int errcode = errno;
          /* ENOTCONN means that the USB device is not yet connected */
              usleep(errcode == ENOTCONN ? 1000 000 :  100000 );

For disconnect we can use POLLHUP

@dagar , @julianoes , the commit moving mavlink touORB subscription fixes the issue, so this issue does not exist in current PX4:master.

I will work on finding a fix that can work for 1.9.1 and update you as I make progress.

I’ve tried bisecting the bug, and it seems that the bug manifests itself in https://github.com/PX4/Firmware/commit/e12acc4b282d26ae1b8c1e1cb4220b53ef54b097 (previous revision, https://github.com/PX4/Firmware/commit/8b71bb45621d682834807086b82ac65cce179d41, is fine). Seems like the only difference is starting mavlink on USB later than on serial ports.

I’ve tried moving the commands that start mavlink over USB to /etc/init.d/rcS, and it seems like the USB instance should be started after all other instances: the bug went away if I ran mavlink over USB after /etc/init.d/rc.board_extras. Not sure whether that breaks UART instances, though.