feat(manual_control): replace stick override threshold with double-flick gesture (#27041)

* feat(manual_control): trigger RC override on stick velocity

COM_RC_STICK_OV is now a velocity threshold (1/s) instead of a deflection percentage.
Default 3.0, range [1.0, 10.0]. A stick held statically cannot trigger override.

* docs(manual_control): update COM_RC_STICK_OV description for velocity-based override

* feat(manual_control): gate RC override with sign-consistency check

* fix(ManualControl): lower threshold and filter constant for RC override, add tests for MovingDiff

* refactor(commander): merge RC override params into COM_RC_OVR_SPEED

Replace the COM_RC_OVERRIDE bitmask + COM_RC_STICK_OV threshold with a
single float COM_RC_OVR_SPEED (stick override velocity, 0 = disabled).
Override now applies uniformly in auto and offboard modes.

- ManualControl: rename param, treat 0 as disabled (FLT_EPSILON guard)
- Commander: drop the per-mode bitmask gate and the RcOverrideBits enum
- param_translation: migrate COM_RC_OVERRIDE on import (enabled -> 1.0,
  disabled -> 0.0) and drop the unit-incompatible COM_RC_STICK_OV value
- docs: collapse the two params into one across the mode pages

* fix(manual_override): Move configuration to manual_control module

with MAN_OVERRIDE_SPD parameter and a negative value disabling the feature. All other logic stays in Commander.

* docs(releases): add release note for RC override rework (MAN_OVERRIDE_SPD)

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
This commit is contained in:
Gennaro Guidone
2026-07-01 14:59:52 +02:00
committed by GitHub
parent 3b9a5a6ada
commit b8c5f66af0
23 changed files with 182 additions and 121 deletions

View File

@@ -318,8 +318,6 @@
1 1 COM_RCL_EXCEPT 0 6 1 1 COM_RCL_EXCEPT 0 6
1 1 COM_RC_IN_MODE 3 6 1 1 COM_RC_IN_MODE 3 6
1 1 COM_RC_LOSS_T 0.500000000000000000 9 1 1 COM_RC_LOSS_T 0.500000000000000000 9
1 1 COM_RC_OVERRIDE 1 6
1 1 COM_RC_STICK_OV 30.000000000000000000 9
1 1 COM_SPOOLUP_TIME 1.000000000000000000 9 1 1 COM_SPOOLUP_TIME 1.000000000000000000 9
1 1 COM_THROW_EN 0 6 1 1 COM_THROW_EN 0 6
1 1 COM_THROW_SPEED 5.000000000000000000 9 1 1 COM_THROW_SPEED 5.000000000000000000 9

View File

@@ -358,8 +358,7 @@ _Offboard mode_ is affected by the following parameters:
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <a id="COM_OF_LOSS_T"></a>[COM_OF_LOSS_T](../advanced_config/parameter_reference.md#COM_OF_LOSS_T) | Time-out (in seconds) to wait when offboard connection is lost before triggering offboard lost failsafe (`COM_OBL_RC_ACT`) | | <a id="COM_OF_LOSS_T"></a>[COM_OF_LOSS_T](../advanced_config/parameter_reference.md#COM_OF_LOSS_T) | Time-out (in seconds) to wait when offboard connection is lost before triggering offboard lost failsafe (`COM_OBL_RC_ACT`) |
| <a id="COM_OBL_RC_ACT"></a>[COM_OBL_RC_ACT](../advanced_config/parameter_reference.md#COM_OBL_RC_ACT) | Flight mode to switch to if offboard control is lost. | | <a id="COM_OBL_RC_ACT"></a>[COM_OBL_RC_ACT](../advanced_config/parameter_reference.md#COM_OBL_RC_ACT) | Flight mode to switch to if offboard control is lost. |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). This is not enabled for offboard mode by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
| <a id="COM_RCL_EXCEPT"></a>[COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Specify modes in which RC loss is ignored and the failsafe action not triggered. Set bit `2` to ignore RC loss in Offboard mode. | | <a id="COM_RCL_EXCEPT"></a>[COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Specify modes in which RC loss is ignored and the failsafe action not triggered. Set bit `2` to ignore RC loss in Offboard mode. |
## Developer Resources ## Developer Resources

View File

@@ -18,8 +18,8 @@ The following topics should be read first if you're using these vehicle types:
- Flying vehicles will failsafe if they lose the position estimate. - Flying vehicles will failsafe if they lose the position estimate.
- Mode requires home position is set. - Mode requires home position is set.
- Mode prevents arming (vehicle cannot be armed while this mode is selected). - Mode prevents arming (vehicle cannot be armed while this mode is selected).
- RC control switches can be used to change flight modes on any vehicle. - RC switches can be used to change flight modes on any vehicle.
- RC stick movement in a multicopter (or VTOL in multicopter mode) will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement in a multicopter (or VTOL in hover) will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
- A VTOL will return as MC or FW based on its mode at the point the return mode was triggered. - A VTOL will return as MC or FW based on its mode at the point the return mode was triggered.
In MC mode it will respect multicopter parameters, such as the landing "cone". In MC mode it will respect multicopter parameters, such as the landing "cone".
In FW mode it will respect fixed-wing parameters (ignore the cone), but unless using a mission landing, will transition to MC mode and land at the destination after loitering at the descent altitude. In FW mode it will respect fixed-wing parameters (ignore the cone), but unless using a mission landing, will transition to MC mode and land at the destination after loitering at the descent altitude.
@@ -221,7 +221,6 @@ The RTL parameters are listed in [Parameter Reference > Return Mode](../advanced
| <a id="RTL_MIN_DIST"></a>[RTL_MIN_DIST](../advanced_config/parameter_reference.md#RTL_MIN_DIST) | Within this distance from the return destination, the return altitude is calculated from the "cone" rather than directly from `RTL_RETURN_ALT`. | | <a id="RTL_MIN_DIST"></a>[RTL_MIN_DIST](../advanced_config/parameter_reference.md#RTL_MIN_DIST) | Within this distance from the return destination, the return altitude is calculated from the "cone" rather than directly from `RTL_RETURN_ALT`. |
| <a id="RTL_CONE_ANG"></a>[RTL_CONE_ANG](../advanced_config/parameter_reference.md#RTL_CONE_ANG) | Half-angle of the cone that defines the vehicle RTL return altitude. Values (in degrees): `0`, `25`, `45`, `65`, `80`, `90`. Note that `0` is "no cone" (always return at `RTL_RETURN_ALT` or higher), while `90` indicates an almost vertical cone, so the vehicle generally returns at its current altitude when close to the destination. The return altitude may still be constrained to avoid flying too low while approaching the destination. | | <a id="RTL_CONE_ANG"></a>[RTL_CONE_ANG](../advanced_config/parameter_reference.md#RTL_CONE_ANG) | Half-angle of the cone that defines the vehicle RTL return altitude. Values (in degrees): `0`, `25`, `45`, `65`, `80`, `90`. Note that `0` is "no cone" (always return at `RTL_RETURN_ALT` or higher), while `90` indicates an almost vertical cone, so the vehicle generally returns at its current altitude when close to the destination. The return altitude may still be constrained to avoid flying too low while approaching the destination. |
| <a id="RTL_APPR_FORCE"></a>[RTL_APPR_FORCE](../advanced_config/parameter_reference.md#RTL_APPR_FORCE) | [VTOL FW only] If set, home or rally-point RTL destinations are only considered when a valid VTOL approach loiter is defined for that landing location. Mission landing patterns are unaffected. | | <a id="RTL_APPR_FORCE"></a>[RTL_APPR_FORCE](../advanced_config/parameter_reference.md#RTL_APPR_FORCE) | [VTOL FW only] If set, home or rally-point RTL destinations are only considered when a valid VTOL approach loiter is defined for that landing location. Mission landing patterns are unaffected. |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md) (unless prevented by the active failsafe state). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
| <a id="RTL_LOITER_RAD"></a>[RTL_LOITER_RAD](../advanced_config/parameter_reference.md#RTL_LOITER_RAD) | [Fixed-wing Only] The radius of the loiter circle (at [RTL_LAND_DELAY](#RTL_LAND_DELAY)). | | <a id="RTL_LOITER_RAD"></a>[RTL_LOITER_RAD](../advanced_config/parameter_reference.md#RTL_LOITER_RAD) | [Fixed-wing Only] The radius of the loiter circle (at [RTL_LAND_DELAY](#RTL_LAND_DELAY)). |
| <a id="MIS_TKO_LAND_REQ"></a>[MIS_TKO_LAND_REQ](../advanced_config/parameter_reference.md#MIS_TKO_LAND_REQ) | Specify whether a mission landing or takeoff pattern is _required_. Generally fixed-wing vehicles set this to require a landing pattern but VTOL do not. | | <a id="MIS_TKO_LAND_REQ"></a>[MIS_TKO_LAND_REQ](../advanced_config/parameter_reference.md#MIS_TKO_LAND_REQ) | Specify whether a mission landing or takeoff pattern is _required_. Generally fixed-wing vehicles set this to require a landing pattern but VTOL do not. |

View File

@@ -18,7 +18,7 @@ It is usually activated with a pre-programmed switch.
- Disarmed vehicles can switch to mode without valid position estimate but can't arm. - Disarmed vehicles can switch to mode without valid position estimate but can't arm.
- Mode requires wind and flight time are within allowed limits (specified via parameters). - Mode requires wind and flight time are within allowed limits (specified via parameters).
- RC control switches can be used to change flight modes on any vehicle. - RC control switches can be used to change flight modes on any vehicle.
- RC stick movement will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp --> <!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp -->
@@ -29,7 +29,7 @@ It is usually activated with a pre-programmed switch.
The vehicle stops and hovers, maintaining its position and altitude. The vehicle stops and hovers, maintaining its position and altitude.
The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude.
RC stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#COM_RC_OVERRIDE)). Stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#MAN_OVERRIDE_SPD)).
### Parameters ### Parameters
@@ -38,8 +38,7 @@ Hold mode behaviour can be configured using the parameters below.
| Parameter | Description | | Parameter | Description |
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <a id="NAV_MIN_LTR_ALT"></a>[NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | This is the minimum altitude above Home the system will always obey in Hold mode if switched into this mode without specifying an altitude (e.g. through switch on RC). | | <a id="NAV_MIN_LTR_ALT"></a>[NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | This is the minimum altitude above Home the system will always obey in Hold mode if switched into this mode without specifying an altitude (e.g. through switch on RC). |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
<!-- Code for this here: https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/navigator/loiter.cpp#L61 --> <!-- Code for this here: https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/navigator/loiter.cpp#L61 -->

View File

@@ -13,7 +13,7 @@ The vehicle will disarm shortly after landing (by default).
- Flying vehicles will failsafe if they lose the position estimate. - Flying vehicles will failsafe if they lose the position estimate.
- Mode prevents arming (vehicle cannot be armed while this mode is selected). - Mode prevents arming (vehicle cannot be armed while this mode is selected).
- RC control switches can be used to change flight modes on any vehicle. - RC control switches can be used to change flight modes on any vehicle.
- RC stick movement in a multicopter (or VTOL in multicopter mode) will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement in a multicopter (or VTOL in hover) will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
- The mode can be triggered using the [MAV_CMD_NAV_LAND](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_LAND) MAVLink command, or by explicitly switching to Land mode. - The mode can be triggered using the [MAV_CMD_NAV_LAND](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_LAND) MAVLink command, or by explicitly switching to Land mode.
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp --> <!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp -->
@@ -25,7 +25,7 @@ The vehicle will disarm shortly after landing (by default).
The vehicle will land at the location at which the mode was engaged. The vehicle will land at the location at which the mode was engaged.
The vehicle descends at the rate specified in [MPC_LAND_SPEED](#MPC_LAND_SPEED) and will disarm after landing (by [default](#COM_DISARM_LAND)). The vehicle descends at the rate specified in [MPC_LAND_SPEED](#MPC_LAND_SPEED) and will disarm after landing (by [default](#COM_DISARM_LAND)).
RC stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#COM_RC_OVERRIDE)). Stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#MAN_OVERRIDE_SPD)).
### Parameters ### Parameters
@@ -35,8 +35,7 @@ Land mode behaviour can be configured using the parameters below.
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <a id="MPC_LAND_SPEED"></a>[MPC_LAND_SPEED](../advanced_config/parameter_reference.md#MPC_LAND_SPEED) | The rate of descent during landing. This should be kept fairly low as the ground conditions are not known. | | <a id="MPC_LAND_SPEED"></a>[MPC_LAND_SPEED](../advanced_config/parameter_reference.md#MPC_LAND_SPEED) | The rate of descent during landing. This should be kept fairly low as the ground conditions are not known. |
| <a id="COM_DISARM_LAND"></a>[COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND) | Time-out for auto disarm after landing, in seconds. If set to -1 the vehicle will not disarm on landing. | | <a id="COM_DISARM_LAND"></a>[COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND) | Time-out for auto disarm after landing, in seconds. If set to -1 the vehicle will not disarm on landing. |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
## See Also ## See Also

View File

@@ -11,8 +11,8 @@ The mission is typically created and uploaded with a Ground Control Station (GCS
- The vehicle must be armed before this mode can be engaged. - The vehicle must be armed before this mode can be engaged.
- This mode is automatic - no user intervention is _required_ to control the vehicle. - This mode is automatic - no user intervention is _required_ to control the vehicle.
- RC control switches can be used to change flight modes on any vehicle. - RC control switches can be used to change flight modes on any vehicle.
- RC stick movement will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
This is true for multicopters and VTOL in MC mode. This is true for multicopters and VTOL in hover.
::: :::
@@ -108,8 +108,7 @@ General parameters:
| Parameter | Description | | Parameter | Description |
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <a id="NAV_RCL_ACT"></a>[NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | RC loss failsafe mode (what the vehicle will do if it looses RC connection) - e.g. enter hold mode, return mode, terminate etc. | | <a id="NAV_RCL_ACT"></a>[NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | RC loss failsafe mode (what the vehicle will do if it looses RC connection) - e.g. enter hold mode, return mode, terminate etc. |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) gives control back to the pilot in [Position mode](../flight_modes_mc/position.md). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
Parameters related to [mission feasibility checks](#mission-feasibility-checks): Parameters related to [mission feasibility checks](#mission-feasibility-checks):

View File

@@ -20,7 +20,7 @@ The default type is recommended.
- Mode requires home position is set. - Mode requires home position is set.
- Mode prevents arming (vehicle cannot be armed while this mode is selected). - Mode prevents arming (vehicle cannot be armed while this mode is selected).
- RC control switches can be used to change flight modes on any vehicle. - RC control switches can be used to change flight modes on any vehicle.
- RC stick movement will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp --> <!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp -->
@@ -67,8 +67,7 @@ The parameters that are relevant to multicopter (assuming the [RTL_TYPE](../adva
| <a id="RTL_LAND_DELAY"></a>[RTL_LAND_DELAY](../advanced_config/parameter_reference.md#RTL_LAND_DELAY) | Time to hover at `RTL_DESCEND_ALT` before landing (default: 0.5s) - by default this period is short so that the vehicle will simply slow and then land immediately. If set to -1 the system will loiter at `RTL_DESCEND_ALT` rather than landing. The delay is provided to allow you to configure time for landing gear to be deployed (triggered automatically). | | <a id="RTL_LAND_DELAY"></a>[RTL_LAND_DELAY](../advanced_config/parameter_reference.md#RTL_LAND_DELAY) | Time to hover at `RTL_DESCEND_ALT` before landing (default: 0.5s) - by default this period is short so that the vehicle will simply slow and then land immediately. If set to -1 the system will loiter at `RTL_DESCEND_ALT` rather than landing. The delay is provided to allow you to configure time for landing gear to be deployed (triggered automatically). |
| <a id="RTL_MIN_DIST"></a>[RTL_MIN_DIST](../advanced_config/parameter_reference.md#RTL_MIN_DIST) | Within this distance from the home position, the return altitude is calculated from the "cone" rather than directly from `RTL_RETURN_ALT`. | | <a id="RTL_MIN_DIST"></a>[RTL_MIN_DIST](../advanced_config/parameter_reference.md#RTL_MIN_DIST) | Within this distance from the home position, the return altitude is calculated from the "cone" rather than directly from `RTL_RETURN_ALT`. |
| <a id="RTL_CONE_ANG"></a>[RTL_CONE_ANG](../advanced_config/parameter_reference.md#RTL_CONE_ANG) | Half-angle of the cone that defines the vehicle RTL return altitude. Values (in degrees): `0`, `25`, `45`, `65`, `80`, `90`. Note that `0` is "no cone" (always return at `RTL_RETURN_ALT` or higher), while `90` indicates an almost vertical cone, so the vehicle generally returns at its current altitude when close to the destination. The return altitude may still be constrained to avoid flying too low while approaching the destination. | | <a id="RTL_CONE_ANG"></a>[RTL_CONE_ANG](../advanced_config/parameter_reference.md#RTL_CONE_ANG) | Half-angle of the cone that defines the vehicle RTL return altitude. Values (in degrees): `0`, `25`, `45`, `65`, `80`, `90`. Note that `0` is "no cone" (always return at `RTL_RETURN_ALT` or higher), while `90` indicates an almost vertical cone, so the vehicle generally returns at its current altitude when close to the destination. The return altitude may still be constrained to avoid flying too low while approaching the destination. |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md) (unless prevented by the active failsafe state). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). |
## See Also ## See Also

View File

@@ -12,7 +12,7 @@ The _Takeoff_ flight mode causes the vehicle to take off to a specified height a
- Flying vehicles will failsafe if they lose the position estimate. - Flying vehicles will failsafe if they lose the position estimate.
- Disarmed vehicles can switch to mode without valid position estimate but can't arm. - Disarmed vehicles can switch to mode without valid position estimate but can't arm.
- RC control switches can be used to change flight modes. - RC control switches can be used to change flight modes.
- RC stick movement will [by default](#COM_RC_OVERRIDE) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state. - Stick movement will [by default](#MAN_OVERRIDE_SPD) change the vehicle to [Position mode](../flight_modes_mc/position.md) unless prevented by the active failsafe state.
- The [Failure Detector](../config/safety.md#failure-detector) will automatically stop the engines if there is a problem on takeoff. - The [Failure Detector](../config/safety.md#failure-detector) will automatically stop the engines if there is a problem on takeoff.
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp --> <!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp -->
@@ -23,7 +23,7 @@ The _Takeoff_ flight mode causes the vehicle to take off to a specified height a
A multi rotor ascends vertically to the altitude defined in [MIS_TAKEOFF_ALT](../advanced_config/parameter_reference.md#MIS_TAKEOFF_ALT) and holds position. A multi rotor ascends vertically to the altitude defined in [MIS_TAKEOFF_ALT](../advanced_config/parameter_reference.md#MIS_TAKEOFF_ALT) and holds position.
RC stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#COM_RC_OVERRIDE)). Stick movement will change the vehicle to [Position mode](../flight_modes_mc/position.md) (by [default](#MAN_OVERRIDE_SPD)).
### Parameters ### Parameters
@@ -33,8 +33,7 @@ Takeoff is affected by the following parameters:
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <a id="MIS_TAKEOFF_ALT"></a>[MIS_TAKEOFF_ALT](../advanced_config/parameter_reference.md#MIS_TAKEOFF_ALT) | Target altitude during takeoff (default: 2.5m) | | <a id="MIS_TAKEOFF_ALT"></a>[MIS_TAKEOFF_ALT](../advanced_config/parameter_reference.md#MIS_TAKEOFF_ALT) | Target altitude during takeoff (default: 2.5m) |
| <a id="MPC_TKO_SPEED"></a>[MPC_TKO_SPEED](../advanced_config/parameter_reference.md#MPC_TKO_SPEED) | Speed of ascent (default: 1.5m/s) | | <a id="MPC_TKO_SPEED"></a>[MPC_TKO_SPEED](../advanced_config/parameter_reference.md#MPC_TKO_SPEED) | Speed of ascent (default: 1.5m/s) |
| <a id="COM_RC_OVERRIDE"></a>[COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). This can be separately enabled for auto modes and for offboard mode, and is enabled in auto modes by default. | | <a id="MAN_OVERRIDE_SPD"></a>[MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) | Speed (normalized stick travel per second) above which moving the sticks controlling a multicopter (or VTOL in hover) gives control back to the pilot by switching to [Position mode](../flight_modes_mc/position.md) (or Altitude mode if position is unavailable). At the default value of 1 a half-stick movement in ~0.5 s triggers it; lower is more sensitive. A stick held statically has zero speed and will not trigger. Set to -1 to disable. <Badge type="tip" text="PX4 v1.18" /> |
| <a id="COM_RC_STICK_OV"></a>[COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled) |
## See Also ## See Also

View File

@@ -22,7 +22,7 @@ Update these notes with features that are going to be in `main` (PX4 v1.18 or la
## Read Before Upgrading ## Read Before Upgrading
- TBD - The RC override parameters `COM_RC_OVERRIDE` and `COM_RC_STICK_OV` are replaced by a single [MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) (minimum stick speed to take over, default `1`; negative disables). `COM_RC_OVERRIDE=0` is migrated to `MAN_OVERRIDE_SPD=-1`. The `COM_RC_STICK_OV` value is not auto-migrated because its unit changed, so re-tune `MAN_OVERRIDE_SPD` if you had customized it.
Please continue reading for [upgrade instructions](#upgrade-guide). Please continue reading for [upgrade instructions](#upgrade-guide).
@@ -82,7 +82,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide).
### RC ### RC
- TBD - Merged the RC override parameters `COM_RC_OVERRIDE` and `COM_RC_STICK_OV` into a single [MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) and made override reject erratic signal jumps. ([PX4-Autopilot#27041](https://github.com/PX4/PX4-Autopilot/pull/27041)).
### Multi-Rotor ### Multi-Rotor

View File

@@ -14,7 +14,7 @@ There are two things you want to setup on the firmware side before starting offb
### Enable RC Override ### Enable RC Override
In _QGroundControl_ you can set the [COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) parameter to automatically switch from offboard mode (or any mode) to Position mode if the RC sticks are moved. In _QGroundControl_ the [MAN_OVERRIDE_SPD](../advanced_config/parameter_reference.md#MAN_OVERRIDE_SPD) parameter controls automatically switching from offboard (or autonomous) mode to Position mode when the remote sticks are moved. This is enabled by default; set it to -1 to disable.
This is the best way to ensure that an operator can easily take control of the vehicle and switch to the safest flight mode. This is the best way to ensure that an operator can easily take control of the vehicle and switch to the safest flight mode.
### Map an RC switch to offboard mode activation ### Map an RC switch to offboard mode activation

View File

@@ -37,7 +37,7 @@ float32 aux4
float32 aux5 float32 aux5
float32 aux6 float32 aux6
bool sticks_moving bool sticks_moving # manual control override request in an auto or offboard mode, only gets true if feature is enabled
uint16 buttons # From uint16 buttons field of Mavlink manual_control message uint16 buttons # From uint16 buttons field of Mavlink manual_control message

View File

@@ -244,6 +244,17 @@ param_modify_on_import_ret param_modify_on_import(bson_node_t node)
} }
} }
// 2026-06-12: merge COM_RC_OVERRIDE + COM_RC_STICK_OV into MAN_OVERRIDE_SPD
{
if ((node->type == bson_type_t::BSON_INT32) && (strcmp("COM_RC_OVERRIDE", node->name) == 0) && (node->i32 == 0)) {
node->d = -1.0;
node->type = bson_type_t::BSON_DOUBLE;
strcpy(node->name, "MAN_OVERRIDE_SPD");
PX4_INFO("migrating %s -> %s (disabled)", "COM_RC_OVERRIDE", "MAN_OVERRIDE_SPD");
return param_modify_on_import_ret::PARAM_MODIFIED;
}
}
// 2026-06-22: translate HEATER*_IMU_ID to HEATER*_SENS_ID // 2026-06-22: translate HEATER*_IMU_ID to HEATER*_SENS_ID
// HEATER_MAX_INSTANCES == 3 (in heater.h) // HEATER_MAX_INSTANCES == 3 (in heater.h)
{ {

View File

@@ -3121,38 +3121,22 @@ void Commander::manualControlCheck()
_last_manual_throttle = manual_control_setpoint.throttle; _last_manual_throttle = manual_control_setpoint.throttle;
if (isArmed()) { if (isArmed()) {
// Abort autonomous mode and switch to position mode if sticks are moved significantly // Hand control back to the pilot when they override with the sticks (see MAN_OVERRIDE_SPD).
// but only if actually in air. // Only applies to multicopters (incl. VTOLs in MC mode) in auto/offboard modes.
if (manual_control_setpoint.sticks_moving const bool rotary_wing = (_vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING);
&& !_vehicle_control_mode.flag_control_manual_enabled const bool overridable_mode = _vehicle_control_mode.flag_control_auto_enabled || _vehicle_control_mode.flag_control_offboard_enabled;
&& (_vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING)
) {
bool override_enabled = false;
if (_vehicle_control_mode.flag_control_auto_enabled) { if (manual_control_setpoint.sticks_moving && rotary_wing && overridable_mode) {
if (_param_com_rc_override.get() & static_cast<int32_t>(RcOverrideBits::AUTO_MODE_BIT)) { // If no failsafe is active, directly change the mode, otherwise pass the request to the failsafe state machine
override_enabled = true; if (_failsafe.selectedAction() <= FailsafeBase::Action::Warn) {
if (_user_mode_intention.change(vehicle_status_s::NAVIGATION_STATE_POSCTL, ModeChangeSource::User, true)) {
tune_positive(true);
mavlink_log_info(&_mavlink_log_pub, "Pilot took over using sticks\t");
events::send(events::ID("commander_rc_override"), events::Log::Info, "Pilot took over using sticks");
} }
}
if (_vehicle_control_mode.flag_control_offboard_enabled) { } else {
if (_param_com_rc_override.get() & static_cast<int32_t>(RcOverrideBits::OFFBOARD_MODE_BIT)) { _failsafe_user_override_request = true;
override_enabled = true;
}
}
if (override_enabled) {
// If no failsafe is active, directly change the mode, otherwise pass the request to the failsafe state machine
if (_failsafe.selectedAction() <= FailsafeBase::Action::Warn) {
if (_user_mode_intention.change(vehicle_status_s::NAVIGATION_STATE_POSCTL, ModeChangeSource::User, true)) {
tune_positive(true);
mavlink_log_info(&_mavlink_log_pub, "Pilot took over using sticks\t");
events::send(events::ID("commander_rc_override"), events::Log::Info, "Pilot took over using sticks");
}
} else {
_failsafe_user_override_request = true;
}
} }
} }

View File

@@ -212,11 +212,6 @@ private:
ALWAYS = 2 ALWAYS = 2
}; };
enum class RcOverrideBits : int32_t {
AUTO_MODE_BIT = (1 << 0),
OFFBOARD_MODE_BIT = (1 << 1),
};
/* Decouple update interval and hysteresis counters, all depends on intervals */ /* Decouple update interval and hysteresis counters, all depends on intervals */
static constexpr uint64_t COMMANDER_MONITORING_INTERVAL{10_ms}; static constexpr uint64_t COMMANDER_MONITORING_INTERVAL{10_ms};
@@ -343,7 +338,6 @@ private:
(ParamBool<px4::params::COM_HOME_IN_AIR>) _param_com_home_in_air, (ParamBool<px4::params::COM_HOME_IN_AIR>) _param_com_home_in_air,
(ParamBool<px4::params::COM_FORCE_SAFETY>) _param_com_force_safety, (ParamBool<px4::params::COM_FORCE_SAFETY>) _param_com_force_safety,
(ParamInt<px4::params::COM_PREARM_MODE>) _param_com_prearm_mode, (ParamInt<px4::params::COM_PREARM_MODE>) _param_com_prearm_mode,
(ParamInt<px4::params::COM_RC_OVERRIDE>) _param_com_rc_override,
(ParamFloat<px4::params::COM_SPOOLUP_TIME>) _param_com_spoolup_time, (ParamFloat<px4::params::COM_SPOOLUP_TIME>) _param_com_spoolup_time,
(ParamInt<px4::params::COM_FLIGHT_UUID>) _param_com_flight_uuid, (ParamInt<px4::params::COM_FLIGHT_UUID>) _param_com_flight_uuid,
(ParamFloat<px4::params::COM_CPU_MAX>) _param_com_cpu_max, (ParamFloat<px4::params::COM_CPU_MAX>) _param_com_cpu_max,

View File

@@ -171,8 +171,8 @@ parameters:
long: |- long: |-
Before entering failsafe (RTL, Land, Hold), wait COM_FAIL_ACT_T seconds in Hold mode Before entering failsafe (RTL, Land, Hold), wait COM_FAIL_ACT_T seconds in Hold mode
for the user to realize. for the user to realize.
During that time the user can switch modes, but cannot take over control via the stick override feature (see COM_RC_OVERRIDE). During that time the user can switch modes, but cannot take over control via the manual control override feature (see MAN_OVERRIDE_SPD).
Afterwards the configured failsafe action is triggered and the user may use stick override. Afterwards the configured failsafe action is triggered and the user may use manual control override.
A zero value disables the delay. A zero value disables the delay.
type: float type: float
@@ -268,34 +268,6 @@ parameters:
1: Deny arming 1: Deny arming
2: Warning only 2: Warning only
default: 2 default: 2
COM_RC_OVERRIDE:
description:
short: Enable manual control stick override
long: |-
When enabled, moving the sticks more than COM_RC_STICK_OV
immediately gives control back to the pilot by switching to Position mode and
if position is unavailable Altitude mode.
Note: Only has an effect on multicopters, and VTOLs in multicopter mode.
type: bitmask
bit:
0: Enable override during auto modes (except for in critical battery reaction)
1: Enable override during offboard mode
default: 1
min: 0
max: 3
COM_RC_STICK_OV:
description:
short: Stick override threshold
long: |-
If COM_RC_OVERRIDE is enabled and the joystick input is moved more than this threshold
the pilot takes over control.
type: float
default: 30.0
unit: '%'
min: 5
max: 80
decimal: 0
increment: 0.05
COM_ARM_MIS_REQ: COM_ARM_MIS_REQ:
description: description:
short: Require valid mission to arm short: Require valid mission to arm

View File

@@ -118,11 +118,6 @@ public:
} }
} }
enum class RcOverrideBits : int32_t {
AUTO_MODE_BIT = (1 << 0),
OFFBOARD_MODE_BIT = (1 << 1),
};
struct State { struct State {
bool armed{false}; bool armed{false};
uint8_t user_intended_mode{0}; uint8_t user_intended_mode{0};

View File

@@ -36,11 +36,11 @@ px4_add_module(
MAIN manual_control MAIN manual_control
COMPILE_FLAGS COMPILE_FLAGS
SRCS SRCS
ManualControl.cpp
ManualControl.cpp ManualControl.cpp
ManualControl.hpp ManualControl.hpp
ManualControlSelector.hpp ManualControlSelector.hpp
ManualControlSelector.cpp ManualControlSelector.cpp
MovingDiff.hpp
MODULE_CONFIG MODULE_CONFIG
manual_control_params.yaml manual_control_params.yaml
DEPENDS DEPENDS
@@ -50,3 +50,4 @@ px4_add_module(
px4_add_functional_gtest(SRC ManualControlTest.cpp LINKLIBS modules__manual_control) px4_add_functional_gtest(SRC ManualControlTest.cpp LINKLIBS modules__manual_control)
px4_add_unit_gtest(SRC ManualControlSelectorTest.cpp LINKLIBS modules__manual_control) px4_add_unit_gtest(SRC ManualControlSelectorTest.cpp LINKLIBS modules__manual_control)
px4_add_unit_gtest(SRC MovingDiffTest.cpp LINKLIBS modules__manual_control)

View File

@@ -139,12 +139,18 @@ void ManualControl::processInput(hrt_abstime now)
// User override by stick // User override by stick
const float dt_s = (now - _timestamp_last_loop) / 1e6f; const float dt_s = (now - _timestamp_last_loop) / 1e6f;
const float minimum_stick_change = 0.01f * _param_com_rc_stick_ov.get(); const float velocity_threshold = _param_man_override_spd.get();
_selector.setpoint().sticks_moving = (fabsf(_roll_diff.update(_selector.setpoint().roll, dt_s)) > minimum_stick_change) _selector.setpoint().sticks_moving =
|| (fabsf(_pitch_diff.update(_selector.setpoint().pitch, dt_s)) > minimum_stick_change) (velocity_threshold >= 0.f) &&
|| (fabsf(_yaw_diff.update(_selector.setpoint().yaw, dt_s)) > minimum_stick_change) ((fabsf(_roll_diff.update(_selector.setpoint().roll, dt_s)) > velocity_threshold
|| (fabsf(_throttle_diff.update(_selector.setpoint().throttle, dt_s)) > minimum_stick_change); && _roll_diff.consecutiveSameSign() >= MIN_SIGN_CONSECUTIVE)
|| (fabsf(_pitch_diff.update(_selector.setpoint().pitch, dt_s)) > velocity_threshold
&& _pitch_diff.consecutiveSameSign() >= MIN_SIGN_CONSECUTIVE)
|| (fabsf(_yaw_diff.update(_selector.setpoint().yaw, dt_s)) > velocity_threshold
&& _yaw_diff.consecutiveSameSign() >= MIN_SIGN_CONSECUTIVE)
|| (fabsf(_throttle_diff.update(_selector.setpoint().throttle, dt_s)) > velocity_threshold
&& _throttle_diff.consecutiveSameSign() >= MIN_SIGN_CONSECUTIVE));
_selector.setpoint().timestamp = now; _selector.setpoint().timestamp = now;
_manual_control_setpoint_pub.publish(_selector.setpoint()); _manual_control_setpoint_pub.publish(_selector.setpoint());

View File

@@ -135,6 +135,8 @@ private:
MovingDiff _yaw_diff{}; MovingDiff _yaw_diff{};
MovingDiff _throttle_diff{}; MovingDiff _throttle_diff{};
static constexpr uint8_t MIN_SIGN_CONSECUTIVE = 3;
perf_counter_t _loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")}; perf_counter_t _loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
perf_counter_t _loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")}; perf_counter_t _loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")};
@@ -150,7 +152,7 @@ private:
DEFINE_PARAMETERS( DEFINE_PARAMETERS(
(ParamInt<px4::params::COM_RC_IN_MODE>) _param_com_rc_in_mode, (ParamInt<px4::params::COM_RC_IN_MODE>) _param_com_rc_in_mode,
(ParamFloat<px4::params::COM_RC_LOSS_T>) _param_com_rc_loss_t, (ParamFloat<px4::params::COM_RC_LOSS_T>) _param_com_rc_loss_t,
(ParamFloat<px4::params::COM_RC_STICK_OV>) _param_com_rc_stick_ov, (ParamFloat<px4::params::MAN_OVERRIDE_SPD>) _param_man_override_spd,
(ParamBool<px4::params::MAN_ARM_GESTURE>) _param_man_arm_gesture, (ParamBool<px4::params::MAN_ARM_GESTURE>) _param_man_arm_gesture,
(ParamFloat<px4::params::MAN_KILL_GEST_T>) _param_man_kill_gest_t, (ParamFloat<px4::params::MAN_KILL_GEST_T>) _param_man_kill_gest_t,
(ParamBool<px4::params::COM_ARM_SWISBTN>) _param_com_arm_swisbtn, (ParamBool<px4::params::COM_ARM_SWISBTN>) _param_com_arm_swisbtn,

View File

@@ -45,25 +45,45 @@ public:
return NAN; return NAN;
} }
_difference_filter.setParameters(dt_s, .1f); _difference_filter.setParameters(dt_s, .05f);
// Leave _diff at 0.0f if we don't have a _last_value yet. // Leave _diff at 0.0f if we don't have a _last_value yet.
if (PX4_ISFINITE(_last_value)) { if (PX4_ISFINITE(_last_value)) {
const float new_diff = (value - _last_value) / dt_s; const float new_diff = (value - _last_value) / dt_s;
_difference_filter.update(new_diff); _difference_filter.update(new_diff);
// Count consecutive same-sign raw-velocity samples (rejects random noise).
const int8_t s = (new_diff > 0.f) ? 1 : (new_diff < 0.f) ? -1 : 0;
if (s != 0) {
if (s == _last_sign && _consecutive_same_sign < UINT8_MAX) {
_consecutive_same_sign++;
} else {
_consecutive_same_sign = 1;
}
_last_sign = s;
}
} }
_last_value = value; _last_value = value;
return _difference_filter.getState(); return _difference_filter.getState();
} }
uint8_t consecutiveSameSign() const { return _consecutive_same_sign; }
void reset() void reset()
{ {
_difference_filter.reset(0.f); _difference_filter.reset(0.f);
_last_value = NAN; _last_value = NAN;
_last_sign = 0;
_consecutive_same_sign = 0;
} }
private: private:
AlphaFilter<float> _difference_filter; AlphaFilter<float> _difference_filter;
float _last_value{NAN}; float _last_value{NAN};
int8_t _last_sign{0};
uint8_t _consecutive_same_sign{0};
}; };

View File

@@ -34,16 +34,86 @@
#include "MovingDiff.hpp" #include "MovingDiff.hpp"
#include <gtest/gtest.h> #include <gtest/gtest.h>
TEST(MovingDiffTest, RcInputContinuous) // Sustained movement in one direction: filter converges to true velocity
// and consecutiveSameSign accumulates past the override threshold (3).
TEST(MovingDiffTest, ConsistentMovement)
{ {
MovingDiff _diff; MovingDiff diff;
EXPECT_FLOAT_EQ(_diff.update(0.0f, 0.0f), 0.f); // 0,0,0 diff.update(0.f, 1.f); // first sample, no diff yet
EXPECT_FLOAT_EQ(_diff.update(1.0f, 1.0f), 0.f); // 1*,0,0 EXPECT_NEAR(diff.update(1.f, 1.f), 1.f, .1f); // diff=+1, ~0.952
EXPECT_FLOAT_EQ(_diff.update(0.0f, 1.0f), 0.f); // 1,-1*,0 EXPECT_NEAR(diff.update(2.f, 1.f), 1.f, .01f); // ~0.998
EXPECT_FLOAT_EQ(_diff.update(0.0f, 1.0f), 0.f); // 0,-1,0* EXPECT_NEAR(diff.update(3.f, 1.f), 1.f, .001f); // ~0.9999
EXPECT_FLOAT_EQ(_diff.update(0.0f, 1.0f), 0.f); // 0*,-1,0 EXPECT_NEAR(diff.update(4.f, 1.f), 1.f, .001f);
EXPECT_FLOAT_EQ(_diff.update(1.0f, 1.0f), 0.f); // 0,1*,0 EXPECT_NEAR(diff.update(5.f, 1.f), 1.f, .001f);
EXPECT_FLOAT_EQ(_diff.update(0.0f, 1.0f), 0.f); // 0,1,-1* EXPECT_FLOAT_EQ(diff.update(6.f, 1.f), 1.f); // fully settled
EXPECT_FLOAT_EQ(_diff.update(2.0f, 1.0f), 1.f); // 2*,1,-1 EXPECT_GE(diff.consecutiveSameSign(), 6);
EXPECT_FLOAT_EQ(_diff.update(4.0f, 1.0f), 2.f); // 2,2*,-1 }
// Erratic same-sign signal at realistic RC rate (50 Hz): every 3rd sample
// spikes to +3/s, the rest are near-zero (+0.05/s), all positive. Raw diff
// peaks above the override threshold (1/s) yet the filter never crosses it,
// which shows the magnitude check adds necessary protection over sign alone.
TEST(MovingDiffTest, ErraticSameSignFilterStaysBelowThreshold)
{
MovingDiff diff;
const float dt = 0.02f; // 50 Hz
diff.update(0.f, dt); // first sample
float val = 0.f;
for (int i = 0; i < 100; i++) {
val += (i % 3 == 0) ? 0.04f : 0.001f; // diffs sometimes exceed with +2/s but are usually +0.05/s
EXPECT_LT(diff.update(val, dt), 1.f); // filter never reaches override threshold
}
EXPECT_GT(diff.consecutiveSameSign(), 3); // consistently same sign throughout
}
// A single-sample outlier (spike up, immediately returns) must not build up
// consecutiveSameSign past 1, so it cannot trigger the override gate (threshold = 3).
TEST(MovingDiffTest, SingleSampleOutlier)
{
MovingDiff diff;
diff.update(0.f, 1.f); // first sample, no diff yet
EXPECT_EQ(diff.consecutiveSameSign(), 0);
diff.update(0.f, 1.f); // diff=0, sign=0, no update
EXPECT_EQ(diff.consecutiveSameSign(), 0);
diff.update(1.f, 1.f); // outlier spike: diff=+1, consecutive=1
EXPECT_EQ(diff.consecutiveSameSign(), 1);
diff.update(0.f, 1.f); // returns: diff=-1, opposite sign resets consecutive to 1
EXPECT_EQ(diff.consecutiveSameSign(), 1);
diff.update(0.f, 1.f); // diff=0, no update
EXPECT_EQ(diff.consecutiveSameSign(), 1);
}
// Switching RC source to a joystick held at a different position produces a single large
// diff followed by zero-diffs (static hold). consecutiveSameSign must stay at 1 so the
// step does not trigger the override gate (threshold = 3).
TEST(MovingDiffTest, SignalStepOnSourceSwitch)
{
MovingDiff diff;
diff.update(0.2f, 1.f); // first sample, no diff yet
EXPECT_EQ(diff.consecutiveSameSign(), 0);
diff.update(0.2f, 1.f); // diff=0
EXPECT_EQ(diff.consecutiveSameSign(), 0);
diff.update(0.2f, 1.f); // diff=0
EXPECT_EQ(diff.consecutiveSameSign(), 0);
diff.update(-0.8f, 1.f); // source switch: single large step diff=-1.0, consecutive=1
EXPECT_EQ(diff.consecutiveSameSign(), 1);
diff.update(-0.8f, 1.f); // joystick static: diff=0, no sign update
EXPECT_EQ(diff.consecutiveSameSign(), 1);
diff.update(-0.8f, 1.f); // diff=0
EXPECT_EQ(diff.consecutiveSameSign(), 1);
diff.update(-0.8f, 1.f); // diff=0
EXPECT_EQ(diff.consecutiveSameSign(), 1);
} }

View File

@@ -40,3 +40,18 @@ parameters:
max: 1 max: 1
decimal: 2 decimal: 2
increment: 0.01 increment: 0.01
MAN_OVERRIDE_SPD:
description:
short: Manual control override speed threshold
long: >-
Stick velocity above which the pilot regains control by switching to Position
mode (or Altitude if position is unavailable). Unit: normalized stick travel
per second — at 1.0, moving a stick half its range in ~0.5s triggers it.
A negative value disables the feature. Only applies to multicopters and VTOLs in MC mode.
type: float
default: 1
unit: '1/s'
min: -1
max: 10.0
decimal: 1
increment: 0.5

View File

@@ -12,7 +12,7 @@ parameters:
stick centered - MPC_LAND_SPEED stick centered - MPC_LAND_SPEED
stick full down - 2 * MPC_LAND_SPEED stick full down - 2 * MPC_LAND_SPEED
Manual override during auto modes has to be disabled to use this feature (see COM_RC_OVERRIDE). Manual override has to be disabled to use this feature (MAN_OVERRIDE_SPD -1).
type: enum type: enum
values: values:
0: Nudging disabled 0: Nudging disabled