<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">Howdy<br>
<br>
Karim, I can certainly match your downright nitpickery and am
therefore all in with crotchty oldfartdom. <br>
<br>
The "timing loops" under consideration seem to be a fairly
undifferentiated amalgamation of things that actually require very
different timing constraints. So for example, the ENCODERS on my
robots are maintained by hardware, once setup. Those are in turn
sampled at a regular interval by an interrupt driven from a
hardware timer. So the latency is that of the ARM NVIC hardware,
which is probably as good as can be had. Same is true of the
array of SONAR senors, for example, but with a different timer and
much higher sample rate (*).<br>
<br>
So what is done with that data is that it's read by the various
subsumption behaviors that do their own filtering or whatever.
Those behaviors all run in a single loop with an RTOS
wake_after(40) command at the bottom of the loop. That loop time
on RCAT is more or less 25 Hz. But it can drift around a bit,
depending on how busy the systems is with other RTOS tasks. The
motor PIDS run in that loop. I can make it more precise by using
a PERIOD() call which subtracts off the loop execution time. But
it doesn't make much difference in the robot's performance. At
this upper level it really doesn't matter. The part of the system
that needs the exact hardware timing has already been done. <br>
<br>
My extended point being that there are some robotly tasks that
need close access to the hardware, and others that do not. They
shouldn't be all clumped together as the "loop timing error
problem." They need to be considered separately in terms of their
implementation. <br>
<br>
(*) My experience with the seismic signal processing we do at
work, which is much like what we do in robotics, is that sampling
is best done at very regular intervals, with Nyquist
considerations and such. It massively simplifies all subsequent
signal processsing. In the cases in which that is not possible
and the data are not evenly sampled, and therefore require
individual timestamps, you end up using some sort of interpolation
to remap the data onto a regular grid anyway, for subsequent
processing. But now you're just guessing :) <br>
<br>
We still use lots of time stamps, but those are generally at the
packet level and higher, not the individual samples. So I guess
I'm not sold on that as the solution for the encoder and pid
timing loops that Murray is addressing.<br>
<br>
cheers!<br>
dpa<br>
<br>
<br>
<br>
On 2/18/21 5:40 PM, Karim Virani via DPRGlist wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAKtnkiyXER7dK++bwVExxARhGn-r+h91Ui-xYoNKD=TrH4qhLA@mail.gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<div dir="ltr">David, I see your pedantic and raise by downright
nitpicky,<br>
<br>
David wrote: "Right tool for the job, as the old guys use to
say."<br>
<br>
<div>Agree. Much of the academic and startup robotics community
has decided that linux is very often the right tool. The
question is what is the job?<br>
<br>
Murray wrote: But that's not solving the problem, which is
having a very accurate millisecond timing loop."<br>
and then: "assume an imprecise clock ... that would make our
code more complicated"<br>
<br>
Disagree. My teams and I haven't seen a precise timing loop
since 2014. In fact under Android our loop times are downright
gnarly. Get into the habit of normalizing all time-sensitive
calculations to actual elapsed time and it becomes second
nature. This tends to work for anything that sits in the time
domain of the kind of robot physical motions we'll experience
in hobby / educational robotics. <br>
<br>
I'm not talking about low level bit banging, ISRs or TOF calcs
- or anything like that. If you're trying to solve those kinds
of things with the same general purpose processor you use for
robot governance and behaviors, maybe the goal is the problem.
This is where we look to dedicated (smart) sensors and comms
chips. The trend in that direction is inexorable. <br>
<br>
Now, if you started out with microcontrollers, might as well
use all their capacity. But they may be more suited to
isolated lone-robot applications and maybe not as much to
highly interconnected environments. There may be conflicting
use cases at play here.<br>
<br>
But we don't always follow our own use cases. The real truth
is that we start with what we are comfortable with (or what we
have to use), and stick with it until it proves insufficient.
Hard to argue with that approach. Getting started with
anything goes a lot further than waiting for the perfect
hardware combo to appear before ye.<br>
<br>
RTC's are a baby red herring. RTOS is the papa red herring.
Unless, maybe, if you're landing on Mars...<br>
<br>
Otherwise, [wise-guy voice] don't worry about it.<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, Feb 18, 2021 at 4:08
PM Murray Altheim 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">On
19/02/21 6:03 am, John Swindle via DPRGlist wrote:<br>
> Going back to a previous topic regarding jitter in timing
intervals.<br>
<br>
Hi John,<br>
<br>
I was trying to find a paragraph of text that I saw a few days
ago on some<br>
web page about how the combination of Linux and Python simply
couldn't<br>
provide the kind of precise timing guarantees one can expect
on a<br>
microcontroller, and I certainly don't contest that notion,
i.e., this<br>
mirrors my own experience.<br>
<br>
Just to reiterate the issue (and I hope I've got all this
correctly), Linux<br>
is a time-sharing operating system that cannot guarantee
precise timing at<br>
an application level, even when the hardware it is running on
(e.g., a<br>
Raspberry Pi or Intel 5.3GHz i9) has an accurate system clock,
and may even<br>
have access to an RTC -- noting that an RTC provides an
extremely accurate<br>
long-term clock but typically provides resolution only down to
a second,<br>
not milli- or nanosecond. I.e., an RTC is a bit of a red
herring.<br>
<br>
So running on a time-sharing OS means that any given
application can't be<br>
guaranteed that it will be able to create precise time
intervals at a<br>
nanosecond or millisecond level, since the application's code
is sharing<br>
system resources with the system itself as well as other
applications.<br>
<br>
One of those applications is the base Python/CPthon
interpreter, which is<br>
an imperfect handler of timing, given its imperfect control of
internal<br>
threading.<br>
<br>
So an application can ask the system clock for the number of
milliseconds<br>
or nanoseconds since the Epoch (1 Jan 1970), and the number
returned will<br>
be accurate, but if the application itself is running a timing
loop it<br>
will be polling the system clock limited by its time share,
not the system<br>
clock. So effectively, the loop will falter but know it's
faltering by<br>
being able to compare its time with the system clock.<br>
<br>
> Why can't parameters used in calculations be scaled by
the actual <br>
> sample interval? I understand 50ms is chosen because it
gives <br>
> optimum control without undue overhead. When the actual
interval is,<br>
> say, 47ms, why not scale the time-related parameters to
47/50 of what<br>
> they nominally are, just for that interval? If the next
interval is<br>
> 74ms, scale the parameters to 74/50. Is this impractical?
Is the<br>
> uncertainty of measuring the time interval too large?
This is, if<br>
> Python says the time interval is 47ms, is the error, say,
+/- 10ms?<br>
<br>
So given our understanding of the limitations of timing loops
within a<br>
Python application running on Linux (i.e., not the operating
system's<br>
internal clock), we can assume that with two levels of
"indirection" any<br>
clock loop will run imprecisely.<br>
<br>
So a 50.00ms loop in Python will return values like 50.01ms,
51.3ms,<br>
49.1ms, etc., and during a surge where another application
pulls a lot<br>
of system resources the values might run 54.33ms, 57.56ms,
etc. In other<br>
words, imprecise, intermittently and unpredictably so. You
suggested<br>
that over a longer period, say several minutes, the average
may be close<br>
to 50.0ms but that's not necessarily a safe assumption since
the<br>
cumulative values are subject to cumulative error, and that
error can<br>
be high. One can compare the value with the (accurate) system
clock,<br>
or even with an RTC. But that's not solving the problem, which
is having<br>
a very accurate millisecond timing loop.<br>
<br>
So the other alternative would be to write code to simply
assume an<br>
imprecise clock and capture the per-loop error. The problem is
that we<br>
haven't escaped the basic problem of "being in situ" with our
code. And<br>
that would also make our code more complicated. A PID
controller is<br>
itself already rather tricky to tune. Having an imprecise
clock doesn't<br>
make that any easier.<br>
<br>
I'm looking into another alternative, since my KR01 has an
Itsy Bitsy M4<br>
on board that is currently not being used. I'm thinking of
using it as<br>
an external clock, triggering a GPIO pin as an interrupt on
the Pi.<br>
<br>
Cheers,<br>
<br>
Murray<br>
<br>
...........................................................................<br>
Murray Altheim <murray18 at altheim dot com>
= = ===<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>
</blockquote>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
DPRGlist mailing list
<a class="moz-txt-link-abbreviated" href="mailto:DPRGlist@lists.dprg.org">DPRGlist@lists.dprg.org</a>
<a class="moz-txt-link-freetext" href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a>
</pre>
</blockquote>
<br>
</body>
</html>