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

Automatically generate required Simulink library files #10

Open
traversaro opened this issue Jan 15, 2019 · 17 comments
Open

Automatically generate required Simulink library files #10

traversaro opened this issue Jan 15, 2019 · 17 comments

Comments

@traversaro
Copy link
Member

Original comment by @traversaro in #5 (comment) :

Generate the XML files after the build by running a program that invokes the configureSizeAndPorts method of the block to wrap as FMU

Interestingly, part of this solution could be eventually re-used to automatize the existing manual process of writing the .slx file of the block library (i.e. the one described in https://robotology.github.io/blockfactory/mkdocs/create_new_library/#create-an-new-simulink-library).

As you can check by manually inspecting an .slx file, and by reading in https://stackoverflow.com/questions/23408186/information-about-simulink-mdl-and-slx-formats, the .slx is just a .zip file that contains a bunch of .xml (and some other format) files. A complete parser for reading/writing .slx does not seem to be available or feasible, but perhaps it could make sense to have a "template" .slx that can be be configured based on the library blocks' and ports.

@traversaro
Copy link
Member Author

Reply by @diegoferigo in #5 (comment) :

Having a templated slx imho does not simplify that much the creation / maintenance of a Simulink Library, it is usually a trivial step from the GUI. I am pretty sure that Matlab (even the cli version) has some functions to automatize it without dealing with the file formats.

The main problem are the masks, the have to be developed from the GUI. I'm afraid that operating only on the slx or mdl would never be enough :/

@traversaro
Copy link
Member Author

Reply by @traversaro in #5 (comment) :

Having a templated slx imho does not simplify that much the creation / maintenance of a Simulink Library, it is usually a trivial step from the GUI.

It is trivial, if you have MATLAB/Simulink. It would be nice to be able to setup a blockfactory library without having MATLAB/Simulink on your PC (my current situation, for example : ) ).

The main problem are the masks, the have to be developed from the GUI. I'm afraid that operating only on the slx or mdl would never be enough :/

Why this should be the case? Everything that you input through the GUI should be contained in the .slx, right? As far as I can see, in particular the Mask information is contained in the <Mask> tag of simulink/blockdiagram.xml , for example for the SignalMath block in the ExampleToolbox:

      <Block BlockType="S-Function" Name="Signal Math" SID="1">
        <P Name="Ports">[2, 1]</P>
        <P Name="Position">[335, 69, 470, 116]</P>
        <P Name="ZOrder">1</P>
        <P Name="FunctionName">BlockFactory</P>
        <P Name="Parameters">&apos;SignalMath&apos;,&apos;ExampleToolbox&apos;,operation</P>
        <P Name="SFunctionDeploymentMode">off</P>
        <P Name="EnableBusSupport">off</P>
        <P Name="SFcnIsStateOwnerBlock">off</P>
        <Mask>
          <Display RunInitForIconRedraw="off">disp(&apos;Signal Math&apos;)

port_label(&apos;input&apos;,1,&apos;Input 1&apos;)
port_label(&apos;input&apos;,2,&apos;Input 2&apos;)

port_label(&apos;output&apos;,1,&apos;Output&apos;)</Display>
          <MaskParameter Name="operation" Type="popup" Evaluate="off">
            <Prompt>Operation</Prompt>
            <Value>Addition</Value>
            <TypeOptions>
              <Option>Addition</Option>
              <Option>Subtraction</Option>
              <Option>Multiplication</Option>
            </TypeOptions>
          </MaskParameter>
        </Mask>
      </Block>

Indeed automatically generating this may not be trivial, but I do not think it is impossible.

@traversaro
Copy link
Member Author

Reply by @diegoferigo in #5 (comment) :

Indeed automatically generating this may not be trivial, but I do not think it is impossible.

Just to be clear, I never intended that this is impossible ^^ It is just complicating your own life. And, btw, if you don't plan to use Simulink (since you don't have it), why do you want to create a Simulink Library? If the aim is using / testing blockfactory, for simple models you could:

  • Create a plugin library containing classes that inherit from blockfactory::core::Block
  • Implement a simple blockfactory::core::BlockInformation for your use case
  • Develop a system that connects the blocks by assigning a simulation order and sharing data between their input / outputs with buffers

Without having Simulink I don't see any benefit of passing through the slx, but probably I didn't get entirely what you're trying to do.

@traversaro
Copy link
Member Author

Develop a system that connects the blocks by assigning a simulation order and sharing data between their input / outputs with buffers

I really like how "re-implement Simulink" is just a minor bullet point. :D

