home >> Low level routines for simulation >> pseudo code/code >> 1st order dynsysts
last update: may 2006

1st order dynsysts

1st order continuous linear low-pass filter C1LL


Equation:
dx/dt= k(u- x) where u is the input, x is the ouput and dx/dt is the first derivative of x.
Parameter: k.

Tuning parameter: { k> 0 } or Time Constant{ τ= 1/k} or Settling Time {ST= 3*τ= 3/k }. The Settling Time is the time after which abs( u-x) stays under 5% of input when u is a step.

if k is negative, the dynsyst is unstable ( divergent): x grows exponentially.
if k is positive, it is stable ( convergent) : x moves towards u.
The greater k is, the faster x reacts to a change in u.

Behavior
On a unit step input ( u(t< 0)=0, u(t≥ 0)= U0 with U0 constant) [see Fig C1Fs]

As a function of time: x= ( 1- exp(-k*t) )* U0 for t<0.
x reaches approx. 63% of U0 at t= 1/k= τ.
x reaches approx. 95% of U0 at t= 3/k= 3*τ= Settling Time by definition.
x reaches approx. 99% of U0 at t= 4.6/k= 4.6*τ.
x reaches approx. 99.9% of U0 at t= 7/k= 7*τ.
dx/dt at t=0 ( ie x slope ) is equal to U0*k= U0/τ.
When t is big enough, exp(-k*t)≅ 0 then x≅ U0.


If x0 is not null, then x= x0+ ( 1- exp(-k*t))* (U0- x0).
Its integral is y= ∫ x= y0+ t* U0- ( U0- x0)* (1- exp(-k*t))/ k, or y= y0+ t* U0- ( x- x0)/ k.

On a ramp input ( u(t< 0)=0, u(t≥ 0)= USpeed*t with USpeed constant) [see Fig C1Fr]
Then x= USpeed*( t- (1- exp(-k*t))/k ) for t≥ 0.
When t is big enough: xUSpeed*( t- 1/k) ie xu- USpeed/k.
We face here an unavoidable drawback of the first order low-pass filter:
on a ramp input, its output x will always "lag" behind the input u, by a value USpeed/k.
More generally, when the input signal varies with time, there is no way for the ouput to get close to the input.
As the error is known, one can think to compensate for it by adding a USpeed/k term to u ( or a portion of it). This does not work as the filter looses its low-pass behaviour.
Another way would be to introduce another low-pass filter fed in by USpeed, providing a smoothed speed used in the compensating term. This would lead to using two first order filters and effectively, the only solution for inputs varying as a ramp, ie u proportional to t, is to use a "special" second order dynsyst. This is addressed in a cleaner way in the 2nd order dynsysts chapter.
More generally, for inputs u proportional to tn a "special" (n+1) order dynsyst is required.

C1LL_vKvStep C1LL_vKvRamp

Numerical linear low-pass filters

1st order numerical linear low-pass filter N1LL

Procedure:
The standard format is: Xn= K* Xn-1 + (1- K) Un-1,
but I prefer: Xn= Xn-1 + A* ( Un-1 - Xn-1 ), where A= 1-K.
Parameter: 0 ≤ A ≤ 1
Tuning parameter:
{ k>0 } then A= 1- K= 1-exp(-k*T), or Time Constant { τ>0 } then A= 1-exp(-T/τ)
or Settling Time { ST> 0}, then A= 1-exp(-3*T/ST).

Behavior:
Assuming U= X= 0 for n< 0...
On a step input ( U(n< 0)=0, U(n≥ 0)= U0 with U0 constant≠ 0) [see Fig N1LLs]
At t=n=0: X= 0;
At n=1, t=T: X= A* U0;

Analytical expression, assuming a non null initial condition X0: Xn= (1- Kn)*U0+ Kn X0.

Assuming X is the input of an integrator such as IXn= IXn-1+ T* Xn-1, then
IXn= IX0+ T*( n*U0+ ( X0- U0)*( 1- Kn)/( 1-K))
If X is a speed, and IX a position, assuming X0 > 0 and U0=0 ( ie a stop order), the distance run until full stop is:
StopDist= T*X0/(1-K)= T*X0/A ( idem if IXn= IXn-1+ T* Xn).

Using this result the other way round, for a mobile the speed dynamics of which obey the X equation, the last formula gives the distance to its final destination at which its speed must be set to zero in order to stop right on target ( prediction).

On a step input, N1LL matches perfectly the continuous filter values, even with high values of timestep.
This is not true for other inputs, as can be seen on a ramp input.


On a ramp input ( U(n< 0)=0, U(n≥ 0)= USpeed*n*T with USpeed constant) [see Fig N1LLr]
At t=n=0: X= 0
In steady state: XDSErr= USpeed*T/A; the error is not null

N1LL_IS100_vT N1LL_IR100_vT

1st order numerical linear low-pass filter N1LL_Ns

Procedure:
Xn= Xn-1 + A * ( Un - Xn-1 ), ie same as N1LL, except for the input which is here the current step value

Behavior: N1LL_Ns is one step ahead of N1LL.
Assuming U= X= 0 for n< 0...
On a step input ( U(n< 0)=0, U(n≥ 0)= U0 with U0 constant≠ 0) [see Fig N1LLn0s]
At t=n=0: X= A*U0 , ie the dynsysts reacts right away at t=n= 0.

Analytical expression, assuming a non null initial condition X0: Xn= (1- Kn+1) * U0+ Kn X0;
Assuming X is the input of an integrator such as IXn= IXn-1+ T* Xn-1 , then
IXn= IX0+ T*( n*U0+ (X0- U0)*K *( 1- Kn)/( 1-K)).

