<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Karim,</p>
    <p>That is amazingly cool.  The location accuracy and repeatability
      is excellent.   The first kick you had to give it was actually
      instructive, as it showed the robot still knew where it was
      despite running off course and getting stuck.  And being kicked. 
      Great video angle too, really able to see what the robot is
      doing.  <br>
    </p>
    <p>I have a modest suggestion for the stuck problem watchdog, which
      I've done on a couple of robots.  I'd noticed with my outdoor
      robot that when it is stuck, it's almost always trying to turn. 
      By calculating a Z rate from the wheel encoders and comparing it
      to the IMU Z rate, or even a Z rate gyro, the difference should be
      small most of the time.  But when it's large, your stuck. 
      Basically the wheels say you're turning while the IMU says you're
      not.<br>
    </p>
    <p> Even though the integrated wheel Z rate would not match the IMU
      heading, the instantaneous wheel Z rate is a pretty good match for
      the IMU Z rate.   (Some IMU's don't have a Z rate, so just
      subtract the last heading from the current one to make your own.)</p>
    <p>Then each time about the control loop, the watchdog tests that
      the wheel Z rate and the IMU Z rate are more or less the same,
      within some limit.  Larger than that triggers an escape behavior.</p>
    <p>You don't need full odometery to do the watchdog, just the zrate
      calculation:  <br>
    </p>
    <p>        zrate = (left_encoder_counts - right_encoder_counts) /
      WHEELBASE;  <br>
    </p>
    <p>And WHEELBASE really doesn't need to be carefully tuned, as it's
      not being used to accumulate an accurate location.  Just close
      enough to work, which you can maybe just measure with a ruler. <br>
    </p>
    <p>Anyway, very cool project.  The navigation and location sensing
      are marvelous.  I know how hard that is :)<br>
    </p>
    <p>cheers!</p>
    <p>dpa</p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 9/30/20 3:51 PM, Karim Virani wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAKtnkix=Jh8CjBL=Km59s2UDMw10bOUJe-ci_1ErM9pDcXGLhg@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <div dir="ltr">David, I see what you did there. Totally threw me
        under the bus. As much as I advocate for logging, my teams don't
        always listen to me. I know we have some logs lying around. I
        just don't have much time to look for them. Got a hot lead from
        a Nigerian prince and I really need to jump on that opportunity
        before it slips away...<br>
        <br>
        All kidding aside, I am pretty busy with work and personal stuff
        right now and the team's data is a mess, so I'm not likely to go
        spelunking. There are plenty of folks here to advise about PID.
        Plus I'm also shamefully tolerant of bad (almost good enough?)
        PID as terribly evident in the latest update for my geo-scribing
        robot:<br>
        <br>
        <a href="https://youtu.be/DUaA3fbXoF8?t=25"
          moz-do-not-send="true">https://youtu.be/DUaA3fbXoF8</a><br>
        <br>
        This is the second run through the DPRG pattern. You might want
        to play this at double speed. The robot is only steered by
        precision GPS - there is no vision tracking on the previous
        ground marks. This helps show that we have pretty good results,
        even when the PID is not tuned correctly. We know there are
        encoder and power imbalance issues with the motors on this robot
        and the PID settings were taken from another robot of similar
        size and weight, but never tuned. I'd have gotten away with it
        too - if it wasn't for that pesky i-term and their crazy dog.
        There are some other issues with drop-out of GPS updates that
        are still being worked on.<br>
        <br>
        The robot also gets stuck every so often and needs a bit of a
        nudge. The team is working on a progress failure watchdog to
        maybe kick it into driving both wheels when it stalls,
        overriding the next waypoint. <br>
        <br>
        The ground marks are not very distinct in the video. This dirt
        is very dry right now. The sand on the beach is more likely to
        have moisture underneath. Sometimes after a rain the previous
        day or with morning dew, this softball field leaves better
        tracks:<br>
        <div><br>
        </div>
        <div><br>
        </div>
        <div><img src="cid:part2.FBC72D61.494419E3@smu.edu"
            alt="image.png" class="" width="412" height="254"><br>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, Sep 30, 2020 at 2:38
          PM David Anderson via DPRGlist <<a
            href="mailto:dprglist@lists.dprg.org" moz-do-not-send="true">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">Hey
          Murray,<br>
          <br>
          OK that explains it.  I'd thought the line numbers represented
          equal <br>
          time intervals.  My bad.  So those graphs are basically
          useless.  Ignore.<br>
          <br>
          I've been looking around for a log plot from one of my robots,
          but <br>
          didn't really find anything PID specific.  I know Karim
          encourages his <br>
          teams to log data, perhaps he might have something more
          germane to your <br>
          specific situation.<br>
          <br>
          Here is the closest I could find to a similar plot, the rcat
          robot <br>
          driving in a straight line between two waypoints 10 feet
          apart, and <br>
          rotating 180  degrees at the endpoints, using acceleration and
          <br>
          deceleration ramps for both the straight line and the
          rotations.  The <br>
          log data rate is the same as the control loop rate, which for
          this robot <br>
          is 25 Hz.  So 25 samples per second, 40 ms between data
          points.<br>
          <br>
          <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/rcat-pid-01.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/rcat-pid-01.png</a><br>
          <br>
          The trace of green x'es is the requested velocity, and the
          blue asterisk <br>
          trace is the requested rotation.   So these are the inputs to
          the PID <br>
          controllers.  The pink open boxes and cyan solid boxes are the
          left and <br>
          right power being sent to the motor, so these are the outputs
          of the PID <br>
          controller.<br>
          <br>
          The brown open circles and tan solid circles are the actual
          measured <br>
          left and right wheel velocities from the encoders.  What the
          robot is <br>
          actually doing.  These are the values from which the PID
          proportional <br>
          error, derivative, and integral are derived.<br>
          <br>
          In the first segment the green requested velocity ramps up to
          400 (top <br>
          speed is 1000) and holds there for about 3 seconds, then ramps
          back down <br>
          to zero.  The blue requested rotation stays at or near zero,
          indicating <br>
          the robot is going in a straight line.  The small
          perturbations around 0 <br>
          reflect the navigation behavior keeping the robot pointed
          toward the <br>
          target waypoint as it drives.  To an observer it just looks
          like it's <br>
          driving in a straight line.<br>
          <br>
          Notice the acceleration and deceleration ramps are not
          symmetrical, as <br>
          the up ramp aims for a velocity set point at 400 and is quite
          linear, <br>
          while the down ramp uses the distance_to_target to set the
          velocity and <br>
          has a softer denouement.<br>
          <br>
          When the robot has come to a stop at the end of the first
          segment, the <br>
          green requested velocity trace remains at zero but the blue
          requested <br>
          rotation ramps to -200, causing the robot to rotate in place <br>
          counter-clockwise. You can see that the power (cyan) and
          velocity (tan) <br>
          of the right wheel again ramp up going forward.  But the power
          (pink) <br>
          and velocity (brown) of the left wheel is in reverse, going
          backward. <br>
          Same thing happens for the return trip, except that the
          rotation at the <br>
          end of that segment is clockwise rather than
          counter-clockwise.<br>
          <br>
          Here's a zoom in on the transition from the straight line
          segment to the <br>
          rotation, in which various values go through zero.  Always
          good to check <br>
          out the transitions :)<br>
          <br>
          <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/rcat-pid-02.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/rcat-pid-02.png</a><br>
          <br>
          <br>
          Hope this is useful<br>
          dpa<br>
          <br>
          <br>
          <br>
          On 9/30/20 3:02 AM, Murray Altheim via DPRGlist wrote:<br>
          > Hi David,<br>
          ><br>
          > Thanks *very* much for going to the trouble of plotting
          that data, I'd<br>
          > like to say it's informative, but informative in as you
          say, being<br>
          > confusing.<br>
          ><br>
          > I'll back up a little and explain again what (in theory)
          we're supposed<br>
          > to be seeing. [Notably, I'm still expressing velocity
          from 0.0 to 100.0,<br>
          > not as I eventually intend in cm/sec. The task is to move
          forward<br>
          > exactly 2 meters.]<br>
          ><br>
          > I have a PID class (the actual PID controller), a
          PIDController wrapper<br>
          > class (that gets system configuration, contains the slew
          limiter and<br>
          > the 20Hz loop running in its own thread). There is then
          the Gamepad<br>
          > controller stuff calling a Behaviour class's one_meter()
          method which<br>
          > is providing a script to "move exactly one meter forward"
          behaviour.<br>
          > I've not changed the name but it actually now tries to
          move two meters.<br>
          ><br>
          > We start on line 122 by accelerating from zero to a
          cruising velocity<br>
          > of 50.0 (half of full speed, in theory). The loop that
          does this is a<br>
          > 20Hz loop so I'm relying on the slew limiter (operating
          from the<br>
          > controller, not the PID loop) to not immediately go from
          zero to half<br>
          > speed. You can see this as the setpoint of both port and
          starboard PID<br>
          > controllers goes from 0.003 (line 124) to 50.0 (lines
          1082 and 1095).<br>
          > You can see the encoder's step outputs gradually spread
          apart as the<br>
          > velocity increases, e.g., at 50.0 the messages are about
          60 steps apart.<br>
          ><br>
          > We then cruise at 50.0 velocity until we get to 9/10 of
          the target<br>
          > distance (lines 7296 and 7301), then begin decelerating
          from 50.0 to<br>
          > the targeting velocity of 10.0. You can then see the PID
          output as a<br>
          > gradually decreasing value as it chips away at the
          robot's velocity,<br>
          > until we hit a velocity around 10.0 and begin correcting
          back and<br>
          > forth, small bits of positive and negative outputs around
          line 8428.<br>
          ><br>
          > At lines 9740 and 9767 for the starboard and port PIDs
          resp. we then<br>
          > change the setpoint to 0.0 and begin to actually stop.
          The robot<br>
          > thinks it's stopped at lines 9834 and 9838 when the two
          callback<br>
          > methods are called.<br>
          ><br>
          > *Then* we can see these flurries of PID messages as the
          wheels rock<br>
          > back and forth about 1/8-1/4 of a turn.<br>
          ><br>
          > But up until that point the overall behaviour of the
          robot seems (at<br>
          > least from the outside) to be working fine. The robot
          accelerates at<br>
          > a reasonable rate up to a cruising speed, maintains that
          until the<br>
          > 9/10th point (1.8 meters) then slows to a crawl, stopping
          always<br>
          > about 2cm past the 2m tape mark on the floor. Then that
          rocking<br>
          > behaviour begins. When on the stand it continues
          indefinitely. It's<br>
          > interesting to note that when the robot is on the floor
          it comes<br>
          > to a stop about 2cm past the 2m mark, waits maybe a half
          second,<br>
          > then reverses almost exactly onto the 2m mark. That may
          be a<br>
          > coincidence though. Then it kinda oscillates back a forth
          a bit<br>
          > randomly, what looks like repeated attempts at error
          correction.<br>
          > During all this time the setpoint is 0.0 (as you can see
          in the log<br>
          > during those PID message bursts from around 9844 til line
          10801<br>
          > when I hit the Kill (Home) button and the robot begins to
          shut down.<br>
          ><br>
          > In looking at your gnuplots I don't understand them
          either. The<br>
          > murray-01 shows the setpoint going from 0.0 to 10.0 but
          then<br>
          > dropping back to zero very quickly, which isn't what's
          happening<br>
          > even in the log. E.g., the setpoint reaches 50.0 on line
          1082, which<br>
          > is about 1/10th of the entire journey. It stays at 50.0
          until line<br>
          > 7286 then changes to 10.0 then later on to 0.0.<br>
          ><br>
          > Are you plotting by line number as a fixed time period?
          It should<br>
          > be noted that the logging messages are coming from
          whatever is that<br>
          > first field in the log after the line number, e.g.,
          "pid:stbd" is<br>
          > the starboard PID controller, "motor:port" is the port
          motor. So<br>
          > the messages themselves aren't coming at a fixed rate at
          all, which<br>
          > makes your point about writing timestamps clear as
          necessary in order<br>
          > to plot time on the X axis.<br>
          ><br>
          > At this point I'm going to (since it's the easiest thing)
          to re-hook<br>
          > up the potentiometer so I can fiddle with the I and/or D
          values of<br>
          > the PID controller to see if that makes any difference.
          I'm mostly<br>
          > suspicious of the fact that when the robot comes to a
          velocity of<br>
          > 0.0 just after the 2 meter mark the P is still
          registering an error,<br>
          > which is likely what's causing the rocking behaviour.
          I'll dig into<br>
          > that in what's left of tonight and over the next few days
          as time<br>
          > permits.<br>
          ><br>
          > And thanks again for the plots. It reminds me that being
          able to<br>
          > visualise the data can be a huge help.<br>
          ><br>
          > Cheers,<br>
          ><br>
          > Murray<br>
          ><br>
          > --------<br>
          > PS. I'm not sure if you've heard of it but there's a
          professional<br>
          > software application called Splunk that runs as a web
          service and<br>
          > receives logging data from a cluster of computers,
          providing<br>
          > monitoring, alerting, and some nice data visualisation
          outputs so<br>
          > you can see what your servers are doing. Almost
          everywhere I've<br>
          > worked in the past 5-6 years is using Splunk.<br>
          ><br>
          > Over the past few days I've considered writing a tiny
          version of<br>
          > Splunk in Python, to examine and chart my log data. Turns
          out that<br>
          > Splink and Skink and Splank and Slunk and Slink are all
          taken,<br>
          > though I think some of those actually involve snakes. But
          given<br>
          > that "splink" is pronounced by some Kiwis as "splunk" (in
          the same<br>
          > way that "Nick Cave" sounds like "Nuck Cave" sometimes
          here in New<br>
          > Zealand, I think I'll name it Splink. The other Splink is
          a<br>
          > "Probabilistic record linkage and deduplication at scale"
          which<br>
          > couldn't possibly get confused with my project.<br>
          ><br>
          > So, spurred on by your graphs, if I manage to find the
          time to<br>
          > rewrite my GnuPlot plotter for the PID controller I'll do
          it to<br>
          > instead just analyse the log outputs from Splink, rather
          than<br>
          > write the data generator inside of the PID controller as
          I did<br>
          > in version 1.<br>
          ><br>
          > On 30/09/20 6:45 pm, David Anderson via DPRGlist wrote:<br>
          >> Hi Murray,<br>
          >><br>
          >> I've plotted some of your data.  Here's the error, P,
          setpoint and <br>
          >> output for your port motor:<br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-01.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-01.png</a><br>
          >><br>
          >> I honestly can't make any sense of it at all.  It
          does not look like <br>
          >> a plot from a PID controller.<br>
          >><br>
          >> The oscillations around the set point you describe
          are clearly <br>
          >> obvious. Here's a zoom in on just that portion:<br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-02.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-02.png</a><br>
          >><br>
          >> It  looks like the set point, the blue trace, is
          moving around, not <br>
          >> steady at 0.  So if the PID controller is being
          commanded to do that <br>
          >> it's not its fault if it's oscillating.  Why is that
          value moving <br>
          >> around?<br>
          >><br>
          >> The initial startup is also bit bizarre.  Here's a
          zoom in on that:<br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-03.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-03.png</a><br>
          >><br>
          >> It looks like the P,I,D terms are logged after they
          are already <br>
          >> scaled by their gain constants.  What you need to see
          are the raw <br>
          >> values calculated for the proportional error, the
          derivative error, <br>
          >> and the integral, and the final output power to the
          motors.<br>
          >><br>
          >> Here are similar plots for your right wheel:<br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-04.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-04.png</a><br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-05.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-05.png</a><br>
          >><br>
          >> <a
            href="http://www.geology.smu.edu/dpa-www/robo/data/murray-06.png"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://www.geology.smu.edu/dpa-www/robo/data/murray-06.png</a><br>
          >><br>
          >> It would be very useful to also log the wheel
          velocities.<br>
          >><br>
          >> And a time stamp.<br>
          >><br>
          >> cheers,<br>
          >><br>
          >> David<br>
          >><br>
          >><br>
          >><br>
          >><br>
          >> On 9/29/20 7:24 PM, Murray Altheim via DPRGlist
          wrote:<br>
          >>> Hi,<br>
          >>><br>
          >>> Addressing the hunting behaviour on the KR01
          robot that we've discussed<br>
          >>> previously (i.e., rocking back and forth about
          1/8 of a wheel turn <br>
          >>> after<br>
          >>> stopping), here's a full color (!) log of the
          journey:<br>
          >>><br>
          >>> <a
href="https://service.robots.org.nz/wiki/attach/PIDController/pid_bounce_log.html"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://service.robots.org.nz/wiki/attach/PIDController/pid_bounce_log.html</a>
          <br>
          >>><br>
          >>><br>
          >>> I may mention this in tonight's video discussion,
          thought to provide <br>
          >>> a link<br>
          >>> here. It basically shows the encoder and PID
          controller output as <br>
          >>> the robot<br>
          >>> accelerates to cruising speed then decelerates to
          a slow, targeting <br>
          >>> velocity<br>
          >>> before attempting to stop at the 2 meter mark.<br>
          >>><br>
          >>> Cheers,<br>
          >>><br>
          >>> Murray<br>
          >>><br>
          >>>
...........................................................................
          <br>
          >>><br>
          >>> Murray Altheim <murray18 at altheim dot
          com>                       = <br>
          >>> =  ===<br>
          >>> <a href="http://www.altheim.com/murray/"
            rel="noreferrer" target="_blank" moz-do-not-send="true">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" moz-do-not-send="true">DPRGlist@lists.dprg.org</a><br>
          >>> <a
            href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a><br>
          >> _______________________________________________<br>
          >> DPRGlist mailing list<br>
          >> <a href="mailto:DPRGlist@lists.dprg.org"
            target="_blank" moz-do-not-send="true">DPRGlist@lists.dprg.org</a><br>
          >> <a
            href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a><br>
          ><br>
          <br>
          _______________________________________________<br>
          DPRGlist mailing list<br>
          <a href="mailto:DPRGlist@lists.dprg.org" target="_blank"
            moz-do-not-send="true">DPRGlist@lists.dprg.org</a><br>
          <a href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a><br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>