robotology / wb-toolbox

Simulink toolbox to rapidly prototype robot controllers
https://robotology.github.io/wb-toolbox/
GNU Lesser General Public License v2.1
24 stars 17 forks source link

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

Closed nunoguedelha closed 3 years ago

nunoguedelha commented 3 years ago

Summary

image

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

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 commented 3 years ago

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 commented 3 years ago

CC @diegoferigo @traversaro

nunoguedelha commented 3 years ago

CC @gabrielenava @CarlottaSartore

nunoguedelha commented 3 years ago

@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 commented 3 years ago

CC @Giulero

traversaro commented 3 years ago

@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.