{"id":389,"date":"2013-02-25T16:41:05","date_gmt":"2013-02-26T00:41:05","guid":{"rendered":"http:\/\/micromouseusa.com\/?p=389"},"modified":"2013-02-26T18:19:20","modified_gmt":"2013-02-27T02:19:20","slug":"an-easy-pid-function","status":"publish","type":"post","link":"http:\/\/micromouseusa.com\/?p=389","title":{"rendered":"an easy PID function"},"content":{"rendered":"<p>As what I promised, I will post my simply PID(PD) controller code here:<\/p>\n<p><span style=\"color: #ff9900;\">void PID(void)\u00a0\u00a0 \u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff9900;\">{\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0if((leftSensor &gt; hasLeftWall &amp;&amp; rightSensor &gt; hasRightWall))\/\/has both walls<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0{\u00a0 \/\/ccw direction is positive<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorP = rightSensor &#8211; leftSensor<\/span> <span style=\"color: #ff9900;\">&#8211; 63;\/\/63 is the offset between left and right sensor when mouse in the middle of cell<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorD = errorP &#8211; oldErrorP;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0}\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0\u00a0 else if((leftSensor &gt; hasLeftWall))\/\/only has left wall<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0{<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorP = 2 * (leftMiddleValue &#8211; leftSensor);<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorD = errorP &#8211; oldErrorP;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0else if((rightSensor &gt; hasRightWall))\/\/only has right wall<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0{<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorP = 2 * (rightSensor &#8211; rightMiddleValue);<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorD = errorP &#8211; oldErrorP;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0else if((leftSensor &lt; hasLeftWall &amp;&amp; rightSensor &lt;hasRightWall))\/\/no wall, use encoder or gyro<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0{<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorP = 0;\/\/(leftEncoder &#8211; rightEncoder*1005\/1000)*3;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorD = 0;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0totalError = P * errorP + D * errorD;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0 \u00a0oldErrorP = errorP;<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0\u00a0 setLeftPwm(leftBaseSpeed &#8211; totalError);<\/span><br \/>\n<span style=\"color: #ff9900;\">\u00a0\u00a0\u00a0 setRightPwm(rightBaseSpeed + totalError);\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff9900;\">}<\/span><\/p>\n<p>It works pretty well especially if you don&#8217;t have a high resolution encoder or accelerometer as feedback. If you use high resolution encoder to generate your own speed profile, you will need to add sensor error onto rotational error associated with encoder for PID.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As what I promised, I will post my simply PID(PD) controller code here: void PID(void)\u00a0\u00a0 \u00a0\u00a0 \u00a0 {\u00a0\u00a0 \u00a0 \u00a0\u00a0 \u00a0if((leftSensor &gt; hasLeftWall &amp;&amp; rightSensor &gt; hasRightWall))\/\/has both walls \u00a0\u00a0 \u00a0{\u00a0 \/\/ccw direction is positive \u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0errorP = rightSensor &hellip; <a href=\"http:\/\/micromouseusa.com\/?p=389\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[7],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/389"}],"collection":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=389"}],"version-history":[{"count":6,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/389\/revisions"}],"predecessor-version":[{"id":415,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/389\/revisions\/415"}],"wp:attachment":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=389"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}