valegagge / models Goto Github PK
View Code? Open in Web Editor NEWThis repo contains draft Simulink models for testing
This repo contains draft Simulink models for testing
I add here the info regarding the code generation using the For Iterator. Model used is here.
First a simple model that does not use the For Iterator:
The model inside returns the third control mode always:
Simulink Generated Code: Empty ❌
void prototype_for_iterator_from_zero_step(void)
{
/* (no output/update code required) */
}
Following this documentation (page 73) I changed the hard coded values for Inports
and Outports
:
Simulink Generated Code: With Code ✔️
void prototype_for_iterator_from_zero_step(void)
{
/* Outport: '<Root>/y1' incorporates:
* Inport: '<Root>/u3'
*/
prototype_for_iterator_from_z_Y.y1 =
prototype_for_iterator_from_z_U.control_mode_p;
}
Now that I get an output I create a simple machine that adds all the inputs to the output:
I implement it using the Function Call paradigm first:
Simulink Generated Code: Code is Copy-Pasted ❓
void prototype_for_iterator_from_zero_step(void)
{
/* Chart: '<Root>/Chart' incorporates:
* SubSystem: '<Root>/Function-Call Subsystem'
*/
/* Chart: '<S2>/Chart' incorporates:
* Inport: '<Root>/u1'
* Outport: '<Root>/y1'
*/
if (prototype_for_iterator_from__DW.is_active_c2_prototype_for_iter == 0U) {
prototype_for_iterator_from__DW.is_active_c2_prototype_for_iter = 1U;
} else if ((prototype_for_iterator_from_z_Y.y1 < 0) &&
(prototype_for_iterator_from_z_U.u1.messages[0].control_mode <
MIN_int32_T - prototype_for_iterator_from_z_Y.y1)) {
/* Outport: '<Root>/y1' */
prototype_for_iterator_from_z_Y.y1 = MIN_int32_T;
} else if ((prototype_for_iterator_from_z_Y.y1 > 0) &&
(prototype_for_iterator_from_z_U.u1.messages[0].control_mode >
MAX_int32_T - prototype_for_iterator_from_z_Y.y1)) {
/* Outport: '<Root>/y1' */
prototype_for_iterator_from_z_Y.y1 = MAX_int32_T;
} else {
/* Outport: '<Root>/y1' incorporates:
* Inport: '<Root>/u1'
*/
prototype_for_iterator_from_z_Y.y1 +=
prototype_for_iterator_from_z_U.u1.messages[0].control_mode;
}
if (prototype_for_iterator_from__DW.is_active_c2_prototype_for_iter == 0U) {
prototype_for_iterator_from__DW.is_active_c2_prototype_for_iter = 1U;
} else if ((prototype_for_iterator_from_z_Y.y1 < 0) &&
(prototype_for_iterator_from_z_U.u1.messages[1].control_mode <
MIN_int32_T - prototype_for_iterator_from_z_Y.y1)) {
/* Outport: '<Root>/y1' */
prototype_for_iterator_from_z_Y.y1 = MIN_int32_T;
} else if ((prototype_for_iterator_from_z_Y.y1 > 0) &&
(prototype_for_iterator_from_z_U.u1.messages[1].control_mode >
MAX_int32_T - prototype_for_iterator_from_z_Y.y1)) {
/* Outport: '<Root>/y1' */
prototype_for_iterator_from_z_Y.y1 = MAX_int32_T;
} else {
/* Outport: '<Root>/y1' incorporates:
* Inport: '<Root>/u1'
*/
prototype_for_iterator_from_z_Y.y1 +=
prototype_for_iterator_from_z_U.u1.messages[1].control_mode;
}
/* I remove the other two repetitions for brevity*/
/* End of Chart: '<S2>/Chart' */
}
This goes against what we had originally thought. I implement the same block using the For Iterator to see the output. I write the machine that adds the inputs again from scratch to prevent any potential errors from copying the models:
Simulink Generated Code: Uses a For Loop ❓
void prototype_for_iterator_from_zero_step(void)
{
int32_T s1_iter;
/* Outputs for Iterator SubSystem: '<Root>/For Iterator Subsystem' incorporates:
* ForIterator: '<S1>/For Iterator'
*/
/* Selector: '<S1>/Selector' */
for (s1_iter = 0; s1_iter < 5; s1_iter++) {
/* Chart: '<S1>/Chart' incorporates:
* Inport: '<Root>/u1'
* Outport: '<Root>/y1'
*/
if (prototype_for_iterator_from__DW.is_active_c4_prototype_for_iter == 0U) {
prototype_for_iterator_from__DW.is_active_c4_prototype_for_iter = 1U;
} else {
int32_T q1;
q1 = prototype_for_iterator_from_z_U.u1.messages[s1_iter].control_mode;
if ((prototype_for_iterator_from_z_Y.y1 < 0) && (q1 < MIN_int32_T
- prototype_for_iterator_from_z_Y.y1)) {
prototype_for_iterator_from_z_Y.y1 = MIN_int32_T;
} else if ((prototype_for_iterator_from_z_Y.y1 > 0) && (q1 > MAX_int32_T -
prototype_for_iterator_from_z_Y.y1)) {
prototype_for_iterator_from_z_Y.y1 = MAX_int32_T;
} else {
prototype_for_iterator_from_z_Y.y1 += q1;
}
}
/* End of Chart: '<S1>/Chart' */
}
/* End of Selector: '<S1>/Selector' */
/* End of Outputs for SubSystem: '<Root>/For Iterator Subsystem' */
}
So the behavior is opposite to what we expected. The For Iterator creates the for loop and the Function Call copy-pastes the code.
At this point I believe the behavior depends on what the machine inside is doing when it's called. So I try again to create a miniature Supervisor.
I swap the adding machine for one similar to our simplified supervisor:
Again, I generate first using the Function Call paradigm:
Simulink Generated Code: Code is Copy-Pasted ❓
void prototype_for_iterator_from_zero_step(void)
{
/* Chart: '<Root>/Chart1' incorporates:
* SubSystem: '<Root>/Function-Call Subsystem1'
*/
/* Chart: '<S2>/Chart' incorporates:
* Inport: '<Root>/u1'
*/
if (prototype_for_iterator_from__DW.is_active_c6_prototype_for_iter == 0U) {
prototype_for_iterator_from__DW.is_active_c6_prototype_for_iter = 1U;
prototype_for_iterator_from__DW.is_c6_prototype_for_iterator_fr =
prototype_for_iterator__IN_idle;
/* Outport: '<Root>/y2' incorporates:
* Inport: '<Root>/u1'
*/
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.u1.messages[0].control_mode;
} else {
switch (prototype_for_iterator_from__DW.is_c6_prototype_for_iterator_fr) {
case prototype_for_iterator_IN_fault:
if (prototype_for_iterator_from_z_U.u1.messages[0].control_mode == 0) {
prototype_for_iterator_from__DW.is_c6_prototype_for_iterator_fr =
prototype_for_iterator__IN_idle;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.u1.messages[0].control_mode;
}
break;
case prototype_for_iterator__IN_idle:
if (prototype_for_iterator_from_z_U.u1.messages[0].control_mode == 1) {
prototype_for_iterator_from__DW.is_c6_prototype_for_iterator_fr =
prototype_for_iterat_IN_running;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.u1.messages[0].control_mode;
}
break;
default:
/* case IN_running: */
if (prototype_for_iterator_from_z_U.u1.messages[0].control_mode == -1) {
prototype_for_iterator_from__DW.is_c6_prototype_for_iterator_fr =
prototype_for_iterator_IN_fault;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.u1.messages[0].control_mode;
}
break;
}
}
/* I remove the other three repetitions for brevity */
}
I again replicate the supervisor and implement using the For Iterator:
Simulink Generated Code: Code is Copy-Pasted ❓
void prototype_for_iterator_from_zero_step(void)
{
/* Outputs for Iterator SubSystem: '<Root>/For Iterator Subsystem1' incorporates:
* ForIterator: '<S1>/For Iterator'
*/
/* Chart: '<S1>/Chart' incorporates:
* Inport: '<Root>/input_1'
* Selector: '<S1>/Selector'
*/
if (prototype_for_iterator_from__DW.is_active_c7_prototype_for_iter == 0U) {
prototype_for_iterator_from__DW.is_active_c7_prototype_for_iter = 1U;
prototype_for_iterator_from__DW.is_c7_prototype_for_iterator_fr =
prototype_for_iterator__IN_init;
/* Outport: '<Root>/y2' incorporates:
* Inport: '<Root>/input_1'
* Selector: '<S1>/Selector'
*/
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.input_1.messages[0].control_mode;
} else {
switch (prototype_for_iterator_from__DW.is_c7_prototype_for_iterator_fr) {
case prototype_for_iterator_IN_fault:
if (prototype_for_iterator_from_z_U.input_1.messages[0].control_mode == 0)
{
prototype_for_iterator_from__DW.is_c7_prototype_for_iterator_fr =
prototype_for_iterator__IN_init;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.input_1.messages[0].control_mode;
}
break;
case prototype_for_iterator__IN_init:
if (prototype_for_iterator_from_z_U.input_1.messages[0].control_mode == 1)
{
prototype_for_iterator_from__DW.is_c7_prototype_for_iterator_fr =
prototype_for_iterat_IN_running;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.input_1.messages[0].control_mode;
}
break;
default:
/* case IN_running: */
if (prototype_for_iterator_from_z_U.input_1.messages[0].control_mode == -1)
{
prototype_for_iterator_from__DW.is_c7_prototype_for_iterator_fr =
prototype_for_iterator_IN_fault;
/* Outport: '<Root>/y2' */
prototype_for_iterator_from_z_Y.y2 =
prototype_for_iterator_from_z_U.input_1.messages[0].control_mode;
}
break;
}
}
/* I remove the others for brevity */
}
Whether the code is generated or not depends on the existance of inputs and outputs for the model. If there are none, Simulink sees it as internal operations that don't affect anything and doesn't generate the code.
I assume in our case having two different blocks in the Function Call made it work like input/output, while in the For Iterator it decided not to need to generate because there was one single block with no in/outports. In any case, a block with inputs and outputs will always generate.
It is unclear still when the code generator decides to implement a for loop or copy-pasting. I assume it depends on the optimization and the complexity of the operations it will create. The only thing we can be sure is that it's not as simple as Function Call = For Loop and For Iterator = Copy-Paste
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.