sample.BASE.sa 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import PowerWindowModel
  2. /*
  3. Declares the name of the module.
  4. Any importing document will import this module by calling "import Controller_SA" and can refer to any of the declarations in this document by, e.g., controller_sa (which refers to the adapted FMU created by the code in this page)
  5. */
  6. module Controller_SA
  7. /*
  8. Declares the name of the adapted FMU.
  9. The resulting FMU will probably have a name that is something like "controller_sa".
  10. There may be extra information required for an appropriate generation of the adapted FMU, so we may have to add extra declarations here.
  11. I'm thinking of things such as company, documentation, etc...
  12. For now, this is fine.
  13. */
  14. semantic adaptation controller_sa
  15. /*
  16. How is the input/output feedthrough calculated?
  17. canInterpolateInputs flag
  18. I/O feedthrough
  19. I think these may have to be declared here in the model.
  20. Later they can be generated from some analysis, but for now, it is declared explicitly.
  21. A possible syntax is to replace the above instruction by
  22. semantic adaptation reactive mealy controller_sa
  23. semantic adaptation delayed mealy controller_sa
  24. semantic adaptation reactive moore controller_sa
  25. ...
  26. */
  27. /*
  28. Declares the set of original FMUs to be adapted.
  29. */
  30. for fmu controller, fmu2, fmu3, semantic_adaptation;
  31. /*
  32. Declare the input ports of the SA FMU.
  33. If these are omitted, then any input port that is not connected in the set of original FMUs declared above, will be assumed to be an input port of the adapted FMU.
  34. In this later case, there may be ports with the same name, so for the code generation, the output ports of the adapted FMU need to be unique (maybe some prefix should be used).
  35. */
  36. input ports armature_current,
  37. passenger_up,
  38. passenger_down,
  39. driver_up,
  40. driver_down;
  41. /*
  42. Declares the output ports of the adapted FMU.
  43. If no ports are declared, then it is assumed that the output ports are the same as the union of the output ports of the connected FMUs.
  44. The same remarks apply to the uniqueness of the output ports in the adapted FMU.
  45. Example, if F1 and F2 are FMUs wrapped by the semantic adaptation and they both have the same output port, then they need to be refered to (when assignments are made in the code) as follows:
  46. F1.out := 1
  47. F2.out := 2
  48. */
  49. output ports up, down;
  50. /*
  51. Declares the parameters in the model.
  52. In the FMU description, these have to have a value, so they have to be resolved at compile time.
  53. */
  54. param REL_TOL = 0.0001;
  55. /*
  56. Declare variables.
  57. These are variables that are part of the state of the adapted FMU.
  58. It is important to know them because the rollback support should be provided automatically.
  59. There are two kinds of variables:
  60. in vars - These can be assigned in the sa_in block, and read in the update_in and control rules block.
  61. out vars - These can be assigned in the update_out block, and read in the sa_out block.
  62. The state of the SA FMU should contain:
  63. the states of the original FMUs
  64. the previous inputs provided to the original FMUs
  65. the values of the state variables
  66. the values of the computed variables (such as the elapsed time for each FMU)
  67. */
  68. in var stored_down := 10;
  69. control var some_control_var;
  70. out var some_var := some_expression;
  71. /*
  72. Declares control rules block.
  73. This block is called whenever there is a doStep call on the SA FMU.
  74. If the control block is not defined, then the generic master will be used.
  75. If the control rules block is defined, then the generic master will not be used.
  76. The code in the block has to ensure that FMUs are run and synchronized correctly.
  77. A few variables are available:
  78. the in vars (can just be read)
  79. time_of_last_doStep (will not be implemented)
  80. elapsed(fmu1) (elapsed time since last doStep of fmu1, can just be read)
  81. e = min(elapsed(fmu1),..., elapsed(fmuN)) (can just be read)
  82. H (the co-simulation step size) (can just be read)
  83. t (the communication time passed in the doStep) (can just be read)
  84. */
  85. control rules {
  86. /*
  87. Local variables can be declared.
  88. */
  89. var step_size;
  90. ...
  91. /*
  92. The proposed step size must be returned.
  93. */
  94. return step_size;
  95. }
  96. /*
  97. This block is run when the setValues function of the SA FMU is called.
  98. */
  99. in rules {
  100. /*
  101. This block is run whenever there is a call to setValues on the adapted FMU.
  102. */
  103. condition_1 -> {
  104. sa_in_1
  105. } --> { update_in_1 };
  106. ...
  107. condition_N -> {
  108. sa_in_N
  109. } --> { update_in_N };
  110. /*
  111. Each of the conditions above are evaluated in order and ALL the ones that are evaluate to true are executed.
  112. Example scenario that forces the inputs to the FMUs to be set:
  113. saFMU1 is the adapted FMU1, and it wraps an original FMU.
  114. Has the following declaration:
  115. Input ports in (m) -> in (cm)
  116. Output ports out -> out.
  117. Scenario:
  118. saFMU1.setValues(“in”, 1) // Forwards 1 to inner FMU.
  119. V1 = saFMU1.getValues(“out”) //out1 is calced from inner FMU.
  120. saFMU1.setValues(“in”, 2)
  121. V2 = saFMU1.getValues(“out”)
  122. V2 != V1 should be the case, in case there is a feedthrough.
  123. */
  124. condition1 -> {
  125. In var Stored_input := input
  126. // This is not allowed.
  127. In var doStepCall := doStepCall + 1
  128. /*
  129. This block is run when doStep of the adapted FMU is called, and condition1 evals to true.
  130. Notice that multiple calls to the setValues function can be made before calling doStep, so these blocks may be run several times.
  131. They should therefore not include counters, or stuff like that depends on the number of calls made by setValues before calling doStep.
  132. */
  133. } --> {
  134. /*
  135. I'm still not sure of the conditions that make this block run.
  136. Possible interpretations:
  137. - This block runs immediately before the control block is used.
  138. Problems: It's pretty much useless for multi-rate adaptations, where the control block may run the internal FMUs multiple times. In those intermediate setValue and doStep calls, the control block code would still have to make the interpolation work. This also violates the data/control separation.
  139. Good things: If there is no control rules block, the generic master algorithm would be used, so this interpretation is fine.
  140. - This block is called by an explicit instruction within the control rules block.
  141. Problems: I cannot think of any right now.
  142. Good things: It allows multi-rate adaptation to be done in a somewhat flexible manner.
  143. Regardless of the possible interpretations, there is still the problem of how to resolve multiple instructions.
  144. What kind of instructions are allowed here?
  145. Certainly, when the control rules calls this block, which instructions should be executed?
  146. It may not make sense to execute all of them, if the control just wants to compute one value...
  147. Another pitfall of this block is the following scenario: suppose setValue of the FMU is called twice before the doStep is called.
  148. In addition, suppose that two different rules were evaluated in each call.
  149. Then, when the control rules is executed, the update_in block of the most recently evaluated rule should be the one used, right?
  150. */
  151. // Not allowed
  152. invar := 10
  153. // Allowed
  154. fmu1.input_port := F(t, invar1, …, invarN)
  155. original_fmu1_input := expression1
  156. original_fmu2_input := expression2
  157. };
  158. condition2 -> {
  159. in_block2
  160. } --> { update_in_block2 };
  161. ...
  162. }
  163. out rules {
  164. /*
  165. This block is run when the control rules block has values to be propagated to the state of the adapted FMU.
  166. The same alternative interpretations identified before apply to this block: when should it be called?
  167. If the control block is doing a multi-rate adaptation, it makes no sense to call this block at everypoint.
  168. We are only interested in getting values at the end of the multi-rate adaptation iteration (or am I missing something?).
  169. So, similarly to the previous case, I suggest that there is a function call, that can be used to invoke this block.
  170. When there is no control block defined, then this block is called simply at the end of the co-simulation step of the internal generic master.
  171. If the control block calls this block multiple times, and multiple rules are selected at each time, then the must recently selected rule will be applied.
  172. Do you agree with this?
  173. */
  174. condition1 -> {
  175. /*
  176. This block is run when condition1 is evaluated to true.
  177. */
  178. } --> {
  179. /*
  180. This block is run when getValues is called on the adapted FMU, and the block above was the most recently executed block.
  181. saFMU.getValues(“port”)
  182. saFMU.doStep(t, H) // this does not run control block, but this run the current block.
  183. saFMU.getValues(“port”)
  184. */
  185. };
  186. Condition2 -> {
  187. } → {
  188. }
  189. }