iUsing ode45, how to pass a parameter from odefun to an events function?

I use ODE45 in a for loop.
In the listings below I show the parameter loadfV in bold, as it is the source of my problem. loadfV is calculated in my odefun and needs to be communicated to my events function without using a global statement.
In the main script in the for loop, I have the following code:
xoverFcn = @(t, svec) BD_impact_06(t, svec, ...
Propulsion.ThrustcheckI, ...
Propulsion.ThrustcheckII, ...
loadfV, loadfmax, ...
Nstage, RE_plus_htarg);
options = odeset('Events', xoverFcn, 'MaxStep', ...
User_Options.stepmax, 'InitialStep',1e-3, ...
'RelTol', 1e-7);
tspan = (tstart:0.1*User_Options.deltout:tII);
[tIIa, svecfIIa, TEIIa, YEIIa, IEIIa] = ...
ode45(@(t, svec) BD_deriv_06(t, svec, ...
Sref, tactI, Nstage, tII, tIIf, tactII, ...
timeI, thrustI, mpropI, mstIe, parefI, AeI, ...
timeII, thrustII, mpropII, mstIIe, parefII, AeII, ...
RE, REf, grav_lat_sl, Lrail, ...
tvecI, CLvecI, CYvecI, ...
tvecII, CLvecII, CYvecII, ...
tvecIII, CLvecIII, CYvecIII, ...
loadfmax, atmos_table, method_atm, ...
wind_table, method_w, Fdetent, kappa, tLE, ...
omega_EI_2, two_omega_EI, T_EL, t31, t32, t33, ...
alt_launch, H_MET, degr2rad, chiT, ...
CDadj_B, CDadj_NB, Aero, Time, Propulsion), ...
tspan, svec0, options);
In my odefun, called BD_deriv_o6.m, I calculate the following (full code not given):
weight0 = mass*grav_lat_sl; % Weight wrt sea level gravity (N)
Lift = q*Sref*CL; % Trimmed lift force (N)
Kk = sign(Lift);
loadfV = Lift/weight0;
My events functions, called BD_impact_ 06, looks as follows:
function [ value, isterminal, direction ] = BD_impact_06(~, svec, ...
ThrustcheckI, ThrustcheckII, loadfV, loadfmax, Nstage, RE_plus_htarg)
value(1) = svec(3)-RE_plus_htarg;
% Detect r = RE+targe altitude
isterminal(1) = 1; % Stop the integration when value(3) = 0
direction(1) = -1; % Descending trajectory
value(2) = ThrustcheckI-1; % Detect thrust < 0 for motor 1
isterminal(2) = 1; % Stop the integration when value(2) = 0
direction(2) = 0; % All zeros detected
if Nstage == 2
value(3) = ThrustcheckII-1; % Detect thrust < 0 for motor 2
isterminal(3) = 1; % Stop the integration when value(3) = 0
direction(3) = 0; % All zeros detected
end
%Temporarily exclude the load factor check
value(4) = abs(loadfV)-loadfmax; % Detect |load factor| > loadfmax
isterminal(4) = 0; % Continue the integration when value(4) = 0
direction(4) = 1; % Ascending zero detected
value(5) = abs(loadfV)-loadfmax; % Detect |load factor| > loadfmax
isterminal(5) = 0; % Continue the integration when value(5) = 0
direction(5) = -1; % Descending zero detected
end

 Accepted Answer

You'll have to calculate loadfV twice if you don't want to use globals.
But you should use a third function different from BD_impact_06 and BD_deriv_06 to do this.
This way, you don't need to have the same lines of code twice in your program.
By the way: it's a good idea to calculate derived quantities in their own functions so that other parts of the program can access these functions if necessary.

1 Comment

Thanks, Torsten, I should have thought of this solution, your answer solves my problem!

Sign in to comment.

More Answers (0)

Products

Release

R2020a

Community Treasure Hunt

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

Start Hunting!