Braking Gain in Loiter mode

I have a question in Loiter Mode code.

I am discussing regarding the calc_desired_velocity() function in loiter::update()

As soon as the pilot sticks are centered at zero, we enter the following section.

if (_desired_accel.is_zero()) {

            if ((AP_HAL::millis()-_brake_timer) > _brake_delay * 1000.0f) {

                float brake_gain = _pos_control.get_vel_xy_pid().kP() * 0.5f;

                loiter_brake_accel = sqrt control(...)


        } else {

            loiter_brake_accel = 0.0f;

            _brake_timer = AP_HAL::millis();


My question is why do we gain schedule by reducing the velocity P gain? As far as my intuition goes, we should make the response faster and increase the P gain rather than reducing it.

Also what is the reason to wait for brake delay? Can’t we just brake as soon as the pilot sticks are centered? If I remove the brake delay condition, will it have any effect over the response?

@Leonardthall can you elucidate here?

Can´t say anything about the P gains, but I also don´t understand the purpose of the brake delay. The copter feels disconnected if it takes some time to brake when the sticks are centered. I set LOIT_BRK_DELAY close to 0, which is much better.

Ok, so there are a number of issues and misunderstandings here.

First up there are two things at play here, there is the kinematic trajectory that the Loiter controller generates based on your stick inputs. Then there is the position controller tune and it’s ability to adjust the pos/vel/accel of the aircraft, finally there is the expectations of how the pilot wants Loiter to “feel”.

We don’t. This P gain shapes the jerk profile of the breaking mauver. We use half the setting used in the position controller because we can safely assume the aircraft is capable of following that. If half the P gain of the position controller is too large then you have bigger problems. The P term here only defines the last portion of the breaking mauver, in particular how quickly the aircraft levels after it finishes decelerating.

A quick explanation of Jerk may be required. Jerk is the rate of change of acceleration and is closely linked to the rate of change of lean angle. You can not go from a 5m/s/s breaking maneuverer to stationary instantly. It takes a finite period of time to reduce the deceleration from 5 m/s/s to 0 m/s/s.

One of my very early posts covers the square root controller:

If follows from the point above, if the position controller has been tuned up perfectly then any value of P larger than that used by the position controller will result in attitude changes that the aircraft is not able to follow. In short, you can’t increase P above the best value unless you have a shitty tune to begin with.

Ok, a quick side to explain what breaking in loiter actually is. Loiter has been designed to be able to fly like Alt_Hold when there is no wind. It works on a theoretical drag model of the aircraft that generates a ideal velocity/acceleration based on your stick inputs and the aircraft speed. Therefore when you let go of the sticks the aircraft will decelerate to a stop based on the theoretical drag coefficient. This is great for very precise control of the aircraft combined with the ability to do fast transits between locations. So the problem is this breaking strength gets progressively less as you slow down, just as we see in Alt_Hold. It is often desirable to have a more assertive stop over and above the natural drag deceleration to provide a clearer feedback to the pilot that the aircraft has stopped. This additional breaking acceleration is what this part of the code does.


You can set it to zero.

When using assertive breaking values to provide a clear: “I am stopping now”, “I have stopped now” feedback to the pilot. With the delay set to zero the aircraft initiates a breaking maneuver each time the sticks pass through zero. This makes it very difficult to make precise adjustments at slow speeds. By adding a 1 second delay (my preference) the pilot can make precises adjustments that take the sticks into and out of the dead band knowing that the aircraft will not grab the park break until the sticks are released for a second.

So loiter has a natural breaking feel when you bring the sticks back to centre or near centre, an aggressive breaking when you pull the stick back away from the direction of travel, and a “park break” when you move the sticks to centre and after the break delay.

Try to make the aircraft do a slow 1m circle over 30 seconds with aggressive breaking and you will see what I mean.

Thank you for the detailed answer.

What is the reason that you kept the position controller in the Loiter mode?

I turned off the position controller from the code by feeding only “desired_velocity” and “vehicle velocity” to the velocity PID controller.
vel_target = _vel_desired.x; error = vel_target - _vehicle_horiz_vel;

Yet it was able to track the velocity with similar performance.

I want to understand the thinking process of keeping the position control when the objective is to control the velocity.

Thanks for the detailed explanation!

When there are little or no disturbances then the position controller doesn’t do anything. If you can perfectly control acceleration then you don’t need to control velocity or position.

The position controller ensures the aircraft follows the precise position that is calculated by integrating the velocity. Mathematically the position controller behaves similarly to the velocity PID I term.

Basically if you want the aircraft to stay where you left it until it is completly impossible for it to do so then you need to run a position controller.

This clears up everything! Thank you for your time to explain this.