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

Reply via email to