UNSUBSCRIBE




----- Original Message -----
From: "Keith R. Bolson" <krbolson-at-visi.com>
To: "Multiple recipients of list" <emc-at-nist.gov>
Sent: Thursday, January 31, 2002 4:29 AM
Subject: RESOLVED: EMC is poorly designed and implemented.


>
> RESOLVED: EMC is poorly designed and implemented.
>
>   I'm an old gray haired assembly hacker and cycle counter with some
> experience in closed-loop motion control.  I have been investigating
> EMC, principally emcmot.c and have come to the conclusion that EMC is
> poorly designed and implemented.  I don't mean to be discourteous,
> but you do not have a good solid product, nor will you without
> a major redesign.  I will support this conclusion in the following.
>
>   What I see in the implementation is wasteful, redundant access to
> I/O ports, lack of insight into floating point speed considerations,
> poor factorization into subroutines and far too many scattered ifdefs
> for reliable code.
>
>   Modern motion control should be adaptive, using Kalman filters, and
> state-space or observer predictor methods.  EMC by design uses PIDs,
> which are from old 1930s analog computers.  PIDs tuned via Ziegler
> Nichols methods are inherently prone to oscillation and instability.
> (The zeros don't cover poles, or drift into right hand plane, etc
> as the dynamics of the plant change with temperature and load.)
>
>   A 8-bit 6502 or 8051 running at 1 MHz could do a nice job of running
> stepper motors in 1978.  Without double precision, 32-bit integers
> or 800MHz clock rates.  Servos were harder, but still possible.  Today
> yoy can go to http://www.jrkerr.com/ and buy a PIC-STEP or PIC-SERVO
> with software for a reasonable price with software that'll get you up
> and running twenty times faster than EMC.
>
> Look at the source code (30-Jan-2002 sourceforge emcmot.c), lines 2422ff
> the polling of the max and min limit switches, home and axis fault bits.
> This is within the for loop on line 2373
>
> L2373    for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
>
>   This is very poorly done, the exact same bits are read repeated,
> (for extsmmot.c) with over one microsecond per pptDioRead inportb
> call.  That's (3 axes)*(4 switches)=12 microseconds, with 16 us
> listed as the max.  Only one 1 us read is required.  The situation
> is worse in stgmod.c, where 4 bytes are read, so it takes 48 us.
> Folks - i/o port access always takes over a microsecond, regardless
> of the speed of your i86 processors.  Reading the same bits
> repeatedly in critical code is foolish and wasteful.
>
>   I believe the choice to poll and debounce these switches within
> the motion loop (rather than, say, using a hardware interrupt or
> a slower emcio task read and debounce), is a very unwise design
> decision.  Furthermore, American and European safety standards
> REQUIRE that hard limit switches bring the machine down even if
> the processor is non-functional.  Meaning the limit switches, through
> a dumb relay, should drop main power to the motors.  So on commercial
> machines, you don't need to check the limit switches, you'll E-stop
> if you hit them.  As implemented here, EMC is likely to be HAZARDEOUS
> to the health of its users.
>
>   And there's this over-dependence upon double precision numbers
> when single or integers will suffice.  For example, in the external
> interface to stgmod.c, passing the raw encoders and dacs as double arrays,
> when they're integers on all hardware, doubles the subroutine call time,
> and then the subroutine itself has to convert it to an integer.
>
>   Floating point is very fast these days, but it still takes time.
> Even on Pentiums, double precision floating point is about half as fast
> as single or integer arithmetic.  Divides take about twice as long as
> multiples.  A subroutine call takes about as long as an integer add
> for each 32-bit parameter.  These are ballpark figures, much affected
> by caching, out-of-order and speculative execution.
>
> So code like on emcmot.c line 2397,
>   L2397  if (fabs(emcmotStatus->input[axis] - emcmotDebug->oldInput[axis])
/
>   L2398      emcmotConfig->servoCycleTime > emcmotDebug->bigVel[axis]) {
> Would be 50% faster if expressed as
>   M2397  if (fabs(emcmotStatus->input[axis] - emcmotDebug->oldInput[axis])
>   M2398      > emcmotConfig->servoCycleTime * emcmotDebug->bigVel[axis]) {
> But both servoCycleTime and bigVel are infrequently changed - on a
> explicit command, dump bigVel for bigLeap=bigVel*cycleTime and have
>   N2397  if (fabs(emcmotStatus->input[axis] - emcmotDebug->oldInput[axis])
>   N2398      > emcmotDebug->bigLeap[axis]) {
> which by my tests on 233 and 800MHz machines, would take about a third
> as long.  I see the "debounce bad feedback" has been changed, it indicates
> a very serious hardware error which still is not logged or reported.
>
> You may consider this the ranting of a dinosaur or as constructive
> critism - as you choose.
>
> God Bless America, President Bush and our fighting men and women.
> --krb
>
>
>
>




Date Index | Thread Index | Back to archive index | Back to Mailing List Page

Problems or questions? Contact