* feat(control_allocator): add reversible-motor failure recovery for hexarotors On a single motor failure (CA_FAILURE_MODE), handle the failed motor's geometric-opposite motor on a hexarotor to recover the lost control authority: 1 = remove failed + shut off opposite (restores symmetry) 2 = remove failed + make opposite reversible (assumes a reverse-capable ESC) Non-hex frames have no opposite and keep the upstream remove-only behavior. The opposite motor is found geometrically (opposite spin, closest antipode) and only for hexarotors. Reverse thrust is modeled as CA_REV_THR_FRAC of forward thrust and the reversible actuator range is rescaled to [-1, 0] on publish. Consumes failure_detector_status.motor_failure_mask, independent of detection. * feat(uavcan): render reversible motor outputs as signed RawCommand Re-encode reversible channels from the mixer's [min,max] range to a signed RawCommand (negative = reverse). A channel at its disarmed value is passed through untouched, so a stopped motor is never inverted to reverse. * fix(dshot): match per-channel minimums to the 3D encoding calculate_output_value() applies the 3D split when DSHOT_3D_ENABLE is set or the channel is reversible, but the per-channel minimum was derived from the reversible bit alone. Two problems followed. A reversible channel made reversible at runtime kept a stale minimum, so its neutral no longer landed on the mid-throttle split. A non-reversible channel with 3D enabled was worse: it mapped from DSHOT_MIN, which sits below the split, so zero commanded thrust decoded as near-full reverse. Select the minimum from the same two facts the encoder uses. A reversible channel keeps the range bottom so neutral lands on the split, a forward-only channel starts just above it, and without 3D the DSHOT_MIN idle floor applies as before. For a split channel the idle floor is applied per direction inside convert_output_to_3d_scaling(), so it must not be added to the minimum. The deadband is now applied only to reversible channels, since a channel that cannot be commanded negative has no neutral to guard. Apply the minimums from a new OutputModuleInterface::reversibleMaskChanged(), called once the new mask is known and before any output is computed with it. Applying them from Run() left the range one cycle behind the mask it depends on, which in 3D mode changed the sign of the output on the transition. The reversible mask can now change while armed, since failure recovery reverses a motor in flight, so the reversibleOutputs() contract is updated to say so. Changes output values for every DSHOT_3D_ENABLE=1 setup that has any non-reversible motor. Verified on fmu-v4 with 3D-mode ESCs: forward-only channels floor at 1001 with no samples below the split across 85 s armed, and a runtime-reversed recovery motor tracks yaw input through the split in both directions. * docs(control_allocator): document motor failure recovery Add a Motor Failure Recovery page covering CA_FAILURE_MODE, the hexarotor stop-or-reverse behaviour of the opposite motor, CA_REV_THR_FRAC, the detection prerequisites and which output protocols can drive a motor in reverse. Document the signed DroneCAN RawCommand encoding for reversible motors, and correct the failure detector section, which claimed motor failures are non-latching while the current-based check holds a flagged motor until the vehicle disarms. Add the page to the navigation and to the v1.18 release notes. * docs(docs): subedit * docs(docs): subedit * refactor(control_allocator): align CA_REV_THR_FRAC naming and description Rename the parameter member to _param_ca_rev_thr_frac to match the parameter name, and note in the description that the reverse thrust fraction is mostly a property of the propeller. * docs(motor_failure_recovery): move under Actuators and target v1.19 The page documents how control allocation is reconfigured, so list it under Actuators next to Actuator Allocation instead of under Safety, and link it from the Actuators and multicopter Features indexes. Safety configuration still links to it from the motor failure trigger section. The release branch for v1.18 is already cut, so move the release notes to main.md and set the version badges to main (PX4 v1.19). * docs(motor_failure_recovery): spell out the reversing requirements Any of the six motors can fail, so every motor has to be reverse-capable, not just one. List the settings that mode 2 needs, split the per-protocol detail out (DroneCAN reverses from the signed RawCommand alone, DShot also needs the ESCs in 3D mode and DSHOT_3D_ENABLE to match), and say what happens when they are not set: a reverse command comes out as forward thrust, and on PWM the recovery motor sits at around half throttle. Also note that motors do not have to be marked bidirectional (CA_R_REV) for this, since the recovery motor is made reversible at runtime. * Apply suggestions from code review Co-authored-by: Hamish Willee <hamishwillee@gmail.com> * fix(uavcan_main): log final value in actuator_outputs, always run through reversible logic We want worst case execution time all the time and as little control paths as possible. Also actuator_outputs is used to debug ESC behavior and should contain the final value that is sent out over the wire. * refactor(DShot): directly calculate minimum dshot value in apply_min_values() * refactor(control_allocator): static_cast, correct CA_FAILURE_MODE description * fix(control_allocator): treat undefined parameter values as default, use matrix function to zero a collumn --------- Co-authored-by: Hamish Willee <hamishwillee@gmail.com> Co-authored-by: Matthias Grob <maetugr@gmail.com>
8.0 KiB
Motor Failure Recovery
PX4 can reconfigure control allocation (mixing) in flight when a motor failure is detected, so that the vehicle can keep flying on the motors that are left.
The failure action is selected with CA_FAILURE_MODE.
This can be set to 0 (the default) to simply warn the user, or 1 to remove the failed motor from allocation.
Hexarotor frames provide additional recovery options, which are outlined in the following sections.
::: warning A vehicle flying with a failed motor has less control authority and thrust margin than a healthy one. Fly gently and land as soon as it is safe to do so. :::
Hexarotor
Stop or Reverse the Opposite Motor
Modes 1 and 2 only differ on a hexarotor; on any other airframe both simply remove the failed motor.
On a hexarotor the rotor opposite the failed one is the rotor that used to cancel its drag (yaw) torque, so what happens to it decides how much yaw authority is left:
- Mode
1stops it, leaving four symmetric rotors and no yaw bias to trim, but a third of the thrust is gone and the heading can still drift. - Mode
2keeps it in the allocation and lets it spin backwards. Driving a rotor in reverse inverts both its thrust and its drag torque, so it can still generate yaw torque. This needs an ESC that can actually reverse the motor.
The opposite motor is taken from the configured geometry: it is the counter-rotating rotor closest to the failed rotor's antipode, and it is only computed for a 6-rotor multirotor geometry.
Reverse Thrust Fraction
A propeller spun backwards produces less thrust than it does forwards, and CA_REV_THR_FRAC tells the allocator what fraction to expect (default 0.4, i.e. 40%, which is representative of a standard multicopter propeller).
A symmetric (3D) propeller produces almost the same thrust either way, so it should be set closer to 1.0.
A value in the right region is best, but it is not critical: a hexarotor still recovers with 1.0 set on a propeller whose real fraction is 0.4.
ESC Requirements for Reversing
Mode 2 reverses whichever motor sits opposite the one that failed, and any of the six can fail, so every motor on the vehicle has to be able to reverse (not just one of them).
Reversing needs all of the following:
- Motors and ESCs that can be driven backwards.
- Reversal enabled in the ESC configuration. This is set in the ESC (PX4 does not set it for you).
- CA_FAILURE_MODE =
2. - For DShot ESCs only: DSHOT_3D_ENABLE =
1.
Nothing else is required, in particular the motors do not have to be marked as bidirectional (CA_R_REV). PX4 makes the recovery motor reversible by itself while handling the failure, and returns it to forward-only if the failure clears.
DroneCAN
Reverse is part of the protocol: PX4 sends the recovery motor a negative RawCommand, and an ESC configured for bidirectional operation spins it backwards.
No additional PX4 parameter is needed.
See Reversible motors in DroneCAN ESCs.
DShot
A reversible output is encoded using the DShot 3D split range, where neutral sits in the middle of the range
The ESC has to be running in 3D mode, which is a persistent ESC setting (see ESC Commands), and PX4 has to be told about it with DSHOT_3D_ENABLE.
DSHOT_3D_ENABLE puts every motor on the matching encoding.
This has nothing to do with Bidirectional DShot, which is about eRPM telemetry rather than reversing a motor.
::: warning
DSHOT_3D_ENABLE and the 3D setting in the ESCs must always agree, whether or not a motor has failed.
If the ESCs run in 3D mode while DSHOT_3D_ENABLE is 0, the lower part of the throttle range is sent in the range those ESCs read as reverse, and the vehicle is not flyable.
:::
PWM, OneShot, and Other Protocols
These cannot reverse a motor, so CA_FAILURE_MODE has to be 1 or 0.
With mode 2 the recovery motor would sit at around half throttle forwards instead of reversing, which is worse than stopping it.
::: warning
PX4 does not check whether an ESC can reverse, and a reverse command sent to an ESC that is not set up for it comes out as forward thrust.
Before flying with mode 2, confirm on the bench that each motor really does spin backwards, for example from the sign of the reported RPM.
:::
Failure Detection
Recovery reacts to the motor failure flag raised by the failure detector, which is set when either:
- an ESC stops sending telemetry, or reports a fault. This requires COM_ARM_CHK_ESCS to be enabled.
- the current reported by an ESC is outside the band expected for its commanded thrust. This requires FD_ACT_EN to be enabled, and the MOTFAIL_* thresholds to be tuned for the vehicle.
Either path needs ESC telemetry, so recovery is only possible with telemetry-capable ESCs (such as DroneCAN or DShot with telemetry).
Note that the two are gated by different parameters: an ESC that goes silent triggers recovery with FD_ACT_EN disabled, as long as COM_ARM_CHK_ESCS is enabled.
The current-based check latches: once a motor is flagged it stays flagged until the vehicle disarms. This is deliberate, because the recovery stops the failed motor, which would otherwise make it look healthy again and clear the failure. The ESC offline/fault check does clear if the ESC starts reporting again, in which case all motors are restored to the allocation and any runtime reverse is removed.
To exercise the whole chain you can take an ESC offline with failure injection: failure esc off -i <n>.
Parameters
| Parameter | Description |
|---|---|
| CA_FAILURE_MODE | What to do on a single motor failure. 0 (default): Ignore and report failure.1: Remove failed motor from allocation. Hexarotor: also stop the opposite motor.2: Remove failed motor from allocation. Hexarotor: also reverse the opposite motor. |
| CA_REV_THR_FRAC | Fraction of forward thrust that the recovery motor is expected to produce in reverse (default 0.4). Only used by mode 2. |
See Also
- Safety Configuration (Failsafes), covering the failure detector and motor failure detection.
- Control Allocation (Mixing)
- Actuator Configuration and Testing, covering geometry, motor order and bidirectional motors.