{"id":1547,"date":"2013-06-05T18:34:16","date_gmt":"2013-06-05T10:34:16","guid":{"rendered":"http:\/\/blog.lolyco.com\/sean\/?p=1547"},"modified":"2013-06-05T18:34:16","modified_gmt":"2013-06-05T10:34:16","slug":"lejos-pidcontroller-not-working-output-is-zero","status":"publish","type":"post","link":"https:\/\/blog.lolyco.com\/sean\/2013\/06\/05\/lejos-pidcontroller-not-working-output-is-zero\/","title":{"rendered":"LeJOS PIDController not working, output is zero"},"content":{"rendered":"<p>This problem had me baffled for more than a few minutes: I wrote a <a href=\"http:\/\/lejos.sourceforge.net\/\">leJOS<\/a> <a href=\"http:\/\/lejos.sourceforge.net\/nxt\/nxj\/api\/lejos\/util\/PIDController.html\">PIDController<\/a> loop for a <a href=\"http:\/\/mindstorms.lego.com\/en-gb\/default.aspx\">LEGO NXT<\/a> project that used one motor&#8217;s rotation encoder as the input to control another motor&#8217;s set point. It didn&#8217;t work: the output from the PIDController&#8217;s doPID(int) was reliably zero. My loop seemed quite reasonable: read encoder from motor A, apply it to setpoint of motorB&#8217;s PIDController, read motorB&#8217;s encoder, apply it to motorB&#8217;s PIDController as the &#8216;process variable&#8217;, get controller output, apply it with motorB&#8217;s setPower() method. It didn&#8217;t work!<\/p>\n<p>I found the answer in lejos.util.PIDController&#8217;s source, in setPIDParam(int paramID, float value):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">case PIDController.PID_SETPOINT:\r\n  this.setpoint = (int)value;\r\n  this.cycleTime = 0;\r\n  break;<\/pre>\n<p>and in doPID(int processVariable):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">if (this.cycleTime==0) {\r\n  this.cycleTime = System.currentTimeMillis();\r\n  return 0;\r\n}<\/pre>\n<p>Setting the setpoint resets the cycle time and the next invocation of doPID returns zero! I don&#8217;t understand why it&#8217;s necessary to reset cycleTime on change of setpoint, but that&#8217;s what the leJOS code does. I kludged around it in my code by only invoking setPIDParam if the setpoint has changed and doPID works as expected.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This problem had me baffled for more than a few minutes: I wrote a leJOS PIDController loop for a LEGO NXT project that used one motor&#8217;s rotation encoder as the input to control another motor&#8217;s set point. It didn&#8217;t work: the output from the PIDController&#8217;s doPID(int) was reliably zero. My loop seemed quite reasonable: read [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30,50],"tags":[75,103,76],"class_list":["post-1547","post","type-post","status-publish","format-standard","hentry","category-breaktime","category-foss","tag-lego","tag-lejos","tag-mindstorms"],"_links":{"self":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/1547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/comments?post=1547"}],"version-history":[{"count":2,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/1547\/revisions"}],"predecessor-version":[{"id":1549,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/1547\/revisions\/1549"}],"wp:attachment":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/media?parent=1547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/categories?post=1547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/tags?post=1547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}