<div dir="ltr"><div dir="ltr"><div><br></div><div>Hi Murray,</div><div><br></div><div>regarding PID tuning of your heading loop -</div><div><br></div><div>have you tried to examine the heading loop step response?</div><div><br></div><div>For example - what happens if you place your robot on that turntable at your desk -</div><div>turn on the PID loop so that the robot tries to maintain a constant heading, without any forward motion -</div><div>then give the turntable various disturbances - especially abrupt step-function changes - where you slew the table 30 or 40 degrees, with the slew-rate change in table rotation speed as high as possible (ie. zero to max turn-rate as quickly as possible, then max turn-rate to zero as quickly as possible).</div><div><br></div><div>If you had a super-beefy motor you could automate turn-table rotation to make a repeatable test-bed.  Otherwise you could just do it by hand.</div><div><br></div><div><div>The robot should try to re-orient itself to maintain the same heading even as you rotate the table underneath it.</div><div><br></div><div>As you observe the robot response - look to see if the heading correction overshoots and rings before it settles on the correct heading, or if it just takes 'forever' to finally creep to the right heading / if it ever even reaches the right heading.</div><div><br></div><div>OR - on a stable surface without the turntable complication -</div><div>perhaps you could do an even better step-response test by adding a tiny bit of code...</div><div><br></div><div>what about adding a software motor drive enable/disable switch, one that you could toggle wirelessly from your laptop?</div><div><ol><li>Give the robot a 'zero' heading set-point with the PID loop and motor drive on - </li><ul><li>let it settle on that heading.</li></ul><li>Then turn the motor drive off, </li><ul><li><b>but leave the PID loop on</b>.</li></ul><li>Then manually turn the robot something like 45 degrees and take your hands off of it.</li><ul><li>At this point, you have introduced a large step error - </li><li>and you're about to ask for the maximum possible slew rate response - a step response</li></ul><li>Then turn the motor drive back on, </li><ul><li>and watch the robot's 'return-to-zero' behavior.</li></ul><li>At first you could iterate steps 1..4 and dial-in PID values just by eyeballing the step-response.</li><ul><li>Your goal is to have the robot 'return-to-zero' as quickly as possible, without overshooting</li></ul><li>But to really dial things in, you could use a video to accurately look for overshoot and measure timing.<br></li></ol></div><div><br></div><div>- Carl</div><div><br></div><div><br></div><div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jan 23, 2021 at 1:28 AM Murray Altheim via DPRGlist <<a href="mailto:dprglist@lists.dprg.org">dprglist@lists.dprg.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Doug,<br>
<br>
My initial question was asking what might be the algorithm for<br>
handling the rug bumps. Finding a Python library that handles this<br>
is great, but I must admit I was still a bit adrift as to how to<br>
actually incorporate it into my robot's behaviour. It'll take me a<br>
bit of time to digest what you've written, and try it out in code<br>
on my robot, but you've actually answered that question, i.e., how<br>
to work out how to take that IMU error and incorporate it into the<br>
robot's motor outputs.<br>
<br>
Thanks very much for that!<br>
<br>
One of the things I keep getting reminded of is that while there's<br>
a lot of focus on fancy sensors and such (but of course!), some of<br>
the more "basic" stuff in robotics is actually pretty tricky to get<br>
right. Precise navigation and odometry is quite difficult, which is<br>
what makes it all the more impressive to see done well.<br>
<br>
Cheers,<br>
<br>
Murray<br>
<br>
On 23/01/21 7:17 pm, <a href="mailto:secretary@dprg.org" target="_blank">secretary@dprg.org</a> wrote:<br>
> Murray,<br>
> <br>
> One approach is to take the theta value from the IMU instead<br>
> of calculating it from the encoders, and then adding the <br>
> heading error to the summing node of the negative feedback loop.<br>
> <br>
> Taking the theta value form the IMU:<br>
> <br>
> /* accumulate total rotation around our center */<br>
> /*theta += (left_inches - right_inches) / WHEEL_BASE; */<br>
> <br>
> /* replace theta value with IMU yaw value */<br>
> theta = read_IMU_yaw();  /* make sure that the units and orientation are correct */<br>
> <br>
> /* and clip the rotation to plus or minus 360 degrees */<br>
> theta -= (float)((int)(theta/TWOPI))*TWOPI;<br>
> <br>
> Now the theta value is from the IMU and should show the impact of<br>
> your rug/floor disturbance.<br>
> <br>
> The next part is to add the heading error (heading error = heading<br>
> target – theta) to the input summing node of your negative feedback<br>
> loop. The heading error is zero when you are going in the right <br>
> direction, elsewise it will have either a negative or positive <br>
> value. It will be summed in with your reference value (desired <br>
> speed in this case) and the -feedback value (PID error). If you <br>
> view it in terms of your PID error, it is like you are changing <br>
> the reference value.<br>
> <br>
> I hope this helps.<br>
...........................................................................<br>
Murray Altheim <murray18 at altheim dot com>                       = =  ===<br>
<a href="http://www.altheim.com/murray/" rel="noreferrer" target="_blank">http://www.altheim.com/murray/</a>                                     ===  ===<br>
                                                                    = =  ===<br>
     In the evening<br>
     The rice leaves in the garden<br>
     Rustle in the autumn wind<br>
     That blows through my reed hut.<br>
            -- Minamoto no Tsunenobu<br>
<br>
_______________________________________________<br>
DPRGlist mailing list<br>
<a href="mailto:DPRGlist@lists.dprg.org" target="_blank">DPRGlist@lists.dprg.org</a><br>
<a href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org" rel="noreferrer" target="_blank">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a><br>
</blockquote></div>