The x86 has 80-bit floating-point registers, but doubles in RAM are only 64 bits wide. Storing a register to RAM results in truncation and loss of precision.
The driver has a bug where a value in RAM (stepgen.maxvel param) is compared to an arithmetic result (physical maxvel) computed from inputs in RAM (stepgen timing params). If maxvel is too high, it prints a warning and sets maxvel to the physical max. However, this assignment is a store from a register to RAM, so it loses precision, and the print gets hit again next servo period. Jeff's fix (implemented in this patch) is to force the computed value down to 64 bits after the computation, before doing the comparison. --- debian/changelog | 4 +++- src/hal/drivers/mesa-hostmot2/stepgen.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/debian/changelog b/debian/changelog index 1dd58eb..e1b548b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,8 +6,10 @@ emc2 (1:2.3.3~pre) hardy; urgency=low * interpreter: show error instead of silently continuing for certain rejected forms of G76 * documentation improvements + * hm2 bugfix: avoid occasionally filling the system log when + stepgen.maxvel is too high for the timings - -- Jeff Epler <jep...@unpythonic.net> Tue, 14 Jul 2009 21:35:59 -0500 + -- Sebastian Kuzminsky <s...@highlab.com> Fri, 24 Jul 2009 09:39:58 -0600 emc2 (1:2.3.2) hardy; urgency=low diff --git a/src/hal/drivers/mesa-hostmot2/stepgen.c b/src/hal/drivers/mesa-hostmot2/stepgen.c index 1e7616c..0e9ea93 100644 --- a/src/hal/drivers/mesa-hostmot2/stepgen.c +++ b/src/hal/drivers/mesa-hostmot2/stepgen.c @@ -191,6 +191,15 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period } +// This function was invented by Jeff Epler. +// It forces a floating-point variable to be degraded from native register +// size (80 bits on x86) to C double size (64 bits). +static double force_precision(double d) __attribute__((__noinline__)); +static double force_precision(double d) { + return d; +} + + static void hm2_stepgen_instance_prepare_tram_write(hostmot2_t *hm2, long l_period_ns, int i) { double new_vel; @@ -212,6 +221,7 @@ static void hm2_stepgen_instance_prepare_tram_write(hostmot2_t *hm2, long l_peri double max_steps_per_s = 1.0e9 / min_ns_per_step; physical_maxvel = max_steps_per_s / fabs(s->hal.param.position_scale); + physical_maxvel = force_precision(physical_maxvel); if (s->hal.param.maxvel < 0.0) { HM2_ERR("stepgen.%02d.maxvel < 0, setting to its absolute value\n", i); -- 1.5.4.3 ------------------------------------------------------------------------------ _______________________________________________ Emc-developers mailing list Emc-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/emc-developers