Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarter RoC/RoD acceleration limit #4448

Merged
merged 1 commit into from
Jun 3, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions src/main/navigation/navigation_multicopter.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,24 @@ static void updateAltitudeVelocityController_MC(timeDelta_t deltaMicros)

posControl.pids.pos[Z].output_constrained = targetVel;

// limit max vertical acceleration to 1/5G (~200 cm/s/s) if we are increasing RoC or RoD (only if vel is of the same sign)
// if we are decelerating - don't limit (allow better recovery from falling)
const bool isSameDirection = (signbit(targetVel) == signbit(posControl.desiredState.vel.z)) && (targetVel != 0) && (posControl.desiredState.vel.z != 0);
if (isSameDirection && (fabsf(targetVel) > fabsf(posControl.desiredState.vel.z))) {
const float maxVelDifference = US2S(deltaMicros) * (GRAVITY_CMSS / 5.0f);
// Limit max up/down acceleration target
const float smallVelChange = US2S(deltaMicros) * (GRAVITY_CMSS * 0.1f);
const float velTargetChange = targetVel - posControl.desiredState.vel.z;

if (velTargetChange <= -smallVelChange) {
// Large & Negative - acceleration is _down_. We can't reach more than -1G in any possible condition. Hard limit to 0.8G to stay safe
// This should be safe enough for stability since we only reduce throttle
const float maxVelDifference = US2S(deltaMicros) * (GRAVITY_CMSS * 0.8f);
posControl.desiredState.vel.z = constrainf(targetVel, posControl.desiredState.vel.z - maxVelDifference, posControl.desiredState.vel.z + maxVelDifference);
}
else if (velTargetChange >= smallVelChange) {
// Large and positive - acceleration is _up_. We are limited by thrust/weight ratio which is usually about 2:1 (hover around 50% throttle).
// T/W ratio = 2 means we are able to reach 1G acceleration in "UP" direction. Hard limit to 0.5G to be on a safe side and avoid abrupt throttle changes
const float maxVelDifference = US2S(deltaMicros) * (GRAVITY_CMSS * 0.5f);
posControl.desiredState.vel.z = constrainf(targetVel, posControl.desiredState.vel.z - maxVelDifference, posControl.desiredState.vel.z + maxVelDifference);
}
else {
// Small - desired acceleration is less than 0.1G. We should be safe setting velocity target directly - any platform should be able to satisfy this
posControl.desiredState.vel.z = targetVel;
}

Expand Down Expand Up @@ -174,8 +184,9 @@ void setupMulticopterAltitudeController(void)
motorConfig()->minthrottle + rcControlsConfig()->alt_hold_deadband + 10,
motorConfig()->maxthrottle - rcControlsConfig()->alt_hold_deadband - 10);

/* Force AH controller to initialize althold integral for pending takeoff on reset */
if (throttleStatus == THROTTLE_LOW) {
// Force AH controller to initialize althold integral for pending takeoff on reset
// Signal for that is low throttle _and_ low actual altitude
if (throttleStatus == THROTTLE_LOW && fabsf(navGetCurrentActualPositionAndVelocity()->pos.z) <= 50.0f) {
prepareForTakeoffOnReset = true;
}
}
Expand Down Expand Up @@ -491,7 +502,7 @@ static void updatePositionAccelController_MC(timeDelta_t deltaMicros, float maxA
if (STATE(NAV_CRUISE_BRAKING)) {
maxAccelChange = maxAccelChange * 2;
}
#endif
#endif

const float accelLimitXMin = constrainf(lastAccelTargetX - maxAccelChange, -accelLimitX, +accelLimitX);
const float accelLimitXMax = constrainf(lastAccelTargetX + maxAccelChange, -accelLimitX, +accelLimitX);
Expand All @@ -513,17 +524,17 @@ static void updatePositionAccelController_MC(timeDelta_t deltaMicros, float maxA
//Boost required accelerations
if (STATE(NAV_CRUISE_BRAKING_BOOST) && navConfig()->mc.braking_boost_factor > 0) {
const float rawBoostFactor = (float)navConfig()->mc.braking_boost_factor / 100.0f;

//Scale boost factor according to speed
const float boostFactor = constrainf(
scaleRangef(
posControl.actualState.velXY,
navConfig()->mc.braking_boost_speed_threshold,
navConfig()->general.max_manual_speed,
posControl.actualState.velXY,
navConfig()->mc.braking_boost_speed_threshold,
navConfig()->general.max_manual_speed,
0.0f,
rawBoostFactor
),
0.0f,
0.0f,
rawBoostFactor
);

Expand Down