Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-implement the Holder block to make it compatible with code generation and "treat as atomic unit" #205

Closed
nunoguedelha opened this issue May 3, 2021 · 6 comments · Fixed by #211

Comments

@nunoguedelha
Copy link
Collaborator

Summary

image

Re-implement the Holder block (in "Utilities") in order to avoid the use of:

  • persistent variables, which are incompatible with code generation.
  • continuous blocks (the clock Simulink block): a sub-system combining discrete and continuous blocks cannot be treated as an atomic unit.

Motivation

Treating sub-systems as atomic units speed up the simulation and allow the use of different sampling times on multiple sub-systems without rate conversion problems.
Code generation increases the compilation time but improves significantly the runtime performance.

Additional context

The whole-body-controllers/controllers/floating-base-balancing-torque-control model uses at least 7 Holder blocks.

@nunoguedelha
Copy link
Collaborator Author

Block testing

image

The block was tested with a input vector of random signals. After execution, the scope should display constant values set to the first sample of the input signal generators.

First Iteration

Design

image

MATLAB Function

function [memorized,y_n] = fcn(memorized,u_n,u_nm1)

% force output size to match input, otherwise Simulink sees it as variable sized output and
% fails compilation.
y_n = u_n;

if memorized
    y_n(:) = u_nm1; % expects u_nm1 to be y_n size
else
    y_n(:) = u_n;   % expects u_nm1 to be y_n size
end

memorized = true;

Execution order

root model level Holder
image image

This holder implementation worked fine and compiled properly the signal dimensions in a model with a single fixed sample time for ll blocks.
But once integrated in a model with multiple fixed sample times, the compilation fails after assigning the wrong dimension (0, i.e. a scalar) to the Unit Delay block output. In fact, for some reason, if the MATLAB Function is executed before the Unit Delay block, the function propagates u_nm1 to y_n while u_nm1 is still = 0, giving a scalar dimension to y_n.

The issue was still present with a Memory block replacing the Unit Delay. This couldn't be solved by forcing the sample time as we want this block to inherit the sample time of the model/system where it is inserted, and we wish to conserve the same block interface as the old "Holder" block.

For avoiding this issue, we came up with an alternative described below.

Second and Final Iteration

image

The initial value of the IC (Initial Condition) block is set to 1 (scalar). The initial condition of the Memory block is 0. All blocks have an inherited sample time. This design work for scalars or vector inputs of any size.

@nunoguedelha
Copy link
Collaborator Author

CC @diegoferigo @traversaro

@nunoguedelha
Copy link
Collaborator Author

CC @gabrielenava @CarlottaSartore

@nunoguedelha
Copy link
Collaborator Author

@traversaro , shall I PR this t devel or master? I would say `master since it's a fix on an existing commonly used block. Then we can merge master to devel with the newly added documentation updates.

@nunoguedelha
Copy link
Collaborator Author

CC @Giulero

@traversaro
Copy link
Member

@traversaro , shall I PR this t devel or master? I would say `master since it's a fix on an existing commonly used block. Then we can merge master to devel with the newly added documentation updates.

Yes, I would say master make sense.

traversaro pushed a commit that referenced this issue May 22, 2021
…code generation and 'treat as atomic unit' (#211)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment