Depth-hold and stabilize flight modes result in vehicle rolling

Hello, we are trying to build a ROV. It uses a Pixhawk as its autopilot. Our frame is exactly the same as the BlueROV2 Heavy, except the motor numbering. We can verify that the frame works, we wrote a quick script using pymavlink to test each axis. All axes work properly with manual Control (even roll and pitch, via the extensions.)

The problem is, that the depth hold and stabilize modes don’t work. The ROV starts rolling randomly and then maybe some pitch movements. We couldn’t understand why it happens, as we verified that the frame works, bu manually giving values and visually seeing it work.

We have tried the Automatic motor directions detection function of QGC. It says “check thruster 1 and frame setup”. But we’re almost sure that the frame is right.

We have tried to calibrate the sensors, as well. Our vehicle rolls slightly to the right and has quite positive buoyancy. We’ve tried calibrating the level horizon both in the surface and in water. Nothing changed but this doesn’t also explain why the motor direction detection doesn’t work.

Thanks for any help

Hi @thndr0,

The motor numbering is how ArduSub knows which output to use for each control axis, so is critical for any of the flight modes that make use of a control system (i.e. everything except manual). It’s possible that manual mode is only seeming to work correctly but actually has one or more axes acting opposite to how it should be.

The automatic direction detection is primarily testing for whether any individual motors are reversed[1], given the known motion axis contribution factors of the motors (which is based on the motor numbering as mapped to the selected vehicle frame).

The test activates one thruster at a time and see whether the vehicle moves:

  1. as expected (success - motor does not need to be reversed)
  2. opposite to expected (success - automatically configures that motor to use reversed outputs)
  3. unexpectedly (failure)

Accordingly, anything causing the vehicle to move unexpectedly during the test will cause it to fail, which could be any of:

cause solution
no movement ensure the vehicle is in the water, the ESC is powered and receiving valid signals, and the connections to the thruster are valid
external movement ensure the vehicle is in calm water
incorrect frame selection choose the frame that matches your vehicle (or make a custom one), and ensure that the selected frame is suited to the motor orientations and positions relative to the vehicle’s centers of mass and buoyancy (may need to calibrate sensors, trim weight / buoyancy distribution, and/or change the motion contribution factors in your custom frame)
incorrect motor mapping physically connect the motors to the selected frame’s expected flight controller output channels, or remap the output channels as relevant via the autopilot’s SERVOn_FUNCTION parameters

The automatic test can be quite finicky if your vehicle dynamics are different to the vehicle(s) it was originally tested against (even if that’s just from adding a payload skid or something), so it can sometimes be preferable to manually run a motor test where you check that each thruster is spinning when and in the intended direction as it’s activated.[2]


  1. For some context, the test was initially created to solve the problem of inconsistent thruster wire colours, which could result in one of the windings being swapped, and the thruster rotating in the opposite direction to what’s intended. The thrusters we manufacture now have consistent colouring relative to the windings, but it’s still possible to connect them with two of the wires swapped, or be using other thrusters, so the test can still be useful. ↩︎

  2. Ideally we’d be able to design an automated motor testing mode that creates a whole frame configuration when given just the number of motors, but unfortunately we’re not yet at that stage. ↩︎