I will be very honest: until very recently I did not really understood how PID controller’s Dterm really works. Yes, something with dampening, something with “looking into future”, bla bla bla. But the reason for not understanding was because I was overthinking it. There is no “magic” only simple mathematics and few basic concepts which I will now explain.

### Setpoint

**Setpoint** is the value which we request from our system. In case of multirotors, PID setpoint will be a rotation speed around axis given in degrees per second [dps]. Setpoint `0`

means we do not want to rotate (keep current attitude) and setpoint `200`

means we want to rotate at 200dps

### Measurement

**Measurement** the value that represents actual state of the system measured by some kind of sensor. In our case, it will be the gyroscope and rotation-around-axis speed measured in degrees per second

### Error

**Error** the difference between *Setpoint* and *Measurement* computed as *Error* = *Setpoint* – *Measurement*. In our case, when *Error* is above `0`

, that means drone is rotating too slow and should speed up. If *Error* is below `0`

, drone is rotating too fast and should slow down

### Derivative

**Derivative** to quote Wikipedia:

The derivative of a function of a real variable measures the sensitivity to change of the function (output) value with respect to a change in its argument (input value)

In layman’s terms: derivative tells us if value is getting bigger or smaller over time. If derivative is above `0`

, it is growing. If it is below `0`

, it is getting smaller. It also tells us something about a speed. The bigger the derivative, the faster something is changing.

The simplest way to compute current *derivative* (value, not function) is to subtract previous value from current value and divide by time derivative (this again…).

For example, if current rotation rate is 100dps, previous was 50dps, and 1 second passed between measurements, derivative equals 50dps^2 (degrees per seconds square) since *(100 – 50) / 1 = 50*. Over 1 second value grew from 50dps to 100dps.

If value would grow from 50dps to 100dps in 0,1s, derivative would be 500dps^2 since *(100 – 50) / 0.1 = 500*

Some of you might have noticed very similar example in real life. Remember acceleration? Acceleration is first derivative of speed!

## How Dterm really works

OK, now we know basics, it’s time to summarize `Dterm`

with one sentence:

Dterm tries to keep derivative (acceleration) at zero!

Pretty simple, right? But tries to keep derivative of what at 0? It depends. Sometimes it is derivative of error, sometimes it is derivative of measurement. Classical PID controllers usually uses derivative of error. PID controller of Betaflight uses by default 60% of error and 40% of measurement to compute derivative. But it can be adjusted.

Let’s take a look at this step by step:

- When we start to request change (stick movement when we want to roll for example) error start to grow fast and
`Dterm`

adds an extra boost to speed up at the very beginning even when error itself is still relatively small - Later on, when our drone starts to roll, and error stops to grow,
`Dterm`

becomes inactive. Derivative (acceleration) is close to 0, it has nothing to do. Error is still be present, but this is**not**`Dterms`

concern. This is a job for`Pterm`

- When
*measurement*starts to catch on*setpoint*, opposite thing starts to happen. Error starts to shrink and derivative is negative. Error is decelerating. Again,`Dterm`

wants to keep derivative at 0 and starts to act in opposite direction to`Pterm`

. Error might be still positive, but error derivative is negative and`Dterm`

counteracts`Pterm`

. This creates “damping” effect when measurement catches on*setpoint*and helps not to overshoot - Damping was not strong enough and overshoot happened. Error was still going down until it became negative. But derivative was all the time negative
`Dterm`

was trying to “slow down” all the time. At the peak of overshoot`Dterm`

became inactive again and then went up again when error started to grow again - After some fighting
*measurement*reached*setpoint*,*error*is stable again,*derivetive*is 0, nothing is changing, Dterm is inactive again

In the example above, not much was happening with *setpoint* and *measurement*. *Setpoint* only changed once. In the same time *measurement* and *error* changed 3 times, but *Dterm* changed 6 times! This is the reason **Dterm** wants to “fry your motors”. It changes very rapidly and if those changes are strong enough and are allowed to enter motors, they will overheat and burn. But this is a topic for a completely different story…