If X is a speed, and IX a position, assuming X0 > 0 and U0=0 ( ie a stop order), the distance run until full stop is :
StopDist= T*X0* K/(1-K)= T*X0*(1-A)/A ( idem if IXn= IXn-1+ T* Xn).

On a ramp input ( U(n< 0)=0, U(n≥ 0)= USpeed*n*T with USpeed constant) [see Fig N1LLn0r]
At t=n=0: X= 0.
In steady state, Un- Xn= USpeed*T(1-A)/A; the error is not equal to zero.

N1LL_n0_IS100_vT N1LL_n0_IR100_vT

Notes :
1.if A= 0 ( zero reaction time, ie k= infinite) then for N1LL_Ns: Xn = Un ie N1LL_Ns is "transparent" as one could expect, whereas for N1LL: Xn = Un-1 ie N1LL introduces a one Timestep pure delay. This tends to make N1LL_Ns a better choice.
The drawback is that, for a given k, N1LL_Ns smoothes less when the Timestep is increasing, wich is counter intuitive.

2.N1LL_Ns can be used as a first order estimator: U is then the unknown modelled as a constant, X is its estimate, which must initialized to the best guess for U.

3.N1LL and N1LL_Ns have the same source code, as the input is an argument of the calling function implementing them.

1st order numerical linear low-pass filter N1LL2

The filter N1LL2 is based on the relationship between output and input of the continuous filter when the input is a ramp. The fit is then perfect for such inputs when Timestep varies, but no more for a step input. This is because the step at n= 0 is implicitely "interpreted" by N1LL2 as a ramp from n=-1 to n=0.
procedure:
U2= (1- b)* Un-1+ b* Un; the input is filtered using an appropriate weighted average
with b= 1/A - 1/(k*T).
Xn= Xn-1+ A * ( U2 - Xn-1 ).
Parameter, tuning parameter: same as N1LL.

N1LL2_n0_IS100_vT_s0 N1LL2_n0_IR100_vT_s0

1st order numerical non-linear low-pass filter N1LA

N1LA_vv_s0

The main purpose of this filter is is to avoid the "slowing down" of X of N1LL and the like when X comes close to U. It also includes a bound on Speed.
To do that, I basically compute the speed as for a rate bounder with parameter SPEEDFLOOR, the speed as for a linear filter with parameter A, and take the max of both. I then bounds the result to SPEEDBOUND.

N1LA_IS100_vt N1LA_IR100_vT

on a unit step input
For large initial values of U-X and proper setting of SPEEDFLOOR and SPEEDBOUND, the first portion of X curve is at constant rate= SPEEDBOUND, the second portion is as a linear filter , and the last portion is at constant speed= SPEEDFLOOR until X reaches U.



float N1LA_angle( float CurrTimeStep_i, float Output_i/*previous output*/, float Input_i)
{
float Delta_a= Input_i- Output_i;
Delta_a= wrapHalfPrd( Delta_a );
float Rate_a= Delta_a/ CurrTimeStep_i;

float RateRBnd_a= minmax( Rate_a, -SPEEDFLOOR, SPEEDFLOOR);
float RateLin_a= A* Rate_a;
if( Rate_a>= 0) Rate_a= RateRBnd_a> RateLin_a? RateRBnd_a: RateLin_a;
else Rate_a= RateRBnd_a< RateLin_a? RateRBnd_a: RateLin_a;

Rate_a= minmax( Rate_a, -SPEEDBOUND, SPEEDBOUND);

Output_i= Output_i+ CurrTimeStep_i* Rate_a;
Output_i= wrapPrd(Output_i) ;
return Output_i;//updated output
}

1st order numerical non-linear low-pass filter N1LB

N1LB_vv

The purpose is the same as for N1LA, but implementation and behaviour are different
I compute the speed as for a rate bounder, split it with a first order filter parameter A , bound the (1-A)Speed term to SPEEDFLOOR, and finally re-combine ( add) the two terms.
Behavior:
on a unit step input
For large initial values of U-X and proper setting of SPEEDFLOOR and SPEEDBOUND, the first portion of X curve will be at constant rate= SPEEDBOUND, and the second and last portion will be as a linear dynsyst, X reaching for U at rate = SPEEDFLOOR.

N1LB_IS100_vT N1LB_IR100_vT


float N1LB_Angles( float CurrTimeStep_i, float Output_i/*previous output*/, float Input_i)
{
float Delta_a= Input_i- Output_i;
Delta_a= wrapHalfPrd( Delta_a);
float Rate_a= Delta_a/ CurrTimeStep_i;

Rate_a= minmax( (1-A)* Rate_a, -SPEEDFLOOR, SPEEDFLOOR)+ A* Rate_a;

Rate_a= minmax( Rate_a, -SPEEDBOUND, SPEEDBOUND);

Output_i= Output_i+ Rate_a * CurrTimeStep_i;
Output_i= wrapPrd(Output_i) ;
return Output_i;
}

Generalization on first order numerical non-linear filters design

1.Starting from Rate= Delta_a/ CurrTimeStep_i, a first order filter can be designed with any function F(y) by setting RateFinal=F(Rate) and Output=PreviousOutput+ T* RateFinal providing F(y) is between 0 and y for any value of y. F(y) is usually a non-decreasing function of y.
2.If one got such functions F1 et F2, and a splitting function S ( 0 < S < 1), then one can use F3(y)=F1(S(y))+F2(y-S(y)) providing again that F3 follows the hereabove rule. Usual S functions also follows the rule, so F3 does too.
3.F3(y)= F2(F1(y)) also works.
This always works for first order filters because the updated output value is always between the previous output and the input.
It can be used on higher order filters, but it needs adaptation as the rule will prevent any crossing of the input by the output or generate glitches at crossing time.