{"id":174,"date":"2012-01-22T07:55:40","date_gmt":"2012-01-22T12:55:40","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/?p=174"},"modified":"2012-01-22T07:55:40","modified_gmt":"2012-01-22T12:55:40","slug":"advanced-s-function-techniques-scheduling-future-events","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2012\/01\/22\/advanced-s-function-techniques-scheduling-future-events\/","title":{"rendered":"Advanced S-function Techniques: Scheduling Future Events"},"content":{"rendered":"<p>Today I will describe how to use a variable sample time s-function to schedule events in the future. This topic is fairly advanced, so hold on tight... or as we say where I come from: <a href=\"http:\/\/www.urbandictionary.com\/define.php?term=Tuque&defid=1008089\">Attachez vos tuques avec d'la broche<\/a><\/p>\r\n\r\n<p><strong>The question<\/strong><\/p>\r\n\r\n<p>The question I received is:<\/p>\r\n\r\n<p><em>I have a model with a variable sample time solver. In this model, I have a signal with a continuous sample time, but discontinuous amplitude. Every time the signal changes amplitude, I need to trigger a subsystem. But I do not want to trigger the subsystem immediately. I need to trigger after fixed delay.<\/em><\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/InitialProblem.png\" alt=\"Original Model\"><\/p>\r\n\r\n<p><strong>First attempt<\/strong><\/p>\r\n\r\n<p>The first thing the user tried is delaying the signal using the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/slref\/transportdelay.html\">Transport Delay<\/a> block and detecting the changes in the delayed signals.<\/p>\r\n\r\n<p>As I explained in a <a href=\"https:\/\/blogs.mathworks.com\/seth\/2011\/09\/20\/troubleshooting-the-transport-delay-block\/\">previous post<\/a>, the Transport Delay expects a smoothly changing continuous signal.  When fed a signal with discontinuities, the output of the Transport Delay is not exactly the input offset by a delay. This is the situation we encounter as shown in this image below.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/FirstAttempt.png\" alt=\"Delaying the input signal\"><\/p>\r\n\r\n<p><strong>Variable Sample Time<\/strong><\/p>\r\n\r\n<p>One way for a block to tell the Simulink solver to take steps at a specific moment in the future is to specify <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/ug\/brrdmmw-5.html#brrdmmw-11\">variable sample time<\/a>. For example, the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/slref\/pulsegenerator.html\">Pulse Generator<\/a> block uses this technique to run only when needed.<\/p>\r\n\r\n<p>If I make a model with the Pulse Generator block configured to have a period of 5s and a pulse width of 40%, the block will tell the variable step solver to take steps at times 0s, 2s, 5s, 7s, 10s,...<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/VariableSampleTime.png\" alt=\"Pulse Generator, a Variable Sample Time block\"><\/p>\r\n\r\n<p><strong>Variable Sample Time S-function<\/strong><\/p>\r\n\r\n<p>With an s-function, you can do the same!<\/p>\r\n\r\n<p>For a basic example, look at the demo model <tt>sfcndemo_vsfunc.mdl<\/tt>. This model shows how to use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdlgettimeofnextvarhit.html\"><tt>mdlGetTimeOfNextVarHit<\/tt><\/a> to specify the next time your block should run.<\/p>\r\n\r\n<p><strong>The solution<\/strong><\/p>\r\n\r\n<p>Based on that, we want to write an s-function that will look at its input every major step of the simulation. When a change will be detected, we will store the time value in a buffer. Every time an event will be generated, we will look into this buffer and schedule the next event.<\/p>\r\n\r\n<p>In S-function specific terms, this means: <\/p>\r\n\r\n<ul>\r\n\r\n\t<li>In <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdlinitializesizes.html\">mdlInitializeSizes<\/a>, we specify the size of the buffer using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/sssetnumrwork.html\">ssSetNumRWork<\/a> . We also define an integer work vector using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/sssetnumiwork.html\">ssSetNumIWork<\/a> to keep the index of events coming in and out of the buffer.<\/li>\r\n\r\n\t<li> In <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdlinitializesampletimes.html\">mdlInitializeSampleTimes<\/a>, we declare 2 sample times: Fixed in <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/ug\/brrdmmw-5.html#brrdmmw-11\">Minor<\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/ug\/brrdmmw-5.html#brrdmmw-11\">Variable<\/a>. The fixed in minor sample time will allow us to monitor each sample of the input signal for detected changes and the variable sample time will be used to generate the events.<\/li>\r\n\r\n\t<li> In <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdlupdate.html\">mdlUpdate<\/a>, we monitor the input. If a change is detected, we store the time in the work vector.<\/li>\r\n\r\n\t<li>Every time a variable sample time is hit, the solver calls <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdlgettimeofnextvarhit.html\">mdlGetTimeOfNextVarHit<\/a> to obtain the time of the next variable sample time hit. When this happens, we look into the work vector to get the time of the next event and use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/sssettnext.html\">ssSetTNext<\/a> to register it.<\/li>\r\n\r\n\t<li>In <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/mdloutputs.html\">mdlOutputs<\/a>, we use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/ssissamplehit.html\">ssIsSampleHit<\/a> to know if the current step is a hit of the variable sample time. If this is the case, we generate a function call using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011b\/toolbox\/simulink\/sfg\/sscallsystemwithtid.html\">ssCallSystemWithTid<\/a>.<\/li>\r\n\r\n<\/ul>\r\n\r\n<p>When this is all implemented, I have a block that can schedule events in the future<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/finalModel.png\" alt=\"Final Model\"><\/p>\r\n\r\n<p>For those interested to see the final results, here are links to the <a href=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/delayed_event.mdl\">model<\/a> and the <a href=\"https:\/\/blogs.mathworks.com\/images\/seth\/2011Q4\/schedule_event.c\">s-function source code<\/a>.<\/p>\r\n\r\n<p><strong>Now it's your turn<\/strong><\/p>\r\n\r\n<p>Do you use variable sample times in your model? Leave us a <a href=\"https:\/\/blogs.mathworks.com\/seth\/?p=174&amp;#comment\">comment here<\/a>.<\/p>\r\n\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Today I will describe how to use a variable sample time s-function to schedule events in the future. This topic is fairly advanced, so hold on tight... or as we say where I come from: Attachez vos... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2012\/01\/22\/advanced-s-function-techniques-scheduling-future-events\/\">read more >><\/a><\/p>","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[71,87],"tags":[240,239],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/174"}],"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=174"}],"version-history":[{"count":7,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/174\/revisions"}],"predecessor-version":[{"id":332,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/174\/revisions\/332"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}