Skip to content

Helper Functions

jengstud edited this page Aug 6, 2021 · 4 revisions

The PARODIS framework defines a number of helper functions, that are not part of any of the PARODIS classes.

createModel

model = createModel( model_fun, T_s, numScenarios, implicitPrediction )

This function creates a model struct from the given arguments. model_fun is a function handle that returns a state space ODE for a given sample rate, T_s is a vector with the sample rates of each step in the prediction horizon, and numScenarios is the number of scenario expressions that should be created. If implicitPrediction is false, the explicit prediction form will be used. In that case, the symbolic expression for $x_s(n+1|k)$ is an expression in terms of $u(n|k)$ and $d_s(n|k)$. Otherwise, $x_s(n+1|k)$ is just a sdpvar and will be implicitly connected to $u(n|k)$ and $d_s(n|k)$ using equality constraints.

[ode_n, n_x, n_u, n_d] = model_fun( T_s_n )

A model struct contains the following fields

Field Description
x0 Symbolic expression for the initial state, sdpvar of size $n_x \times 1$
x Cell array of length numScenarios, where each cell contains a $n_x \times N_{pred}+1$ sdpvar that describes the symbolic state trajectory in terms of model.x0, model.u and model.dPred
u Symbolic expression representing the predict input, sdpvar of size $n_u \times N_{pred}$
d Cell array of length numScenarios, where each cell contains a $n_d \times N_{pred}$ sdpvar representing the predicted disturbance in each scenari
n_x Number of states $n_x$
n_u Number of inputs $n_u$
n_d Number of disturbances $n_d$
ode0 The ODE for performing $x(k+1) = f_0( x(k), u(k), d(k) )$
odes Cell array, containing the ODEs for each time step in the horizon
model_fun The function handle of the model function used to create the model
implicitPrediction If false, x is expressed in terms of u and d. Otherwise they will be connected using equality constraints $x(n+1|k) == f_n( x(n|k), u(n|k), d(n|k) )$
flrMatrices Matrices for fast linear representation, set only if FLR is supported but matrices are parameter variant
x_flat Function @(x0, u_flat, d_flat)( .. ) that returns entire (flattend) state trajectory over prediction horizon based on x0, the input vector and disturbance vector, set if either your model returns it's own x_flat or if FLR is LTI

For more details, see Models.

extractScenario

This helper function extracts a single struct from a scenario struct. (Symbolic) Parameters are stored in structs, where each field contains a cell array, where each cell contains the symbolic expression or the numerical value of the parameter for one scenario.

paramValues.myParam1 = { valueInScenario1, valueInScenario2, ... }
paramValues.myParam2 = { valueInScenario1, valueInScenario2, ... }

In eval functions or cost functions, one may only want to access all the values of one scenario. extractScenario will do exactly that and return a struct where each field's value is the scenario value, so applied to the example struct, this would return:

scenarioValues = extractScenario(paramValues, 2);
scenarioValues.myParam1 = valueInScenario2
scenarioValues.myParam2 = ...

mergeStructs

This helper function will merge the fields of all structs passed to the functions into one struct containing all their fields.

newStruct = mergeStruct(struct1, struct2, ...)

If the structs contain fields of the same name, the value of the last struct containing that field name will be set.

s1 = struct;
s1.a = 1;

s2 = struct;
s2.b = 2;

s3 = mergeStructs(s1, s2)
disp(s3) => s3.a = 1, s3.b = 2

eval_const

[function_handle] = eval_const( constant );

This helper function will return a function handle compatible with addEvalFunction, which will simply return the constant given as the input argument. This is very useful for adding constant values, e.g. constraints, into plots. Example:

% temperature shall be between 18 and 24 deg celsius
agent.addEvalFunction( 'temperature_lb', eval_const(18), false );
agent.addEvalFunction( 'temperature_ub', eval_const(24), false );
...

% plot lower bound, temperature, upper bound
plot.addLine( agent, 'eval', 'temperature_lb', 1, 1);
plot.addLine( agent, 'x', 1, 1, 1);
plot.addLine( agent, 'eval', 'temperature_ub', 1, 1);

eval_parameter

[function_handle] = eval_parameter( parameter[, index = 1] );

This helper function will return a function handle compatible with addEvalFunction, which will simply the given value of the given parameter. **Note*: The parameter to be evaluated must have at least as many entries as steps within the prediction horizon! Also, since parameters have no clearly defined value outside of the prediction horizon, NaN will be assumed as their value in the eval history.

% temperature shall follow some reference temperature within horizon
agent.addEvalFunction( 'temperature_ref', eval_parameter( 'temperature_ref' ) );
...

% plot temperature, and the reference temperature
plot.addLine( agent, 'x', 1, 1, 1);
plot.addLine( agent, 'eval', 'temperature_ref', 1, 1);

getDataFromSource

[data] = simulation.sourceManager.getDataFromSource(T, source, callingAgent, agents, numScenarios)

This function is used by PARODIS to retrieve data from parameter and disturbance sources. The source manager is a public property of the simulation instance and handles caching of data sources. Sources can be one of three types, which triggers three different behaviours of getDataFromSource:

  • source is a constant matrix, in this case the function returns a cell array with numScenarios cells, where each cell has the value source
  • source is a string, in which case it is treated as a path to a CSV file. The function then reads this file and interpolates length(T) many entries at the times specified in T from the CSV file. THis data is then formated into a $N_{\mathrm{columns} \times \mathrm{length}(T)$ matrix, which is repeated into a cell array with numScenarios entries. See CSV Data Sources for a description of the file structure
  • source is a function handle, which is then called by getDataFromSource. It is expected to return a cell array with numScenarios (uniform) entries
data = source(T, callingAgent, agents, numScenarios)

If the source is a CSV file and thus cachable, the source manager will store the retrieved data on the first call of getDataFromSource with that source and will return the data from memory on successive calls. This greatly speeds up simulation speeds if data sources are relatively large. Note: This means that a CSV file will only be read once per simulation run. When you restart a simulation, the source manager cache will be cleared.