Jokes apart, my scenario is the following:
I want to wrap my library (let's say iDynTree, or the wholebodydynamics torque-estimation algorithm) as a blockfactory-based dynamical system representation. Let's say that I have a way to test it locally without Matlab, for example by having a Drake or FMI-based backed for blockfactory. However, I want my library to be easily consumable by Simulink users (let's say that I want @gabrielenava to be able to just get it and start to use it in Simulink). Once I finished the development of the C++-part, at the moment I need to find a machine or someone with access to Simulink, to manually create the Simulink library and the mask to make sure that @gabrielenava can use it. This is not only necessary when I first create the library: I need to find someone that can give me access to Simulink whenever I want to add a block to the library. Furthermore, it is also a complication for any external developer that want to contribute a block to the library: even if it going just to use it via the Drake/FMI backend, it needs Simulink otherwise the library in Simulink will not have that block.

This situation is similar to what we were experiencing with Matlab bindings, but fortunately now that we build the same exact bindings also against the mex interface of Octave, we do not have the same problem anymore.

@traversaro
Copy link
Member Author

traversaro commented Jan 15, 2019

To clarify: this could be entirely optional from the user point of view, in a way that if a user as a complex system of manually coded .slx model (such as in the case of WB-Toolbox) it would not be necessary to change anything.

@diegoferigo
Copy link
Member

diegoferigo commented Jan 15, 2019

I really like how "re-implement Simulink" is just a minor bullet point. :D

For canonical examples (see AutogenerationExample.cpp or torqueBalancingYoga.cpp, and yes, in the Yoga controller we do not use any super fancy Simulink feature) effectively Simulink does not do this massive amount of work. Ok, they provide a lot of blocks ootb :) Of course it is a huge framework, but this is because its use case tends to infinity.

[...] any external developer that want to contribute a block to the library [...] needs Simulink otherwise the library in Simulink will not have that block

Your point is clear and I understand it. However, considering possible contributions to any project that has Simulink support, I would be really skeptical of accepting an arbitrarily complex PR with a new block if the contributor never tested it directly in Simulink (should I do the tests personally? At the moment there is no way to use CI for this). I am not against implementing it if we think that it can speed up our workflow.

@traversaro
Copy link
Member Author

traversaro commented Jan 15, 2019

However, considering possible contributions to any project that has Simulink support, I would be really skeptical of accepting an arbitrarily complex PR with a new block if the contributor never tested it directly in Simulink (should I do the tests personally? At the moment there is no way to use CI for this).

That's true. Probably I am thinking about more simple cases. Let's think for example about the orientation filters that @prashanthr05 is implementing in iDynTree: if a user implements an additional type of estimation, and assuming the rest of signal processing and plumbing has been already tested in Simulink, I would not block the PR on a test on Simulink.

@diegoferigo
Copy link
Member

In those case I agree. In the end it would translate to adding a single <Option> line in the following section:

<MaskParameter Name="filterType" Type="popup" Evaluate="off">
    <Prompt>Filter Type</Prompt>
    <Value>DefaultFilter</Value>
    <TypeOptions>
        <Option>DefaultFilter</Option>
        <Option>FilterFoo1</Option>
        <Option>FilterFoo2</Option>
    </TypeOptions>
</MaskParameter>

As a last comment, we should consider that the Simulink Library must be in slx that is a binary format, and the diff of the contained xml file coudn't be seen in clear from a PR.

@traversaro
Copy link
Member Author

As a last comment, we should consider that the Simulink Library must be in slx that is a binary format, and the diff of the contained xml file coudn't be seen in clear from a PR.

And that is exactly why I think it would be good if downstream users of blockfactory could avoid committing and manual modifying this kind of files.

By the way, this example seem to highlight that it would be nice to have a enumeration kind of parameter to explicitly specify the allowed options for the filterType, similar to the Enumeration type in FMI: https://fmi-standard.org/docs/2.0.1-develop/#_definition_of_types_typedefinitions .

@traversaro
Copy link
Member Author

Related discussion (a bit in an unusual place): robotology/wb-toolbox#168 (comment) .

@traversaro
Copy link
Member Author

I finally got a lot of things from robotology/wb-toolbox#168 (comment) , especially that it could be feasible to just automatically generate a .mdl (much easier, given that it is just a textual file) and transform it in a .slx suitable for installation in the Simulink Library Browser on the machine of the user that is compiling the library.

@traversaro
Copy link
Member Author

@diegoferigo if we could export once the .mdl for 2014b corresponding to the SignalMath example, I would be curious to check it.

@diegoferigo
Copy link
Member

All for you @traversaro

@traversaro
Copy link
Member Author

As .mdl models are just textual models, a possible approach for their generation (instead of directly "generating" code from in C++ using operator<< or fprintf) is to use a template engine (see https://en.wikipedia.org/wiki/Template_processor).

This is the strategy that we used in sdf-modelica, using the single header libraries nlohmann/json and kainjow/Mustache. See for example the mustache template that we use in sdf-modelica: https://github.com/robotology/sdf-modelica/blob/master/src/sdf-modelica-lib/template/mustache-modelica.txt and the code actually used for generation: https://github.com/robotology/sdf-modelica/blob/6d6dd676ef04c74baec90a73e7c3fe71c5f6ad14/src/sdf-modelica-lib/src/sdf_modelica.cpp#L91 .

@diegoferigo
Copy link
Member

Cool, I didn't know this C++ version of Mustache, in the past I used the python version with nice results. As probably I just said somewhere else, in my opinion the most difficult part to templatize is the block mask (check the Configuration block as a complex example). For simple blocks instead it should be trivial.

Honestly my main concern is Simulink compatibility, there are so many options added every release that are hard to track. Just think that Simulink models are never compatible with older releases.

@traversaro
Copy link
Member Author

traversaro commented Feb 4, 2019

As probably I just said somewhere else, in my opinion the most difficult part to templatize is the block mask (check the Configuration block as a complex example). For simple blocks instead it should be trivial.

Yes, my idea would be to offer automatic generation of the Simulink file as options. If someone needs more fancy stuff like strange masks of nested "subgroups" in the library like in WB-Toolbox, he/she would need to code them directly bypassing the automatic generation.

Honestly my main concern is Simulink compatibility, there are so many options added every release that are hard to track. Just think that Simulink models are never compatible with older releases.

My idea was to use an old version .mdl (such as the one that you produced, for 2014b) as a initial model, and use it as a model of the template. As long as we produce a valid "old" model, everything should work fine also with newer Simulink releases, right?

@diegoferigo
Copy link
Member

As long as we produce a valid "old" model, everything should work fine also with newer Simulink releases, right?

Hopefully, yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants