From 812fbfd3868b8bb02cba09f023ba1babce4ebed4 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 22 Apr 2020 12:39:51 +0200 Subject: [PATCH 01/55] Create README.md --- RationaleMCP/0036/README.md | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 RationaleMCP/0036/README.md diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md new file mode 100644 index 000000000..abca313ea --- /dev/null +++ b/RationaleMCP/0036/README.md @@ -0,0 +1,47 @@ +Modelica Change Proposal MCP-0036 +Setting states +Hans Olsson +(In Development) +-- + +# Summary +The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), +and we need to update those states in the model within the modle based on more accurate measurements of during the simulation, +and have the state-updating as part of the model (and not as some tool-specific solution). + +# Revisions +| Date | Description | +| --- | --- | +| 2020-04-22 | Hans Olsson. Created. | + +# Contributor License Agreement +All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". + +# Rationale +See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 +and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf + +This is still work in progress as the main challenge is figuring out a specific syntax. + +The alternatives considered are: + - stateSelect.Measurement and binding equation + - replace "reinit" by "measurement"-operator, or forceState(…) + - possibly reinit within a Clock – check if possible + - the implemented annotation does not seem like a good idea + +# Backwards Compatibility +Will depend on exact syntax. + +# Tool Implementation +The preliminary variant with annotation has been implemented in Dymola. + +## Experience with Prototype +The implementation effort was small and it works. +However, as noted in the paper the procedure for using it is still slightly messy. + - Attempt to translate the model + - For each input add appropriate number of integrators and the state-update-component + - Have parameters for those integrators etc. + +# Required Patents +At best of your knowledge state any patents that would be required for implementation of this proposal. +# References From fe6892165054b2dd919ccfc5a654c94c53cbfd1e Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 8 Jul 2020 11:58:20 +0200 Subject: [PATCH 02/55] Update README.md Add discussion about reinit and correct spelling error. --- RationaleMCP/0036/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index abca313ea..69aea4514 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -6,13 +6,14 @@ Hans Olsson # Summary The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), -and we need to update those states in the model within the modle based on more accurate measurements of during the simulation, +and we need to update those states in the model within the model based on more accurate measurements of during the simulation, and have the state-updating as part of the model (and not as some tool-specific solution). # Revisions | Date | Description | | --- | --- | | 2020-04-22 | Hans Olsson. Created. | +| 2020-07-08 | Hans Olsson. Updated with reinit. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -25,10 +26,19 @@ This is still work in progress as the main challenge is figuring out a specific The alternatives considered are: - stateSelect.Measurement and binding equation - - replace "reinit" by "measurement"-operator, or forceState(…) - possibly reinit within a Clock – check if possible + - replace "reinit" by "measurement"-operator, or forceState(…) - the implemented annotation does not seem like a good idea +# Alternatives such as reinit +As discussed in https://github.com/modelica/ModelicaSpecification/issues/2285#issuecomment-641275627 the conclusion of +https://github.com/modelica/ModelicaSpecification/issues/578 was that all reinits are done at the end of the event iteration using previously computed values. + +Thus the current reinit(v, -v/2); does not lead to a loop with reinit, but first evaluates -v/2 (and other reinit-values) and then sets v (and other reinit-values). +One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the behaviour of a restricted set of continuous-time models; having two different variants of reinit (with same syntax but different semantics) is counter to that. +In addition the current reinit might possibly in the future be replaced by some form of impulses, indicating that the changes are physical and influence other parts of the system, this does not seem consistent with how states are set in this MCP. +Finally having a conditional setting of states is more complicated, and reinit and other similar operators naturally suggest that - and we either need to determine what it means or forbid it. + # Backwards Compatibility Will depend on exact syntax. From 498a189cb7cd2a01d3a3b43256eae7a2e87b5bb6 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 15 Sep 2020 18:53:08 +0200 Subject: [PATCH 03/55] Update README.md (#2613) Add new proposal for setting states. --- RationaleMCP/0036/README.md | 49 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 69aea4514..ff4798f71 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -24,13 +24,27 @@ and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ This is still work in progress as the main challenge is figuring out a specific syntax. +# Alternatives The alternatives considered are: - stateSelect.Measurement and binding equation + - *special binding equation without stateSelect.Measurement* - possibly reinit within a Clock – check if possible - replace "reinit" by "measurement"-operator, or forceState(…) - the implemented annotation does not seem like a good idea -# Alternatives such as reinit +Ideally the proposal should allow us to hide this "turning a measurement into a state" in a block, and thus many of the details will be less important. + +## Annotation variant +The annotation variant was proposed in the paper (not good since it influences the semantics) and is: + +Real xs annotation(useAsInputForState=x); + +This means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). +What might seem as odd is that the annotation is associated with the measurement variable, not with the state-variable. +The reason is that this allows setting of states deeply nested in existing models (which can otherwise be solved with an extra variable), but +instead requires work-arounds for complicated measurement expressions as in Kalman filters. + +## Alternatives such as reinit(x, xnew) As discussed in https://github.com/modelica/ModelicaSpecification/issues/2285#issuecomment-641275627 the conclusion of https://github.com/modelica/ModelicaSpecification/issues/578 was that all reinits are done at the end of the event iteration using previously computed values. @@ -39,19 +53,46 @@ One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the b In addition the current reinit might possibly in the future be replaced by some form of impulses, indicating that the changes are physical and influence other parts of the system, this does not seem consistent with how states are set in this MCP. Finally having a conditional setting of states is more complicated, and reinit and other similar operators naturally suggest that - and we either need to determine what it means or forbid it. +## Proposed alternative +Use a special binding equation: + +Real x=measurement(xs); + +This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). + +The name of the operator can be discussed. The prototype re-used "reinit" to avoid introducing new reserved words. + +Key points: +- Associated with state, not measurement variable. +- Allows general expressions, not only variables. +- Unconditional. +- Only clocked. +- Few corner cases. +- Easy to recognize for humans and tools. +- Straightforward to implement. Adapting the existing prototype to the new syntax was straightforward. + +Remaining: +- Decide if the way to go +- Name of operator (measurement, reinit, ...) +- Figure out how it impacts equation count and write specification text (a few paragraphs) + # Backwards Compatibility -Will depend on exact syntax. +Will depend on exact syntax. +In the proposed alternative it will depend on the measurement keyword; if we use "reinit" it is fully backwards compatible. # Tool Implementation -The preliminary variant with annotation has been implemented in Dymola. +Both the preliminary variant with annotation and proposed alternative have been implemented in Dymola. ## Experience with Prototype -The implementation effort was small and it works. +The implementation effort was small and it works; both variants give the same results. + However, as noted in the paper the procedure for using it is still slightly messy. - Attempt to translate the model - For each input add appropriate number of integrators and the state-update-component - Have parameters for those integrators etc. +That could be automated in tools. # Required Patents At best of your knowledge state any patents that would be required for implementation of this proposal. # References +https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf From 600d7b1f4d81efad4d0b873a6c83cb807eeb781b Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Fri, 25 Sep 2020 09:40:52 +0200 Subject: [PATCH 04/55] Update README.md Update with semantics discussion - based on https://github.com/modelica/ModelicaSpecification/pull/2613#discussion_r493489246 --- RationaleMCP/0036/README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index ff4798f71..7dcf8c270 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -14,6 +14,7 @@ and have the state-updating as part of the model (and not as some tool-specific | --- | --- | | 2020-04-22 | Hans Olsson. Created. | | 2020-07-08 | Hans Olsson. Updated with reinit. | +| 2020-09-25 | Hans Olsson. Updated with new semantics. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -58,7 +59,7 @@ Use a special binding equation: Real x=measurement(xs); -This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). +This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and its meaning is discussed in the semantics part. The name of the operator can be discussed. The prototype re-used "reinit" to avoid introducing new reserved words. @@ -76,6 +77,34 @@ Remaining: - Name of operator (measurement, reinit, ...) - Figure out how it impacts equation count and write specification text (a few paragraphs) +# Semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and was originally defined as "means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x)", but that seems unclear. + +Thus we present an alternative below, + +## Original semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition". + +The meaning is that +1. StateSelect.always is defined for variable x. +2. It is treated as a state during the usual index reduction and state selection. +3. Afterwards x is deselected as state and the equation x = xs is added. Its derivative is set as a dummy derivative. + +This is not ideal as it uses words like "treated as", and variables are changed from being states to non-states. + +## Discretization method semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition". + +The meaning is that +1. StateSelect.always is defined for variable x. +2. It is a state and thus participate in the usual index reduction and state selection. +3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method +https://specification.modelica.org/master/synchronous-language-elements.html#solver-methods + +This makes it clear that the variable is an actual state, just integrated differently. + +Step (3) requires that it is a state (guaranteed by (1)), and that it is a continuous variable in a "Clocked Discretized Continuous-Time Partition", as stated at the start. + # Backwards Compatibility Will depend on exact syntax. In the proposed alternative it will depend on the measurement keyword; if we use "reinit" it is fully backwards compatible. From 5e6c9daf14702733b11842203c78604386c3fc17 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:20:45 +0200 Subject: [PATCH 05/55] Add files via upload Test-cases. --- RationaleMCP/0036/BothControl.png | Bin 0 -> 11469 bytes RationaleMCP/0036/TestSettingStates.mo | 576 +++++++++++++++++++++++++ 2 files changed, 576 insertions(+) create mode 100644 RationaleMCP/0036/BothControl.png create mode 100644 RationaleMCP/0036/TestSettingStates.mo diff --git a/RationaleMCP/0036/BothControl.png b/RationaleMCP/0036/BothControl.png new file mode 100644 index 0000000000000000000000000000000000000000..caec8b8326a700e0431597514d8dc4bf8540f2ab GIT binary patch literal 11469 zcmb_?XIKMs#<&Pwf8FxHARYxOcx;tqELD$_ZWiC ztU?fx_4zZP#a`)g8~As@>7l+01W|q^{1L_RQ8Gi&HAqSBzP9Iw)rtF&V>&ep8}V<> z&gQRuCe2Zc*Mj|3FXQADCg4aiODCSp`h?wmo$a z5HNMLq&aJyA;>%u@RH&7dKg5jruIF>(6qQ30L6C#||A(XgOG-(rOFC2a!&-6DO5W=RMYNPGSm!S? zMNbT!l_Y+B`OBn-j@1)A+dX1dX(1XCyfTt?1zG7Fd~8WY85$EjeXz6OKQrI^1$Ssr z`&(q)K?FSz$EL4V(c|G-fnw(q(T#KZLIsKqcOICaHz zbd9_IrSB*WOD5mFQuyuRKq@X@x}Uha2kWZzWr`74bA01gkm-S42K~~uZYREowCo`> zWtQQ#+i##dxIyz&@bNFg8N!*wI^r#my^Ba1kfVq|$ThtlOY=5yj^-gn!t7M^&npo27;P3O=q4H8S5IcXe9 zF(qsygKYj{3}4fElw!8ZEj$JchVs}Q=)o@>@SFVh=cNNlh0AIWaKTp%8MqP(mpr^FC?;*_5i zsYS*61>ef8ua+F*ZIJtW)*Rn3K2ViaDt~ZtO>7XCkvgk)vua7-#fX+P_4k@S&sywq z{8fbxK^8HzP=Wbi)7S{sV{q)w?WB>w)qN6WM zFcY^DaqTNt=4(oS`WHk~+6p zhl-r&HJ@Bbl@1(nSdx##p(2F+7?rga4 zHbu|+qGTsl`2iXiMH%EN%tEE;9Ea1KQn%75Qww1b(6%4P2Y8&>w0?R}{|DF7_iw zyv->tX1wUZ*80$e?>jy{NfuuV*G_H47~V-X#Uy(!U}pPigdR!z(Bt3yoVVDWZuZ5@ z6q!8zZGJ_4**j&z#-n9tneMIb?-%?nnl;_y`se|xo1P1uq}iFBRGZqOI-d^f4SY26 zsL>y_sy}8D_YSsrt3_(u7jt^xuUJ&swYWw~8M?aa#kPA%(Z&(qNH(r2yI>5vT1JYY z(Xrp?!iKuTc_;BMvTJmtvQkB(qxV+Mp$F;*0~bBZM4k>KB}pKtoOTulK`908|JUQs zPFPtPJ6*wH?}zYfK5fILFM)^3*M5ZV54;oQ9K)eB_j0niBlKy3P<$plTiamc5(EXr z*>=E6h6n9X7DcBbTAsP#n}43tQABr;#0A;aVhxsY7Q>ch%6wOW!z=#bBOF-^Z z?EP>VRj$~UmKIC9;tX z{>7;;{#&~*li!?9ow6h}$j==-av7m28mygLaM)_}@IRa$DvGr58qTesCypN3GJN<5 zf`kjti7)i}|L)m7f@M#coPIn+?e2Npo|^P|?(F4_+WuuEN4XH&qh8d|dvEJ0oqi=} z?TR0)M-Y6e%ngGmk6-PS;xm-5 z8oYCRC=O^-zMVK1HiL0?ayFbw`h8pCp5vt7UKLx$TG@?wy?1V%SU134UZEEg@`VRk zq$E#G{12p)k0VbH0RS9Q35(CqN^k&kRdTFD|GvS(hS3A;?v)2#b8o)j58c?JsDOSb_nA{Z=qoX(VwqwnvzJ0D>eU zScJHxHoE8W9pUu1yCqiLGZ}Btn}mr#0cz~nISdbSpc`23bZy=c>s(k^m{@4XXY<_4 z_xT;ftZEh!RL&}%C9{?7kr zu{}A$1Lwsp&j~fTo-8fRZM1@Su9zg$!3y6&kTolKWN=wnO7f1bwX(XDN&{&$-S)Sn_$jzEh@jC|ELub37UgV7{)e;g!B?)S zC&H>O2t!bwU{QIcPvmWtM6ZpR){nu=tVu`%*R7dqmMPzllO#}zW&}2$UrKkf4ojbf z%%Vz%=icc}vQ)GN1G+Q|doQTj7SWl&Gg!ij8*;u3>>tb!iPLb`CK%sU$$jdUapq+x zpzb=>USMpWkKIx`tN(SP+-*U~^fW>D6BfKsk*c>RN5%h#ADMG2G1NFIcvUNS`!WvB z97o^{S>d*iC2-$euR{Uo8`$sHR^wpYorn0Hz2xVcN`vzHFNE+!koyZ3tw`a{jO=%2 z+FY$(fke>V2k2Z?CJVV2ni%l@3nH|Vw8Ls+5D~s! z-px5G;=|wtqB3Y4n_6_$Wg%54pdt$C&V#7u_`vSyOWq9-i5pE+=-Wk-1$AaJ)@fMu# z#H-n(@fgahFHT~o-6Ep(?4&lmh4RY3g4F;PnlM5>941H%N$FzU*pUVDapR7URWdj} zPhP>MDQF67v!?-?VdP?XaZ#TuR*AyxS#}$fTKyMEe^(Cn#Yi+)Y{!U+|Ek!xp`oFq zuF(Vvk+7SyI4$vdK6b|>DTjO#vQdpt(8y{rsu4V@`QN8{S_*YP+hK*D-ah3JQce%m zgsU_-Az0g2cUe)-k55 zorH@bWhq=N62!A+YY&s{OP}d(*OENyEKdE$!KX6^!Mdf~=~jX6abU&H)L@L#dz*3O zF@!ilIbL{2p>i>vOwb_`%?K@J8yq}GWHw*xd-}MmeBMKuA|02OVV&`njk{l?2g}Hc z-HOD&99OoVKBMAhDnbKoEAxvhP^6dK-DJUTJdlRlnhlWz80V%-E69CiTRbrMF4%derrRNLIVv!$JNc(aiTe2=3{Q(W4di-tgwxvi znL8eU@7~EVwp+mA)g@xcR|aikT&TIQx%~o{$XVAVj-r#Meh?n~cpqJ&R;fwY-Bi-dgIk8T zB`l#7p>|m1Y|Od458e_5P+r68Svjx9ggxKhzq3B|<+vr!_nlXK-Q2Fcz7$t*`9f6TS?wi#XWQM5ie7a+=x z)#D%GaXDEEdqlT#g)l0CIfgvi-J^QXjUY`7;!h`mEXdkc9+&lvbLsHfHWnJF{ET>( zuQkymRiZypqu*Qt9S^xcx4>$k&51+JMX2%dTtekc%sB`mylt+lYbD;O)HFE(c?Kej zMjEUGzhUNXLnYQk4(Wxl403@Li?WOF<|Io%{9sN4jUg<9@UCw>Eh__)efwn4?lo+= z`t&BJ%YA#Ugk5~_)JY-!GL*934nss4UwVHb%h!8r<)(`Y)OQP|V#xnZfN`qsc~?&N zWS;;r)WeP~e`1#24Sc)*PB;})Zgy1|9O}Dp)hB^b7< z88F;#1k2#F5WDy_sd`V~Wp_=;KbLbrD~#eX|z;0CXXXWh7%PR^uQOAf7E5zo5&4&mL=EdXo!e*T9AWSZR$ z`&jz36ckQ+2#t)Ns$+^Xkb-Jp1NG?}*stAGLh>h0_FRJ6ymGhIWm< z{eQvQT=P=VyyIhKVX%Z$^p{jPc=Al9F$wPp5Ys)neC;>!l<=mmD(v zG?!)E8FAV;%A&9+FZ&0A{Q zK_sGWt=)wMOLlC%5`OE$t*lPjVxKN=KXLIS2e6hkpA2jrc5o;ES@s`X@^Nw**{dUOo#gvk`BSZB7J~vDy?`Fia|UL>QDoin6v!6 zekmo{*neH@+sDBdEXacQ^u6=H3;TqLQ;HZO1KVRN9>r8&6HSK?gDq||$O*|H+hLdV zhj>~z$qWL;xgaSybd$EyTeH>2d|bpnii2^Z z*&X+mo7%wk?Rye|HI+3gg`hq$6uFL}XcGrJuqN5Z21p{*i_;#B%N&N$s1RN?cs7NZ zA+pJKUaA2-JMQzmY2|S^z(9g0$jOlGJldxM*qMu9h$QNxm}Ahc@ZP^H)c^$?vtv_4 z0dW9N^t;mPQPHSC25(q`cRoD#(*Ha`-r>{{Gz_bQXD~wi^5`b-Z)~h_dq=O&)5qA; z3z$GDb>Qp9Iv>#q@(wD1*|ffaA{Q+|aaKBASArVXqLIa^oAZx=AFE3+J=4cN$FOp- z>=D0w5qSXJb*w2LpH;lrkRx+R*aaCwCtptcR^iSolywO_u^g|$qL2nJD@~w+Mo;p} zCz*@7VneqfQ_^nY1t9oG073b)U>zrxcJ%JdaYIL*JAZcGTm z3zT7&?lwFGkO@nh-tNNt7Us3+snEf*Rl89CU}{W7O)>CK-<`Y+b}8`t8*25Ery%H~ z#+lk@@zr2#5} zNdf6GCyt&C@iV96#y1Kb*Pe)Nw&*K5rl_cQkGGL-zHl3v&>q<0`|z{Mkg#FGY6@xa zkuJXcwhWw@_bo@n7w@F`C<}04{DP~^Le1NS`7PAmVpV7Yq-JZ*j#l$>$HBr&_6+H5 z+rXY)F+t42WH2!s3FV7>fSU+(Wjbw}jY(oa@=lijpK7Ju&^sZN~gWv5iYrP#Ftw~mLXz4nNJh2L%a?AMh zUjWnGP3Yax?u?LOnl#C3RNaS+urJSXuJ?0@SK(0QS5NX=kDY^*vUh2s||S~G_Ckq2M1B5nQ0a? zm^+Pg;v_nT%gyJ?yIe053qi`Dr`ie~!3*ID5-$N_bAoRRtVknIhfg5W$Zbd(*+GwH z1$KfL(%~Onwr0cu38jlh_OV6)8Z#Az?1OK223+8RZlcHyEX#};2UOyL1+M|jI5bL1 zA^_Yb1y^T=4S_m?czgFT)9%;uE&#>gQDs0ab{rhCw6yhWknj1gP;e>CngAklC4u6%zG9c+1HpK+B zT(ZtGZmQ(Y?OZ6C!VMlw*}TA|pMZS&pG{Oi=$meg81V@-{sVfisfa2~y)A|v;;9q; zYs1itDPthkl=wvgSBv3zb=22o8CQKb*7^!n*512&XGed`D=PrI1c-<=5A%oZ*=Q9RC!uu_+w>k-Iv=qX%Mq5)lS9XXxIh+tzvxK>Jj6w%xuW#$%SUh`Leta}{83z5ASTlPmMCy~;30(5 z_INYOrzS+a0vKctPSmbUer{6wxCLy%M9cHS1#O<>#ddQHDVEEHJpxKX<=>pb`I`JiPYcDjnk?K5dlSw$enXF0f(|zu>Od@m`1K~7mU@VqFcD*!E!exZ|k>A zR-v;@DRgrTrfjw!Y&tVBY{qqYwR$VWNFf=*|C9h}`ZI%HPQOE$UC*aCO8!n$FE*iUsLj27?>`jU17#c6qjtDD-3^QU{Z^T-P?WxpW zvLN^i$k1MJ@GVD2fninWAo*gF4ePKa@lZ4psx`Mt{A8Y(mzNjUBJ|i5$3MZ5Ttt?ftv}u!E1?Kaemb?H#? z@C6g!cQY%{vWq&AH&__QC*gavwO5**i911<66f1IkOnLCS?5P}$ATwnv{oO@hgolJ zkyVQi8J9gXmOTBds^LaY3ilsB@O;55(D;iM>Ew!#^Cf|2UC&4~%37%tdvu-^#n}v4 zCK~1APF7Q11KGGV>w=W#zry!>u`h^kZ>NJiHV0E{u+0EqyjZ;A{Af`+CB!*EowzM2 z%uF?q-z{7nPZMgJ*r-Bt0MaY}i0(g-!Oa*BT2e1lQ-gH80hS%GK!Tb{T3qiM)%Lu4 zSw+htCseQOF8HLEV3tcUa)dbF{aFW_m4acjpzstE;L2qfPRqCe%S;+|W>?bek@3O= z8}km09-wmKRAftY>8*NYb;UXP`13B3s->j0M^tzF!qiEVKn`438~2`F;@8#oSiI~- zY0{#?!b<+jjS|3%s5mA|OME(MG^~1N(O|U4w%!pR5Bz-h)I!&3U>s4zdGE#H0z;9rk@@C6{SR|BT_^CUWBInx_?f%iz8GW77w^~OKr4MR$jR}F zpoz-<@kCK8B@sZJUI22HepTqIv{U`@#v8AR?R7{0=ds6HnGtm*si7Gt#v(u8qn{(# zp5bCU(YI!@6t6@qzMuGe|B*LU2meF@BRv#t1kDAmc2Us=DsP?{AFSaQ>3FWI+NzW@ zKCrgpWjBE18MN90nx4wTf>sq#5yZLTI0FUiKf33M2EI(=u%)_H5fqC=-%T=!5x#Sn zG3)t*i@Xtq8$4?@f-*_ckw|rfOFt-Mu!ylG{uVy1Ah#xU(lw9A67m2dsbGCS>=paq zYZ|w>o?7k}Y98zkH0~TT;bHV*gxq(Y*UzbGOtu9XYpqi0`h%Av`TRdb96Mj}NfLrn zB}*=!AU zw&2uUQt?4v)dTmBqJbpC>{w_tkGG@kY*-9;?$u|?_5PUVFyx7GgcyEmp%6^A_rTV))xd3lkT4vm5rQ}##M$F+I3MDI3mPm>6GE@M! zZ|l$bRi+l9VxV&byg_+!`dkPxD%C$)kmoeBnBQEl2vRG|XjRG^pTbpX!Mn?z9eC~k zoEY1i98LDG3G^j^&4Ba#x@tFk1T7e!i@9wPPZ3sG%Ew0`rkFH@dW4jTCD8P*&_3x8RIz{Ujdcj`OK+pw=s#>p&@gpT-Rc~T~gMd<02R0an9c4kL9TL4CIea|{=deiE?}|-36~3%hX+`z%!zbZS`mJ(yyy^!?U?)ZtIuAarA$d(DxwECc4#!VwY~JS z=<6+9ehBDFCKeTK0qg1W(js&m;D%Z(>zL>|(tb_2)}@`CY_NL_5*kEM3faZQ?9z*h z&dT)-w1ob*A58P8J$n?Fk9@)n2cv^jo^(h&k%;c9`W^-zhK6+}Uwv^6pZ#vw*89^} z0#q^7-)5M!M|D(6g{XEvy$v%RF_11j|zc>&G-&pIqQza@*b*I{A*@Oi{EhMjDL zx&{M&ajxMXd%o1vZd1BuV)4q&g4>|tgq_`1Y`X%jD@CXa2>O>+?Vi@o#*Osfm1hW5 zuFfM=6=>XNU5*1P^^@QCSUrP1ue^zS_<8%fnkKi)v;q+ITnKv1lZPO5V+7S=a3Pg0 zHc*rCEPPfhoO!Q1l}K8U;*qptwjxqADvW%p-s}kf9b5J+0m} zkWuODq_N7HiJIzWjMCn8mw%0jeo8paEnIs|_a(1z?SP_~@A1m(E4A#cg%3*zr`oz6 z@^_|aA!v!Xun4^12Vq|See7Idp&`^TvS5v_*EYERC63_>+Cx<>H43du)N&tG@}WqZ zckbb*rlZGbM-JH!D{JfdhQ*+RYQDnt<$md?W<>u^uezN}1m%~&2#|tdm)@pB_nh=K z1$Xaz98??rDT4zx1Z8rA{%%rZw9}24yVQd__c~VI`mMws6-GJzg*O8?z}*$8yiuOo z(uBUVym$BYKl6G2+Q;bGu7pdA-bs&EcHC1He%!fNH06KWIF0e|TKjy~7vhKN5@r(>jnAlex(LFdXTc+h*tbWlw z1W1cB++YQ<7^RWJD$>ht#H#CMQ=eBN)n8q_ zr&(zDxn!$0ZHB0?3(-H-+uNF+MwOgQu`{24<;~lKg^b-h*Bx%w5_?x07EYDpw}c&Q z{cG9%uidK0Pp-u7S9wg7dQJ?C?jTCqi28aFFb@xtd(vbc@>KVv3wmHmF`~B+dj@-2 zYl6%3&#Ippch#>Zt-c=jSKWg1!GV1@+3N5cn&l-e85`{yZfOi&)Bwbr920I?w@c{RDh2c|*)0a!iMu>b%7 literal 0 HcmV?d00001 diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo new file mode 100644 index 000000000..b81ae8507 --- /dev/null +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -0,0 +1,576 @@ +within ; +package TestSettingStates + model TrivialDemonstration + model DiscretizedWithReinit + input Real u; + Real x=reinit(u); + Real y=2*x; + equation + der(y)=u-y; + end DiscretizedWithReinit; + + model Discretized + input Real u; + Real x(stateSelect=StateSelect.always); + Real y=2*x; + equation + der(y)=u-y; + end Discretized; + Discretized discretized1(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + annotation (Documentation(info=" +

The result of this model will be similar to:

+
+when sample(1e-3) then
+ /* without state reset */ 
+ discretized1.u=time;
+ discretized1.x=discretized1.x+...; // Euler discretization
+ discretized1.y=2*discretized1.x;
+ discretized1.der_y=time-discretized1.y;
+ discretized1.der_x=0.5*discretized1.der_y;
+ 
+ /* with state reset */ 
+ discretized2.u=time;
+ discretized2.x=time; // Just using input!
+ discretized2.y=2*discretized2.x;
+ discretized2.der_y=time-discretized2.y;
+ discretized2.der_x=0.5*discretized2.der_y;
+end when;
+
+

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

+")); + end TrivialDemonstration; + + package System + model FeedforwardControl + extends Modelica.Clocked.Examples.Systems.ControlledMixingUnit(pro=1.1); + annotation (Documentation(info=" +

An example from Modelica Standard Library, but changed to have same difference between plant and plant in controller for easier comparison.

+

This does not need the possibility for setting states due to using a different controller.

+")); + end FeedforwardControl; + + model FeedbackControl + "Simple example of a mixing unit where a (discretized) nonlinear inverse plant model is used as feedback linearization controller" + extends Modelica.Icons.Example; + + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration"; + parameter Modelica.Units.SI.Temperature T0=308.5 "Nominal temperature"; + parameter Real a1_inv = 0.2674 "Process parameter of inverse plant model (see references in help)"; + parameter Real a21_inv = 1.815 "Process parameter of inverse plant model (see references in help)"; + parameter Real a22_inv = 0.4682 "Process parameter of inverse plant model (see references in help)"; + parameter Real b_inv = 1.5476 "Process parameter of inverse plant model (see references in help)"; + parameter Real k0_inv = 1.05e14 "Process parameter of inverse plant model (see references in help)"; + parameter Real eps = 34.2894 "Process parameter (see references in help)"; + parameter Real x10 = 0.42 "Relative offset between nominal concentration and initial concentration"; + parameter Real x20 = 0.01 "Relative offset between nominal temperature and initial temperature"; + parameter Real u0 = -0.0224 "Relative offset between initial cooling temperature and nominal temperature"; + final parameter Real c_start(unit="mol/l") = c0*(1-x10) "Initial concentration"; + final parameter Modelica.Units.SI.Temperature T_start=T0*(1 + x20) + "Initial temperature"; + final parameter Real c_high_start(unit="mol/l") = c0*(1-0.72) "Reference concentration"; + final parameter Real T_c_start = T0*(1+u0) "Initial cooling temperature"; + parameter Real pro=1.1 "Deviations of plant to inverse plant parameters"; + final parameter Real a1=a1_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a21=a21_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a22=a22_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real b=b_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real k0=k0_inv*pro "Process parameter of plant model (see references in help)"; + + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit invMixingUnit( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-10},{-10,10}}, origin={2,26}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints + annotation (Placement(transformation(extent={{-26,-16},{26,16}}, origin={0,28}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit mixingUnit( + c(start=c_start, fixed=true), + T(start=T_start, fixed=true), + c0=c0, + T0=T0, + a1=a1, + a21=a21, + a22=a22, + b=b, + k0=k0, + eps=eps) annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={86,-16}))); + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.CriticalDamping + filter( + n=3, + f=freq, + x(start={0.49,0.49,0.49}, fixed={true,false,false})) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-78,30}))); + Modelica.Clocked.RealSignals.Sampler.Hold hold1(y_start=300) + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={62,-16}))); + Modelica.Clocked.ClockSignals.Clocks.PeriodicRealClock periodicClock1( + useSolver=true, + period=1, + solverMethod="Rosenbrock2") + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-130,-22}))); + Modelica.Blocks.Sources.Step step(height=c_high_start - c_start, offset= + c_start, + startTime=0) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-130,30}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample2 + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-106,30}))); + Modelica.Clocked.RealSignals.Sampler.Sample sample_c + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={78,68}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample_T + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={70,-44}))); + Utilities.InputToState inputToState annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={8,-4}))); + Utilities.InputToState inputToState1 annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={-6,56}))); + Utilities.FeedbackController controller( + freq=freq) annotation (Placement(transformation(rotation=0, extent={{-58,20},{-38, + 40}}))); + equation + connect(inverseBlockConstraints.y2, invMixingUnit.T_c) annotation (Line( + points={{22.1,28},{22.1,26},{14,26}}, + color={0,0,127})); + connect(invMixingUnit.c, inverseBlockConstraints.u2) annotation (Line( + points={{-10,32},{-20,32},{-20,28},{-20.8,28}}, + color={0,0,127})); + connect(hold1.y, mixingUnit.T_c) annotation (Line( + points={{68.6,-16},{70,-16},{70,-18},{72,-18},{72,-16},{74,-16}}, + color={0,0,127})); + connect(sample2.u,step. y) annotation (Line( + points={{-113.2,30},{-119,30}}, + color={0,0,127})); + connect(filter.u, sample2.y) annotation (Line( + points={{-90,30},{-99.4,30}}, + color={0,0,127})); + connect(periodicClock1.y, sample2.clock) annotation (Line( + points={{-123.4,-22},{-106,-22},{-106,22.8}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + connect(hold1.u, inverseBlockConstraints.y1) annotation (Line(points={{54.8,-16}, + {36,-16},{36,28},{27.3,28}}, color={0,0,127})); + connect(mixingUnit.c, sample_c.u) annotation (Line(points={{98,-10},{104,-10}, + {104,68},{85.2,68}},color={0,0,127})); + connect(sample_T.u, mixingUnit.T) annotation (Line(points={{77.2,-44},{104,-44}, + {104,-22},{98,-22}}, color={0,0,127})); + connect(sample_T.clock, periodicClock1.y) annotation (Line( + points={{70,-51.2},{78,-51.2},{78,-72},{-126,-72},{-126,-22},{-123.4,-22}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + + connect(sample_T.y, inputToState.measurement) annotation (Line(points={{63.4,-44}, + {26,-44},{26,-4},{18,-4}}, color={0,0,127})); + connect(inputToState.stateToSet, invMixingUnit.T) annotation (Line(points={{-2,-4}, + {-10,-4},{-10,20}}, color={0,0,127})); + connect(inputToState1.measurement, sample_c.y) annotation (Line(points={{4,56},{ + 62,56},{62,68},{71.4,68}}, color={0,0,127})); + connect(controller.y, inverseBlockConstraints.u1) annotation (Line( + points={{-38,28},{-28.6,28}}, color={0,0,127})); + connect(filter.y,controller.u1) + annotation (Line(points={{-67,30},{-58,30}}, + color={0,0,127})); + connect(controller.u2, + sample_c.y) + annotation (Line(points={{-56,40},{-56,72},{62,72},{62,68},{71.4,68}}, + color={0,0,127})); + connect(inputToState1.stateToSet, inverseBlockConstraints.u2) annotation ( + Line(points={{-16,56},{-28,56},{-28,28},{-20.8,28}}, + color={0,0,127})); + annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-140, + -100},{120,100}}), graphics={Rectangle(extent={{-96,70},{40,-18}}, + lineColor={255,0,0}), Text( + extent={{-84,-4},{-38,-12}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="feedback linearization")}), + experiment(StopTime=300), + Documentation(info=" +

This demonstrates using feedback linearization to improve the control of the plant.

+")); + end FeedbackControl; + + model BothControl + "Simple example of a mixing unit where a (discretized) nonlinear inverse plant model is used as feedback linearization controller and another inverse model as feedforward control" + extends Modelica.Icons.Example; + + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration"; + parameter Modelica.Units.SI.Temperature T0=308.5 "Nominal temperature"; + parameter Real a1_inv = 0.2674 "Process parameter of inverse plant model (see references in help)"; + parameter Real a21_inv = 1.815 "Process parameter of inverse plant model (see references in help)"; + parameter Real a22_inv = 0.4682 "Process parameter of inverse plant model (see references in help)"; + parameter Real b_inv = 1.5476 "Process parameter of inverse plant model (see references in help)"; + parameter Real k0_inv = 1.05e14 "Process parameter of inverse plant model (see references in help)"; + parameter Real eps = 34.2894 "Process parameter (see references in help)"; + parameter Real x10 = 0.42 "Relative offset between nominal concentration and initial concentration"; + parameter Real x20 = 0.01 "Relative offset between nominal temperature and initial temperature"; + parameter Real u0 = -0.0224 "Relative offset between initial cooling temperature and nominal temperature"; + final parameter Real c_start(unit="mol/l") = c0*(1-x10) "Initial concentration"; + final parameter Modelica.Units.SI.Temperature T_start=T0*(1 + x20) + "Initial temperature"; + final parameter Real c_high_start(unit="mol/l") = c0*(1-0.72) "Reference concentration"; + final parameter Real T_c_start = T0*(1+u0) "Initial cooling temperature"; + parameter Real pro=1.1 "Deviations of plant to inverse plant parameters"; + final parameter Real a1=a1_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a21=a21_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a22=a22_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real b=b_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real k0=k0_inv*pro "Process parameter of plant model (see references in help)"; + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit invMixingUnit( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-10},{-10,10}}, origin={2,26}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints + annotation (Placement(transformation(extent={{-26,-16},{26,16}}, origin={0,28}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit mixingUnit( + c(start=c_start, fixed=true), + T(start=T_start, fixed=true), + c0=c0, + T0=T0, + a1=a1, + a21=a21, + a22=a22, + b=b, + k0=k0, + eps=eps) annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={86,-16}))); + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.CriticalDamping + filter( + n=3, + f=freq, + x(start={0.49,0.49,0.49}, fixed={true,false,false})) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-78,30}))); + Modelica.Clocked.RealSignals.Sampler.Hold hold1(y_start=300) + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={62,-16}))); + Modelica.Clocked.ClockSignals.Clocks.PeriodicRealClock periodicClock1( + useSolver=true, + period=1, + solverMethod="Rosenbrock2") + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-130,-22}))); + Modelica.Blocks.Sources.Step step(height=c_high_start - c_start, offset= + c_start, + startTime=0) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-130,30}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample2 + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-106,30}))); + Modelica.Clocked.RealSignals.Sampler.Sample sample_c + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={78,68}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample_T + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={70,-44}))); + Utilities.InputToState inputToState annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={8,-4}))); + Utilities.InputToState inputToState1 annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={-6,56}))); + Utilities.FeedbackController controller( + freq=freq) annotation (Placement(transformation(rotation=0, extent={{-58,20},{-38, + 40}}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit + invMixingUnit1( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true, + stateSelect=StateSelect.always), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-48},{-10,-28}}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints1 + annotation (Placement(transformation(extent={{-32,-52},{20,-20}}))); + Modelica.Blocks.Math.Gain gain(k=20) annotation (Placement(transformation( + extent={{28,-68},{48,-48}}))); + Modelica.Blocks.Math.Feedback feedback + annotation (Placement(transformation(extent={{-8,-80},{12,-60}}))); + Modelica.Blocks.Math.Add add + annotation (Placement(transformation(extent={{46,14},{66,34}}))); + equation + connect(inverseBlockConstraints.y2, invMixingUnit.T_c) annotation (Line( + points={{22.1,28},{22.1,26},{14,26}}, + color={0,0,127})); + connect(invMixingUnit.c, inverseBlockConstraints.u2) annotation (Line( + points={{-10,32},{-20,32},{-20,28},{-20.8,28}}, + color={0,0,127})); + connect(hold1.y, mixingUnit.T_c) annotation (Line( + points={{68.6,-16},{70,-16},{70,-18},{72,-18},{72,-16},{74,-16}}, + color={0,0,127})); + connect(sample2.u,step. y) annotation (Line( + points={{-113.2,30},{-119,30}}, + color={0,0,127})); + connect(filter.u, sample2.y) annotation (Line( + points={{-90,30},{-99.4,30}}, + color={0,0,127})); + connect(periodicClock1.y, sample2.clock) annotation (Line( + points={{-123.4,-22},{-106,-22},{-106,22.8}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + connect(mixingUnit.c, sample_c.u) annotation (Line(points={{98,-10},{104,-10}, + {104,68},{85.2,68}},color={0,0,127})); + connect(sample_T.u, mixingUnit.T) annotation (Line(points={{77.2,-44},{104,-44}, + {104,-22},{98,-22}}, color={0,0,127})); + connect(sample_T.clock, periodicClock1.y) annotation (Line( + points={{70,-51.2},{78,-51.2},{78,-72},{-126,-72},{-126,-22},{-123.4,-22}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + + connect(sample_T.y, inputToState.measurement) annotation (Line(points={{63.4,-44}, + {28,-44},{28,-4},{18,-4}}, color={0,0,127})); + connect(inputToState.stateToSet, invMixingUnit.T) annotation (Line(points={{-2,-4}, + {-10,-4},{-10,20}}, color={0,0,127})); + connect(inputToState1.measurement, sample_c.y) annotation (Line(points={{4,56},{ + 62,56},{62,68},{71.4,68}}, color={0,0,127})); + connect(controller.y, inverseBlockConstraints.u1) annotation (Line( + points={{-38,28},{-28.6,28}}, color={0,0,127})); + connect(filter.y,controller.u1) + annotation (Line(points={{-67,30},{-58,30}}, + color={0,0,127})); + connect(controller.u2, + sample_c.y) + annotation (Line(points={{-56,40},{-56,72},{62,72},{62,68},{71.4,68}}, + color={0,0,127})); + connect(inputToState1.stateToSet, inverseBlockConstraints.u2) annotation ( + Line(points={{-16,56},{-28,56},{-28,28},{-20.8,28}}, + color={0,0,127})); + connect(invMixingUnit1.T, feedback.u1) + annotation (Line(points={{-12,-44},{-12,-70},{-6,-70}}, color={0,0,127})); + connect(feedback.y,gain. u) annotation (Line(points={{11,-70},{20,-70},{20,-58}, + {26,-58}}, + color={0,0,127})); + connect(invMixingUnit1.c, inverseBlockConstraints1.u2) annotation (Line( + points={{-12,-32},{-22,-32},{-22,-36},{-26.8,-36}}, color={0,0,127})); + connect(filter.y, inverseBlockConstraints1.u1) annotation (Line(points={{-67,30}, + {-62,30},{-62,-36},{-34.6,-36}}, color={0,0,127})); + connect(feedback.u2, inputToState.measurement) annotation (Line(points={{2,-78}, + {2,-90},{56,-90},{56,-44},{28,-44},{28,-4},{18,-4}}, color={0,0,127})); + connect(inverseBlockConstraints1.y2, invMixingUnit1.T_c) annotation (Line( + points={{16.1,-36},{14.05,-36},{14.05,-38},{12,-38}}, color={0,0,127})); + connect(inverseBlockConstraints.y1, add.u1) annotation (Line(points={{27.3,28}, + {38,28},{38,30},{44,30}}, color={0,0,127})); + connect(gain.y, add.u2) annotation (Line(points={{49,-58},{54,-58},{54,-26},{38, + -26},{38,18},{44,18}}, color={0,0,127})); + connect(add.y, hold1.u) annotation (Line(points={{67,24},{72,24},{72,-4},{48,-4}, + {48,-16},{54.8,-16}}, color={0,0,127})); + annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-140, + -100},{120,100}}), graphics={Rectangle(extent={{-96,70},{40,-18}}, + lineColor={255,0,0}), Text( + extent={{-82,-6},{-36,-14}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="feedback linearization"), + Rectangle(extent={{-36,-18},{62,-94}}, + lineColor={255,0,0}), Text( + extent={{-40,-82},{6,-90}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="controller")}), + experiment(StopTime=300), + Documentation(info=" +

This demonstrates using feedback linearization to improve the control of the plant.

+")); + end BothControl; + + package Utilities + model FeedbackController + Modelica.Blocks.Math.Feedback feedback annotation (Placement( + transformation(extent={{-10,10},{10,-10}}, origin={-64,0}))); + Modelica.Blocks.Math.Gain gain1(k=K0) annotation (Placement( + transformation(extent={{-10,-10},{10,10}}, origin={-30,0}))); + Modelica.Blocks.Math.Feedback feedback1 annotation (Placement( + transformation(extent={{-10,10},{10,-10}}, origin={2,0}))); + Modelica.Blocks.Math.Gain gain(k=K1) annotation (Placement( + transformation(extent={{10,-10},{-10,10}}, origin={26,30}))); + SimpleIntegrator simpleIntegrator1(initType=Modelica.Blocks.Types.Init.NoInit) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={32,0}))); + SimpleIntegrator simpleIntegrator(initType=Modelica.Blocks.Types.Init.NoInit) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={72,0}))); + final parameter Real K0 = (2*pi*freq)^2; + final parameter Real K1 = 2*(2*pi*freq); + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + constant Real pi = Modelica.Constants.pi; + Modelica.Blocks.Interfaces.RealInput u1 annotation (Placement( + transformation(rotation=0, extent={{-100,-10},{-80,10}}))); + Modelica.Blocks.Interfaces.RealInput u2 annotation (Placement( + transformation(rotation=0, extent={{-80,90},{-60,110}}))); + Modelica.Blocks.Interfaces.RealOutput y(start=simpleIntegrator.y_start) + annotation (Placement(transformation(rotation=0, extent={{100,-30},{ + 120,-10}}))); + equation + connect(simpleIntegrator1.y, simpleIntegrator.u) annotation (Line(points={{43,0},{ + 60,0}}, color={0,0,127})); + connect(feedback1.u2, gain.y) + annotation (Line(points={{2,8},{2,30},{15,30}}, color={0,0,127})); + connect(gain1.y, feedback1.u1) annotation (Line(points={{-19,0},{-6,0}}, + color={0,0,127})); + connect(feedback1.y, simpleIntegrator1.u) annotation (Line(points={{11,0},{ + 20,0}}, color={0,0, + 127})); + connect(simpleIntegrator1.y, gain.u) annotation (Line(points={{43,0},{ + 48,0},{48,30},{38,30}}, + color={0,0,127})); + connect(feedback.y, gain1.u) + annotation (Line(points={{-55,0},{-42,0}}, color={0,0,127})); + connect(u1, feedback.u1) + annotation (Line(points={{-90,0},{-72,0}}, color={0,0,127})); + connect(u2, feedback.u2) annotation (Line(points={{-70,100},{-70,14},{ + -64,14},{-64,8}}, color={0,0,127})); + connect(y, simpleIntegrator.y) annotation (Line(points={{110,-20},{88, + -20},{88,0},{83,0}}, color={0,0,127})); + annotation (Diagram(coordinateSystem(extent={{-90,-100},{110,100}})), + Icon(coordinateSystem(extent={{-90,-100},{110,100}}))); + end FeedbackController; + + block SimpleIntegrator + "Output the integral of the input signal with optional reset" + import Modelica.Blocks.Types.Init; + parameter Real k(unit="1")=1 "Integrator gain"; + /* InitialState is the default, because it was the default in Modelica 2.2 + and therefore this setting is backward compatible + */ + parameter Init initType=Init.InitialState + "Type of initialization (1: no init, 2: steady state, 3,4: initial output)" annotation(Evaluate=true, + Dialog(group="Initialization")); + parameter Real y_start=0 "Initial or guess value of output (= state)" + annotation (Dialog(group="Initialization")); + extends Modelica.Blocks.Interfaces.SISO(y(start=y_start)); + equation + der(y) = k*u; + annotation ( + Documentation(info=" +

+This blocks computes output y as +integral of the input u multiplied with +the gain k: +

+
+    k
+y = - u
+    s
+
+ +

+It might be difficult to initialize the integrator in steady state. +This is discussed in the description of package +Continuous. +

+ +

+If the reset port is enabled, then the output y is reset to set +or to y_start (if the set port is not enabled), whenever the reset +port has a rising edge. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100.0,-100.0},{100.0,100.0}}), + graphics={ + Line( + points={{-80.0,78.0},{-80.0,-90.0}}, + color={192,192,192}), + Polygon( + lineColor={192,192,192}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid, + points={{-80.0,90.0},{-88.0,68.0},{-72.0,68.0},{-80.0,90.0}}), + Line( + points={{-90.0,-80.0},{82.0,-80.0}}, + color={192,192,192}), + Polygon( + lineColor={192,192,192}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid, + points={{90.0,-80.0},{68.0,-72.0},{68.0,-88.0},{90.0,-80.0}}), + Text( + extent={{-150.0,-150.0},{150.0,-110.0}}, + textString="k=%k"), + Line( + points=DynamicSelect({{-80.0,-80.0},{80.0,80.0}}, if use_reset then {{-80.0,-80.0},{60.0,60.0},{60.0,-80.0},{80.0,-60.0}} else {{-80.0,-80.0},{80.0,80.0}}), + color={0,0,127}), + Line( + visible=use_reset, + points={{60,-100},{60,-80}}, + color={255,0,255}, + pattern=LinePattern.Dot)})); + end SimpleIntegrator; + + block InputToState + Modelica.Blocks.Interfaces.RealInput measurement + annotation (Placement(transformation(extent={{120,-20},{80,20}}))); + RealInputSetState stateToSet=reinit(measurement) + annotation (Placement(transformation(extent={{-120,-20},{-80,20}}))); + annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( + coordinateSystem(preserveAspectRatio=false))); + end InputToState; + + connector RealInputSetState = + input Real "'input Real' as connector" annotation ( + defaultComponentName="u", + Icon(graphics={ + Polygon( + lineColor={0,0,127}, + fillColor={238,46,47}, + fillPattern=FillPattern.Solid, + points={{-100.0,100.0},{100.0,0.0},{-100.0,-100.0}})}, + coordinateSystem(extent={{-100.0,-100.0},{100.0,100.0}}, + preserveAspectRatio=true, + initialScale=0.2)), + Diagram( + coordinateSystem(preserveAspectRatio=true, + initialScale=0.2, + extent={{-100.0,-100.0},{100.0,100.0}}), + graphics={ + Polygon( + lineColor={0,0,127}, + fillColor={238,46,47}, + fillPattern=FillPattern.Solid, + points={{0.0,50.0},{100.0,0.0},{0.0,-50.0},{0.0,50.0}}), + Text( + textColor={0,0,127}, + extent={{-10.0,60.0},{-10.0,85.0}}, + textString="%name")}), + Documentation(info=" +

+Connector with one input signal of type Real. +

+")); + end Utilities; + end System; + annotation (uses(Modelica(version="4.0.0"))); +end TestSettingStates; From 55374dbdba22df8214c35f9c3204775e93013afb Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:38:36 +0200 Subject: [PATCH 06/55] Update README.md Updated with test-case and more complete description. --- RationaleMCP/0036/README.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 7dcf8c270..40968f32b 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -15,6 +15,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2020-04-22 | Hans Olsson. Created. | | 2020-07-08 | Hans Olsson. Updated with reinit. | | 2020-09-25 | Hans Olsson. Updated with new semantics. | +| 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -71,19 +72,21 @@ Key points: - Few corner cases. - Easy to recognize for humans and tools. - Straightforward to implement. Adapting the existing prototype to the new syntax was straightforward. +- The special binding equation is ignored for equation counting. Remaining: -- Decide if the way to go -- Name of operator (measurement, reinit, ...) -- Figure out how it impacts equation count and write specification text (a few paragraphs) +- Decide if the way to go. Proposal: Yes +- Name of operator (measurement, reinit, ...). Proposal: reinit +- Must the partition have a discretization method? Proposal: No +- Write specification text (a few paragraphs) # Semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and was originally defined as "means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x)", but that seems unclear. +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", but the original semantics was unclear Thus we present an alternative below, -## Original semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition". +## Original semantics (only of historic interest) +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x) The meaning is that 1. StateSelect.always is defined for variable x. @@ -93,13 +96,14 @@ The meaning is that This is not ideal as it uses words like "treated as", and variables are changed from being states to non-states. ## Discretization method semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition". +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and only as the entire declaration equation for a variable. The meaning is that -1. StateSelect.always is defined for variable x. -2. It is a state and thus participate in the usual index reduction and state selection. +1. StateSelect.always is set for the variable x. +2. Therefore it is a state and thus participate in the usual index reduction and state selection. 3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method https://specification.modelica.org/master/synchronous-language-elements.html#solver-methods +4. This declaration equation is ignored for the equation count. This makes it clear that the variable is an actual state, just integrated differently. @@ -121,7 +125,14 @@ However, as noted in the paper the procedure for using it is still slightly mess - Have parameters for those integrators etc. That could be automated in tools. +(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that will be corrected in the next release.) + +## Test-cases +The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. +![Plot showing result](BothControl.png) + # Required Patents -At best of your knowledge state any patents that would be required for implementation of this proposal. +At best of your knowledge state any patents that would be required for implementation of this proposal. + # References https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf From 8454746a636175564d3b90fbc1d6d10ce5668155 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:39:09 +0200 Subject: [PATCH 07/55] Update README.md Space --- RationaleMCP/0036/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 40968f32b..c914eafa8 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -129,6 +129,7 @@ That could be automated in tools. ## Test-cases The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. + ![Plot showing result](BothControl.png) # Required Patents From 4b65c7ac44da374e84856ff38fda27e05c8f8e1d Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:33:14 +0100 Subject: [PATCH 08/55] Add a number of incorrect examples. And minor spelling correction. --- RationaleMCP/0036/TestSettingStates.mo | 49 ++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index b81ae8507..67c2056fd 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -16,8 +16,8 @@ package TestSettingStates equation der(y)=u-y; end Discretized; - Discretized discretized1(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); - DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + Discretized discretized1(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); + DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); annotation (Documentation(info="

The result of this model will be similar to:

@@ -45,7 +45,7 @@ end when;
     model FeedforwardControl
       extends Modelica.Clocked.Examples.Systems.ControlledMixingUnit(pro=1.1);
       annotation (Documentation(info="
-

An example from Modelica Standard Library, but changed to have same difference between plant and plant in controller for easier comparison.

+

An example from Modelica Standard Library, but changed to have some difference between plant and plant in controller for easier comparison.

This does not need the possibility for setting states due to using a different controller.

")); end FeedforwardControl; @@ -572,5 +572,48 @@ Connector with one input signal of type Real. ")); end Utilities; end System; + package ErrorExamples + model DiscretizedIncorrect1 "Illegal since rhs must just be reinit, use reinit(-u) instead." + input Real u; + Real x=-reinit(u); + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(x)=u-x; + end when; + end DiscretizedIncorrect1; + model DiscretizedIncorrect2 "Illegal since reinit must be in a binding declaration" + input Real u; + Real x; + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(x)=u-x; + x=reinit(u); + end when; + end DiscretizedIncorrect2; + model DiscretizedIncorrect3 "Illegal, since cannot have both x and y as states" + input Real u; + Real x=reinit(u); + Real y(stateSelect=StateSelect.always)=2*x; + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(y)=u-y; + end when; + end DiscretizedIncorrect3; + model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give desired result for y" + model DiscretizedWithReinitOther "Using normal reinit instead, different result for y" + input Real u; + Real x(stateSelect=StateSelect.always); + Real y=2*x; + equation + der(y)=u-y; + when Clock() then + reinit(x,u); + end when; + end DiscretizedWithReinitOther; + DiscretizedWithReinitOther discretized3(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); + + extends TrivialDemonstration; + end DiscretizedIncorrect4; + end ErrorExamples; annotation (uses(Modelica(version="4.0.0"))); end TestSettingStates; From e0cda4511f86b4be350aaee753a958f379389705 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:34:37 +0100 Subject: [PATCH 09/55] ChangedSampling --- RationaleMCP/0036/TestSettingStates.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index 67c2056fd..bd1b79cfd 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -21,7 +21,7 @@ package TestSettingStates annotation (Documentation(info="

The result of this model will be similar to:

-when sample(1e-3) then
+when sample(1e-1) then
  /* without state reset */ 
  discretized1.u=time;
  discretized1.x=discretized1.x+...; // Euler discretization

From 8acbf0013a4572ba777c435e6e27742d32a0b578 Mon Sep 17 00:00:00 2001
From: OLSSON Hans 
Date: Mon, 14 Feb 2022 14:38:42 +0100
Subject: [PATCH 10/55] AddArrayExample

---
 RationaleMCP/0036/TestSettingStates.mo | 40 ++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo
index bd1b79cfd..13fa0675b 100644
--- a/RationaleMCP/0036/TestSettingStates.mo
+++ b/RationaleMCP/0036/TestSettingStates.mo
@@ -40,6 +40,46 @@ end when;
 

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

")); end TrivialDemonstration; + model TrialArrayDemonstration + model DiscretizedWithReinit + input Real u[:]; + Real x[size(u,1)]=reinit(u); + Real y[:]=2*x; + equation + der(y)=u-y; + end DiscretizedWithReinit; + + model Discretized + input Real u[:]; + Real x[size(u,1)](each stateSelect=StateSelect.always); + Real y[:]=2*x; + equation + der(y)=u-y; + end Discretized; + Discretized discretized1(u={sample(time, Clock(Clock(1, 10), "ExplicitEuler"))}); + DiscretizedWithReinit discretized2(u={sample(time, Clock(Clock(1, 10), "ExplicitEuler"))}); + annotation (Documentation(info=" +

The result of this model will be similar to:

+
+when sample(1e-1) then
+ /* without state reset */ 
+ discretized1.u[1]=time;
+ discretized1.x[1]=discretized1.x[1]+...; // Euler discretization
+ discretized1.y[1]=2*discretized1.x[1];
+ discretized1.der_y[1]=time-discretized1.y[1];
+ discretized1.der_x[1]=0.5*discretized1.der_y[1];
+ 
+ /* with state reset */ 
+ discretized2.u[1]=time;
+ discretized2.x[1]=time; // Just using input!
+ discretized2.y[1]=2*discretized2.x[1];
+ discretized2.der_y[1]=time-discretized2.y[1];
+ discretized2.der_x[1]=0.5*discretized2.der_y[1];
+end when;
+
+

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

+")); + end TrialArrayDemonstration; package System model FeedforwardControl From 7bfd4f0cd2326df99a0faed498ea709aaaad243d Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:49:16 +0100 Subject: [PATCH 11/55] ExplainNewExamples --- RationaleMCP/0036/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index c914eafa8..3ebee98b2 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -16,6 +16,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2020-07-08 | Hans Olsson. Updated with reinit. | | 2020-09-25 | Hans Olsson. Updated with new semantics. | | 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | +| 2022-02-14 | Hans Olsson. More test-cases. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -97,8 +98,9 @@ This is not ideal as it uses words like "treated as", and variables are changed ## Discretization method semantics The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and only as the entire declaration equation for a variable. +The variable must be a scalar or array variable that is a subtype of Real. -The meaning is that +The meaning of Real x=reinit(xs); is that 1. StateSelect.always is set for the variable x. 2. Therefore it is a state and thus participate in the usual index reduction and state selection. 3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method @@ -125,7 +127,7 @@ However, as noted in the paper the procedure for using it is still slightly mess - Have parameters for those integrators etc. That could be automated in tools. -(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that will be corrected in the next release.) +(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that was corrected in Dymola 2022x.) ## Test-cases The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. From 1ebcf63f6fc9230578fbb7bba2211e6094f9e230 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 15:06:08 +0100 Subject: [PATCH 12/55] ExplainMore --- RationaleMCP/0036/TestSettingStates.mo | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index 13fa0675b..d402803a6 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -639,8 +639,16 @@ Connector with one input signal of type Real. der(y)=u-y; end when; end DiscretizedIncorrect3; - model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give desired result for y" + model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give the desired result for y" model DiscretizedWithReinitOther "Using normal reinit instead, different result for y" + /* + Specifically the normal reinit semantics imply that x will be updated at the end of the step. + The clocked semantics normally only evaluate y once per step. + Combined this means one step delay in y. + There are also additional minor changes related to der(y) and using y during the calculation. + + (And normally reinit would be in a non-clocked when.) + */ input Real u; Real x(stateSelect=StateSelect.always); Real y=2*x; From d518549b83568bd16867eb1aa0ef05129f20d0d2 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 22 Apr 2020 12:39:51 +0200 Subject: [PATCH 13/55] Create README.md --- RationaleMCP/0036/README.md | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 RationaleMCP/0036/README.md diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md new file mode 100644 index 000000000..abca313ea --- /dev/null +++ b/RationaleMCP/0036/README.md @@ -0,0 +1,47 @@ +Modelica Change Proposal MCP-0036 +Setting states +Hans Olsson +(In Development) +-- + +# Summary +The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), +and we need to update those states in the model within the modle based on more accurate measurements of during the simulation, +and have the state-updating as part of the model (and not as some tool-specific solution). + +# Revisions +| Date | Description | +| --- | --- | +| 2020-04-22 | Hans Olsson. Created. | + +# Contributor License Agreement +All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". + +# Rationale +See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 +and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf + +This is still work in progress as the main challenge is figuring out a specific syntax. + +The alternatives considered are: + - stateSelect.Measurement and binding equation + - replace "reinit" by "measurement"-operator, or forceState(…) + - possibly reinit within a Clock – check if possible + - the implemented annotation does not seem like a good idea + +# Backwards Compatibility +Will depend on exact syntax. + +# Tool Implementation +The preliminary variant with annotation has been implemented in Dymola. + +## Experience with Prototype +The implementation effort was small and it works. +However, as noted in the paper the procedure for using it is still slightly messy. + - Attempt to translate the model + - For each input add appropriate number of integrators and the state-update-component + - Have parameters for those integrators etc. + +# Required Patents +At best of your knowledge state any patents that would be required for implementation of this proposal. +# References From 8a1679eb78dc741164349a3aa1d7900738cb003b Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 8 Jul 2020 11:58:20 +0200 Subject: [PATCH 14/55] Update README.md Add discussion about reinit and correct spelling error. --- RationaleMCP/0036/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index abca313ea..69aea4514 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -6,13 +6,14 @@ Hans Olsson # Summary The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), -and we need to update those states in the model within the modle based on more accurate measurements of during the simulation, +and we need to update those states in the model within the model based on more accurate measurements of during the simulation, and have the state-updating as part of the model (and not as some tool-specific solution). # Revisions | Date | Description | | --- | --- | | 2020-04-22 | Hans Olsson. Created. | +| 2020-07-08 | Hans Olsson. Updated with reinit. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -25,10 +26,19 @@ This is still work in progress as the main challenge is figuring out a specific The alternatives considered are: - stateSelect.Measurement and binding equation - - replace "reinit" by "measurement"-operator, or forceState(…) - possibly reinit within a Clock – check if possible + - replace "reinit" by "measurement"-operator, or forceState(…) - the implemented annotation does not seem like a good idea +# Alternatives such as reinit +As discussed in https://github.com/modelica/ModelicaSpecification/issues/2285#issuecomment-641275627 the conclusion of +https://github.com/modelica/ModelicaSpecification/issues/578 was that all reinits are done at the end of the event iteration using previously computed values. + +Thus the current reinit(v, -v/2); does not lead to a loop with reinit, but first evaluates -v/2 (and other reinit-values) and then sets v (and other reinit-values). +One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the behaviour of a restricted set of continuous-time models; having two different variants of reinit (with same syntax but different semantics) is counter to that. +In addition the current reinit might possibly in the future be replaced by some form of impulses, indicating that the changes are physical and influence other parts of the system, this does not seem consistent with how states are set in this MCP. +Finally having a conditional setting of states is more complicated, and reinit and other similar operators naturally suggest that - and we either need to determine what it means or forbid it. + # Backwards Compatibility Will depend on exact syntax. From 6103335c68d7de67e0c39a325a01e2d6d318708d Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 15 Sep 2020 18:53:08 +0200 Subject: [PATCH 15/55] Update README.md (#2613) Add new proposal for setting states. --- RationaleMCP/0036/README.md | 49 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 69aea4514..ff4798f71 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -24,13 +24,27 @@ and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ This is still work in progress as the main challenge is figuring out a specific syntax. +# Alternatives The alternatives considered are: - stateSelect.Measurement and binding equation + - *special binding equation without stateSelect.Measurement* - possibly reinit within a Clock – check if possible - replace "reinit" by "measurement"-operator, or forceState(…) - the implemented annotation does not seem like a good idea -# Alternatives such as reinit +Ideally the proposal should allow us to hide this "turning a measurement into a state" in a block, and thus many of the details will be less important. + +## Annotation variant +The annotation variant was proposed in the paper (not good since it influences the semantics) and is: + +Real xs annotation(useAsInputForState=x); + +This means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). +What might seem as odd is that the annotation is associated with the measurement variable, not with the state-variable. +The reason is that this allows setting of states deeply nested in existing models (which can otherwise be solved with an extra variable), but +instead requires work-arounds for complicated measurement expressions as in Kalman filters. + +## Alternatives such as reinit(x, xnew) As discussed in https://github.com/modelica/ModelicaSpecification/issues/2285#issuecomment-641275627 the conclusion of https://github.com/modelica/ModelicaSpecification/issues/578 was that all reinits are done at the end of the event iteration using previously computed values. @@ -39,19 +53,46 @@ One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the b In addition the current reinit might possibly in the future be replaced by some form of impulses, indicating that the changes are physical and influence other parts of the system, this does not seem consistent with how states are set in this MCP. Finally having a conditional setting of states is more complicated, and reinit and other similar operators naturally suggest that - and we either need to determine what it means or forbid it. +## Proposed alternative +Use a special binding equation: + +Real x=measurement(xs); + +This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). + +The name of the operator can be discussed. The prototype re-used "reinit" to avoid introducing new reserved words. + +Key points: +- Associated with state, not measurement variable. +- Allows general expressions, not only variables. +- Unconditional. +- Only clocked. +- Few corner cases. +- Easy to recognize for humans and tools. +- Straightforward to implement. Adapting the existing prototype to the new syntax was straightforward. + +Remaining: +- Decide if the way to go +- Name of operator (measurement, reinit, ...) +- Figure out how it impacts equation count and write specification text (a few paragraphs) + # Backwards Compatibility -Will depend on exact syntax. +Will depend on exact syntax. +In the proposed alternative it will depend on the measurement keyword; if we use "reinit" it is fully backwards compatible. # Tool Implementation -The preliminary variant with annotation has been implemented in Dymola. +Both the preliminary variant with annotation and proposed alternative have been implemented in Dymola. ## Experience with Prototype -The implementation effort was small and it works. +The implementation effort was small and it works; both variants give the same results. + However, as noted in the paper the procedure for using it is still slightly messy. - Attempt to translate the model - For each input add appropriate number of integrators and the state-update-component - Have parameters for those integrators etc. +That could be automated in tools. # Required Patents At best of your knowledge state any patents that would be required for implementation of this proposal. # References +https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf From 799d76faa7f354f494abb6da0c947ddd48fc8a6a Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Fri, 25 Sep 2020 09:40:52 +0200 Subject: [PATCH 16/55] Update README.md Update with semantics discussion - based on https://github.com/modelica/ModelicaSpecification/pull/2613#discussion_r493489246 --- RationaleMCP/0036/README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index ff4798f71..7dcf8c270 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -14,6 +14,7 @@ and have the state-updating as part of the model (and not as some tool-specific | --- | --- | | 2020-04-22 | Hans Olsson. Created. | | 2020-07-08 | Hans Olsson. Updated with reinit. | +| 2020-09-25 | Hans Olsson. Updated with new semantics. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -58,7 +59,7 @@ Use a special binding equation: Real x=measurement(xs); -This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x). +This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and its meaning is discussed in the semantics part. The name of the operator can be discussed. The prototype re-used "reinit" to avoid introducing new reserved words. @@ -76,6 +77,34 @@ Remaining: - Name of operator (measurement, reinit, ...) - Figure out how it impacts equation count and write specification text (a few paragraphs) +# Semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and was originally defined as "means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x)", but that seems unclear. + +Thus we present an alternative below, + +## Original semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition". + +The meaning is that +1. StateSelect.always is defined for variable x. +2. It is treated as a state during the usual index reduction and state selection. +3. Afterwards x is deselected as state and the equation x = xs is added. Its derivative is set as a dummy derivative. + +This is not ideal as it uses words like "treated as", and variables are changed from being states to non-states. + +## Discretization method semantics +The operator is only legal in a "Clocked Discretized Continuous-Time Partition". + +The meaning is that +1. StateSelect.always is defined for variable x. +2. It is a state and thus participate in the usual index reduction and state selection. +3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method +https://specification.modelica.org/master/synchronous-language-elements.html#solver-methods + +This makes it clear that the variable is an actual state, just integrated differently. + +Step (3) requires that it is a state (guaranteed by (1)), and that it is a continuous variable in a "Clocked Discretized Continuous-Time Partition", as stated at the start. + # Backwards Compatibility Will depend on exact syntax. In the proposed alternative it will depend on the measurement keyword; if we use "reinit" it is fully backwards compatible. From e2450fb8338b44d7fe01827fdba944da8e1729e7 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:20:45 +0200 Subject: [PATCH 17/55] Add files via upload Test-cases. --- RationaleMCP/0036/BothControl.png | Bin 0 -> 11469 bytes RationaleMCP/0036/TestSettingStates.mo | 576 +++++++++++++++++++++++++ 2 files changed, 576 insertions(+) create mode 100644 RationaleMCP/0036/BothControl.png create mode 100644 RationaleMCP/0036/TestSettingStates.mo diff --git a/RationaleMCP/0036/BothControl.png b/RationaleMCP/0036/BothControl.png new file mode 100644 index 0000000000000000000000000000000000000000..caec8b8326a700e0431597514d8dc4bf8540f2ab GIT binary patch literal 11469 zcmb_?XIKMs#<&Pwf8FxHARYxOcx;tqELD$_ZWiC ztU?fx_4zZP#a`)g8~As@>7l+01W|q^{1L_RQ8Gi&HAqSBzP9Iw)rtF&V>&ep8}V<> z&gQRuCe2Zc*Mj|3FXQADCg4aiODCSp`h?wmo$a z5HNMLq&aJyA;>%u@RH&7dKg5jruIF>(6qQ30L6C#||A(XgOG-(rOFC2a!&-6DO5W=RMYNPGSm!S? zMNbT!l_Y+B`OBn-j@1)A+dX1dX(1XCyfTt?1zG7Fd~8WY85$EjeXz6OKQrI^1$Ssr z`&(q)K?FSz$EL4V(c|G-fnw(q(T#KZLIsKqcOICaHz zbd9_IrSB*WOD5mFQuyuRKq@X@x}Uha2kWZzWr`74bA01gkm-S42K~~uZYREowCo`> zWtQQ#+i##dxIyz&@bNFg8N!*wI^r#my^Ba1kfVq|$ThtlOY=5yj^-gn!t7M^&npo27;P3O=q4H8S5IcXe9 zF(qsygKYj{3}4fElw!8ZEj$JchVs}Q=)o@>@SFVh=cNNlh0AIWaKTp%8MqP(mpr^FC?;*_5i zsYS*61>ef8ua+F*ZIJtW)*Rn3K2ViaDt~ZtO>7XCkvgk)vua7-#fX+P_4k@S&sywq z{8fbxK^8HzP=Wbi)7S{sV{q)w?WB>w)qN6WM zFcY^DaqTNt=4(oS`WHk~+6p zhl-r&HJ@Bbl@1(nSdx##p(2F+7?rga4 zHbu|+qGTsl`2iXiMH%EN%tEE;9Ea1KQn%75Qww1b(6%4P2Y8&>w0?R}{|DF7_iw zyv->tX1wUZ*80$e?>jy{NfuuV*G_H47~V-X#Uy(!U}pPigdR!z(Bt3yoVVDWZuZ5@ z6q!8zZGJ_4**j&z#-n9tneMIb?-%?nnl;_y`se|xo1P1uq}iFBRGZqOI-d^f4SY26 zsL>y_sy}8D_YSsrt3_(u7jt^xuUJ&swYWw~8M?aa#kPA%(Z&(qNH(r2yI>5vT1JYY z(Xrp?!iKuTc_;BMvTJmtvQkB(qxV+Mp$F;*0~bBZM4k>KB}pKtoOTulK`908|JUQs zPFPtPJ6*wH?}zYfK5fILFM)^3*M5ZV54;oQ9K)eB_j0niBlKy3P<$plTiamc5(EXr z*>=E6h6n9X7DcBbTAsP#n}43tQABr;#0A;aVhxsY7Q>ch%6wOW!z=#bBOF-^Z z?EP>VRj$~UmKIC9;tX z{>7;;{#&~*li!?9ow6h}$j==-av7m28mygLaM)_}@IRa$DvGr58qTesCypN3GJN<5 zf`kjti7)i}|L)m7f@M#coPIn+?e2Npo|^P|?(F4_+WuuEN4XH&qh8d|dvEJ0oqi=} z?TR0)M-Y6e%ngGmk6-PS;xm-5 z8oYCRC=O^-zMVK1HiL0?ayFbw`h8pCp5vt7UKLx$TG@?wy?1V%SU134UZEEg@`VRk zq$E#G{12p)k0VbH0RS9Q35(CqN^k&kRdTFD|GvS(hS3A;?v)2#b8o)j58c?JsDOSb_nA{Z=qoX(VwqwnvzJ0D>eU zScJHxHoE8W9pUu1yCqiLGZ}Btn}mr#0cz~nISdbSpc`23bZy=c>s(k^m{@4XXY<_4 z_xT;ftZEh!RL&}%C9{?7kr zu{}A$1Lwsp&j~fTo-8fRZM1@Su9zg$!3y6&kTolKWN=wnO7f1bwX(XDN&{&$-S)Sn_$jzEh@jC|ELub37UgV7{)e;g!B?)S zC&H>O2t!bwU{QIcPvmWtM6ZpR){nu=tVu`%*R7dqmMPzllO#}zW&}2$UrKkf4ojbf z%%Vz%=icc}vQ)GN1G+Q|doQTj7SWl&Gg!ij8*;u3>>tb!iPLb`CK%sU$$jdUapq+x zpzb=>USMpWkKIx`tN(SP+-*U~^fW>D6BfKsk*c>RN5%h#ADMG2G1NFIcvUNS`!WvB z97o^{S>d*iC2-$euR{Uo8`$sHR^wpYorn0Hz2xVcN`vzHFNE+!koyZ3tw`a{jO=%2 z+FY$(fke>V2k2Z?CJVV2ni%l@3nH|Vw8Ls+5D~s! z-px5G;=|wtqB3Y4n_6_$Wg%54pdt$C&V#7u_`vSyOWq9-i5pE+=-Wk-1$AaJ)@fMu# z#H-n(@fgahFHT~o-6Ep(?4&lmh4RY3g4F;PnlM5>941H%N$FzU*pUVDapR7URWdj} zPhP>MDQF67v!?-?VdP?XaZ#TuR*AyxS#}$fTKyMEe^(Cn#Yi+)Y{!U+|Ek!xp`oFq zuF(Vvk+7SyI4$vdK6b|>DTjO#vQdpt(8y{rsu4V@`QN8{S_*YP+hK*D-ah3JQce%m zgsU_-Az0g2cUe)-k55 zorH@bWhq=N62!A+YY&s{OP}d(*OENyEKdE$!KX6^!Mdf~=~jX6abU&H)L@L#dz*3O zF@!ilIbL{2p>i>vOwb_`%?K@J8yq}GWHw*xd-}MmeBMKuA|02OVV&`njk{l?2g}Hc z-HOD&99OoVKBMAhDnbKoEAxvhP^6dK-DJUTJdlRlnhlWz80V%-E69CiTRbrMF4%derrRNLIVv!$JNc(aiTe2=3{Q(W4di-tgwxvi znL8eU@7~EVwp+mA)g@xcR|aikT&TIQx%~o{$XVAVj-r#Meh?n~cpqJ&R;fwY-Bi-dgIk8T zB`l#7p>|m1Y|Od458e_5P+r68Svjx9ggxKhzq3B|<+vr!_nlXK-Q2Fcz7$t*`9f6TS?wi#XWQM5ie7a+=x z)#D%GaXDEEdqlT#g)l0CIfgvi-J^QXjUY`7;!h`mEXdkc9+&lvbLsHfHWnJF{ET>( zuQkymRiZypqu*Qt9S^xcx4>$k&51+JMX2%dTtekc%sB`mylt+lYbD;O)HFE(c?Kej zMjEUGzhUNXLnYQk4(Wxl403@Li?WOF<|Io%{9sN4jUg<9@UCw>Eh__)efwn4?lo+= z`t&BJ%YA#Ugk5~_)JY-!GL*934nss4UwVHb%h!8r<)(`Y)OQP|V#xnZfN`qsc~?&N zWS;;r)WeP~e`1#24Sc)*PB;})Zgy1|9O}Dp)hB^b7< z88F;#1k2#F5WDy_sd`V~Wp_=;KbLbrD~#eX|z;0CXXXWh7%PR^uQOAf7E5zo5&4&mL=EdXo!e*T9AWSZR$ z`&jz36ckQ+2#t)Ns$+^Xkb-Jp1NG?}*stAGLh>h0_FRJ6ymGhIWm< z{eQvQT=P=VyyIhKVX%Z$^p{jPc=Al9F$wPp5Ys)neC;>!l<=mmD(v zG?!)E8FAV;%A&9+FZ&0A{Q zK_sGWt=)wMOLlC%5`OE$t*lPjVxKN=KXLIS2e6hkpA2jrc5o;ES@s`X@^Nw**{dUOo#gvk`BSZB7J~vDy?`Fia|UL>QDoin6v!6 zekmo{*neH@+sDBdEXacQ^u6=H3;TqLQ;HZO1KVRN9>r8&6HSK?gDq||$O*|H+hLdV zhj>~z$qWL;xgaSybd$EyTeH>2d|bpnii2^Z z*&X+mo7%wk?Rye|HI+3gg`hq$6uFL}XcGrJuqN5Z21p{*i_;#B%N&N$s1RN?cs7NZ zA+pJKUaA2-JMQzmY2|S^z(9g0$jOlGJldxM*qMu9h$QNxm}Ahc@ZP^H)c^$?vtv_4 z0dW9N^t;mPQPHSC25(q`cRoD#(*Ha`-r>{{Gz_bQXD~wi^5`b-Z)~h_dq=O&)5qA; z3z$GDb>Qp9Iv>#q@(wD1*|ffaA{Q+|aaKBASArVXqLIa^oAZx=AFE3+J=4cN$FOp- z>=D0w5qSXJb*w2LpH;lrkRx+R*aaCwCtptcR^iSolywO_u^g|$qL2nJD@~w+Mo;p} zCz*@7VneqfQ_^nY1t9oG073b)U>zrxcJ%JdaYIL*JAZcGTm z3zT7&?lwFGkO@nh-tNNt7Us3+snEf*Rl89CU}{W7O)>CK-<`Y+b}8`t8*25Ery%H~ z#+lk@@zr2#5} zNdf6GCyt&C@iV96#y1Kb*Pe)Nw&*K5rl_cQkGGL-zHl3v&>q<0`|z{Mkg#FGY6@xa zkuJXcwhWw@_bo@n7w@F`C<}04{DP~^Le1NS`7PAmVpV7Yq-JZ*j#l$>$HBr&_6+H5 z+rXY)F+t42WH2!s3FV7>fSU+(Wjbw}jY(oa@=lijpK7Ju&^sZN~gWv5iYrP#Ftw~mLXz4nNJh2L%a?AMh zUjWnGP3Yax?u?LOnl#C3RNaS+urJSXuJ?0@SK(0QS5NX=kDY^*vUh2s||S~G_Ckq2M1B5nQ0a? zm^+Pg;v_nT%gyJ?yIe053qi`Dr`ie~!3*ID5-$N_bAoRRtVknIhfg5W$Zbd(*+GwH z1$KfL(%~Onwr0cu38jlh_OV6)8Z#Az?1OK223+8RZlcHyEX#};2UOyL1+M|jI5bL1 zA^_Yb1y^T=4S_m?czgFT)9%;uE&#>gQDs0ab{rhCw6yhWknj1gP;e>CngAklC4u6%zG9c+1HpK+B zT(ZtGZmQ(Y?OZ6C!VMlw*}TA|pMZS&pG{Oi=$meg81V@-{sVfisfa2~y)A|v;;9q; zYs1itDPthkl=wvgSBv3zb=22o8CQKb*7^!n*512&XGed`D=PrI1c-<=5A%oZ*=Q9RC!uu_+w>k-Iv=qX%Mq5)lS9XXxIh+tzvxK>Jj6w%xuW#$%SUh`Leta}{83z5ASTlPmMCy~;30(5 z_INYOrzS+a0vKctPSmbUer{6wxCLy%M9cHS1#O<>#ddQHDVEEHJpxKX<=>pb`I`JiPYcDjnk?K5dlSw$enXF0f(|zu>Od@m`1K~7mU@VqFcD*!E!exZ|k>A zR-v;@DRgrTrfjw!Y&tVBY{qqYwR$VWNFf=*|C9h}`ZI%HPQOE$UC*aCO8!n$FE*iUsLj27?>`jU17#c6qjtDD-3^QU{Z^T-P?WxpW zvLN^i$k1MJ@GVD2fninWAo*gF4ePKa@lZ4psx`Mt{A8Y(mzNjUBJ|i5$3MZ5Ttt?ftv}u!E1?Kaemb?H#? z@C6g!cQY%{vWq&AH&__QC*gavwO5**i911<66f1IkOnLCS?5P}$ATwnv{oO@hgolJ zkyVQi8J9gXmOTBds^LaY3ilsB@O;55(D;iM>Ew!#^Cf|2UC&4~%37%tdvu-^#n}v4 zCK~1APF7Q11KGGV>w=W#zry!>u`h^kZ>NJiHV0E{u+0EqyjZ;A{Af`+CB!*EowzM2 z%uF?q-z{7nPZMgJ*r-Bt0MaY}i0(g-!Oa*BT2e1lQ-gH80hS%GK!Tb{T3qiM)%Lu4 zSw+htCseQOF8HLEV3tcUa)dbF{aFW_m4acjpzstE;L2qfPRqCe%S;+|W>?bek@3O= z8}km09-wmKRAftY>8*NYb;UXP`13B3s->j0M^tzF!qiEVKn`438~2`F;@8#oSiI~- zY0{#?!b<+jjS|3%s5mA|OME(MG^~1N(O|U4w%!pR5Bz-h)I!&3U>s4zdGE#H0z;9rk@@C6{SR|BT_^CUWBInx_?f%iz8GW77w^~OKr4MR$jR}F zpoz-<@kCK8B@sZJUI22HepTqIv{U`@#v8AR?R7{0=ds6HnGtm*si7Gt#v(u8qn{(# zp5bCU(YI!@6t6@qzMuGe|B*LU2meF@BRv#t1kDAmc2Us=DsP?{AFSaQ>3FWI+NzW@ zKCrgpWjBE18MN90nx4wTf>sq#5yZLTI0FUiKf33M2EI(=u%)_H5fqC=-%T=!5x#Sn zG3)t*i@Xtq8$4?@f-*_ckw|rfOFt-Mu!ylG{uVy1Ah#xU(lw9A67m2dsbGCS>=paq zYZ|w>o?7k}Y98zkH0~TT;bHV*gxq(Y*UzbGOtu9XYpqi0`h%Av`TRdb96Mj}NfLrn zB}*=!AU zw&2uUQt?4v)dTmBqJbpC>{w_tkGG@kY*-9;?$u|?_5PUVFyx7GgcyEmp%6^A_rTV))xd3lkT4vm5rQ}##M$F+I3MDI3mPm>6GE@M! zZ|l$bRi+l9VxV&byg_+!`dkPxD%C$)kmoeBnBQEl2vRG|XjRG^pTbpX!Mn?z9eC~k zoEY1i98LDG3G^j^&4Ba#x@tFk1T7e!i@9wPPZ3sG%Ew0`rkFH@dW4jTCD8P*&_3x8RIz{Ujdcj`OK+pw=s#>p&@gpT-Rc~T~gMd<02R0an9c4kL9TL4CIea|{=deiE?}|-36~3%hX+`z%!zbZS`mJ(yyy^!?U?)ZtIuAarA$d(DxwECc4#!VwY~JS z=<6+9ehBDFCKeTK0qg1W(js&m;D%Z(>zL>|(tb_2)}@`CY_NL_5*kEM3faZQ?9z*h z&dT)-w1ob*A58P8J$n?Fk9@)n2cv^jo^(h&k%;c9`W^-zhK6+}Uwv^6pZ#vw*89^} z0#q^7-)5M!M|D(6g{XEvy$v%RF_11j|zc>&G-&pIqQza@*b*I{A*@Oi{EhMjDL zx&{M&ajxMXd%o1vZd1BuV)4q&g4>|tgq_`1Y`X%jD@CXa2>O>+?Vi@o#*Osfm1hW5 zuFfM=6=>XNU5*1P^^@QCSUrP1ue^zS_<8%fnkKi)v;q+ITnKv1lZPO5V+7S=a3Pg0 zHc*rCEPPfhoO!Q1l}K8U;*qptwjxqADvW%p-s}kf9b5J+0m} zkWuODq_N7HiJIzWjMCn8mw%0jeo8paEnIs|_a(1z?SP_~@A1m(E4A#cg%3*zr`oz6 z@^_|aA!v!Xun4^12Vq|See7Idp&`^TvS5v_*EYERC63_>+Cx<>H43du)N&tG@}WqZ zckbb*rlZGbM-JH!D{JfdhQ*+RYQDnt<$md?W<>u^uezN}1m%~&2#|tdm)@pB_nh=K z1$Xaz98??rDT4zx1Z8rA{%%rZw9}24yVQd__c~VI`mMws6-GJzg*O8?z}*$8yiuOo z(uBUVym$BYKl6G2+Q;bGu7pdA-bs&EcHC1He%!fNH06KWIF0e|TKjy~7vhKN5@r(>jnAlex(LFdXTc+h*tbWlw z1W1cB++YQ<7^RWJD$>ht#H#CMQ=eBN)n8q_ zr&(zDxn!$0ZHB0?3(-H-+uNF+MwOgQu`{24<;~lKg^b-h*Bx%w5_?x07EYDpw}c&Q z{cG9%uidK0Pp-u7S9wg7dQJ?C?jTCqi28aFFb@xtd(vbc@>KVv3wmHmF`~B+dj@-2 zYl6%3&#Ippch#>Zt-c=jSKWg1!GV1@+3N5cn&l-e85`{yZfOi&)Bwbr920I?w@c{RDh2c|*)0a!iMu>b%7 literal 0 HcmV?d00001 diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo new file mode 100644 index 000000000..b81ae8507 --- /dev/null +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -0,0 +1,576 @@ +within ; +package TestSettingStates + model TrivialDemonstration + model DiscretizedWithReinit + input Real u; + Real x=reinit(u); + Real y=2*x; + equation + der(y)=u-y; + end DiscretizedWithReinit; + + model Discretized + input Real u; + Real x(stateSelect=StateSelect.always); + Real y=2*x; + equation + der(y)=u-y; + end Discretized; + Discretized discretized1(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + annotation (Documentation(info=" +

The result of this model will be similar to:

+
+when sample(1e-3) then
+ /* without state reset */ 
+ discretized1.u=time;
+ discretized1.x=discretized1.x+...; // Euler discretization
+ discretized1.y=2*discretized1.x;
+ discretized1.der_y=time-discretized1.y;
+ discretized1.der_x=0.5*discretized1.der_y;
+ 
+ /* with state reset */ 
+ discretized2.u=time;
+ discretized2.x=time; // Just using input!
+ discretized2.y=2*discretized2.x;
+ discretized2.der_y=time-discretized2.y;
+ discretized2.der_x=0.5*discretized2.der_y;
+end when;
+
+

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

+")); + end TrivialDemonstration; + + package System + model FeedforwardControl + extends Modelica.Clocked.Examples.Systems.ControlledMixingUnit(pro=1.1); + annotation (Documentation(info=" +

An example from Modelica Standard Library, but changed to have same difference between plant and plant in controller for easier comparison.

+

This does not need the possibility for setting states due to using a different controller.

+")); + end FeedforwardControl; + + model FeedbackControl + "Simple example of a mixing unit where a (discretized) nonlinear inverse plant model is used as feedback linearization controller" + extends Modelica.Icons.Example; + + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration"; + parameter Modelica.Units.SI.Temperature T0=308.5 "Nominal temperature"; + parameter Real a1_inv = 0.2674 "Process parameter of inverse plant model (see references in help)"; + parameter Real a21_inv = 1.815 "Process parameter of inverse plant model (see references in help)"; + parameter Real a22_inv = 0.4682 "Process parameter of inverse plant model (see references in help)"; + parameter Real b_inv = 1.5476 "Process parameter of inverse plant model (see references in help)"; + parameter Real k0_inv = 1.05e14 "Process parameter of inverse plant model (see references in help)"; + parameter Real eps = 34.2894 "Process parameter (see references in help)"; + parameter Real x10 = 0.42 "Relative offset between nominal concentration and initial concentration"; + parameter Real x20 = 0.01 "Relative offset between nominal temperature and initial temperature"; + parameter Real u0 = -0.0224 "Relative offset between initial cooling temperature and nominal temperature"; + final parameter Real c_start(unit="mol/l") = c0*(1-x10) "Initial concentration"; + final parameter Modelica.Units.SI.Temperature T_start=T0*(1 + x20) + "Initial temperature"; + final parameter Real c_high_start(unit="mol/l") = c0*(1-0.72) "Reference concentration"; + final parameter Real T_c_start = T0*(1+u0) "Initial cooling temperature"; + parameter Real pro=1.1 "Deviations of plant to inverse plant parameters"; + final parameter Real a1=a1_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a21=a21_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a22=a22_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real b=b_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real k0=k0_inv*pro "Process parameter of plant model (see references in help)"; + + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit invMixingUnit( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-10},{-10,10}}, origin={2,26}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints + annotation (Placement(transformation(extent={{-26,-16},{26,16}}, origin={0,28}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit mixingUnit( + c(start=c_start, fixed=true), + T(start=T_start, fixed=true), + c0=c0, + T0=T0, + a1=a1, + a21=a21, + a22=a22, + b=b, + k0=k0, + eps=eps) annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={86,-16}))); + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.CriticalDamping + filter( + n=3, + f=freq, + x(start={0.49,0.49,0.49}, fixed={true,false,false})) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-78,30}))); + Modelica.Clocked.RealSignals.Sampler.Hold hold1(y_start=300) + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={62,-16}))); + Modelica.Clocked.ClockSignals.Clocks.PeriodicRealClock periodicClock1( + useSolver=true, + period=1, + solverMethod="Rosenbrock2") + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-130,-22}))); + Modelica.Blocks.Sources.Step step(height=c_high_start - c_start, offset= + c_start, + startTime=0) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-130,30}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample2 + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-106,30}))); + Modelica.Clocked.RealSignals.Sampler.Sample sample_c + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={78,68}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample_T + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={70,-44}))); + Utilities.InputToState inputToState annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={8,-4}))); + Utilities.InputToState inputToState1 annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={-6,56}))); + Utilities.FeedbackController controller( + freq=freq) annotation (Placement(transformation(rotation=0, extent={{-58,20},{-38, + 40}}))); + equation + connect(inverseBlockConstraints.y2, invMixingUnit.T_c) annotation (Line( + points={{22.1,28},{22.1,26},{14,26}}, + color={0,0,127})); + connect(invMixingUnit.c, inverseBlockConstraints.u2) annotation (Line( + points={{-10,32},{-20,32},{-20,28},{-20.8,28}}, + color={0,0,127})); + connect(hold1.y, mixingUnit.T_c) annotation (Line( + points={{68.6,-16},{70,-16},{70,-18},{72,-18},{72,-16},{74,-16}}, + color={0,0,127})); + connect(sample2.u,step. y) annotation (Line( + points={{-113.2,30},{-119,30}}, + color={0,0,127})); + connect(filter.u, sample2.y) annotation (Line( + points={{-90,30},{-99.4,30}}, + color={0,0,127})); + connect(periodicClock1.y, sample2.clock) annotation (Line( + points={{-123.4,-22},{-106,-22},{-106,22.8}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + connect(hold1.u, inverseBlockConstraints.y1) annotation (Line(points={{54.8,-16}, + {36,-16},{36,28},{27.3,28}}, color={0,0,127})); + connect(mixingUnit.c, sample_c.u) annotation (Line(points={{98,-10},{104,-10}, + {104,68},{85.2,68}},color={0,0,127})); + connect(sample_T.u, mixingUnit.T) annotation (Line(points={{77.2,-44},{104,-44}, + {104,-22},{98,-22}}, color={0,0,127})); + connect(sample_T.clock, periodicClock1.y) annotation (Line( + points={{70,-51.2},{78,-51.2},{78,-72},{-126,-72},{-126,-22},{-123.4,-22}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + + connect(sample_T.y, inputToState.measurement) annotation (Line(points={{63.4,-44}, + {26,-44},{26,-4},{18,-4}}, color={0,0,127})); + connect(inputToState.stateToSet, invMixingUnit.T) annotation (Line(points={{-2,-4}, + {-10,-4},{-10,20}}, color={0,0,127})); + connect(inputToState1.measurement, sample_c.y) annotation (Line(points={{4,56},{ + 62,56},{62,68},{71.4,68}}, color={0,0,127})); + connect(controller.y, inverseBlockConstraints.u1) annotation (Line( + points={{-38,28},{-28.6,28}}, color={0,0,127})); + connect(filter.y,controller.u1) + annotation (Line(points={{-67,30},{-58,30}}, + color={0,0,127})); + connect(controller.u2, + sample_c.y) + annotation (Line(points={{-56,40},{-56,72},{62,72},{62,68},{71.4,68}}, + color={0,0,127})); + connect(inputToState1.stateToSet, inverseBlockConstraints.u2) annotation ( + Line(points={{-16,56},{-28,56},{-28,28},{-20.8,28}}, + color={0,0,127})); + annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-140, + -100},{120,100}}), graphics={Rectangle(extent={{-96,70},{40,-18}}, + lineColor={255,0,0}), Text( + extent={{-84,-4},{-38,-12}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="feedback linearization")}), + experiment(StopTime=300), + Documentation(info=" +

This demonstrates using feedback linearization to improve the control of the plant.

+")); + end FeedbackControl; + + model BothControl + "Simple example of a mixing unit where a (discretized) nonlinear inverse plant model is used as feedback linearization controller and another inverse model as feedforward control" + extends Modelica.Icons.Example; + + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration"; + parameter Modelica.Units.SI.Temperature T0=308.5 "Nominal temperature"; + parameter Real a1_inv = 0.2674 "Process parameter of inverse plant model (see references in help)"; + parameter Real a21_inv = 1.815 "Process parameter of inverse plant model (see references in help)"; + parameter Real a22_inv = 0.4682 "Process parameter of inverse plant model (see references in help)"; + parameter Real b_inv = 1.5476 "Process parameter of inverse plant model (see references in help)"; + parameter Real k0_inv = 1.05e14 "Process parameter of inverse plant model (see references in help)"; + parameter Real eps = 34.2894 "Process parameter (see references in help)"; + parameter Real x10 = 0.42 "Relative offset between nominal concentration and initial concentration"; + parameter Real x20 = 0.01 "Relative offset between nominal temperature and initial temperature"; + parameter Real u0 = -0.0224 "Relative offset between initial cooling temperature and nominal temperature"; + final parameter Real c_start(unit="mol/l") = c0*(1-x10) "Initial concentration"; + final parameter Modelica.Units.SI.Temperature T_start=T0*(1 + x20) + "Initial temperature"; + final parameter Real c_high_start(unit="mol/l") = c0*(1-0.72) "Reference concentration"; + final parameter Real T_c_start = T0*(1+u0) "Initial cooling temperature"; + parameter Real pro=1.1 "Deviations of plant to inverse plant parameters"; + final parameter Real a1=a1_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a21=a21_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real a22=a22_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real b=b_inv*pro "Process parameter of plant model (see references in help)"; + final parameter Real k0=k0_inv*pro "Process parameter of plant model (see references in help)"; + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit invMixingUnit( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-10},{-10,10}}, origin={2,26}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints + annotation (Placement(transformation(extent={{-26,-16},{26,16}}, origin={0,28}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit mixingUnit( + c(start=c_start, fixed=true), + T(start=T_start, fixed=true), + c0=c0, + T0=T0, + a1=a1, + a21=a21, + a22=a22, + b=b, + k0=k0, + eps=eps) annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={86,-16}))); + + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.CriticalDamping + filter( + n=3, + f=freq, + x(start={0.49,0.49,0.49}, fixed={true,false,false})) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-78,30}))); + Modelica.Clocked.RealSignals.Sampler.Hold hold1(y_start=300) + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={62,-16}))); + Modelica.Clocked.ClockSignals.Clocks.PeriodicRealClock periodicClock1( + useSolver=true, + period=1, + solverMethod="Rosenbrock2") + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-130,-22}))); + Modelica.Blocks.Sources.Step step(height=c_high_start - c_start, offset= + c_start, + startTime=0) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-130,30}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample2 + annotation (Placement(transformation(extent={{-6,-6},{6,6}}, origin={-106,30}))); + Modelica.Clocked.RealSignals.Sampler.Sample sample_c + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={78,68}))); + Modelica.Clocked.RealSignals.Sampler.SampleClocked sample_T + annotation (Placement(transformation(extent={{6,-6},{-6,6}}, origin={70,-44}))); + Utilities.InputToState inputToState annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={8,-4}))); + Utilities.InputToState inputToState1 annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, origin={-6,56}))); + Utilities.FeedbackController controller( + freq=freq) annotation (Placement(transformation(rotation=0, extent={{-58,20},{-38, + 40}}))); + Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit.MixingUnit + invMixingUnit1( + c0=c0, + T0=T0, + a1=a1_inv, + a21=a21_inv, + a22=a22_inv, + b=b_inv, + k0=k0_inv, + eps=eps, + c(start=c_start, fixed=true), + T(start=T_start, + fixed=true, + stateSelect=StateSelect.always), + T_c(start=T_c_start)) + annotation (Placement(transformation(extent={{10,-48},{-10,-28}}))); + Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints1 + annotation (Placement(transformation(extent={{-32,-52},{20,-20}}))); + Modelica.Blocks.Math.Gain gain(k=20) annotation (Placement(transformation( + extent={{28,-68},{48,-48}}))); + Modelica.Blocks.Math.Feedback feedback + annotation (Placement(transformation(extent={{-8,-80},{12,-60}}))); + Modelica.Blocks.Math.Add add + annotation (Placement(transformation(extent={{46,14},{66,34}}))); + equation + connect(inverseBlockConstraints.y2, invMixingUnit.T_c) annotation (Line( + points={{22.1,28},{22.1,26},{14,26}}, + color={0,0,127})); + connect(invMixingUnit.c, inverseBlockConstraints.u2) annotation (Line( + points={{-10,32},{-20,32},{-20,28},{-20.8,28}}, + color={0,0,127})); + connect(hold1.y, mixingUnit.T_c) annotation (Line( + points={{68.6,-16},{70,-16},{70,-18},{72,-18},{72,-16},{74,-16}}, + color={0,0,127})); + connect(sample2.u,step. y) annotation (Line( + points={{-113.2,30},{-119,30}}, + color={0,0,127})); + connect(filter.u, sample2.y) annotation (Line( + points={{-90,30},{-99.4,30}}, + color={0,0,127})); + connect(periodicClock1.y, sample2.clock) annotation (Line( + points={{-123.4,-22},{-106,-22},{-106,22.8}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + connect(mixingUnit.c, sample_c.u) annotation (Line(points={{98,-10},{104,-10}, + {104,68},{85.2,68}},color={0,0,127})); + connect(sample_T.u, mixingUnit.T) annotation (Line(points={{77.2,-44},{104,-44}, + {104,-22},{98,-22}}, color={0,0,127})); + connect(sample_T.clock, periodicClock1.y) annotation (Line( + points={{70,-51.2},{78,-51.2},{78,-72},{-126,-72},{-126,-22},{-123.4,-22}}, + color={175,175,175}, + pattern=LinePattern.Dot, + thickness=0.5)); + + connect(sample_T.y, inputToState.measurement) annotation (Line(points={{63.4,-44}, + {28,-44},{28,-4},{18,-4}}, color={0,0,127})); + connect(inputToState.stateToSet, invMixingUnit.T) annotation (Line(points={{-2,-4}, + {-10,-4},{-10,20}}, color={0,0,127})); + connect(inputToState1.measurement, sample_c.y) annotation (Line(points={{4,56},{ + 62,56},{62,68},{71.4,68}}, color={0,0,127})); + connect(controller.y, inverseBlockConstraints.u1) annotation (Line( + points={{-38,28},{-28.6,28}}, color={0,0,127})); + connect(filter.y,controller.u1) + annotation (Line(points={{-67,30},{-58,30}}, + color={0,0,127})); + connect(controller.u2, + sample_c.y) + annotation (Line(points={{-56,40},{-56,72},{62,72},{62,68},{71.4,68}}, + color={0,0,127})); + connect(inputToState1.stateToSet, inverseBlockConstraints.u2) annotation ( + Line(points={{-16,56},{-28,56},{-28,28},{-20.8,28}}, + color={0,0,127})); + connect(invMixingUnit1.T, feedback.u1) + annotation (Line(points={{-12,-44},{-12,-70},{-6,-70}}, color={0,0,127})); + connect(feedback.y,gain. u) annotation (Line(points={{11,-70},{20,-70},{20,-58}, + {26,-58}}, + color={0,0,127})); + connect(invMixingUnit1.c, inverseBlockConstraints1.u2) annotation (Line( + points={{-12,-32},{-22,-32},{-22,-36},{-26.8,-36}}, color={0,0,127})); + connect(filter.y, inverseBlockConstraints1.u1) annotation (Line(points={{-67,30}, + {-62,30},{-62,-36},{-34.6,-36}}, color={0,0,127})); + connect(feedback.u2, inputToState.measurement) annotation (Line(points={{2,-78}, + {2,-90},{56,-90},{56,-44},{28,-44},{28,-4},{18,-4}}, color={0,0,127})); + connect(inverseBlockConstraints1.y2, invMixingUnit1.T_c) annotation (Line( + points={{16.1,-36},{14.05,-36},{14.05,-38},{12,-38}}, color={0,0,127})); + connect(inverseBlockConstraints.y1, add.u1) annotation (Line(points={{27.3,28}, + {38,28},{38,30},{44,30}}, color={0,0,127})); + connect(gain.y, add.u2) annotation (Line(points={{49,-58},{54,-58},{54,-26},{38, + -26},{38,18},{44,18}}, color={0,0,127})); + connect(add.y, hold1.u) annotation (Line(points={{67,24},{72,24},{72,-4},{48,-4}, + {48,-16},{54.8,-16}}, color={0,0,127})); + annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-140, + -100},{120,100}}), graphics={Rectangle(extent={{-96,70},{40,-18}}, + lineColor={255,0,0}), Text( + extent={{-82,-6},{-36,-14}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="feedback linearization"), + Rectangle(extent={{-36,-18},{62,-94}}, + lineColor={255,0,0}), Text( + extent={{-40,-82},{6,-90}}, + textColor={255,0,0}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid, + textString="controller")}), + experiment(StopTime=300), + Documentation(info=" +

This demonstrates using feedback linearization to improve the control of the plant.

+")); + end BothControl; + + package Utilities + model FeedbackController + Modelica.Blocks.Math.Feedback feedback annotation (Placement( + transformation(extent={{-10,10},{10,-10}}, origin={-64,0}))); + Modelica.Blocks.Math.Gain gain1(k=K0) annotation (Placement( + transformation(extent={{-10,-10},{10,10}}, origin={-30,0}))); + Modelica.Blocks.Math.Feedback feedback1 annotation (Placement( + transformation(extent={{-10,10},{10,-10}}, origin={2,0}))); + Modelica.Blocks.Math.Gain gain(k=K1) annotation (Placement( + transformation(extent={{10,-10},{-10,10}}, origin={26,30}))); + SimpleIntegrator simpleIntegrator1(initType=Modelica.Blocks.Types.Init.NoInit) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={32,0}))); + SimpleIntegrator simpleIntegrator(initType=Modelica.Blocks.Types.Init.NoInit) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + origin={72,0}))); + final parameter Real K0 = (2*pi*freq)^2; + final parameter Real K1 = 2*(2*pi*freq); + parameter Modelica.Units.SI.Frequency freq=1/300 + "Critical frequency of filter"; + constant Real pi = Modelica.Constants.pi; + Modelica.Blocks.Interfaces.RealInput u1 annotation (Placement( + transformation(rotation=0, extent={{-100,-10},{-80,10}}))); + Modelica.Blocks.Interfaces.RealInput u2 annotation (Placement( + transformation(rotation=0, extent={{-80,90},{-60,110}}))); + Modelica.Blocks.Interfaces.RealOutput y(start=simpleIntegrator.y_start) + annotation (Placement(transformation(rotation=0, extent={{100,-30},{ + 120,-10}}))); + equation + connect(simpleIntegrator1.y, simpleIntegrator.u) annotation (Line(points={{43,0},{ + 60,0}}, color={0,0,127})); + connect(feedback1.u2, gain.y) + annotation (Line(points={{2,8},{2,30},{15,30}}, color={0,0,127})); + connect(gain1.y, feedback1.u1) annotation (Line(points={{-19,0},{-6,0}}, + color={0,0,127})); + connect(feedback1.y, simpleIntegrator1.u) annotation (Line(points={{11,0},{ + 20,0}}, color={0,0, + 127})); + connect(simpleIntegrator1.y, gain.u) annotation (Line(points={{43,0},{ + 48,0},{48,30},{38,30}}, + color={0,0,127})); + connect(feedback.y, gain1.u) + annotation (Line(points={{-55,0},{-42,0}}, color={0,0,127})); + connect(u1, feedback.u1) + annotation (Line(points={{-90,0},{-72,0}}, color={0,0,127})); + connect(u2, feedback.u2) annotation (Line(points={{-70,100},{-70,14},{ + -64,14},{-64,8}}, color={0,0,127})); + connect(y, simpleIntegrator.y) annotation (Line(points={{110,-20},{88, + -20},{88,0},{83,0}}, color={0,0,127})); + annotation (Diagram(coordinateSystem(extent={{-90,-100},{110,100}})), + Icon(coordinateSystem(extent={{-90,-100},{110,100}}))); + end FeedbackController; + + block SimpleIntegrator + "Output the integral of the input signal with optional reset" + import Modelica.Blocks.Types.Init; + parameter Real k(unit="1")=1 "Integrator gain"; + /* InitialState is the default, because it was the default in Modelica 2.2 + and therefore this setting is backward compatible + */ + parameter Init initType=Init.InitialState + "Type of initialization (1: no init, 2: steady state, 3,4: initial output)" annotation(Evaluate=true, + Dialog(group="Initialization")); + parameter Real y_start=0 "Initial or guess value of output (= state)" + annotation (Dialog(group="Initialization")); + extends Modelica.Blocks.Interfaces.SISO(y(start=y_start)); + equation + der(y) = k*u; + annotation ( + Documentation(info=" +

+This blocks computes output y as +integral of the input u multiplied with +the gain k: +

+
+    k
+y = - u
+    s
+
+ +

+It might be difficult to initialize the integrator in steady state. +This is discussed in the description of package +Continuous. +

+ +

+If the reset port is enabled, then the output y is reset to set +or to y_start (if the set port is not enabled), whenever the reset +port has a rising edge. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100.0,-100.0},{100.0,100.0}}), + graphics={ + Line( + points={{-80.0,78.0},{-80.0,-90.0}}, + color={192,192,192}), + Polygon( + lineColor={192,192,192}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid, + points={{-80.0,90.0},{-88.0,68.0},{-72.0,68.0},{-80.0,90.0}}), + Line( + points={{-90.0,-80.0},{82.0,-80.0}}, + color={192,192,192}), + Polygon( + lineColor={192,192,192}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid, + points={{90.0,-80.0},{68.0,-72.0},{68.0,-88.0},{90.0,-80.0}}), + Text( + extent={{-150.0,-150.0},{150.0,-110.0}}, + textString="k=%k"), + Line( + points=DynamicSelect({{-80.0,-80.0},{80.0,80.0}}, if use_reset then {{-80.0,-80.0},{60.0,60.0},{60.0,-80.0},{80.0,-60.0}} else {{-80.0,-80.0},{80.0,80.0}}), + color={0,0,127}), + Line( + visible=use_reset, + points={{60,-100},{60,-80}}, + color={255,0,255}, + pattern=LinePattern.Dot)})); + end SimpleIntegrator; + + block InputToState + Modelica.Blocks.Interfaces.RealInput measurement + annotation (Placement(transformation(extent={{120,-20},{80,20}}))); + RealInputSetState stateToSet=reinit(measurement) + annotation (Placement(transformation(extent={{-120,-20},{-80,20}}))); + annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( + coordinateSystem(preserveAspectRatio=false))); + end InputToState; + + connector RealInputSetState = + input Real "'input Real' as connector" annotation ( + defaultComponentName="u", + Icon(graphics={ + Polygon( + lineColor={0,0,127}, + fillColor={238,46,47}, + fillPattern=FillPattern.Solid, + points={{-100.0,100.0},{100.0,0.0},{-100.0,-100.0}})}, + coordinateSystem(extent={{-100.0,-100.0},{100.0,100.0}}, + preserveAspectRatio=true, + initialScale=0.2)), + Diagram( + coordinateSystem(preserveAspectRatio=true, + initialScale=0.2, + extent={{-100.0,-100.0},{100.0,100.0}}), + graphics={ + Polygon( + lineColor={0,0,127}, + fillColor={238,46,47}, + fillPattern=FillPattern.Solid, + points={{0.0,50.0},{100.0,0.0},{0.0,-50.0},{0.0,50.0}}), + Text( + textColor={0,0,127}, + extent={{-10.0,60.0},{-10.0,85.0}}, + textString="%name")}), + Documentation(info=" +

+Connector with one input signal of type Real. +

+")); + end Utilities; + end System; + annotation (uses(Modelica(version="4.0.0"))); +end TestSettingStates; From 0c6a7535d80c780b604a5f74d14dab6da5636ae5 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:38:36 +0200 Subject: [PATCH 18/55] Update README.md Updated with test-case and more complete description. --- RationaleMCP/0036/README.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 7dcf8c270..40968f32b 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -15,6 +15,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2020-04-22 | Hans Olsson. Created. | | 2020-07-08 | Hans Olsson. Updated with reinit. | | 2020-09-25 | Hans Olsson. Updated with new semantics. | +| 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -71,19 +72,21 @@ Key points: - Few corner cases. - Easy to recognize for humans and tools. - Straightforward to implement. Adapting the existing prototype to the new syntax was straightforward. +- The special binding equation is ignored for equation counting. Remaining: -- Decide if the way to go -- Name of operator (measurement, reinit, ...) -- Figure out how it impacts equation count and write specification text (a few paragraphs) +- Decide if the way to go. Proposal: Yes +- Name of operator (measurement, reinit, ...). Proposal: reinit +- Must the partition have a discretization method? Proposal: No +- Write specification text (a few paragraphs) # Semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and was originally defined as "means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x)", but that seems unclear. +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", but the original semantics was unclear Thus we present an alternative below, -## Original semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition". +## Original semantics (only of historic interest) +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and means that 'x' is first seen as a state, but after index reduction x is no longer a state and x=xs replaces the integration of der(x) The meaning is that 1. StateSelect.always is defined for variable x. @@ -93,13 +96,14 @@ The meaning is that This is not ideal as it uses words like "treated as", and variables are changed from being states to non-states. ## Discretization method semantics -The operator is only legal in a "Clocked Discretized Continuous-Time Partition". +The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and only as the entire declaration equation for a variable. The meaning is that -1. StateSelect.always is defined for variable x. -2. It is a state and thus participate in the usual index reduction and state selection. +1. StateSelect.always is set for the variable x. +2. Therefore it is a state and thus participate in the usual index reduction and state selection. 3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method https://specification.modelica.org/master/synchronous-language-elements.html#solver-methods +4. This declaration equation is ignored for the equation count. This makes it clear that the variable is an actual state, just integrated differently. @@ -121,7 +125,14 @@ However, as noted in the paper the procedure for using it is still slightly mess - Have parameters for those integrators etc. That could be automated in tools. +(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that will be corrected in the next release.) + +## Test-cases +The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. +![Plot showing result](BothControl.png) + # Required Patents -At best of your knowledge state any patents that would be required for implementation of this proposal. +At best of your knowledge state any patents that would be required for implementation of this proposal. + # References https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf From a71dfba69f3c5608e3608d87b13c9ce668ef03f5 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 29 Apr 2021 15:39:09 +0200 Subject: [PATCH 19/55] Update README.md Space --- RationaleMCP/0036/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 40968f32b..c914eafa8 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -129,6 +129,7 @@ That could be automated in tools. ## Test-cases The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. + ![Plot showing result](BothControl.png) # Required Patents From cdb0435fa0bb4bb0000225b10829ef79ed0c101f Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:33:14 +0100 Subject: [PATCH 20/55] Add a number of incorrect examples. And minor spelling correction. --- RationaleMCP/0036/TestSettingStates.mo | 49 ++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index b81ae8507..67c2056fd 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -16,8 +16,8 @@ package TestSettingStates equation der(y)=u-y; end Discretized; - Discretized discretized1(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); - DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 1000), "ExplicitEuler"))); + Discretized discretized1(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); + DiscretizedWithReinit discretized2(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); annotation (Documentation(info="

The result of this model will be similar to:

@@ -45,7 +45,7 @@ end when;
     model FeedforwardControl
       extends Modelica.Clocked.Examples.Systems.ControlledMixingUnit(pro=1.1);
       annotation (Documentation(info="
-

An example from Modelica Standard Library, but changed to have same difference between plant and plant in controller for easier comparison.

+

An example from Modelica Standard Library, but changed to have some difference between plant and plant in controller for easier comparison.

This does not need the possibility for setting states due to using a different controller.

")); end FeedforwardControl; @@ -572,5 +572,48 @@ Connector with one input signal of type Real. ")); end Utilities; end System; + package ErrorExamples + model DiscretizedIncorrect1 "Illegal since rhs must just be reinit, use reinit(-u) instead." + input Real u; + Real x=-reinit(u); + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(x)=u-x; + end when; + end DiscretizedIncorrect1; + model DiscretizedIncorrect2 "Illegal since reinit must be in a binding declaration" + input Real u; + Real x; + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(x)=u-x; + x=reinit(u); + end when; + end DiscretizedIncorrect2; + model DiscretizedIncorrect3 "Illegal, since cannot have both x and y as states" + input Real u; + Real x=reinit(u); + Real y(stateSelect=StateSelect.always)=2*x; + equation + when Clock(Clock(1,10), "ExplicitEuler") then + der(y)=u-y; + end when; + end DiscretizedIncorrect3; + model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give desired result for y" + model DiscretizedWithReinitOther "Using normal reinit instead, different result for y" + input Real u; + Real x(stateSelect=StateSelect.always); + Real y=2*x; + equation + der(y)=u-y; + when Clock() then + reinit(x,u); + end when; + end DiscretizedWithReinitOther; + DiscretizedWithReinitOther discretized3(u=sample(time, Clock(Clock(1, 10), "ExplicitEuler"))); + + extends TrivialDemonstration; + end DiscretizedIncorrect4; + end ErrorExamples; annotation (uses(Modelica(version="4.0.0"))); end TestSettingStates; From e6710e82e42e107f8ff909d219e15d1186bb0aea Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:34:37 +0100 Subject: [PATCH 21/55] ChangedSampling --- RationaleMCP/0036/TestSettingStates.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index 67c2056fd..bd1b79cfd 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -21,7 +21,7 @@ package TestSettingStates annotation (Documentation(info="

The result of this model will be similar to:

-when sample(1e-3) then
+when sample(1e-1) then
  /* without state reset */ 
  discretized1.u=time;
  discretized1.x=discretized1.x+...; // Euler discretization

From 4b9539c010426970816311b597ac5c82d8b99c7d Mon Sep 17 00:00:00 2001
From: OLSSON Hans 
Date: Mon, 14 Feb 2022 14:38:42 +0100
Subject: [PATCH 22/55] AddArrayExample

---
 RationaleMCP/0036/TestSettingStates.mo | 40 ++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo
index bd1b79cfd..13fa0675b 100644
--- a/RationaleMCP/0036/TestSettingStates.mo
+++ b/RationaleMCP/0036/TestSettingStates.mo
@@ -40,6 +40,46 @@ end when;
 

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

")); end TrivialDemonstration; + model TrialArrayDemonstration + model DiscretizedWithReinit + input Real u[:]; + Real x[size(u,1)]=reinit(u); + Real y[:]=2*x; + equation + der(y)=u-y; + end DiscretizedWithReinit; + + model Discretized + input Real u[:]; + Real x[size(u,1)](each stateSelect=StateSelect.always); + Real y[:]=2*x; + equation + der(y)=u-y; + end Discretized; + Discretized discretized1(u={sample(time, Clock(Clock(1, 10), "ExplicitEuler"))}); + DiscretizedWithReinit discretized2(u={sample(time, Clock(Clock(1, 10), "ExplicitEuler"))}); + annotation (Documentation(info=" +

The result of this model will be similar to:

+
+when sample(1e-1) then
+ /* without state reset */ 
+ discretized1.u[1]=time;
+ discretized1.x[1]=discretized1.x[1]+...; // Euler discretization
+ discretized1.y[1]=2*discretized1.x[1];
+ discretized1.der_y[1]=time-discretized1.y[1];
+ discretized1.der_x[1]=0.5*discretized1.der_y[1];
+ 
+ /* with state reset */ 
+ discretized2.u[1]=time;
+ discretized2.x[1]=time; // Just using input!
+ discretized2.y[1]=2*discretized2.x[1];
+ discretized2.der_y[1]=time-discretized2.y[1];
+ discretized2.der_x[1]=0.5*discretized2.der_y[1];
+end when;
+
+

In particular note that the relation between der_y and der_x is the same regardless of resetting states, i.e., it only influences the integration of x not the differentation before that.

+")); + end TrialArrayDemonstration; package System model FeedforwardControl From 113a8708b9bbafefb91c963ea243804b03d36acc Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 14:49:16 +0100 Subject: [PATCH 23/55] ExplainNewExamples --- RationaleMCP/0036/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index c914eafa8..3ebee98b2 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -16,6 +16,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2020-07-08 | Hans Olsson. Updated with reinit. | | 2020-09-25 | Hans Olsson. Updated with new semantics. | | 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | +| 2022-02-14 | Hans Olsson. More test-cases. | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -97,8 +98,9 @@ This is not ideal as it uses words like "treated as", and variables are changed ## Discretization method semantics The operator is only legal in a "Clocked Discretized Continuous-Time Partition", and only as the entire declaration equation for a variable. +The variable must be a scalar or array variable that is a subtype of Real. -The meaning is that +The meaning of Real x=reinit(xs); is that 1. StateSelect.always is set for the variable x. 2. Therefore it is a state and thus participate in the usual index reduction and state selection. 3. During discretization the state is equal to the new value xs during the entire step, instead of using the discretization method @@ -125,7 +127,7 @@ However, as noted in the paper the procedure for using it is still slightly mess - Have parameters for those integrators etc. That could be automated in tools. -(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that will be corrected in the next release.) +(Note: The reinit-variant in Dymola 2022 and earlier requires that the argument to reinit must be declared before reinit, that was corrected in Dymola 2022x.) ## Test-cases The package [TestSettingStates](TestSettingStates.mo) contain a trivial example showing how the model is supposed to be handled, with relevant details, and the previously constructed test-case. From 7dfc81aacde0e4e422cc8f0cb7947917fe13a850 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 14 Feb 2022 15:06:08 +0100 Subject: [PATCH 24/55] ExplainMore --- RationaleMCP/0036/TestSettingStates.mo | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/RationaleMCP/0036/TestSettingStates.mo b/RationaleMCP/0036/TestSettingStates.mo index 13fa0675b..d402803a6 100644 --- a/RationaleMCP/0036/TestSettingStates.mo +++ b/RationaleMCP/0036/TestSettingStates.mo @@ -639,8 +639,16 @@ Connector with one input signal of type Real. der(y)=u-y; end when; end DiscretizedIncorrect3; - model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give desired result for y" + model DiscretizedIncorrect4 "Using normal reinit is legal, but does not give the desired result for y" model DiscretizedWithReinitOther "Using normal reinit instead, different result for y" + /* + Specifically the normal reinit semantics imply that x will be updated at the end of the step. + The clocked semantics normally only evaluate y once per step. + Combined this means one step delay in y. + There are also additional minor changes related to der(y) and using y during the calculation. + + (And normally reinit would be in a non-clocked when.) + */ input Real u; Real x(stateSelect=StateSelect.always); Real y=2*x; From 0017f5ef23a7580d805615e14ae438f0b28679a8 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Tue, 3 May 2022 13:26:45 +0200 Subject: [PATCH 25/55] Rebase and everything but the actual semantics. --- chapters/equations.tex | 3 ++- chapters/synchronous.tex | 9 +++++++++ mls.bib | 12 ++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/chapters/equations.tex b/chapters/equations.tex index 47872e9e5..7014f6eff 100644 --- a/chapters/equations.tex +++ b/chapters/equations.tex @@ -412,7 +412,8 @@ \subsubsection{Single Assignment Rule Applied to When-Equations}\label{applicati \subsection{reinit}\label{reinit} -\lstinline!reinit! can only be used in the body of a \lstinline!when!-equation. +There are two variants of \lstinline!reinit!, the other is restricted to declaration equations, see \cref{setting-states}. +This \lstinline!reinit! can only be used in the body of a \lstinline!when!-equation. It has the following syntax: \begin{lstlisting}[language=modelica] reinit(x, expr); diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 9cd0c6935..817708b5d 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1044,6 +1044,8 @@ \section{Clocked Discretized Partition}\label{continuous-time-equations-in-clock This feature also allows defining multi-rate systems: Different parts of the continuous-time model are associated to different clocks and are solved with different integration methods between clock ticks, e.g., a very fast sub-system with an implicit solver with a small step-size and a slow sub-system with an explicit solver with a large step-size. + +There is also a special handling for repeatedly setting the states based on measurements, \cref{setting-states}. \end{nonnormative} With the language elements defined in this section, continuous-time @@ -1265,6 +1267,13 @@ \subsection{Solver Methods}\label{solver-methods} This data is tool specific and is typically either defined with a vendor annotation or is given in the simulation environment. \end{nonnormative} +\subsection{Setting states}\label{setting-states} +\begin{nonnormative} +In order to handle measurement it is necessary to consistently update the discretized states, see \textcite{OlssonEtAl2017ModelBased}. +This replaces the previous discretization methods for specific variables. +Note that \lstinline!reinit! also has another definiton, see \cref{reinit}. +\end{nonnormative} + \subsection{Associating a Solver to a Partition}\label{associating-a-solver-to-a-partition} A \lstinline!SolverMethod! can be associated to a clock with the overloaded \lstinline!Clock! constructor \lstinline!Clock($c$, solverMethod=$\ldots$)!, see \cref{clock-constructors}. diff --git a/mls.bib b/mls.bib index 405d64b71..d01b70337 100644 --- a/mls.bib +++ b/mls.bib @@ -65,6 +65,18 @@ @Article{Harel1987Statecharts url = {http://www.inf.ed.ac.uk/teaching/courses/seoc1/2005_2006/resources/statecharts.pdf}, } +@InProceedings{OlssonEtAl2017ModelBased, + author = {Olsson, Hans and Mattsson, Sven Erik and Otter, Martin and Pfeiffer, Andreas and Bürger, Christoff and Henriksson, Dan}, + title = {Model-based Embedded Control using Rosenbrock Integration Methods}, + year = {2017}, + month = may, + day = {15--17}, + booktitle = {Proceedings of the 12\textsuperscript{th} International Modelica Conference}, + pages = {517--526}, + address = {Prague, Czech Republic}, + url = {https://doi.org/10.3384/ecp17132517}, +} + @InProceedings{ThummelEtAl2005InverseModels, author = {Thümmel, Michael and Looye, Gertjan and Kurze, Matthias and Otter, Martin and Bals, Johann}, title = {Nonlinear Inverse Models for Control}, From e16a486599d87716832673631edb374ec39f15c6 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Tue, 3 May 2022 14:22:32 +0200 Subject: [PATCH 26/55] Added semantics. --- chapters/synchronous.tex | 50 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 817708b5d..4538ae799 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1112,6 +1112,7 @@ \subsection{Solver Methods}\label{solver-methods} The integration method associated with a clocked discretized continuous-time partition is defined with a string. A predefined type \lstinline!ModelicaServices.Types.SolverMethod! defines the methods supported by the respective tool by using the \lstinline!choices! annotation. +See also \cref{setting-states}. \begin{nonnormative} The \lstinline!ModelicaServices! package contains tool specific definitions. A string is used instead of an enumeration, since different tools might have different values and then the integer mapping of an enumeration is misleading since the same value might characterize different integrators. @@ -1269,9 +1270,54 @@ \subsection{Solver Methods}\label{solver-methods} \subsection{Setting states}\label{setting-states} \begin{nonnormative} -In order to handle measurement it is necessary to consistently update the discretized states, see \textcite{OlssonEtAl2017ModelBased}. +In order to handle measurement in control systems it is necessary to consistently update the discretized states, see \textcite{OlssonEtAl2017ModelBased}. This replaces the previous discretization methods for specific variables. -Note that \lstinline!reinit! also has another definiton, see \cref{reinit}. +\end{nonnormative} + +A declaration equation can have the form \lstinline!Real x=reinit(xs);! +The restrictions are that: +\begin{itemize} +\item It is only legal in a Discretized Continuous-Time partition. +\item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of Real. +\item The right-hand-side must be solely consist of a call to \lstinline!reinit!. +\item The argument to \lstinline!reinit! (i.e,\ \lstinline!xs!) must be compatible with the variable, and may be an expression. +\end{itemize} + +The semantics are: +\begin{itemize} +\item The variable implicitly always has \lstinline!StateSelect.always!. +\item The variable participate in the usual index reduction and state selection (where it must be selected as a state). +\item The discretization of the state is equal to the new value \lstinline!xs! during the entire step, instead of using the discretization method in \cref{solver-methods}. +\item This declaration equation is ignored for the equation count. +\end{itemize} + +\begin{example} +The example will only shortly demonstrate the semantics; for realistic use-cases see \textcite{OlssonEtAl2017ModelBased}. +\begin{lstlisting}[language=modelica] +model DiscretizedWithReinit + Real u = sample(time, Clock(Clock(1, 10), "ExplicitEuler")); + Real x = reinit(u); + Real y = 2 * x; +equation + der(y) = u - y; +end DiscretizedWithReinit; +\end{lstlisting} +This is similar to the following equations: +\begin{lstlisting}[language=modelica] +when sample(0.1) then + u = time; + x = u; // Discretization - just using input! + y = 2 * x; + der_y = time - y; + der_x = 0.5 * der_y; +\end{lstlisting} +Here we see that \lstinline!x! was selected as a state in favor of \lstinline!y!, despite the latter being differentiated. +Without the \lstinline!reinit!-call the equation for \lstinline!x! would be \lstinline!pre(x) + 0.1 * pre(der_x)!. +Note that replacing the discretization for \lstinline!x! does not change the equations for \lstinline!der_y! and \lstinline!der_x! compared to solver method discretization. +\end{example} + +\begin{nonnormative} +Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} \subsection{Associating a Solver to a Partition}\label{associating-a-solver-to-a-partition} From d2ec158ade0b4d5e65776b14f08472d205943601 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 3 May 2022 14:30:45 +0200 Subject: [PATCH 27/55] Update README.md Updated date etc. --- RationaleMCP/0036/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 3ebee98b2..0d2e05f51 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -1,7 +1,6 @@ Modelica Change Proposal MCP-0036 Setting states Hans Olsson -(In Development) -- # Summary @@ -17,6 +16,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2020-09-25 | Hans Olsson. Updated with new semantics. | | 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | | 2022-02-14 | Hans Olsson. More test-cases. | +| 2022-05-03 | Hans Olsson. Update specification text, clarified that ready | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -25,7 +25,7 @@ All authors of this MCP or their organizations have signed the "Modelica Contrib See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf -This is still work in progress as the main challenge is figuring out a specific syntax. +A specific syntax is proposed. # Alternatives The alternatives considered are: @@ -35,7 +35,7 @@ The alternatives considered are: - replace "reinit" by "measurement"-operator, or forceState(…) - the implemented annotation does not seem like a good idea -Ideally the proposal should allow us to hide this "turning a measurement into a state" in a block, and thus many of the details will be less important. +The proposal does allow us to hide this "turning a measurement into a state" in a block, and thus many of the details will be less important. ## Annotation variant The annotation variant was proposed in the paper (not good since it influences the semantics) and is: @@ -52,7 +52,7 @@ As discussed in https://github.com/modelica/ModelicaSpecification/issues/2285#is https://github.com/modelica/ModelicaSpecification/issues/578 was that all reinits are done at the end of the event iteration using previously computed values. Thus the current reinit(v, -v/2); does not lead to a loop with reinit, but first evaluates -v/2 (and other reinit-values) and then sets v (and other reinit-values). -One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the behaviour of a restricted set of continuous-time models; having two different variants of reinit (with same syntax but different semantics) is counter to that. +One goal of "Clocked Discretized Continuous-Time Partition" is to preserve the behaviour of a restricted set of continuous-time models; having two different variants of reinit (with _the same syntax_ but different semantics) is counter to that. In addition the current reinit might possibly in the future be replaced by some form of impulses, indicating that the changes are physical and influence other parts of the system, this does not seem consistent with how states are set in this MCP. Finally having a conditional setting of states is more complicated, and reinit and other similar operators naturally suggest that - and we either need to determine what it means or forbid it. @@ -108,12 +108,13 @@ https://specification.modelica.org/master/synchronous-language-elements.html#sol 4. This declaration equation is ignored for the equation count. This makes it clear that the variable is an actual state, just integrated differently. +Note that even if it reuses reinit it avoids the problems with the reinit(x, xs) proposal. Step (3) requires that it is a state (guaranteed by (1)), and that it is a continuous variable in a "Clocked Discretized Continuous-Time Partition", as stated at the start. # Backwards Compatibility Will depend on exact syntax. -In the proposed alternative it will depend on the measurement keyword; if we use "reinit" it is fully backwards compatible. +In the proposed alternative it will depend on the measurement keyword; using "reinit" it is fully backwards compatible. # Tool Implementation Both the preliminary variant with annotation and proposed alternative have been implemented in Dymola. From 3a25cdcdcc16a2794645a83ae77d1cee4a3fe19a Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Wed, 11 May 2022 17:02:38 +0200 Subject: [PATCH 28/55] FixMerging --- RationaleMCP/0036/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 299bad73f..0d2e05f51 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -1,6 +1,7 @@ Modelica Change Proposal MCP-0036 Setting states Hans Olsson +-- # Summary The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), From bc63a923154b7a958c4d06b9e8270c410d1b80d4 Mon Sep 17 00:00:00 2001 From: HOS Date: Wed, 30 Aug 2023 15:04:28 +0200 Subject: [PATCH 29/55] From review. --- RationaleMCP/0036/README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 0d2e05f51..1296e716c 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -5,7 +5,7 @@ Hans Olsson # Summary The main idea is that in many cases we use a model within a model (e.g. in Model-Predictive-Control and Feedback Linearization), -and we need to update those states in the model within the model based on more accurate measurements of during the simulation, +and we need to update those states in the model within the model based on more accurate measurements of them during the simulation, and have the state-updating as part of the model (and not as some tool-specific solution). # Revisions @@ -17,6 +17,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2021-04-29 | Hans Olsson. Added test-cases and more complete proposal. | | 2022-02-14 | Hans Olsson. More test-cases. | | 2022-05-03 | Hans Olsson. Update specification text, clarified that ready | +| 2023-08-30 | Hans Olsson. Review comments | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -59,11 +60,12 @@ Finally having a conditional setting of states is more complicated, and reinit a ## Proposed alternative Use a special binding equation: -Real x=measurement(xs); +Real x=reinit(xs); -This special operator, measurement, is only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and its meaning is discussed in the semantics part. +This new use of reinit can be separated from the existing use of reinit. +An alternative would be to introduce a new operator, measurement, only legal in a "Clocked Discretized Continuous-Time Partition" and only in this way and its meaning is discussed in the semantics part. -The name of the operator can be discussed. The prototype re-used "reinit" to avoid introducing new reserved words. +The name of the operator can be discussed. The current proposal re-uses "reinit" to avoid introducing new reserved words. Key points: - Associated with state, not measurement variable. @@ -81,6 +83,10 @@ Remaining: - Must the partition have a discretization method? Proposal: No - Write specification text (a few paragraphs) +The reason the partition doesn't need a discretization method is that if we use reinit for all states there is nothing to integrate with the discretization method making it a meaingless choice. +Obviously it is possible to specify a discretization method even if not used. +However, if the intent is to require that all states are measured the proposed semantics allow a check for that. + # Semantics The operator is only legal in a "Clocked Discretized Continuous-Time Partition", but the original semantics was unclear From c65f9b384db85beb07bda17df368855fbfde17d2 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 30 Aug 2023 15:04:41 +0200 Subject: [PATCH 30/55] Update RationaleMCP/0036/README.md Co-authored-by: Henrik Tidefelt --- RationaleMCP/0036/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 0d2e05f51..ecb1e24ce 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -108,7 +108,7 @@ https://specification.modelica.org/master/synchronous-language-elements.html#sol 4. This declaration equation is ignored for the equation count. This makes it clear that the variable is an actual state, just integrated differently. -Note that even if it reuses reinit it avoids the problems with the reinit(x, xs) proposal. +Note that even if the proposed syntax reuses the `reinit` keyword, it avoids the problems with the alternative `reinit(x, xs)` proposal. Step (3) requires that it is a state (guaranteed by (1)), and that it is a continuous variable in a "Clocked Discretized Continuous-Time Partition", as stated at the start. From e64220adf80abf96d6c4f3241ca434198888523e Mon Sep 17 00:00:00 2001 From: HOS Date: Wed, 30 Aug 2023 15:05:11 +0200 Subject: [PATCH 31/55] No patent --- RationaleMCP/0036/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 1296e716c..c23c7d728 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -142,7 +142,7 @@ The package [TestSettingStates](TestSettingStates.mo) contain a trivial example ![Plot showing result](BothControl.png) # Required Patents -At best of your knowledge state any patents that would be required for implementation of this proposal. +At best of my knowledge no patents would be required for implementation of this proposal. # References https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf From 337ec6acf583cd7ef0e70fe908a4e65012966f67 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 30 Aug 2023 15:06:09 +0200 Subject: [PATCH 32/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 4538ae799..678358c90 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1285,7 +1285,7 @@ \subsection{Setting states}\label{setting-states} The semantics are: \begin{itemize} -\item The variable implicitly always has \lstinline!StateSelect.always!. +\item The variable implicitly has \lstinline!StateSelect.always!. \item The variable participate in the usual index reduction and state selection (where it must be selected as a state). \item The discretization of the state is equal to the new value \lstinline!xs! during the entire step, instead of using the discretization method in \cref{solver-methods}. \item This declaration equation is ignored for the equation count. From 7c057228439c2b78e5e14ad59e10283a579221c7 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 30 Aug 2023 15:06:46 +0200 Subject: [PATCH 33/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 678358c90..12fdc5aee 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1286,7 +1286,7 @@ \subsection{Setting states}\label{setting-states} The semantics are: \begin{itemize} \item The variable implicitly has \lstinline!StateSelect.always!. -\item The variable participate in the usual index reduction and state selection (where it must be selected as a state). +\item The variable participates in the usual index reduction and state selection (where it must be selected as a state). \item The discretization of the state is equal to the new value \lstinline!xs! during the entire step, instead of using the discretization method in \cref{solver-methods}. \item This declaration equation is ignored for the equation count. \end{itemize} From 5671dbac7583d0eab5784b8d0ffe4de83cfda151 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 30 Aug 2023 15:07:36 +0200 Subject: [PATCH 34/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 12fdc5aee..c68416a1b 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1292,7 +1292,7 @@ \subsection{Setting states}\label{setting-states} \end{itemize} \begin{example} -The example will only shortly demonstrate the semantics; for realistic use-cases see \textcite{OlssonEtAl2017ModelBased}. +This example shortly demonstrates the semantics; for realistic use-cases, see \textcite{OlssonEtAl2017ModelBased}. \begin{lstlisting}[language=modelica] model DiscretizedWithReinit Real u = sample(time, Clock(Clock(1, 10), "ExplicitEuler")); From 41c0f49732010596267a992940783b01a8a4f333 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 30 Aug 2023 15:08:04 +0200 Subject: [PATCH 35/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index c68416a1b..316c10b92 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1288,7 +1288,7 @@ \subsection{Setting states}\label{setting-states} \item The variable implicitly has \lstinline!StateSelect.always!. \item The variable participates in the usual index reduction and state selection (where it must be selected as a state). \item The discretization of the state is equal to the new value \lstinline!xs! during the entire step, instead of using the discretization method in \cref{solver-methods}. -\item This declaration equation is ignored for the equation count. +\item This declaration equation is ignored for the equation count, see \cref{local equation size}. \end{itemize} \begin{example} From 637fd173f05e90d557788dc80988a2f779ab0739 Mon Sep 17 00:00:00 2001 From: HOS Date: Tue, 12 Sep 2023 15:22:39 +0200 Subject: [PATCH 36/55] Explain that reinit is excluded from local equation size. --- chapters/classes.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/classes.tex b/chapters/classes.tex index d245aa8a6..728de9145 100644 --- a/chapters/classes.tex +++ b/chapters/classes.tex @@ -960,7 +960,7 @@ \section{Balanced Models}\label{balanced-models} The local equation size of a \lstinline!model! or \lstinline!block! class is the sum of the following numbers: \begin{itemize} \item - The number of equations defined locally (i.e.\ not in any \lstinline!model! or \lstinline!block! component), including binding equations, and equations generated from \lstinline!connect!-equations. + The number of equations defined locally (i.e.\ not in any \lstinline!model! or \lstinline!block! component), including binding equations (excluding \lstline!reinit! calls, see \cref{setting-states}), and equations generated from \lstinline!connect!-equations. \begin{nonnormative} This includes the proper count for \lstinline!when!-clauses (see \cref{when-equations}), and algorithms (see \cref{algorithm-sections}), and is also used for the flat Hybrid DAE formulation (see \cref{modelica-dae-representation}). From a914e9fe6c67bd8e643f8bed4000be9787715571 Mon Sep 17 00:00:00 2001 From: HOS Date: Tue, 12 Sep 2023 15:48:55 +0200 Subject: [PATCH 37/55] Cross-reference the two definitions. --- chapters/operatorsandexpressions.tex | 1 + chapters/synchronous.tex | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/chapters/operatorsandexpressions.tex b/chapters/operatorsandexpressions.tex index c14225b99..3538c04b6 100644 --- a/chapters/operatorsandexpressions.tex +++ b/chapters/operatorsandexpressions.tex @@ -1376,6 +1376,7 @@ \subsection{Event-Related Operators with Function Syntax}\label{event-related-op $x$ is a scalar or array \lstinline!Real! variable that is implicitly defined to have \lstinline!StateSelect.always!. \begin{nonnormative} It is an error if the variable cannot be selected as a state. +Note that there is also the \lstinline!reinit! declaration equation, \cref{setting-states}. \end{nonnormative} $\mathit{expr}$ needs to be type-compatible with $x$. \lstinline!reinit! can only be applied once for the same variable -- either as an individual variable or as part of an array of variables. diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 316c10b92..7c5443036 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1272,6 +1272,7 @@ \subsection{Setting states}\label{setting-states} \begin{nonnormative} In order to handle measurement in control systems it is necessary to consistently update the discretized states, see \textcite{OlssonEtAl2017ModelBased}. This replaces the previous discretization methods for specific variables. +Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} A declaration equation can have the form \lstinline!Real x=reinit(xs);! @@ -1316,9 +1317,6 @@ \subsection{Setting states}\label{setting-states} Note that replacing the discretization for \lstinline!x! does not change the equations for \lstinline!der_y! and \lstinline!der_x! compared to solver method discretization. \end{example} -\begin{nonnormative} -Note that \lstinline!reinit! also has another definition, see \cref{reinit}. -\end{nonnormative} \subsection{Associating a Solver to a Partition}\label{associating-a-solver-to-a-partition} From 7fc53d40bb049aa6af2018b09bffb5ea6f8d2033 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 15:55:15 +0200 Subject: [PATCH 38/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 7c5443036..e929d2edf 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1045,7 +1045,7 @@ \section{Clocked Discretized Partition}\label{continuous-time-equations-in-clock This feature also allows defining multi-rate systems: Different parts of the continuous-time model are associated to different clocks and are solved with different integration methods between clock ticks, e.g., a very fast sub-system with an implicit solver with a small step-size and a slow sub-system with an explicit solver with a large step-size. -There is also a special handling for repeatedly setting the states based on measurements, \cref{setting-states}. +There is also a special handling for determining states according to measurements instead of the normal integration method, \cref{setting-states}. \end{nonnormative} With the language elements defined in this section, continuous-time From 28a89f78a7c4b25fd6d57416388dd754573f170e Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 15:55:35 +0200 Subject: [PATCH 39/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index e929d2edf..d161fdc0a 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1111,8 +1111,8 @@ \subsection{Solver Methods}\label{solver-methods} The integration method associated with a clocked discretized continuous-time partition is defined with a string. A predefined type \lstinline!ModelicaServices.Types.SolverMethod! defines the methods supported by the respective tool by using the \lstinline!choices! annotation. - See also \cref{setting-states}. + \begin{nonnormative} The \lstinline!ModelicaServices! package contains tool specific definitions. A string is used instead of an enumeration, since different tools might have different values and then the integer mapping of an enumeration is misleading since the same value might characterize different integrators. From 0ee411342f1fae95512ce6e1a7e190229769e988 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 15:56:57 +0200 Subject: [PATCH 40/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index d161fdc0a..b7b93a6c5 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1270,7 +1270,7 @@ \subsection{Solver Methods}\label{solver-methods} \subsection{Setting states}\label{setting-states} \begin{nonnormative} -In order to handle measurement in control systems it is necessary to consistently update the discretized states, see \textcite{OlssonEtAl2017ModelBased}. +In model-based control systems, a natural way of incorporating measurements can be to update discretized model states based on the measurements, see \textcite{OlssonEtAl2017ModelBased}. This replaces the previous discretization methods for specific variables. Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} From 0ceb693ea6e046bfa2ef9bbe960f7d0f8ffffe76 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 15:59:38 +0200 Subject: [PATCH 41/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index b7b93a6c5..10610e695 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1275,7 +1275,7 @@ \subsection{Setting states}\label{setting-states} Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} -A declaration equation can have the form \lstinline!Real x=reinit(xs);! +A declaration equation can have the form \lstinline!Real x = reinit(expr)!. The restrictions are that: \begin{itemize} \item It is only legal in a Discretized Continuous-Time partition. From 4180066b0a96c88fcb9f02de733a48677952277e Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:00:01 +0200 Subject: [PATCH 42/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 10610e695..05ee2d0a6 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1281,7 +1281,7 @@ \subsection{Setting states}\label{setting-states} \item It is only legal in a Discretized Continuous-Time partition. \item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of Real. \item The right-hand-side must be solely consist of a call to \lstinline!reinit!. -\item The argument to \lstinline!reinit! (i.e,\ \lstinline!xs!) must be compatible with the variable, and may be an expression. +\item The argument to \lstinline!reinit! (i.e,\ \lstinline!expr!) must be compatible with the variable. \end{itemize} The semantics are: From 12af404b69080b106871cbd21f131b7e45952718 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:00:24 +0200 Subject: [PATCH 43/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 05ee2d0a6..b83ce1d34 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1280,7 +1280,7 @@ \subsection{Setting states}\label{setting-states} \begin{itemize} \item It is only legal in a Discretized Continuous-Time partition. \item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of Real. -\item The right-hand-side must be solely consist of a call to \lstinline!reinit!. +\item The right-hand-side must consist solely of a call to \lstinline!reinit!. \item The argument to \lstinline!reinit! (i.e,\ \lstinline!expr!) must be compatible with the variable. \end{itemize} From 8822655f6a028677b27d115ea104f94d180ff3a4 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:00:47 +0200 Subject: [PATCH 44/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index b83ce1d34..1a43dd378 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1279,7 +1279,7 @@ \subsection{Setting states}\label{setting-states} The restrictions are that: \begin{itemize} \item It is only legal in a Discretized Continuous-Time partition. -\item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of Real. +\item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of \lstinline!Real!. \item The right-hand-side must consist solely of a call to \lstinline!reinit!. \item The argument to \lstinline!reinit! (i.e,\ \lstinline!expr!) must be compatible with the variable. \end{itemize} From 8fe192c021b30f2b4c8d0d5547858c616c066f91 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:02:03 +0200 Subject: [PATCH 45/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 1 - 1 file changed, 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 1a43dd378..18947df17 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1271,7 +1271,6 @@ \subsection{Solver Methods}\label{solver-methods} \subsection{Setting states}\label{setting-states} \begin{nonnormative} In model-based control systems, a natural way of incorporating measurements can be to update discretized model states based on the measurements, see \textcite{OlssonEtAl2017ModelBased}. -This replaces the previous discretization methods for specific variables. Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} From 051602c83f46835699f9f6183a3810dcf1c290be Mon Sep 17 00:00:00 2001 From: HOS Date: Tue, 12 Sep 2023 16:06:28 +0200 Subject: [PATCH 46/55] Difference between "reinit equation" and "reinit declaration equation". --- chapters/equations.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chapters/equations.tex b/chapters/equations.tex index 7014f6eff..1f3fd9c71 100644 --- a/chapters/equations.tex +++ b/chapters/equations.tex @@ -412,8 +412,8 @@ \subsubsection{Single Assignment Rule Applied to When-Equations}\label{applicati \subsection{reinit}\label{reinit} -There are two variants of \lstinline!reinit!, the other is restricted to declaration equations, see \cref{setting-states}. -This \lstinline!reinit! can only be used in the body of a \lstinline!when!-equation. +The \lstinline!reinit!-equation can only be used in the body of a \lstinline!when!-equation. +(There is also \lstinline!reinit! declaration equation, \cref{setting-states}.) It has the following syntax: \begin{lstlisting}[language=modelica] reinit(x, expr); From 8e52fd8b70507ef818ad8a11bc42b079fb3a084e Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:13:38 +0200 Subject: [PATCH 47/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 1 - 1 file changed, 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 18947df17..85e4c264e 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1269,7 +1269,6 @@ \subsection{Solver Methods}\label{solver-methods} \end{nonnormative} \subsection{Setting states}\label{setting-states} -\begin{nonnormative} In model-based control systems, a natural way of incorporating measurements can be to update discretized model states based on the measurements, see \textcite{OlssonEtAl2017ModelBased}. Note that \lstinline!reinit! also has another definition, see \cref{reinit}. \end{nonnormative} From b0641f22ef07278aa417ff850690fda9b96cb270 Mon Sep 17 00:00:00 2001 From: HOS Date: Tue, 12 Sep 2023 16:14:25 +0200 Subject: [PATCH 48/55] Use expr consistently. --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 85e4c264e..8a3ce6cb9 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1286,7 +1286,7 @@ \subsection{Setting states}\label{setting-states} \begin{itemize} \item The variable implicitly has \lstinline!StateSelect.always!. \item The variable participates in the usual index reduction and state selection (where it must be selected as a state). -\item The discretization of the state is equal to the new value \lstinline!xs! during the entire step, instead of using the discretization method in \cref{solver-methods}. +\item The discretization of the state is equal to the new value \lstinline!expr! during the entire step, instead of using the discretization method in \cref{solver-methods}. \item This declaration equation is ignored for the equation count, see \cref{local equation size}. \end{itemize} From 98b6860f1ab612c624637057a7792408080f224f Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Tue, 12 Sep 2023 16:15:48 +0200 Subject: [PATCH 49/55] Update chapters/synchronous.tex Co-authored-by: Henrik Tidefelt --- chapters/synchronous.tex | 1 - 1 file changed, 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 8a3ce6cb9..2637d952f 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1271,7 +1271,6 @@ \subsection{Solver Methods}\label{solver-methods} \subsection{Setting states}\label{setting-states} In model-based control systems, a natural way of incorporating measurements can be to update discretized model states based on the measurements, see \textcite{OlssonEtAl2017ModelBased}. Note that \lstinline!reinit! also has another definition, see \cref{reinit}. -\end{nonnormative} A declaration equation can have the form \lstinline!Real x = reinit(expr)!. The restrictions are that: From 782d5b2f32d1a0c0c0c1c8e65c36393b07b6517f Mon Sep 17 00:00:00 2001 From: HOS Date: Tue, 12 Sep 2023 16:32:04 +0200 Subject: [PATCH 50/55] Cleaned up latex errors --- chapters/classes.tex | 4 ++-- chapters/synchronous.tex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chapters/classes.tex b/chapters/classes.tex index 728de9145..71ff204ef 100644 --- a/chapters/classes.tex +++ b/chapters/classes.tex @@ -956,11 +956,11 @@ \section{Balanced Models}\label{balanced-models} \end{itemize} \end{definition} -\begin{definition}[Local equation size]\index{local equation size} +\begin{definition}[Local equation size]\index{local equation size}\label{local-equation-size} The local equation size of a \lstinline!model! or \lstinline!block! class is the sum of the following numbers: \begin{itemize} \item - The number of equations defined locally (i.e.\ not in any \lstinline!model! or \lstinline!block! component), including binding equations (excluding \lstline!reinit! calls, see \cref{setting-states}), and equations generated from \lstinline!connect!-equations. + The number of equations defined locally (i.e.\ not in any \lstinline!model! or \lstinline!block! component), including binding equations (excluding \lstinline!reinit! calls, see \cref{setting-states}), and equations generated from \lstinline!connect!-equations. \begin{nonnormative} This includes the proper count for \lstinline!when!-clauses (see \cref{when-equations}), and algorithms (see \cref{algorithm-sections}), and is also used for the flat Hybrid DAE formulation (see \cref{modelica-dae-representation}). diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 2637d952f..9e7afe743 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1286,7 +1286,7 @@ \subsection{Setting states}\label{setting-states} \item The variable implicitly has \lstinline!StateSelect.always!. \item The variable participates in the usual index reduction and state selection (where it must be selected as a state). \item The discretization of the state is equal to the new value \lstinline!expr! during the entire step, instead of using the discretization method in \cref{solver-methods}. -\item This declaration equation is ignored for the equation count, see \cref{local equation size}. +\item This declaration equation is ignored for the equation count, see \cref{local-equation-size}. \end{itemize} \begin{example} From 9c8a5c03ae579ab4b9e2d9f34f242c53f5291897 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 16 May 2024 11:32:50 +0200 Subject: [PATCH 51/55] Update chapters/synchronous.tex --- chapters/synchronous.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/synchronous.tex b/chapters/synchronous.tex index 9e7afe743..4ad69154e 100644 --- a/chapters/synchronous.tex +++ b/chapters/synchronous.tex @@ -1275,7 +1275,7 @@ \subsection{Setting states}\label{setting-states} A declaration equation can have the form \lstinline!Real x = reinit(expr)!. The restrictions are that: \begin{itemize} -\item It is only legal in a Discretized Continuous-Time partition. +\item It is only legal in a discretized sub-partition. \item The variable (i.e.,\ \lstinline!x!) must be a scalar or array variable that is a subtype of \lstinline!Real!. \item The right-hand-side must consist solely of a call to \lstinline!reinit!. \item The argument to \lstinline!reinit! (i.e,\ \lstinline!expr!) must be compatible with the variable. From 18e369515069274f3df56ab657e26823a932d5a8 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Thu, 6 Mar 2025 17:13:28 +0100 Subject: [PATCH 52/55] Update README.md Fix broken link --- RationaleMCP/0036/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 0b475fab0..957109c26 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -24,7 +24,7 @@ All authors of this MCP or their organizations have signed the "Modelica Contrib # Rationale See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 -and paper https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf +and paper https://2017.international.conference.modelica.org/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf A specific syntax is proposed. From 74494ba768f206d7d77aeee4b2b4c00d62b46efe Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Mon, 14 Apr 2025 09:19:37 +0200 Subject: [PATCH 53/55] Update README.md Fix reference to use doi --- RationaleMCP/0036/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 957109c26..7e4c781f9 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -18,13 +18,14 @@ and have the state-updating as part of the model (and not as some tool-specific | 2022-02-14 | Hans Olsson. More test-cases. | | 2022-05-03 | Hans Olsson. Update specification text, clarified that ready | | 2023-08-30 | Hans Olsson. Review comments | +| 2025-04-14 | Hans Olsson. Fix reference | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". # Rationale See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 -and paper https://2017.international.conference.modelica.org/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf +and paper ttps://doi.org/10.3384/ecp17132517 A specific syntax is proposed. @@ -145,4 +146,4 @@ The package [TestSettingStates](TestSettingStates.mo) contain a trivial example At best of my knowledge no patents would be required for implementation of this proposal. # References -https://modelica.org/events/modelica2017/proceedings/html/submissions/ecp17132517_OlssonMattssonOtterPfeifferBurgerHenriksson.pdf +https://doi.org/10.3384/ecp17132517 From dd77acadd06ff50deff36ff234b012554a7366a9 Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 7 May 2025 14:50:53 +0200 Subject: [PATCH 54/55] Update README.md Fix link --- RationaleMCP/0036/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 7e4c781f9..8024829ba 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -25,7 +25,7 @@ All authors of this MCP or their organizations have signed the "Modelica Contrib # Rationale See previous discussion https://github.com/modelica/ModelicaSpecification/issues/2285 -and paper ttps://doi.org/10.3384/ecp17132517 +and paper https://doi.org/10.3384/ecp17132517 A specific syntax is proposed. From dd7bfd73b835c07c99ccfa61484c0bff414706cf Mon Sep 17 00:00:00 2001 From: Hans Olsson Date: Wed, 7 May 2025 15:02:14 +0200 Subject: [PATCH 55/55] Update README.md Added possible extension. --- RationaleMCP/0036/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/RationaleMCP/0036/README.md b/RationaleMCP/0036/README.md index 8024829ba..b08842362 100644 --- a/RationaleMCP/0036/README.md +++ b/RationaleMCP/0036/README.md @@ -19,6 +19,7 @@ and have the state-updating as part of the model (and not as some tool-specific | 2022-05-03 | Hans Olsson. Update specification text, clarified that ready | | 2023-08-30 | Hans Olsson. Review comments | | 2025-04-14 | Hans Olsson. Fix reference | +| 2025-05-07 | Hans Olsson. Minor update | # Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -119,6 +120,18 @@ Note that even if the proposed syntax reuses the `reinit` keyword, it avoids the Step (3) requires that it is a state (guaranteed by (1)), and that it is a continuous variable in a "Clocked Discretized Continuous-Time Partition", as stated at the start. +## Possibly extension to continuous-time + +It may be possible to generalize this to non-clocked partitions. +This is not proposed at the moment, but included to show that a possible generalization. + +The meaning of Real x=reinit(xs); in a non-clocked partition is then: +1. StateSelect.always is set for the variable x. +2. Therefore it is a state and thus participate in the usual index reduction and state selection. +3. During the simulation the state is equal to the new value xs during each model evaluation, instead of the solver integrating its derivative. +(The "derivative" may still exist, but the relation between state and derivative no longer holds.) +5. This declaration equation is ignored for the equation count. + # Backwards Compatibility Will depend on exact syntax. In the proposed alternative it will depend on the measurement keyword; using "reinit" it is fully backwards compatible.