How to use a global variable when using ode45()?

I have a function named "my_carcontrol3" that gets passed the time "tau" in the ode45() function call. My idea was to use a global variable "i" as an index for "timesV", which is vector containing a series of time instants. I want "i" to increment by 1 when "tau" hits "timesV(i)." So in the my_carcontrol3(), for 0<t<100, i=1. Once "t" hits 100, it increments by 1. And for 100<t<460, i=2. And when "t" hits 460, it increments again and so on. But for whatever reason, the if conditional statement never got triggered in my_carcontrol3().
This is my main function:
z0 = [ 0 0 0];
t0 = 0;
tf = 1000;
timesV=[100,460,720];
global i;
i=1;
[ t1, y1 ] = ode45( @(tau, y1 ) my_carmodel3( tau, y1, @( tau ) my_carcontrol3( tau,timesV,y1(2))), [ t0 tf ], z0 );
This is my_carcontrol3():
function [ control ] = my_carcontrol3( t,timesV,v)
global i;
if t==timesV(i)
i=i+1;
end
control=1
my_carmodel3():
function dydt = my_carmodel3 (t, y, control)
m=1400;
dydt = zeros( 3, 1 );
c = control( t );
dydt( 1 ) = y( 2 );
dydt( 2 ) = c/m;

1 comentario

Torsten
Torsten el 10 de Dic. de 2023
Even if "i" would be incremented, I don't understand how it influences the time derivatives dydt.
In the code you provided, "control " is always =1 - independent of t (and i).

Iniciar sesión para comentar.

Respuestas (2)

Walter Roberson
Walter Roberson el 9 de Dic. de 2023

1 voto

The first parameter to the ode function, often referred to as t, is mostly not an integer (but might turn out to be an integer by chance from time to time.)
You are using == comparisons, which is only suitable for exact equality -- the test you have written is effectively (t-timesV(i)) == 0 (exactly). If timesV is double precision (which it is) then your test is checking whether t and timesV(i) have the exact same bit pattern (except negative zero and positive zero compare equal, and NaN never compare equal even if they have the same bit pattern.)
That is why your value never changes -- because the exact comparison never happens to be true.

3 comentarios

You might be tempted to rewrite as
if t>=timesV(i)
i=i+1;
end
but you need to resist that.
The ode*() series of functions sample the function at carefully chosen locations, including at future times. This does not mean that time has "advanced" to those future times. The situation is like walking on a hill in the dark with a flashlight: you shine the light at several places you are not intending to step, in order to get information about the slope of the hill.
Because of this behaviour, the first time that t>=timesV(i) will generally be when ode*() is making one of those probes into the future, fully intending to end its step before that. And there will be further trial steps with times earlier than that.
There is a further issue that the ode*() routines are only mathematically valid for situations in which the first and second derivatives of the equations are continuous. With you switching the c value during execution, you have discontinuous derivatives at each of those times. If you are lucky, the ode*() routines will fail and tell you they failed. If you are unlucky the ode routines will continue... and give you the wrong answer.

Iniciar sesión para comentar.

Before delving into the technical aspects of constructing the time-based event-triggered control signal, there are a few issues I would like you to address:
It appears that the local function 'my_carcontrol3()' is incomplete, and it seems to depend on the velocity y(2). Can you write out the piecewise math equation of the control law? We can help check if it is coded correctly.
Next, the control objectives or requirements are not described. Thus, it is unclear whether you want to control the position or the velocity of the car. Additionally, you can specify the time you want to reach the desired position or achieve the desired velocity.
Lastly, 'control()' is not a defined function but an output variable declared in the 'my_carcontrol3()' function. Consequently, you are unable to call it correctly inside the main function 'my_carmodel3()'. If you call 'control(t)', it will attempt to access a particular 't' element of the 'control' array. Since 't' begins at 0, calling 'control(0)' will result in an error.
control = -5:5
control = 1×11
-5 -4 -3 -2 -1 0 1 2 3 4 5
t = 7; % the 7th element
control(t)
ans = 1
t = 0; % the 0th element???
control(t)
Array indices must be positive integers or logical values.

Productos

Versión

R2023b

Preguntada:

el 9 de Dic. de 2023

Respondida:

el 10 de Dic. de 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by