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

5 vues (au cours des 30 derniers jours)
David
David le 9 Déc 2023
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 commentaire
Torsten
Torsten le 10 Déc 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).

Connectez-vous pour commenter.

Réponses (2)

Walter Roberson
Walter Roberson le 9 Déc 2023
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 commentaires
Walter Roberson
Walter Roberson le 9 Déc 2023
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.

Connectez-vous pour commenter.


Sam Chak
Sam Chak le 10 Déc 2023
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.

Produits


Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by