home >> Low level routines for simulation >> Numerical dynamic systems design process
last update: may 2006

Numerical dynamic systems design process

Design process

(There is no need to read this chapter to be able to use the code).

My approach to numerical dynsysts design is different than the one game programmers can usually read about, and this explains why and in what way, with several examples. This can be helpful for those who want to create their own dynsyst/filter and those whose face an unexpected behaviour of their code.

The widespread approach, referred to as "A" in the following, is
- to select a continuous dynsyst known as behaving as required( eg: the good ole' spring and damper system),
- then to set the dynamic characteristics ( stability/damping and responsiveness) by tuning the parameters of the equations of the continuous model,
- and last to select an integration scheme to get a set of numerical equations.

This approach has some pitfalls:
- it can lead to unnecessary complicated numerical equations ( resulting from the integration scheme), eventhough a 100% faithfull simulation might not be an objective,
- sampling ( and possibly the integration scheme) generates its own stability problems which cannot be addressed based on the continuous system analysis.
As a consequence, the numerical dynsyst may show for certain values of parameters and/or for high values of the timestep the dreaded "weird" behavior, while not knowing why and how to prevent that.
The main issue is the underlying assumption in "A" process that stability and responsiveness characteristics of the continuous system will be carried over to the numerical system. This is unfortunately not true, theory tells that stability analysis is different between the two type of systems. This is why my approach, referred to as "B" in the following, departs from the usual approach by applying their own appropriate rules to the numerical dynsysts; I also sometimes allow myself to forget about the 100% faithfull simulation of a continuous system.

EXAMPLE: selecting the numerical input for the numerical design of the rate bounder

This simple study focuses on one of the differences between the two approaches( no stability issues here).
The rate bounder bounds the speed - ie the rate of variation with time- of the input. T is the timestep between 2 computation loops (ie 2 updates) , and SPEEDBOUND is the constant value of the bound on the absolute value of speed
input and output are the continuous values of the continuous dynsyst, Input and Output are those of the numerical dynsyst.
For any computation step n: Input(step= n)= input( t=n*T); The question here is to select either Inputn or Inputn-1 for Input? in the following procedure

Speed=( Input? - Outputn-1)/T;
if (Speed> SPEEDBOUND) v= SPEEDBOUND;
else if( Speed< -SPEEDBOUND) v= -SPEEDBOUND;
Outputn= Outputn-1+ T* Speed;

-"A" standpoint : to get the numerical simulation of its continuous dynsyst counterpart, ie same outputs, equation must be:

Speed=( Inputn-1 - Outputn-1)/T;

Assuming input(t< 0)=output(t< 0)=0, then, at t= 0 (corresponding to n=0) on a large enough step input, Output0= Inputn-1= 0.
Moreover, assuming the step final value is m*SpeedBound*T with m integer, Output reaches the final value on the mith loop, ie at t= m*T.

-"B" standpoint : considering that bounding the speed of Input is really the only purpose of the design, I do not refer to the continuous case at all, and I can write directly the simplest equation that fits the need, with Input argument= current value of Input.

Speed=( Inputn - Outputn-1)/T;

The behavior is different:
Assuming Input(n<0)= Output(n<0)= 0, then, at n= 0 on a large enough step input, Output= Input0= SpeedBound*T. Moreover, assuming the step final value is m*SpeedBound*T with m integer, Output reaches the final value on the (m-1)ith loop, ie at t= (m-1)*T.

Approach "B" does not introduce an one time-step lag (pure delay). This lag can create problems when several numerical dynsysts/filters are placed in a row ( one step pure delay is introduced for each of the dynsyst).
Moreover, I expect the filter to have no effect whenever the absolute value of the input speed stays under the max speed. "B" fulfills this requirement, but not "A".
On the other end, for "B", the greater the timestep T, the closer the output to the input for a step input , which is counter-intuitive when expecting a smoothing behavior.
As a conclusion, when the choice is open, I always use "B".
More generally, if I really need a behavior such as "A" with several dynsysts in a row ( one and only one step delay), I use "B" for all of them except one, or simply add the lag to the first input or to the last output.
A case where Input= Inputn-1 is preferable is when using complementary filters ( 2 filters are complementary when "fed in" with the same input, the sum of their output is equal to the input for all t or n; the highpass filter one should use Inputn whereas its companion lowpass filter should use Inputn-1).

EXAMPLE: designing a 1st order linear system, using 2 different processes

Process "A", based on the simulation of a continuous system

The equation of the continuous 1st order low-pass filter is
dx/dt= k( u-x), u being the input, x the output and k the parameter.

A1.1.Deriving the numerical design using a simple integration scheme
Vn= k*(Un- Xn) and Xn= Xn-1+ T*Vn-1.
Then Xn= Xn-1+ k*T*(Un-1- Xn-1).

A1.2.Deriving the numerical design using an implicit integration scheme
Vn= k*(Un- Xn) and Xn= Xn-1+ T*Vn,
then Xn= Xn-1+ (1/(1+k*T))*(Un- Xn-1)

A1.3.Deriving the numerical design assuming constant acceleration
Vn= k*(Un- Xn) and Xn= Xn-1+ 0.5*T*(Vn+Vn-1).
Then Xn= Xn-1+ (k*T/(1+0.5*k*T))*( 0.5*(Un+Un-1)- Xn-1)

A2. Selecting a particular input, finding x as a function of time, and deriving a numerical system by allowing any input.
With a step as input,
dx/dt= k( u- K_UO), with u= K_UO being the constant step value for t≥ 0;
then for t≥ 0:
x= x0* exp( -k*t)+ ( 1- exp( -k*t))* K_U0
or x= x0+ ( 1- exp(-k*t))* (K_UO- x0)
Endly, releasing the constraint that the input be a step, and considering x values between 2 steps with T= t:
Xn= Xn-1+ (1- exp(-k*T))*(Un-1- Xn-1)
K_U0 is replaced by Un-1 to insure X0= x0= 0.
Whatever T, even if variable, on a step input the output will be equal to the continuous one. because the continuous equation has been solved for such an input.
This does not holds true for other inputs.

Process "B", starting straight from a numerical procedure and analyzing stability on those

Starting from the simplest 1st order numerical dynsyst one can think of:
Xn= Xn-1+ A*(Un- Xn-1) or Xn= Xn-1+ A*(Un-1- Xn-1)

Stability analysis ( not detailed here) results in the following constraints: 0< 1-A < 1, ie 0< A< 1.
Neither "A1.1" nor "A1.3" solutions guarantee that.
"A1.2" and "A2" solutions are OK, though "A1.2" will obviously not provide an output similar to the one of the continuous system.

One can set parameter A directly, but my choice is to have the numerical system getting the same stability characteristics as the continuous one ( the roots of the characteristic equation of the numerical dynsyst are function of those of its continuous counterpart).
Here, this fully defines A ( and K= 1- A) as A= (1- exp(-k T)).

"A2" solution, though resulting from a process not involving stability criteria, fulfills the stability requirement and even gets the same formula for A, but this does not always work.
I prefer then to use stability analysis, because
-I use a robust process consistent with my main goal, which is to insure stability and not to model a continuous system,
-getting the analytical solution of more complex continuous equations quickly becomes a nightmare,
-I can use its criteria for non linear systems.

Please note that applying stability criteria does not require using Un, Un-1 or whatever combination of current and previous inputs. This is a matter of selecting the behavior of the dynsyst: "A2" approach can be used for that, but it is only an opportunity not a requirement.

N1LL_IS100_vT N1LL_IS100_vT

Process "A" again, with the reference input being a ramp instead of a step.

The input is then u= u0+ K_Vc* t, with K_Vc a constant speed.
dx/dt= k( u- x) Then for t≥ 0:
x= (u0-x0)* exp(-kt)- u0+ K_Vc* ( t- (1- exp(-kt))/ k),
then, as K_Vc= (u- u0)/ t:
x= x0*exp(-kt) + u0*(1- exp(-kt))+ (u- u0)*(1- (1- exp(-kt))/(kt))
or x= x0+ (1- exp(-kt))*(u0- x0)+ (u- u0)*(1- (1- exp(-kt))/(kt))
Endly, releasing the constraint that the input be a ramp, considering x values between 2 steps with T= t and introducing A= 1-exp(-kT):
Xn= Xn-1+ A*(Un-1- Xn-1)+ (Un- Un-1)*(1-(1- A)/(kT))
A correcting term appear compared to the previous system.
Introducing b defined as b= 1/A- 1/(kT),
the process can be split into two steps:
UTemp= Un-1+ b*(Un- Un-1), ie a combination of the inputs ( actually a non recursive filter),
and Xn= Xn-1+ A*(UTemp- Xn-1), which is the equation seen in the preceding paragraph.
Whatever T, even if variable, and on a ramp input, the output will be equal to the output of continuous filter.
This does not holds true for other inputs, including a step input.
Note that the stability criterion is the same as before ( 0< A <1), and the behavior has been changed by modifying the input.

N1LL2_n0_IS100_vT N1LL2_n0_IR100_vT

EXAMPLE: designing a non linear filter with a continuous system as a starting point

This study elaborates on the preceding one, with a filter which is non-linear. My specification is that the output should decelerate at a max deceleration a when moving from its current value towards the input, when the input is a step.
Here, I use "A2" process just to get a set of equations, and end with stability analysis.
From the specs, x is a parabola that must pass through the previous output x0=x(t=0), and through the constant input U= K_UO with a null speed; after having reached the input, the parabola should obviously not apply anymore.
The equations should give the remaining unknown, ie the current speed and finally the set of equations.
Obviously, the speed should have the same sign as K_UO-x0, and the acceleration should have the opposite sign.
for any point between x(t=0) and K_UO:
x= x0+ v0* t- 0.5* Sgn* a* t2
with a> 0 being the deceleration, Sgn the sign of ( K_UO-x0) , x0 and v0 being the value and speed at t= 0
K_UO must be the apex reached at tf where vf= v(tf)= 0,
tf= t0+ abs(v0)/a.
Hence, v0 must be such as K_U0= x0+ 0.5*Sgn*v02/ a
ie v0= Sgn* sqrt( 2*a*abs(K_U0-x0)), which gives
x= x0+ Sgn* sqrt( 2*a*abs(K_U0-x0))* t- 0.5*Sgn*a*t2.
With T= t, x0= Xn-1, and replacing the constant K_U0 by any input...
Xn= Xn-1+ T * Rate, with Rate= Sgn*( -0.5*a*T+ sqrt( 2*a*abs(Un- Xn-1))).
We wind up with a non linear 1st order dynsyst.
Translating stability requirement on parameter A from the preceding example
results in the requirement that Rate as above be replaced by (Un- Xn-1)/T whenever abs(Un- Xn-1)/T ≤ 0.5*a*T.

Actually, instead of using Rate as a command and forcing x to a parabola, using it as a bound provides more flexibility; the final pseudo-code is then:

Rate= (Un- Xn-1)/T // or any lower value with the same sign implementing possible additional constraints from specs;
if( abs(Rate)> 0.5*a*T)
{
RateParabMaxTmp= ( -0.5* a* T+ sqrt( 2*a*abs(Un- Xn-1)));
if( Rate> 0) Rate= RateParabMaxTmp;
else Rate= -RateParabMaxTmp;
}
Xn= Xn-1+ T * Rate;