From 3f5c935dd8585a0024bbde20099283e9b8aec54f Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sat, 12 Sep 2026 21:47:42 +0200 Subject: [PATCH] change external offset to float --- .../dynamic_offsets_panel.hal | 5 +- .../sim/axis/external_offsets/eoffsets.txt | 2 +- .../sim/axis/external_offsets/eoffsets_es.txt | 2 +- .../sim/axis/external_offsets/jwp_z_panel.hal | 2 +- .../qtdragon_hd_xyz/qtdragon_hd_postgui.hal | 13 +- .../qtdragon_hd_postgui.hal | 13 +- .../1280x1024_5axis/woodpecker_handler.py | 10 +- docs/src/config/ini-config.adoc | 2 +- docs/src/gui/qtdragon.adoc | 13 +- docs/src/man/man9/motion.9.adoc | 5 +- docs/src/motion/external-offsets.adoc | 6 +- .../screens/qtdragon/qtdragon_handler.py | 2 +- .../qtdragon_hd/qtdragon_hd_handler.py | 6 +- .../qtdragon_hd_vert_handler.py | 6 +- .../qtdragon_lathe/qtdragon_lathe_handler.py | 2 +- .../screens/qtplasmac/qtplasmac_handler.py | 2 +- src/emc/motion/axis.c | 22 ++- src/hal/components/eoffset_per_angle.comp | 8 +- src/hal/components/plasmac.comp | 167 ++++++++++-------- src/hal/components/updown.comp | 2 + src/hal/user_comps/z_level_compensation.py | 6 +- 21 files changed, 163 insertions(+), 133 deletions(-) diff --git a/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal b/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal index 2595ac3d9dd..286fa1a3837 100644 --- a/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal +++ b/configs/sim/axis/external_offsets/dynamic_offsets_panel.hal @@ -1,12 +1,10 @@ loadrt siggen names=gen loadrt scale names=scalea -loadrt conv_float_s32 names=cvt loadrt not names=nota loadrt or2 names=or2a addf gen.update servo-thread addf scalea servo-thread -addf cvt servo-thread addf nota servo-thread addf or2a servo-thread @@ -23,8 +21,7 @@ net E:frequency <= pyvcp.gen-frequency => gen.frequency # can also use sawtooth (others inappropriate on a reset) net G:waveform <= gen.sine => scalea.in -net G:swaveform <= scalea.out => cvt.in -net G:counts <= cvt.out => axis.z.eoffset-counts +net G:counts <= scalea.out => axis.z.eoffset-counts net E:enable <= pyvcp.z-enable => axis.z.eoffset-enable net E:enable => nota.in diff --git a/configs/sim/axis/external_offsets/eoffsets.txt b/configs/sim/axis/external_offsets/eoffsets.txt index 0af5ef6d7ed..120ebd77aaa 100644 --- a/configs/sim/axis/external_offsets/eoffsets.txt +++ b/configs/sim/axis/external_offsets/eoffsets.txt @@ -21,6 +21,6 @@ Input hal pins: axis.L.eoffset-enable (bit) axis.L.eoffset-clear (bit) axis.L.eoffset-scale (float) - axis.L.eoffset-counts (s32) + axis.L.eoffset-counts (float) Requested offset == counts*scale diff --git a/configs/sim/axis/external_offsets/eoffsets_es.txt b/configs/sim/axis/external_offsets/eoffsets_es.txt index 0559ac2a288..84cbdfe1753 100644 --- a/configs/sim/axis/external_offsets/eoffsets_es.txt +++ b/configs/sim/axis/external_offsets/eoffsets_es.txt @@ -21,6 +21,6 @@ Pines Input hal: axis.L.eoffset-enable (bit) axis.L.eoffset-clear (bit) axis.L.eoffset-scale (float) - axis.L.eoffset-counts (s32) + axis.L.eoffset-counts (float) Offset solicitado == counts*scale diff --git a/configs/sim/axis/external_offsets/jwp_z_panel.hal b/configs/sim/axis/external_offsets/jwp_z_panel.hal index 848151cd8c4..1d5f4c072e9 100644 --- a/configs/sim/axis/external_offsets/jwp_z_panel.hal +++ b/configs/sim/axis/external_offsets/jwp_z_panel.hal @@ -3,7 +3,7 @@ addf zctr servo-thread net E:z-plus <= pyvcp.z-plus => zctr.countup net E:z-minus <= pyvcp.z-minus => zctr.countdown -net E:z-counts <= zctr.count => axis.z.eoffset-counts +net E:z-counts <= zctr.count-f => axis.z.eoffset-counts net E:z-scale <= pyvcp.z-scale => axis.z.eoffset-scale net E:z-offset <= axis.z.eoffset => pyvcp.z-offset-f net E:limited <= motion.eoffset-limited => pyvcp.limited diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal index 10273528865..2b495e43010 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_postgui.hal @@ -5,8 +5,9 @@ loadrt logic names=logic-and personality=0x102 addf logic-and servo-thread # load a summing component for adding spindle lift and Z compensation -loadrt scaled_s32_sums -addf scaled-s32-sums.0 servo-thread +# (eoffset counts are floats, so sum2 rather than scaled_s32_sums) +loadrt sum2 +addf sum2.0 servo-thread loadusr -Wn z_level_compensation z_level_compensation # method parameter must be one of nearest(2), linear(1), cubic (0) @@ -51,8 +52,8 @@ net zpos-cmd z_level_compensation.z-pos <= axis.z.pos-cmd net z_compensation_on z_level_compensation.enable-in <= qtdragon.comp-on net eoffset-zlevel-count z_level_compensation.counts => qtdragon.eoffset-zlevel-count -net eoffset-spindle-count scaled-s32-sums.0.in0 -net eoffset-zlevel-count scaled-s32-sums.0.in1 -setp scaled-s32-sums.0.scale0 1000 -net eoffset-counts scaled-s32-sums.0.out-s +net eoffset-spindle-count sum2.0.in0 +net eoffset-zlevel-count sum2.0.in1 +setp sum2.0.gain0 1000 +net eoffset-counts sum2.0.out diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal b/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal index 567b82e52fb..a4a3bc26b71 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal +++ b/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_postgui.hal @@ -5,8 +5,9 @@ loadrt logic names=logic-and personality=0x102 addf logic-and servo-thread # load a summing component for adding spindle lift and Z compensation -loadrt scaled_s32_sums -addf scaled-s32-sums.0 servo-thread +# (eoffset counts are floats, so sum2 rather than scaled_s32_sums) +loadrt sum2 +addf sum2.0 servo-thread loadusr -Wn z_level_compensation z_level_compensation # method parameter must be one of nearest(2), linear(1), cubic (0) @@ -51,8 +52,8 @@ net zpos-cmd z_level_compensation.z-pos <= axis.z.pos-cmd net z_compensation_on z_level_compensation.enable-in <= qtdragon.comp-on net eoffset-zlevel-count z_level_compensation.counts => qtdragon.eoffset-zlevel-count -net eoffset-spindle-count scaled-s32-sums.0.in0 -net eoffset-zlevel-count scaled-s32-sums.0.in1 -setp scaled-s32-sums.0.scale0 1000 -net eoffset-counts scaled-s32-sums.0.out-s +net eoffset-spindle-count sum2.0.in0 +net eoffset-zlevel-count sum2.0.in1 +setp sum2.0.gain0 1000 +net eoffset-counts sum2.0.out diff --git a/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py b/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py index 4efd28be1c6..c77133c120b 100644 --- a/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py +++ b/configs/sim/woodpecker/1280x1024_5axis/woodpecker_handler.py @@ -283,15 +283,15 @@ def init_pins(self): # external offset control pins QHAL.newpin("eoffset-enable", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newpin("eoffset-clear", QHAL.HAL_BIT, QHAL.HAL_OUT) - QHAL.newpin("eoffset-spindle-count", QHAL.HAL_S32, QHAL.HAL_OUT) - QHAL.newpin("eoffset-count", QHAL.HAL_S32, QHAL.HAL_OUT) + QHAL.newpin("eoffset-spindle-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) + QHAL.newpin("eoffset-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) - pin = QHAL.newpin("eoffset-value", QHAL.HAL_S32, QHAL.HAL_IN) + pin = QHAL.newpin("eoffset-value", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.value_changed.connect(self.eoffset_changed) - pin = QHAL.newpin("eoffset-zlevel-count", QHAL.HAL_S32, QHAL.HAL_IN) + pin = QHAL.newpin("eoffset-zlevel-count", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.value_changed.connect(self.comp_count_changed) - pin = QHAL.newpin("comp-count", QHAL.HAL_S32, QHAL.HAL_IN) + pin = QHAL.newpin("comp-count", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.value_changed.connect(self.compensate_count_changed) pin = QHAL.newpin("map-ready", Qhal.HAL_BIT, Qhal.HAL_IN) pin.value_changed.connect(self.map_ready_changed) diff --git a/docs/src/config/ini-config.adoc b/docs/src/config/ini-config.adoc index 9f932eb01cb..4ee50873644 100644 --- a/docs/src/config/ini-config.adoc +++ b/docs/src/config/ini-config.adoc @@ -1058,7 +1058,7 @@ Example: `loadrt motmod ... unlock_joints_mask=0x38` creates unlock-pins for joi [source,hal] ---- axis..eoffset-enable -axis..eoffset-count +axis..eoffset-counts axis..eoffset-scale ---- diff --git a/docs/src/gui/qtdragon.adoc b/docs/src/gui/qtdragon.adoc index 692eac20a5d..339f3af49f2 100644 --- a/docs/src/gui/qtdragon.adoc +++ b/docs/src/gui/qtdragon.adoc @@ -838,8 +838,9 @@ loadrt logic names=logic-and personality=0x102 addf logic-and servo-thread # load a summing component for adding spindle lift and Z compensation -loadrt scaled_s32_sums -addf scaled-s32-sums.0 servo-thread +# (eoffset counts are floats, so sum2 rather than scaled_s32_sums) +loadrt sum2 +addf sum2.0 servo-thread loadusr -Wn z_level_compensation z_level_compensation # method parameter must be one of nearest(2), linear(1), cubic (0) @@ -872,10 +873,10 @@ net z_compensation_on z_level_compensation.enable-in <= qtdragon.comp-on net eoffset-zlevel-count z_level_compensation.counts => qtdragon.eoffset-zlevel-count # add Z level and scaled spindle raise level values together -net eoffset-spindle-count scaled-s32-sums.0.in0 -net eoffset-zlevel-count scaled-s32-sums.0.in1 -setp scaled-s32-sums.0.scale0 1000 -net eoffset-counts scaled-s32-sums.0.out-s +net eoffset-spindle-count sum2.0.in0 +net eoffset-zlevel-count sum2.0.in1 +setp sum2.0.gain0 1000 +net eoffset-counts sum2.0.out ---- diff --git a/docs/src/man/man9/motion.9.adoc b/docs/src/man/man9/motion.9.adoc index 0270a7930d6..682a3162026 100644 --- a/docs/src/man/man9/motion.9.adoc +++ b/docs/src/man/man9/motion.9.adoc @@ -317,13 +317,14 @@ These pins represent the *commanded geometric intent* from the interpreter and a Current external offset. **axis.**_L_**.eoffset-clear** IN BIT:: Clear external offset request -**axis.**_L_**.eoffset-counts** IN S32:: +**axis.**_L_**.eoffset-counts** IN FLOAT:: Counts input for external offset. The eoffset-counts are transferred to an internal register. The applied external offset is the product of the register counts and the eoffset-scale value. The register is *reset to zero at each machine startup*. If the machine is turned off with an external offset active, the eoffset-counts pin should be set - to zero before restarting. + to zero before restarting. Non-finite values (NaN, infinity) are + ignored. **axis.**_L_**.eoffset-enable** IN BIT:: Enable for external offset (also requires INI file setting for [AXIS_L]OFFSET_AV_RATIO) **axis.**_L_**.eoffset-request** OUT FLOAT:: diff --git a/docs/src/motion/external-offsets.adoc b/docs/src/motion/external-offsets.adoc index 9548d705a4a..de630282cea 100644 --- a/docs/src/motion/external-offsets.adoc +++ b/docs/src/motion/external-offsets.adoc @@ -48,7 +48,7 @@ For each axis letter (*_L_* in xyzabcuvw) . *axis._L_.eoffset-enable* Input(bit): enable . *axis._L_.eoffset-scale* Input(float): scale factor -. *axis._L_.eoffset-counts* Input(s32): input to counts register +. *axis._L_.eoffset-counts* Input(float): input to counts register . *axis._L_.eoffset-clear* Input(bit): clear requested offset . *axis._L_.eoffset* Output(float): current external offset . *axis._L_.eoffset-request* Output(float): requested external offset @@ -68,7 +68,9 @@ pins used for wheel jogging. At each servo period, the 'axis._L_.eoffset-counts' pin is compared to its value in the prior period. The increase or decrease (positive or negative delta) of the 'axis._L_.eoffset-counts' pin is multiplied -by the current 'axis._L_.eoffset-scale' pin value. This product is +by the current 'axis._L_.eoffset-scale' pin value. The pin is a float, +so the counts need not be whole numbers; a non-finite value (NaN or +infinity) is ignored and leaves the register unchanged. This product is accumulated in an internal register and exported to the 'axis._L_.eoffset-request' HAL pin. The accumulation register is reset to zero at each machine-on. diff --git a/share/qtvcp/screens/qtdragon/qtdragon_handler.py b/share/qtvcp/screens/qtdragon/qtdragon_handler.py index e6460795b0e..d040ba7edd2 100644 --- a/share/qtvcp/screens/qtdragon/qtdragon_handler.py +++ b/share/qtvcp/screens/qtdragon/qtdragon_handler.py @@ -359,7 +359,7 @@ def init_pins(self): QHAL.newPin("eoffset-enable", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newPin("eoffset-clear", QHAL.HAL_BIT, QHAL.HAL_OUT) self.h['eoffset-clear'] = True - QHAL.newPin("eoffset-spindle-count", QHAL.HAL_S32, QHAL.HAL_OUT) + QHAL.newPin("eoffset-spindle-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) pin = QHAL.newPin("eoffset-is-active", QHAL.HAL_BIT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.external_offset_state_changed(v)) diff --git a/share/qtvcp/screens/qtdragon_hd/qtdragon_hd_handler.py b/share/qtvcp/screens/qtdragon_hd/qtdragon_hd_handler.py index fcba159bd4b..015471ff2ce 100644 --- a/share/qtvcp/screens/qtdragon_hd/qtdragon_hd_handler.py +++ b/share/qtvcp/screens/qtdragon_hd/qtdragon_hd_handler.py @@ -288,8 +288,8 @@ def init_pins(self): QHAL.newPin("eoffset-enable", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newPin("eoffset-clear", QHAL.HAL_BIT, QHAL.HAL_OUT) self.h['eoffset-clear'] = False - QHAL.newPin("eoffset-spindle-count", QHAL.HAL_S32, QHAL.HAL_OUT) - QHAL.newPin("eoffset-count", QHAL.HAL_S32, QHAL.HAL_OUT) + QHAL.newPin("eoffset-spindle-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) + QHAL.newPin("eoffset-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) pin = QHAL.newPin("eoffset-is-active", QHAL.HAL_BIT, QHAL.HAL_IN) @@ -297,7 +297,7 @@ def init_pins(self): pin = QHAL.newPin("eoffset-value", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.external_offset_state_changed(v)) - pin = QHAL.newPin("eoffset-zlevel-count", QHAL.HAL_S32, QHAL.HAL_IN) + pin = QHAL.newPin("eoffset-zlevel-count", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.comp_count_changed(v)) QHAL.newPin("comp-on", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newPin("spindle-lift-on", QHAL.HAL_BIT, QHAL.HAL_OUT) diff --git a/share/qtvcp/screens/qtdragon_hd_vert/qtdragon_hd_vert_handler.py b/share/qtvcp/screens/qtdragon_hd_vert/qtdragon_hd_vert_handler.py index 589c95b4959..a4cd06e6dbc 100644 --- a/share/qtvcp/screens/qtdragon_hd_vert/qtdragon_hd_vert_handler.py +++ b/share/qtvcp/screens/qtdragon_hd_vert/qtdragon_hd_vert_handler.py @@ -288,8 +288,8 @@ def init_pins(self): QHAL.newPin("eoffset-enable", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newPin("eoffset-clear", QHAL.HAL_BIT, QHAL.HAL_OUT) self.h['eoffset-clear'] = False - QHAL.newPin("eoffset-spindle-count", QHAL.HAL_S32, QHAL.HAL_OUT) - QHAL.newPin("eoffset-count", QHAL.HAL_S32, QHAL.HAL_OUT) + QHAL.newPin("eoffset-spindle-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) + QHAL.newPin("eoffset-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) pin = QHAL.newPin("eoffset-is-active", QHAL.HAL_BIT, QHAL.HAL_IN) @@ -297,7 +297,7 @@ def init_pins(self): pin = QHAL.newPin("eoffset-value", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.external_offset_state_changed(v)) - pin = QHAL.newPin("eoffset-zlevel-count", QHAL.HAL_S32, QHAL.HAL_IN) + pin = QHAL.newPin("eoffset-zlevel-count", QHAL.HAL_FLOAT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.comp_count_changed(v)) QHAL.newPin("comp-on", Qhal.HAL_BIT, Qhal.HAL_OUT) QHAL.newPin("spindle-lift-on", Qhal.HAL_BIT, Qhal.HAL_OUT) diff --git a/share/qtvcp/screens/qtdragon_lathe/qtdragon_lathe_handler.py b/share/qtvcp/screens/qtdragon_lathe/qtdragon_lathe_handler.py index e1a480d7ffe..6b85d2fadd1 100644 --- a/share/qtvcp/screens/qtdragon_lathe/qtdragon_lathe_handler.py +++ b/share/qtvcp/screens/qtdragon_lathe/qtdragon_lathe_handler.py @@ -349,7 +349,7 @@ def init_pins(self): QHAL.newPin("eoffset-enable", QHAL.HAL_BIT, QHAL.HAL_OUT) QHAL.newPin("eoffset-clear", QHAL.HAL_BIT, QHAL.HAL_OUT) self.h['eoffset-clear'] = True - QHAL.newPin("eoffset-spindle-count", QHAL.HAL_S32, QHAL.HAL_OUT) + QHAL.newPin("eoffset-spindle-count", QHAL.HAL_FLOAT, QHAL.HAL_OUT) pin = QHAL.newPin("eoffset-is-active", QHAL.HAL_BIT, QHAL.HAL_IN) pin.pinValueChanged.connect(lambda p,v: self.external_offset_state_changed(v)) diff --git a/share/qtvcp/screens/qtplasmac/qtplasmac_handler.py b/share/qtvcp/screens/qtplasmac/qtplasmac_handler.py index dfdaeab8c85..b6d28f49e99 100644 --- a/share/qtvcp/screens/qtplasmac/qtplasmac_handler.py +++ b/share/qtvcp/screens/qtplasmac/qtplasmac_handler.py @@ -925,7 +925,7 @@ def make_hal_pins(self): self.xOffsetPin = self.h.newpin('x_offset', hal.HAL_FLOAT, hal.HAL_IN) self.yOffsetPin = self.h.newpin('y_offset', hal.HAL_FLOAT, hal.HAL_IN) self.zHeightPin = self.h.newpin('z_height', hal.HAL_FLOAT, hal.HAL_IN) - self.zOffsetPin = self.h.newpin('z_offset_counts', hal.HAL_S32, hal.HAL_IN) + self.zOffsetPin = self.h.newpin('z_offset_counts', hal.HAL_FLOAT, hal.HAL_IN) self.xMinPierceExtentPin = self.h.newpin('x_min_pierce_extent', hal.HAL_FLOAT, hal.HAL_IN) self.xMaxPierceExtentPin = self.h.newpin('x_max_pierce_extent', hal.HAL_FLOAT, hal.HAL_IN) self.yMinPierceExtentPin = self.h.newpin('y_min_pierce_extent', hal.HAL_FLOAT, hal.HAL_IN) diff --git a/src/emc/motion/axis.c b/src/emc/motion/axis.c index 9e1908a6aa4..abc7209e71e 100644 --- a/src/emc/motion/axis.c +++ b/src/emc/motion/axis.c @@ -23,7 +23,7 @@ typedef struct { double ext_offset_vel_limit; /* upper limit of axis speed for ext offset */ double ext_offset_acc_limit; /* upper limit of axis accel for ext offset */ - int old_eoffset_counts; + double old_eoffset_counts; simple_tp_t ext_offset_tp; /* planner for external coordinate offsets*/ } emcmot_axis_t; @@ -44,7 +44,7 @@ typedef struct { hal_bool_t eoffset_enable; hal_bool_t eoffset_clear; - hal_sint_t eoffset_counts; + hal_real_t eoffset_counts; hal_real_t eoffset_scale; hal_real_t external_offset; hal_real_t external_offset_requested; @@ -135,7 +135,7 @@ int axis_init_hal_io(int mot_comp_id) CALL_CHECK(hal_pin_new_bool(mot_comp_id, HAL_OUT, &axis_data->teleop_tp_enable, 0, "axis.%c.teleop-tp-enable",c)); CALL_CHECK(hal_pin_new_bool(mot_comp_id, HAL_IN, &axis_data->eoffset_enable, 0, "axis.%c.eoffset-enable", c)); CALL_CHECK(hal_pin_new_bool(mot_comp_id, HAL_IN, &axis_data->eoffset_clear, 0, "axis.%c.eoffset-clear", c)); - CALL_CHECK(hal_pin_new_si32(mot_comp_id, HAL_IN, &axis_data->eoffset_counts, 0, "axis.%c.eoffset-counts", c)); + CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_IN, &axis_data->eoffset_counts, 0.0, "axis.%c.eoffset-counts", c)); CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_IN, &axis_data->eoffset_scale, 0.0, "axis.%c.eoffset-scale", c)); CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_OUT, &axis_data->external_offset, 0.0, "axis.%c.eoffset", c)); CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_OUT, &axis_data->external_offset_requested, @@ -486,7 +486,7 @@ bool axis_plan_external_offsets(double servo_period, bool motion_enable_flag, bo int n; emcmot_axis_t *axis; axis_hal_t *axis_data; - int new_eoffset_counts, delta; + double new_eoffset_counts, delta, increment; static int last_eoffset_enable[EMCMOT_MAX_AXIS]; double ext_offset_epsilon; bool eoffset_active = 0; @@ -499,7 +499,14 @@ bool axis_plan_external_offsets(double servo_period, bool motion_enable_flag, bo axis_data = &hal_data->axis[n]; - new_eoffset_counts = hal_get_si32(axis_data->eoffset_counts); + new_eoffset_counts = hal_get_real(axis_data->eoffset_counts); + /* eoffset-counts is a float pin, so a HAL writer can hand us a + non-finite value. Latching it would make every subsequent delta + NaN as well, so keep the previous value and let delta come out + zero instead. */ + if (!isfinite(new_eoffset_counts)) { + new_eoffset_counts = axis->old_eoffset_counts; + } delta = new_eoffset_counts - axis->old_eoffset_counts; axis->old_eoffset_counts = new_eoffset_counts; @@ -548,7 +555,10 @@ bool axis_plan_external_offsets(double servo_period, bool motion_enable_flag, bo if (!all_homed) { continue; } if (!motion_enable_flag) { continue; } - axis->ext_offset_tp.pos_cmd += delta * hal_get_real(axis_data->eoffset_scale); + increment = delta * hal_get_real(axis_data->eoffset_scale); + if (!isfinite(increment)) { continue; } + + axis->ext_offset_tp.pos_cmd += increment; hal_set_real(axis_data->external_offset_requested, axis->ext_offset_tp.pos_cmd); } // for n first_pass = 0; diff --git a/src/hal/components/eoffset_per_angle.comp b/src/hal/components/eoffset_per_angle.comp index aa0922c148b..8f08f60f55a 100644 --- a/src/hal/components/eoffset_per_angle.comp +++ b/src/hal/components/eoffset_per_angle.comp @@ -6,9 +6,9 @@ description An offset is computed (from one of several functions) based on an input angle in degrees. The angle could be a rotary coordinate value or a spindle angle. -The computed offset is represented as an s32 *kcounts* output pin that is a +The computed offset is represented as a float *kcounts* output pin that is a compatible input to external offset pins like *axis.L.eoffset-counts* where *L* -is the coordinate letter. Scaling of the s32 *kcounts* is controlled by the +is the coordinate letter. Scaling of the *kcounts* value is controlled by the input (*k*) -- its reciprocal value is presented on an output pin *kreciprocal* for connection to *axis.L.eoffset-scale*. The default value for *k* should be suitable for most uses. @@ -77,7 +77,7 @@ pin out bool is_off "invert is_on (for convenience)"; pin out bool enable_out "To: axis.L.eoffset-enable"; pin out bool clear "To: axis.L.eoffset-clear"; -pin out si32 kcounts "To: axis.L.eoffset-counts"; +pin out real kcounts "To: axis.L.eoffset-counts"; pin out real kreciprocal "To: axis.L.eoffset-scale (1/k)"; pin out real eoffset_dbg "offset (debug pin--use kcounts & kreciprocal)"; @@ -137,7 +137,7 @@ static ofunc func0,func1,func2,func3; #define LVL RTAPI_MSG_INFO #define dprint(msg,n) do { \ rtapi_set_msg_level(LVL); \ - rtapi_print_msg(LVL,"%20s %5d\n",msg,n); \ + rtapi_print_msg(LVL,"%20s %9.3f\n",msg,(double)(n)); \ } while (0) #else #define dprint(msg,n) diff --git a/src/hal/components/plasmac.comp b/src/hal/components/plasmac.comp index 92a9ba5b432..c8d5e86b6fe 100644 --- a/src/hal/components/plasmac.comp +++ b/src/hal/components/plasmac.comp @@ -213,11 +213,11 @@ pin out bool thc_enabled "thc is enabled"; pin out bool torch_on "turn torch on, connect to your torch on input"; pin out real torch_time "torch on time of current job"; pin out bool voidlock_is_locked "voidlock is locked indicator [mode 0 & mode 1]"; -pin out si32 x_offset_counts "x offset for consumable change, connect to axis.x.eoffset-counts"; +pin out real x_offset_counts "x offset for consumable change, connect to axis.x.eoffset-counts"; pin out bool xy_offset_enable "enable x and y offsets, connect to axis..eoffset-enable"; -pin out si32 y_offset_counts "y offset for consumable change, connect to axis.y.eoffset-counts"; +pin out real y_offset_counts "y offset for consumable change, connect to axis.y.eoffset-counts"; pin out real z_height "current z axis height relative to the probed zero height"; -pin out si32 z_offset_counts "z offset for height control, connect to axis.z.eoffset-counts"; +pin out real z_offset_counts "z offset for height control, connect to axis.z.eoffset-counts"; pin out bool z_offset_enable "enable z offsets, connect to axis.z.eoffset-enable"; pin out real z_relative "distance of Z from last probed height"; @@ -236,72 +236,72 @@ variable double axis_y_finish; /* axis y position at end of cut */ variable double axis_y_start; /* axis y position at start of cut */ variable int cons_change_clear; /* consumable change is clearing */ variable int count; /* for counting */ -variable int cut_height_first; /* cut height at start of cut */ -variable int cut_height_last; /* cut height at end of cut */ +variable double cut_height_first; /* cut height at start of cut */ +variable double cut_height_last; /* cut height at end of cut */ variable double cut_offset; /* offset from last cut end to this cut start */ variable bool cut_started; /* cut has started */ -variable int cut_target; /* cut height target offset */ +variable double cut_target; /* cut height target offset */ variable bool error_message; /* 1 if error message has been sent */ variable bool first_cut_finished; /* first cut is complete */ variable bool float_detected; /* float switch detected */ -variable int height_ovr_counts; /* number of counts to change height via override */ +variable double height_ovr_counts; /* number of counts to change height via override */ variable double height_ovr_old; /* old height override value */ variable bool initialized; /* initialization flag */ -variable int laser_x_target; /* target count for laser recovery x offset */ -variable int laser_y_target; /* target count for laser recovery y offset */ +variable double laser_x_target; /* target count for laser recovery x offset */ +variable double laser_y_target; /* target count for laser recovery y offset */ variable double last_arc_voltage; /* last sensed arc voltage */ variable bool manual_cut; /* manual cut mode is active */ -variable int offset_datum; /* datum for safe height calcs */ +variable double offset_datum; /* datum for safe height calcs */ variable bool offset_limit_error = false; /* has an offset error been reported (prevents repeat messages)*/ -variable int offset_max; /* maximum allowed offset */ -variable int offset_min; /* minimum allowed offset */ +variable double offset_max; /* maximum allowed offset */ +variable double offset_min; /* minimum allowed offset */ variable double offset_probe_timer; /* offset probe deployment delay time */ variable bool offset_probing; /* offset probing is enabled */ variable int offset_res; /* resolution for comparing offset move to target*/ variable bool offset_set; /* probe or scribe is being offset*/ -variable int offset_velocity; /* velocity for probe offset moves */ +variable double offset_velocity; /* velocity for probe offset moves */ variable int ohmic_attempts; /* current ohmic probe attempts */ variable bool ohmic_detected; /* true if ohmic probe detected */ variable int ohmic_sense_counts; /* ohmic sense debounce counter */ variable int ok_sampler_samples; /* required number of arc ok samples [mode0] */ variable int old_resolution; /* previous resolution value */ -variable int op_x_start; /* x offset when offset probing started */ -variable int op_x_target; /* target offset for x probe offset */ -variable int op_x_velocity; /* velocity for x probe offset */ +variable double op_x_start; /* x offset when offset probing started */ +variable double op_x_target; /* target offset for x probe offset */ +variable double op_x_velocity; /* velocity for x probe offset */ variable double op_xy_angle; /* angle for x/y probe offset calcs in radians*/ -variable int op_y_start; /* y offset when offset probing started */ -variable int op_y_target; /* target offset for y probe offset */ -variable int op_y_velocity; /* velocity for y probe offset */ +variable double op_y_start; /* y offset when offset probing started */ +variable double op_y_target; /* target offset for y probe offset */ +variable double op_y_velocity; /* velocity for y probe offset */ variable double pause_at_end_timer; /* pause at end of cut timer */ variable double paused_motion_timer; /* minimum run timer for paused motion */ variable double pid_error_now; /* current error for pid calcs */ variable double pid_error_old; /* old error for pid calcs */ variable double pid_output; /* calculated pid output value */ -variable int pierce_target; /* pierce height target offset */ +variable double pierce_target; /* pierce height target offset */ variable double pierce_timer; /* pierce delay timer */ variable double probe_at_bottom; /* probe is at bottom limit */ variable bool probe_inhibit; /* inhibit probing */ -variable int probe_offset; /* offset for active probe */ +variable double probe_offset; /* offset for active probe */ variable bool probe_required = 1; /* a probe sequence is required */ variable bool probe_retry; /* probe will retry after contact before probe height */ -variable int probe_start_target; /* probe start height target */ +variable double probe_start_target; /* probe start height target */ variable bool probe_testing; /* probe test active */ -variable int probe_velocity; /* probe down velocity */ +variable double probe_velocity; /* probe down velocity */ variable int puddle_jump_percent; /* puddle jump height as percentage of pierce height */ -variable int puddle_jump_target; /* puddle jump height target offset */ +variable double puddle_jump_target; /* puddle jump height target offset */ variable double puddle_jump_timer; /* puddle jump delay timer */ variable double recovery_velocity; /* cut recovery step velocity */ variable int res; /* resolution of offset move*/ variable double restart_timer; /* time between torch on attempts*/ -variable int safe_alarm; /* warn if safe_available falls below this value during a cut */ -variable int safe_available; /* available safe height */ -variable int safe_min; /* minimum safe height allowed */ -variable int safe_preferred; /* preferred safe height offset */ -variable int safe_target; /* safe height target offset */ +variable double safe_alarm; /* warn if safe_available falls below this value during a cut */ +variable double safe_available; /* available safe height */ +variable double safe_min; /* minimum safe height allowed */ +variable double safe_preferred; /* preferred safe height offset */ +variable double safe_target; /* safe height target offset */ variable double scribe_arm_timer; /* scribe timer from arm to on*/ variable double scribe_on_timer; /* scribe timer from on to motion*/ variable bool scribe_pause; /* scribe pause flag */ -variable int setup_velocity; /* velocity for setup moves */ +variable double setup_velocity; /* velocity for setup moves */ variable bool spotting; /* spotting flag */ variable double spotting_timer; /* spotting timer */ variable int state_old = -1; /* old state */ @@ -315,7 +315,7 @@ variable bool thc_activated; /* thc was activated */ variable double thc_activated_timer; /* timer to reset thc_activated - end of cut is detected from userspace :( */ variable double thc_delay_timer; /* thc delay timer [non auto THC] */ variable int thc_sampler_samples; /* required number of thc samples [auto THC] */ -variable int thc_velocity; /* velocity for thc moves */ +variable double thc_velocity; /* velocity for thc moves */ variable double torch_off_timer; /* arc off delay timer */ variable double torch_pulse_timer; /* torch pulse timer */ variable double velocity_scale; /* the velocity multiplier */ @@ -323,18 +323,18 @@ variable double voidlock_change; /* voltage change this cycle */ variable double voidlock_off_count; /* current count of voidlock deactivate cycles */ variable int voidlock_on_count; /* current count of voidlock activate cycles */ variable double voidlock_threshold; /* voidlock threshold voltage per cycle */ -variable int x_velocity; /* velocity for x motion for consumable change */ -variable int y_velocity; /* velocity for y motion for consumable change */ -variable int z_max; /* max height for testing against pierce height*/ -variable int z_pierce; /* pierce height for testing against max height*/ -variable int zero_target; /* zero height target offset */ +variable double x_velocity; /* velocity for x motion for consumable change */ +variable double y_velocity; /* velocity for y motion for consumable change */ +variable double z_max; /* max height for testing against pierce height*/ +variable double z_pierce; /* pierce height for testing against max height*/ +variable double zero_target; /* zero height target offset */ // Pierce type user control variables variable double creep_speed_dist_travelled; /* Sum of distance traveled during creep stage */ variable double creep_speed_scale; /* scale of creep speed in proportion to standard cut feed rate */ variable double cut_height_delay_timer; /* at the end of transition to end-perice-height how long to pause before transition to cut height*/ variable double gouge_speed_dist_travelled; /* Sum of distance traveled during gouge stage */ variable double gouge_speed_scale; /* scale of gouge speed in proportion to standard cut feed rate */ -variable int pierce_end_target; /* Target pierce height at end of pierce motion. Usually less than the starting pierce height */ +variable double pierce_end_target; /* Target pierce height at end of pierce motion. Usually less than the starting pierce height */ variable double pierce_motion_delay_timer; /* delay starting motion during pierce delay period. Only used when pierce-type is 2. Is calced from a % of Pierce Delay*/ variable double pierce_old_x; /* tracking the last x location during pierce */ variable double pierce_old_y; /* tracking the last y location during pierce */ @@ -468,8 +468,23 @@ float read_arc_voltage_buffer(int caller, int size, int index, float target, flo } } +/* offsets are floating point counts: compare them with a tolerance instead + of for exact equality. One thousandth of a count is far below the + resolution any offset is ever commanded at, so this only absorbs the + rounding of the arithmetic, never a real difference. */ +#define OFFSET_EPSILON 0.001 +static int offset_eq(double a, double b){ + return fabs(a - b) < OFFSET_EPSILON; +} + /* set an axis eoffset position at a set velocity */ -int offset_move(int offset, int vel, int target){ +double offset_move(double offset, double vel, double target){ + if(!isfinite(vel) || !isfinite(target) || vel <= 0){ + /* a non-positive velocity never advanced the offset before this was + floating point either, so stay put rather than step by a bogus + amount */ + return offset; + } if(offset - vel > target){ offset -= vel; }else if(offset + vel < target){ @@ -1127,13 +1142,13 @@ FUNCTION(_) { y_velocity = fabs(cut_feed_rate * velocity_scale * sin(angle_x_y)); laser_recovery_state_set(RESETTING); }else if(laser_recovery_state == RESETTING){ - if(x_offset_counts == x_offset && y_offset_counts == y_offset){ + if(offset_eq(x_offset_counts, x_offset) && offset_eq(y_offset_counts, y_offset)){ laser_recovery_state_set(OFF); }else{ - if(x_offset_counts != x_offset){ + if(!offset_eq(x_offset_counts, x_offset)){ x_offset_counts_set(offset_move(x_offset_counts, x_velocity, x_offset)); } - if(y_offset_counts != y_offset){ + if(!offset_eq(y_offset_counts, y_offset)){ y_offset_counts_set(offset_move(y_offset_counts, y_velocity, y_offset)); } } @@ -1191,11 +1206,11 @@ FUNCTION(_) { /* move probe to x/y offsets if required */ if(offset_probing){ xy_offset_enable_set(TRUE); - if(x_offset_counts != op_x_target || y_offset_counts != op_y_target){ - if(x_offset_counts != op_x_target){ + if(!offset_eq(x_offset_counts, op_x_target) || !offset_eq(y_offset_counts, op_y_target)){ + if(!offset_eq(x_offset_counts, op_x_target)){ x_offset_counts_set(offset_move(x_offset_counts, op_x_velocity, op_x_target)); } - if(y_offset_counts != op_y_target){ + if(!offset_eq(y_offset_counts, op_y_target)){ y_offset_counts_set(offset_move(y_offset_counts, op_y_velocity, op_y_target)); } } @@ -1227,7 +1242,7 @@ FUNCTION(_) { } } break; - }else if(ohmic_probe_enable && (x_offset_counts != op_x_target || y_offset_counts != op_y_target)){ + }else if(ohmic_probe_enable && (!offset_eq(x_offset_counts, op_x_target) || !offset_eq(y_offset_counts, op_y_target))){ stop_type = PAUSE; program_pause_set(TRUE); rtapi_print_msg(RTAPI_MSG_ERR,"probe contact detected before probe offset reached\n" @@ -1238,7 +1253,7 @@ FUNCTION(_) { probe_retry = TRUE; state = PROBE_UP; /* move to probe height at setup velocity */ - }else if(z_offset_counts != probe_start_target){ + }else if(!offset_eq(z_offset_counts, probe_start_target)){ z_offset_counts_set(offset_move(z_offset_counts, setup_velocity, probe_start_target)); }else{ if(float_detected){ @@ -1248,7 +1263,7 @@ FUNCTION(_) { }else{ /* test if probing offset is reached */ if(offset_probing){ - if(x_offset_counts == op_x_target && y_offset_counts == op_y_target && + if(offset_eq(x_offset_counts, op_x_target) && offset_eq(y_offset_counts, op_y_target) && z_offset_current - probe_start_target * offset_scale < 0.001){ state = PROBE_DOWN; } @@ -1444,10 +1459,10 @@ FUNCTION(_) { /* clear x/y probe offsets if required */ if(offset_probing){ xy_offset_enable_set(TRUE); - if(x_offset_counts != op_x_start){ + if(!offset_eq(x_offset_counts, op_x_start)){ x_offset_counts_set(offset_move(x_offset_counts, op_x_velocity, op_x_start)); } - if(y_offset_counts != op_y_start){ + if(!offset_eq(y_offset_counts, op_y_start)){ y_offset_counts_set(offset_move(y_offset_counts, op_y_velocity, op_y_start)); } if(ohmic_probe_enable && offset_probe_timer < offset_probe_delay){ @@ -1456,9 +1471,9 @@ FUNCTION(_) { } if(pierce_height && cut_height && (use_auto_volts || (!use_auto_volts && cut_volts))){ feed_hold_set(TRUE); - if(z_offset_counts == pierce_target){ + if(offset_eq(z_offset_counts, pierce_target)){ if((int)(z_offset_current * offset_res) == (int)(pierce_target * offset_scale * offset_res) && - (((offset_probing && x_offset_counts == op_x_start && y_offset_counts == op_y_start)) || !offset_probing)){ + (((offset_probing && offset_eq(x_offset_counts, op_x_start) && offset_eq(y_offset_counts, op_y_start))) || !offset_probing)){ arc_starts = 0; if(probe_testing){ state = PROBE_TEST; @@ -1641,7 +1656,7 @@ FUNCTION(_) { // Sequence 1 rtapi_print_msg(RTAPI_MSG_DBG,"PIERCE_DELAY - Seq 1\n"); pierce_motion_delay_timer -= fperiod; - }else if(z_offset_counts != pierce_end_target){ + }else if(!offset_eq(z_offset_counts, pierce_end_target)){ // Sequence 2 rtapi_print_msg(RTAPI_MSG_DBG,"PIERCE_DELAY - Seq 2\n"); z_offset_enable_set(TRUE); @@ -1681,7 +1696,7 @@ FUNCTION(_) { case PUDDLE_JUMP: z_offset_enable_set(TRUE); feed_hold_set(FALSE); - if(z_offset_counts == puddle_jump_target){ + if(offset_eq(z_offset_counts, puddle_jump_target)){ if((int)(z_offset_current * offset_res) == (int)(puddle_jump_target * offset_scale * offset_res)){ count = 0; if(puddle_jump_timer > 0){ @@ -1703,7 +1718,7 @@ FUNCTION(_) { // if(!cut_recovering){ // feed_hold = FALSE; // } - if(z_offset_counts == cut_target){ + if(offset_eq(z_offset_counts, cut_target)){ if((int)(z_offset_current * offset_res) == (int)(cut_target * offset_scale * offset_res)){ count = 0; if(cut_recovering){ @@ -1792,7 +1807,7 @@ FUNCTION(_) { height_ovr_counts -= (height_override - height_ovr_old) * height_per_volt / offset_scale; height_ovr_old = height_override; /* height override z motion */ - }else if(height_ovr_counts != 0){ + }else if(!offset_eq(height_ovr_counts, 0)){ if((setup_velocity) < height_ovr_counts){ z_offset_counts_set(z_offset_counts - setup_velocity); height_ovr_counts -= setup_velocity; @@ -2011,7 +2026,7 @@ FUNCTION(_) { if(!torch_off_timer || !torch_on){ cornerlock_is_locked_set(FALSE); if(!probe_test || probe_test_error){ - if(z_offset_counts == safe_target){ + if(offset_eq(z_offset_counts, safe_target)){ if((int)(z_offset_current * offset_res) == (int)(safe_target * offset_scale * offset_res)){ if(stop_type == WAIT){ feed_hold_set(FALSE); @@ -2034,7 +2049,7 @@ FUNCTION(_) { torch_on_set(FALSE); cornerlock_is_locked_set(FALSE); if(!probe_test || probe_test_error){ - if(z_offset_counts == 0){ + if(offset_eq(z_offset_counts, 0)){ if((int)(z_offset_current * offset_res) == 0){ if(stop_type == WAIT){ feed_hold_set(FALSE); @@ -2046,11 +2061,11 @@ FUNCTION(_) { }else if(cut_recovery && stop_type != STOP){ state = CUT_RECOVERY_ON; /* clear x/y probe offsets if required */ - }else if((offset_probe_x || offset_probe_y) && (x_offset_counts || y_offset_counts)){ - if(x_offset_counts != 0){ + }else if((offset_probe_x || offset_probe_y) && (!offset_eq(x_offset_counts, 0) || !offset_eq(y_offset_counts, 0))){ + if(!offset_eq(x_offset_counts, 0)){ x_offset_counts_set(offset_move(x_offset_counts, op_x_velocity, 0)); } - if(y_offset_counts != 0){ + if(!offset_eq(y_offset_counts, 0)){ y_offset_counts_set(offset_move(y_offset_counts, op_y_velocity, 0)); } }else{ @@ -2089,7 +2104,7 @@ FUNCTION(_) { cut_height_last = 0; if(program_is_idle){ z_offset_enable_set(TRUE); - if (z_offset_counts == 0){ + if (offset_eq(z_offset_counts, 0)){ if(!offsets_active){ first_cut_finished = FALSE; stop_type = NONE; @@ -2172,11 +2187,11 @@ FUNCTION(_) { if(!probe_test){ /* clear z offset at setup velocity */ z_offset_counts_set(offset_move(z_offset_counts, setup_velocity, 0)); - if((offset_probe_x || offset_probe_y) && (x_offset_counts || y_offset_counts)){ + if((offset_probe_x || offset_probe_y) && (!offset_eq(x_offset_counts, 0) || !offset_eq(y_offset_counts, 0))){ x_offset_counts_set(offset_move(x_offset_counts, op_x_velocity, 0)); y_offset_counts_set(offset_move(y_offset_counts, op_y_velocity, 0)); } - if(!x_offset_counts && !y_offset_counts && !z_offset_counts){ + if(offset_eq(x_offset_counts, 0) && offset_eq(y_offset_counts, 0) && offset_eq(z_offset_counts, 0)){ probe_inhibit = FALSE; probe_testing = FALSE; probe_required = TRUE; @@ -2256,7 +2271,7 @@ FUNCTION(_) { !consumable_change){ state = IDLE; }else if(consumable_change){ - if(x_velocity && x_offset_counts != x_offset){ + if(x_velocity && !offset_eq(x_offset_counts, x_offset)){ if(x_offset > 0){ if(x_offset_counts + x_velocity < x_offset){ x_offset_counts_set(x_offset_counts + x_velocity); @@ -2271,7 +2286,7 @@ FUNCTION(_) { } } } - if(y_velocity && y_offset_counts != y_offset){ + if(y_velocity && !offset_eq(y_offset_counts, y_offset)){ if(y_offset > 0){ if(y_offset_counts + y_velocity < y_offset){ y_offset_counts_set(y_offset_counts + y_velocity); @@ -2301,7 +2316,7 @@ FUNCTION(_) { break; } error_message = FALSE; - if(x_offset_counts == 0 && y_offset_counts == 0){ + if(offset_eq(x_offset_counts, 0) && offset_eq(y_offset_counts, 0)){ if((int)(x_offset_current * offset_res) == 0 && (int)(y_offset_current * offset_res) == 0){ consumable_changing_set(FALSE); cons_change_clear = FALSE; @@ -2309,7 +2324,7 @@ FUNCTION(_) { state = IDLE; } }else{ - if(x_velocity && x_offset_counts != 0){ + if(x_velocity && !offset_eq(x_offset_counts, 0)){ if(x_offset_counts > 0){ if(x_offset_counts - x_velocity > 0){ x_offset_counts_set(x_offset_counts - x_velocity); @@ -2324,7 +2339,7 @@ FUNCTION(_) { } } } - if(y_velocity && y_offset_counts != 0){ + if(y_velocity && !offset_eq(y_offset_counts, 0)){ if(y_offset_counts > 0){ if(y_offset_counts - y_velocity > 0){ y_offset_counts_set(y_offset_counts - y_velocity); @@ -2372,24 +2387,24 @@ FUNCTION(_) { laser_y_target = y_offset_counts + laser_y_offset; laser_recovery_state_set(SETTING); }else if(laser_recovery_state == SETTING){ - if(x_offset_counts == laser_x_target && y_offset_counts == laser_y_target){ + if(offset_eq(x_offset_counts, laser_x_target) && offset_eq(y_offset_counts, laser_y_target)){ laser_recovery_state_set(ON); }else{ - if(x_offset_counts != laser_x_target){ + if(!offset_eq(x_offset_counts, laser_x_target)){ x_offset_counts_set(offset_move(x_offset_counts, x_velocity, laser_x_target)); } - if(y_offset_counts != laser_y_target){ + if(!offset_eq(y_offset_counts, laser_y_target)){ y_offset_counts_set(offset_move(y_offset_counts, y_velocity, laser_y_target)); } } /* laser recovery offset is clear */ }else if(cut_recovery){ /* move x axis to recovery position at recovery velocity */ - if(x_offset_counts != x_offset + laser_x_offset * (laser_recovery_state > 1)){ + if(!offset_eq(x_offset_counts, x_offset + laser_x_offset * (laser_recovery_state > 1))){ x_offset_counts_set(offset_move(x_offset_counts, recovery_velocity, x_offset + laser_x_offset * (laser_recovery_state > 1))); } /* move y axis to recovery position at recovery velocity */ - if(y_offset_counts != y_offset + laser_y_offset * (laser_recovery_state > 1)){ + if(!offset_eq(y_offset_counts, y_offset + laser_y_offset * (laser_recovery_state > 1))){ y_offset_counts_set(offset_move(y_offset_counts, recovery_velocity, y_offset + laser_y_offset * (laser_recovery_state > 1))); } }else{ @@ -2409,7 +2424,7 @@ FUNCTION(_) { x_velocity = fabs(recovery_velocity * cos(angle_x_y)); y_velocity = fabs(recovery_velocity * sin(angle_x_y)); } - if(x_offset_counts == 0 && y_offset_counts == 0){ + if(offset_eq(x_offset_counts, 0) && offset_eq(y_offset_counts, 0)){ if((int)(x_offset_current * offset_res) == 0 && (int)(y_offset_current * offset_res) == 0){ laser_recovery_state_set(OFF); if(cut_recovering){ @@ -2432,11 +2447,11 @@ FUNCTION(_) { } }else{ /* clear x axis offset at recovery velocity */ - if(x_offset_counts != 0){ + if(!offset_eq(x_offset_counts, 0)){ x_offset_counts_set(offset_move(x_offset_counts, x_velocity, 0)); } /* clear y axis offset at recovery velocity */ - if(y_offset_counts != 0){ + if(!offset_eq(y_offset_counts, 0)){ y_offset_counts_set(offset_move(y_offset_counts, y_velocity, 0)); } } diff --git a/src/hal/components/updown.comp b/src/hal/components/updown.comp index 51bea6764be..fbcc83587f8 100644 --- a/src/hal/components/updown.comp +++ b/src/hal/components/updown.comp @@ -3,6 +3,7 @@ pin in bool countup "Increment count when this pin goes from 0 to 1"; pin in bool countdown "Decrement count when this pin goes from 0 to 1"; pin in bool reset "Reset count when this pin goes from 0 to 1"; pin out si32 count "The current count"; +pin out real count_f "The current count, as a float"; param rw bool clamp_ "If TRUE, then clamp the output to the min and max parameters."; param rw bool wrap "If TRUE, then wrap around when the count goes above or below the min and max parameters. Note that wrap implies (and overrides) clamp."; param rw si32 max_ = 0x7FFFFFFF "If clamp or wrap is set, count will never exceed this number"; @@ -45,6 +46,7 @@ FUNCTION(_) { temp_count = min_; } count_set(temp_count); + count_f_set((double)temp_count); oldup = countup; olddown = countdown; } diff --git a/src/hal/user_comps/z_level_compensation.py b/src/hal/user_comps/z_level_compensation.py index 366c2889587..ccac4d0fd23 100644 --- a/src/hal/user_comps/z_level_compensation.py +++ b/src/hal/user_comps/z_level_compensation.py @@ -99,11 +99,11 @@ def compensate(self): self.Xn = self.xpos - self.xMin self.Yn = self.ypos - self.yMin - # get the nearest compensation offset and convert to counts (s32) with a scale (float) + # get the nearest compensation offset and convert to counts (float) with a scale (float) # Requested offset == counts * scale zo = self.zi[self.Xn, self.Yn] try: - compensation = int(zo / self.scale) + compensation = float(zo / self.scale) except: compensation = 0.0 return compensation @@ -112,7 +112,7 @@ def run(self): self.h = hal.component("z_level_compensation") self.h.newpin("enable-in", hal.HAL_BIT, hal.HAL_IN) self.h.newpin("scale", hal.HAL_FLOAT, hal.HAL_OUT) - self.h.newpin("counts", hal.HAL_S32, hal.HAL_OUT) + self.h.newpin("counts", hal.HAL_FLOAT, hal.HAL_OUT) self.h.newpin("clear", hal.HAL_BIT, hal.HAL_IN) self.h.newpin("x-pos", hal.HAL_FLOAT, hal.HAL_IN) self.h.newpin("y-pos", hal.HAL_FLOAT, hal.HAL_IN)