{"id":853,"date":"2012-06-11T13:54:57","date_gmt":"2012-06-11T18:54:57","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/?p=853"},"modified":"2012-06-11T13:54:57","modified_gmt":"2012-06-11T18:54:57","slug":"writing-your-own-block-with-discrete-states-matlab-s-function","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2012\/06\/11\/writing-your-own-block-with-discrete-states-matlab-s-function\/","title":{"rendered":"Writing your own block with discrete states (MATLAB S-Function)"},"content":{"rendered":"<p>A few weeks ago, I noticed the following question on <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/\">MATLAB Answers<\/a> by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/contributors\/1596298-k-e\">K E<\/a>:<\/p>\r\n\r\n<p><em><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/36663-what-are-continuous-and-discrete-states-in-simulink\">What are continuous and discrete states in Simulink?<\/a><\/em><\/p>\r\n\r\n<p>In my opinion, the best way to understand how states work in Simulink is by implementing an S-Function. So this week we will see how to create a MATLAB S-Function with discrete states.<\/p>\r\n\r\n<p>If you are not familiar with MATLAB S-Functions, I recommend looking at my previous post introducing the <a href=\"https:\/\/blogs.mathworks.com\/seth\/2012\/05\/23\/how-to-make-your-own-blocks-with-code-introduction-to-s-functions\/\">basics of MATLAB S-Functions<\/a><\/p>\r\n\r\n<p><strong>What is a state?<\/strong><\/p>\r\n\r\n<p>Before starting to implement our S-Function, let's see the answer my friend <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/contributors\/1280935-kaustubha-govind\">Kaustubha Govind<\/a> provided to the above question:<\/p>\r\n\r\n<p><em>In my own words, a crude word to use in place of \"state\" is \"memory\". A state adds memory to a system in such a way that the output at a given time depends not only on its current input, but also on its previous inputs. There is a more formal explanation about states <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/ug\/f7-20739.html#f7-23387\">here<\/a>.<\/em><\/p>\r\n\r\n<p><em>Discrete states can be thought purely as internal memory - for example a <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/slref\/unitdelay.html\">Unit Delay<\/a> block has one discrete state...<\/em><\/p>\r\n\r\n<p>Let's stop here and see how to implement a Unit Delay in a MATLAB S-Function.<\/p>\r\n\r\n<p><strong>Setup<\/strong><\/p>\r\n\r\n<p>In the <tt>setup<\/tt> function, we define one parameter, one input port and one output port.<\/p>\r\n\r\n<p><em>Direct Feedthrough?<\/em><\/p>\r\n\r\n<p>\"Does this block have Direct Feedthrough?\" This is the question Simulink needs to know to determine the sorting order for all the blocks in the model.  Direct feedthrough means that the <tt>Outputs<\/tt> function uses the input variable in its calculation. Since we are not planning to use the input value in the <tt>Outputs<\/tt> function to calculate the output value, we can set the <tt>DirectFeedthrough<\/tt> property of the input port to false.<\/p>\r\n\r\n<p>Finally, we need to register 4 methods: <tt>PostPropagationSetup<\/tt>, <tt>InitializeConditions<\/tt>, <tt>Outputs<\/tt> and <tt>Update<\/tt>.<\/p>\r\n\r\n<p>Here is how this looks:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2012Q2\/setup_discrete.png\" alt=\"setup function of a Unit Delay\"><\/p>\r\n\r\n<p><strong>Post Propagation Setup<\/strong><\/p>\r\n\r\n<p>In terms of S-Function, the discrete state is stored in what we call a <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/sfg\/brd0qif.html\">work vector<\/a>, the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/sfg\/brd0qif-1.html\">Dwork<\/a>. The properties of the work vector are defined in the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/sfg\/mdlsetworkwidths.html\">DoPostPropSetup<\/a> callback method.<\/p>\r\n\r\n<p>In our case, we need one Dwork vector, of dimension 1, and we want to mark it as a discrete state:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2012Q2\/DoPostPropSetup.png\" alt=\"Declaring a Dwork vector\"><\/p>\r\n\r\n<p>Setting the <tt>UsedAsDiscState<\/tt> to <tt>true<\/tt> makes the states visible to the Simulink engine. That way it will be included if we save the model states and will be seen by <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2012a\/toolbox\/simulink\/slref\/simulink.blockdiagram.getinitialstate.html\"><tt>Simulink.BlockDiagram.getInitialState<\/tt><\/a>. If you prefer to hide the internal state of your block, you can set <tt>UsedAsDiscState<\/tt> to <tt>false<\/tt>.<\/p>\r\n\r\n<p><strong>Initial Conditions<\/strong><\/p>\r\n\r\n<p>When the simulation starts, you can set the initial value of the state. Here we do it using a dialog parameter<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2012Q2\/InitCondition.png\" alt=\"Initializing the work vector\"><\/p>\r\n\r\n<p><strong>Outputs<\/strong><\/p>\r\n\r\n<p>Now the simulation loop can start. First, the <tt>Outputs<\/tt> method of the block is called. We read the value stored in the work vector and assign it to the output port:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2012Q2\/discrete_output.png\" alt=\"Output method of the unit delay S-Function\"><\/p>\r\n\r\n<p><strong>Update<\/strong><\/p>\r\n\r\n<p>After the <tt>Outputs<\/tt> method is completed, we grab the input and store it in the work vector. This is done in the <tt>Update<\/tt> method:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2012Q2\/delay_update.png\" alt=\"Update method of the unit delay S-Function\"><\/p>\r\n\r\n<p>The next time the <tt>Outputs<\/tt> method runs, this value will be available.<\/p>\r\n\r\n<p><strong>Conclusion<\/strong><\/p>\r\n\r\n<p>It is important to realize here that Simulink does nothing to the discrete states. The solver only stores the values to be used in the next step.<\/p>\r\n\r\n<p>Next week, we will follow a similar process with continuous states.<\/p>\r\n\r\n<p><strong>Now it's your turn<\/strong><\/p>\r\n\r\n<p>Share your S-Function experiences by leaving a <a href=\"https:\/\/blogs.mathworks.com\/seth\/?p=853&#comment\">comment here<\/a>.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>A few weeks ago, I noticed the following question on MATLAB Answers by K E:\r\n\r\nWhat are continuous and discrete states in Simulink?\r\n\r\nIn my opinion, the best way to understand how states work in... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2012\/06\/11\/writing-your-own-block-with-discrete-states-matlab-s-function\/\">read more >><\/a><\/p>","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[67,87],"tags":[269,459],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/853"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=853"}],"version-history":[{"count":44,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/853\/revisions"}],"predecessor-version":[{"id":1046,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/853\/revisions\/1046"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}