mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-09-25 03:38:22 +08:00
* 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>