{"id":3492,"date":"2014-04-03T16:30:28","date_gmt":"2014-04-03T21:30:28","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/?p=3492"},"modified":"2017-10-10T10:12:59","modified_gmt":"2017-10-10T15:12:59","slug":"control-system-tuning-without-guess-or-stress","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2014\/04\/03\/control-system-tuning-without-guess-or-stress\/","title":{"rendered":"Control System Tuning without Guess or Stress"},"content":{"rendered":"<p><!--introduction--><\/p>\n<p>This week I am happy to welcome guest bloggers Pascal Gahinet, Suat Gumussoy, <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/87056\">Erman Korkut<\/a>, and Mathieu Cuenant to introduce systune and the new Control System Tuner app from <a href=\"https:\/\/www.mathworks.com\/products\/robust\/\">Robust Control Toolbox<\/a>.<\/p>\n<p><!--\/introduction--><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/SystuneTeam.png\" alt=\"Systune team\" \/><\/p>\n<p><strong>The Cure for Tuning Headaches<\/strong><\/p>\n<p>Simulink makes it easy to model and simulate feedback control systems. But how do you pick the gains of your controller to get adequate performance and robustness? Simple enough when tuning a single PI loop, harder for control systems with multiple loops, configurations, and operating conditions. You probably use a combination of know-how, experience, trial-and-error, and home-grown tools. Wouldn\u2019t it be nice if you could just enter your specifications and let the computer figure out the gain values? Welcome to <tt>systune<\/tt>!<\/p>\n<p><strong>Tuning Workflow in Simulink<\/strong><\/p>\n<p>To see how this works, let\u2019s tune a cascade controller for setting and regulating the speed of a DC motor. This controller consists of two feedback loops: an inner loop for controlling the current in the armature, and an outer loop for controlling the motor speed. Both loops use digital proportional-integral (PI) controllers, so there is a total of four gains to tune.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/systune_model.png\" alt=\"DC Motor Controller\" \/><\/p>\n<p>The first step is to create a <a href=\"https:\/\/www.mathworks.com\/help\/slcontrol\/ug\/sltuner.html\"><tt>slTuner<\/tt><\/a> object for interacting with your Simulink model and to specify which blocks you want to tune:<\/p>\n<pre class=\"codeinput\">ST0 = slTuner(<span class=\"string\">'DCMotor'<\/span>,{<span class=\"string\">'SpeedController'<\/span>,<span class=\"string\">'CurrentController'<\/span>});<\/pre>\n<p>Next, you list the signals and points of interest for tuning and validation. For example, the reference signal Ref and the output Speed will come handy for specifying how fast the control system should respond and for checking the actual response of the tuned system.<\/p>\n<pre class=\"codeinput\">addPoint(ST0,{<span class=\"string\">'Ref'<\/span> , <span class=\"string\">'Speed'<\/span> , <span class=\"string\">'SpeedMeas'<\/span> , <span class=\"string\">'CurrentMeas'<\/span>});<\/pre>\n<p>If these two steps look familiar, it\u2019s because <tt>slTuner<\/tt> is just an extension of the <a href=\"https:\/\/www.mathworks.com\/help\/slcontrol\/ug\/sllinearizer.html\"><tt>slLinearizer<\/tt><\/a> interface we discussed in this <a href=\"https:\/\/blogs.mathworks.com\/seth\/2013\/10\/16\/sllinearizer-batch-linearization-of-simulink-models\/\">earlier blog post<\/a>.<\/p>\n<p>Third and last step, you specify the tuning goals, that is, how the control system is supposed to perform. There is a lot to choose from, with goals ranging from tracking and disturbance rejection to loop shape, stability margins, and minimum closed-loop damping. For the DC motor application, I use the following goals:<\/p>\n<ul>\n<li><strong>Goal 1:<\/strong> The closed-loop system should respond to a step change in Speed setpoint with time constant of 0.05 seconds (rise time of about 0.1 seconds)<\/li>\n<li><strong>Goal 2:<\/strong> The inner (current) loop should have a bandwidth of about 200 Hz.<\/li>\n<\/ul>\n<p>I use the <tt>StepResp<\/tt> and <tt>LoopShape<\/tt> objects from the <tt>TuningGoal<\/tt> library to express these goals:<\/p>\n<pre class=\"codeinput\">Goal1 = TuningGoal.StepResp(<span class=\"string\">'Ref'<\/span>,<span class=\"string\">'Speed'<\/span>,0.05);\r\nBandWidth = 2*pi*200;   <span class=\"comment\">% 200 Hz in rad\/s<\/span>\r\nGoal2 = TuningGoal.LoopShape(<span class=\"string\">'CurrentMeas'<\/span>,BandWidth);\r\nGoal2.Openings = <span class=\"string\">'SpeedMeas'<\/span>;\r\n<\/pre>\n<p>Note that the inner-loop bandwidth should be evaluated with the outer loop open, so I specify a loop opening at the location SpeedMeas in the Simulink model.<\/p>\n<p>I can now launch the tuning algorithm:<\/p>\n<pre class=\"codeinput\">ST1 = systune(ST0,[Goal1,Goal2]);<\/pre>\n<pre class=\"codeoutput\">Final: Soft = 0.802, Hard = -Inf, Iterations = 60<\/pre>\n<p>Each tuning goal receives a normalized score and <tt>systune<\/tt> works on improving the overall score. A final score \u2264 1 means \u201cpass\u201d and a final score &gt; 1 means \u201cfail\u201d. Here <tt>systune<\/tt> did well with a score of 0.8, and plotting the tuning goals confirms that the tuned responses are dead on spec:<\/p>\n<pre class=\"codeinput\">viewSpec([Goal1,Goal2],ST1)<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/tuner_response.png\" alt=\"Tuned System\" \/><\/p>\n<p>The <tt>slTuner<\/tt> object <tt>ST1<\/tt> represents the tuned control system and I can use it to access other system response for further validation. This is entirely similar to the <a href=\"https:\/\/blogs.mathworks.com\/seth\/2013\/10\/16\/sllinearizer-batch-linearization-of-simulink-models\/\"><tt>slLinearizer<\/tt><\/a> workflow. For example, I can use <tt>getLoopTransfer<\/tt> to compute the stability margins of the current loop:<\/p>\n<pre class=\"codeinput\">L = getLoopTransfer(ST1,<span class=\"string\">'CurrentMeas'<\/span>,-1);\r\nmargin(L), grid <span class=\"string\">on<\/span>\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/tuner_response2.png\" alt=\"Tuned System\" \/><\/p>\n<p>When I am happy with the linear analysis results, I use writeBlockValue to push the tuned values of the PI gains to the Simulink model and perform additional validation in Simulink.<\/p>\n<pre class=\"codeinput\">writeBlockValue(ST1)<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/tuner_results.png\" alt=\"Tuned System\" \/><\/p>\n<p><strong>Control System Tuner App<\/strong><\/p>\n<p>With the new Control System Tuner app, you can do all the above without a single line of code! You launch this app from the \u201cAnalysis\u201d menu in the Simulink model. Here is what it looks like:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/systune_blog.gif\" alt=\"Control System Tuner app\" \/><\/p>\n<p><strong>Now It&#8217;s Your Turn<\/strong><\/p>\n<p>There is a lot more you can do with <tt>systune<\/tt> and <tt>slTuner<\/tt>:<\/p>\n<ul>\n<li>Tune any linear block in your model: Gain, PID Controller, Transfer Function, State Space, etc<\/li>\n<li>Tune <a href=\"https:\/\/www.mathworks.com\/videos\/control-system-tuning-in-simulink-made-easy-81839.html\">any control architecture<\/a>, no matter the layout, number of feedback loops, and number or type of tuned blocks<\/li>\n<li>Tune the controller against multiple models of the plant representing different operating conditions or parameter values<\/li>\n<li>Tune <a href=\"https:\/\/www.mathworks.com\/videos\/automatic-tuning-of-gain-scheduled-controllers-86776.html\">gain-scheduled controllers<\/a>. These are controllers whose gains vary with operating condition, for example, with engine speed in a diesel engine or air speed in an aircraft.<\/li>\n<\/ul>\n<p>Check out the many <a href=\"\">examples and applications<\/a> and try it on your control system. And as usual, we&#8217;d love to <a href=\"https:\/\/blogs.mathworks.com\/seth\/?p=3492\ufffd\">hear your thoughts<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2014Q2\/systune_blog.gif\" onError=\"this.style.display ='none';\" \/><\/div>\n<p><!--introduction--><\/p>\n<p>This week I am happy to welcome guest bloggers Pascal Gahinet, Suat Gumussoy, <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/87056\">Erman Korkut<\/a>, and Mathieu Cuenant to introduce systune and the new Control System Tuner app from <a href=\"https:\/\/www.mathworks.com\/products\/robust\/\">Robust Control Toolbox<\/a>.<\/p>\n<p><!--\/introduction-->&#8230; <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2014\/04\/03\/control-system-tuning-without-guess-or-stress\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[115,16],"tags":[247,374,441],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/3492"}],"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=3492"}],"version-history":[{"count":29,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/3492\/revisions"}],"predecessor-version":[{"id":6789,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/3492\/revisions\/6789"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=3492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=3492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=3492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}