When performing slow turns, the heading rate response can remain below the gyro deadzone for periods of many seconds. During this period, the gyro angle is not accumulating the true turn rate and the error is equal to amount the robot turned during this period. (i.e. the area under the heading rate curve).

The gyro deadzone is hidden from the user but is set by a

#define nGyroJitterRange 4

which places its value at 2.8 degs/sec. The time spent below this rate multiplied by the average rate is the heading error. If the rate response is exponential… then the error is tau*2.8 deg/sec where tau is the time constant of the response.
I.e. I use a PID way point tracker which commands a heading response with a tau = 1 second. The rate can be modeled as 100 deg/sec*exp(-time/tau). The area under the tail when the rate gets below the deadzone is 2.8 degs. So this error occurs for every turn and is cumulative if the turns are in the same direction.

Edit: One way to minimize this error is to delay the deadzone until the turn is finished. For an exponential turn rate response this is about 3 time constants to get about 99% of the rate response included. For a tau = 1 sec this is 3 seconds.

Since the deadzone is delayed for 3 seconds gyro drift due to noise can occur. For a typical drift rate of .1 deg/sec we can pick up a .3 deg error which would not have been there if the deadzone were active. So this is the trade off…the net savings makes it worth while.

I have some sample code that implements the above timed deadzone.

First in loadBuildOptions routine set the internal deadzone to zero by this define:

```
#define nGyroJitterRange 0
```

Then in my user code I let the RobotC gyro do its integration and use the gyro angle to derive my own rate for the period of say dt = 10 ms. I then process the rate with a timed deadzone and then reintegrate. Its a little weird but here is my code: You have to be careful of gyro rollovers unless you use the continuous version which I have assumed here.

```
float psi_est = 0; // my float heading estimate
float delta_psi = 0;//difference in heading for an iteration
int dt = 0; // iteration time
int start_time_delay = 0; // this is the time when the rate first falls below deadzone
//..............................................................
gyro_10 = SensorValue[gyro];
delta_psi = gyro_10 - gyro_10_last)/10.;
gyro_10_last = gyro_10;
dt = time1[T4];
ClearTimer(T4);
if(abs(delta_psi) > 2.8*dt/1000. )
// this is equivalent to #define nGyroJitterRange 4 in loadBuildOptions
// I have set #define nGyroJitterRange 0 so gyro has no deadzone.
{
psi_est = psi_est + delta_psi ;
start_time_decay = time1[T1];
}
else
{
if(time1[T1] < start_time_decay + 3000)
//this allows the deadzone to remain out for 3 extra seconds
{
psi_est = psi_est + delta_psi ;
}
else delta_psi = 0;
}
```