diff --git a/src/emc/iotask/ioControl.cc b/src/emc/iotask/ioControl.cc index 788a2d1cd4a..32fa19e72d9 100644 --- a/src/emc/iotask/ioControl.cc +++ b/src/emc/iotask/ioControl.cc @@ -864,9 +864,6 @@ int main(int argc, char *argv[]) int t = ((EMC_TOOL_PREPARE*)emcioCommand)->tool; rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_PREPARE tool=%d pocket=%d\n", t, p); - // it doesn't make sense to prep the spindle pocket - if(random_toolchanger && p == 0) break; - // Set HAL pins/params for tool number, pocket, and index. iocontrol_data->tool_prep_index = p; *(iocontrol_data->tool_prep_pocket) = random_toolchanger? p: fms[p]; @@ -875,6 +872,13 @@ int main(int argc, char *argv[]) } else { *(iocontrol_data->tool_prep_number) = emcioStatus.tool.toolTable[p].toolno; } + + // it doesn't make sense to prep the spindle pocket + if (random_toolchanger && p == 0) { + emcioStatus.tool.pocketPrepped = 0; + break; + } + /* then set the prepare pin to tell external logic to get started */ *(iocontrol_data->tool_prepare) = 1; // the feedback logic is done inside read_hal_inputs() diff --git a/tests/toolchanger/reload-tool/README b/tests/toolchanger/reload-tool/README new file mode 100644 index 00000000000..df4e77cdd43 --- /dev/null +++ b/tests/toolchanger/reload-tool/README @@ -0,0 +1,3 @@ +This test reproduces https://github.com/LinuxCNC/linuxcnc/issues/330. + +It tests the behavior for both random and non-random toolchanger machines. diff --git a/tests/toolchanger/reload-tool/checkresult b/tests/toolchanger/reload-tool/checkresult new file mode 100755 index 00000000000..24dc9aa53e3 --- /dev/null +++ b/tests/toolchanger/reload-tool/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/toolchanger/reload-tool/core_sim.hal b/tests/toolchanger/reload-tool/core_sim.hal new file mode 100644 index 00000000000..0448af4cece --- /dev/null +++ b/tests/toolchanger/reload-tool/core_sim.hal @@ -0,0 +1,60 @@ +# core HAL config file for simulation + +# first load all the RT modules that will be needed +# kinematics +loadrt trivkins +# motion controller, get name and thread periods from ini file +loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES +# load 6 differentiators (for velocity and accel signals +loadrt ddt count=6 +# load additional blocks +loadrt hypot count=2 +loadrt comp count=3 +loadrt or2 count=1 + +# add motion controller functions to servo thread +addf motion-command-handler servo-thread +addf motion-controller servo-thread +# link the differentiator functions into the code +addf ddt.0 servo-thread +addf ddt.1 servo-thread +addf ddt.2 servo-thread +addf ddt.3 servo-thread +addf ddt.4 servo-thread +addf ddt.5 servo-thread +addf hypot.0 servo-thread +addf hypot.1 servo-thread + +# create HAL signals for position commands from motion module +# loop position commands back to motion module feedback +net Xpos axis.0.motor-pos-cmd => axis.0.motor-pos-fb ddt.0.in +net Ypos axis.1.motor-pos-cmd => axis.1.motor-pos-fb ddt.2.in +net Zpos axis.2.motor-pos-cmd => axis.2.motor-pos-fb ddt.4.in + +# send the position commands thru differentiators to +# generate velocity and accel signals +net Xvel ddt.0.out => ddt.1.in hypot.0.in0 +net Xacc <= ddt.1.out +net Yvel ddt.2.out => ddt.3.in hypot.0.in1 +net Yacc <= ddt.3.out +net Zvel ddt.4.out => ddt.5.in hypot.1.in0 +net Zacc <= ddt.5.out + +# Cartesian 2- and 3-axis velocities +net XYvel hypot.0.out => hypot.1.in1 +net XYZvel <= hypot.1.out + +# estop loopback +net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in + +# create signals for tool loading loopback +net tool-prepare <= iocontrol.0.tool-prepare +net tool-prepared => iocontrol.0.tool-prepared + +net tool-change <= iocontrol.0.tool-change +net tool-changed => iocontrol.0.tool-changed + +net tool-number <= iocontrol.0.tool-number +net tool-prep-number <= iocontrol.0.tool-prep-number +net tool-prep-pocket <= iocontrol.0.tool-prep-pocket + diff --git a/tests/toolchanger/reload-tool/non-random/checkresult b/tests/toolchanger/reload-tool/non-random/checkresult new file mode 120000 index 00000000000..e826ab2e5b2 --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/checkresult @@ -0,0 +1 @@ +../checkresult \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/non-random/core_sim.hal b/tests/toolchanger/reload-tool/non-random/core_sim.hal new file mode 120000 index 00000000000..ead32827019 --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/core_sim.hal @@ -0,0 +1 @@ +../core_sim.hal \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/non-random/postgui.hal b/tests/toolchanger/reload-tool/non-random/postgui.hal new file mode 120000 index 00000000000..d5ae19df5df --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/postgui.hal @@ -0,0 +1 @@ +../postgui.hal \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/non-random/test-ui.py b/tests/toolchanger/reload-tool/non-random/test-ui.py new file mode 100755 index 00000000000..aa3f224784a --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/test-ui.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python + +import linuxcnc +import hal + +import math +import time +import sys +import subprocess +import os +import signal +import glob +import re + + +def wait_for_linuxcnc_startup(status, timeout=10.0): + + """Poll the Status buffer waiting for it to look initialized, + rather than just allocated (all-zero). Returns on success, throws + RuntimeError on failure.""" + + start_time = time.time() + while time.time() - start_time < timeout: + status.poll() + if (status.angular_units == 0.0) \ + or (status.axes == 0) \ + or (status.axis_mask == 0) \ + or (status.cycle_time == 0.0) \ + or (status.exec_state != linuxcnc.EXEC_DONE) \ + or (status.interp_state != linuxcnc.INTERP_IDLE) \ + or (status.inpos == False) \ + or (status.linear_units == 0.0) \ + or (status.max_acceleration == 0.0) \ + or (status.max_velocity == 0.0) \ + or (status.program_units == 0.0) \ + or (status.rapidrate == 0.0) \ + or (status.state != linuxcnc.STATE_ESTOP) \ + or (status.task_state != linuxcnc.STATE_ESTOP): + time.sleep(0.1) + else: + # looks good + return + + # timeout, throw an exception + raise RuntimeError + + +def wait_for_hal_pin(name, value, timeout=10): + start_time = time.time() + while (time.time() - start_time) < timeout: + if h[name] == value: + return + time.sleep(0.1) + raise RuntimeError("hal pin %s didn't get to %s after %.3f seconds" % (name, value, timeout)) + + +# After doing something that should change the stat buffer, wait this +# long before polling to let the change propagate through. +# FIXME: this is bogus +stat_poll_wait = 0.100 + + +c = linuxcnc.command() +s = linuxcnc.stat() +e = linuxcnc.error_channel() + +h = hal.component("test-ui") + +h.newpin("tool-change", hal.HAL_BIT, hal.HAL_IN) +h.newpin("tool-changed", hal.HAL_BIT, hal.HAL_OUT) +h["tool-changed"] = False + +h.newpin("tool-prepare", hal.HAL_BIT, hal.HAL_IN) +h.newpin("tool-prepared", hal.HAL_BIT, hal.HAL_OUT) +h["tool-prepared"] = False + +h.newpin("tool-number", hal.HAL_S32, hal.HAL_IN) +h.newpin("tool-prep-number", hal.HAL_S32, hal.HAL_IN) +h.newpin("tool-prep-pocket", hal.HAL_S32, hal.HAL_IN) + +h.ready() + +os.system("halcmd source ./postgui.hal") + + +# Wait for LinuxCNC to initialize itself so the Status buffer stabilizes. +wait_for_linuxcnc_startup(s) + +c.state(linuxcnc.STATE_ESTOP_RESET) +c.state(linuxcnc.STATE_ON) +c.home(-1) +c.wait_complete() + +c.mode(linuxcnc.MODE_MDI) + + +# +# At startup there's no tool in the spindle and no tool prep or change +# is being requested. +# + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 0) +assert(h['tool-prep-number'] == 0) +assert(h['tool-prep-pocket'] == 0) + +s.poll() +assert(s.tool_in_spindle == 0) +assert(s.pocket_prepped == -1) + + +# +# Prepare T2 +# + +c.mdi('t2') +wait_for_hal_pin('tool-prepare', True) + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == True) +assert(h['tool-number'] == 0) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +s.poll() +assert(s.tool_in_spindle == 0) +assert(s.pocket_prepped == -1) + +h['tool-prepared'] = True +wait_for_hal_pin('tool-prepare', False) +h['tool-prepared'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 0) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 0) +assert(s.pocket_prepped == 6) # ugh, non-random tc gives you tool-table-array index, not pocket + + +# +# Change to T2 +# + +c.mdi('m6') +wait_for_hal_pin('tool-change', True) + +assert(h['tool-change'] == True) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 0) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 0) +assert(s.pocket_prepped == 6) + +h['tool-changed'] = True +wait_for_hal_pin('tool-change', False) +h['tool-changed'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 0) +assert(h['tool-prep-pocket'] == 0) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == -1) + + +# +# Prepare T12 +# + +c.mdi('t12') +wait_for_hal_pin('tool-prepare', True) + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == True) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 12) +assert(h['tool-prep-pocket'] == 9) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == -1) + +h['tool-prepared'] = True +wait_for_hal_pin('tool-prepare', False) +h['tool-prepared'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 12) +assert(h['tool-prep-pocket'] == 9) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 4) + + +# +# Prepare T2 +# This tool is already in the spindle. +# + +c.mdi('t2') +wait_for_hal_pin('tool-prepare', True) + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == True) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 4) + +h['tool-prepared'] = True +wait_for_hal_pin('tool-prepare', False) +h['tool-prepared'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 6) + + +# +# Change to prepared tool (T2 again) +# + +c.mdi('m6') +try: + wait_for_hal_pin('tool-change', True, timeout=5) +except RuntimeError: + # It *should* time out, no tool change should be performed since + # the prepared tool is already in the spindle. + pass + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 6) + + +sys.exit(0) diff --git a/tests/toolchanger/reload-tool/non-random/test.ini b/tests/toolchanger/reload-tool/non-random/test.ini new file mode 100644 index 00000000000..66e8cab0521 --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/test.ini @@ -0,0 +1,82 @@ +[EMC] +#DEBUG = 0x0 +DEBUG = 0xffffffff + +[DISPLAY] +DISPLAY = ./test-ui.py + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var +USER_M_PATH = ./subs + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +COMM_WAIT = 0.010 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[HAL] +HALFILE = core_sim.hal + +[TRAJ] +NO_FORCE_HOMING=1 +AXES = 3 +COORDINATES = X Y Z +HOME = 0 0 0 +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +CYCLE_TIME = 0.010 +DEFAULT_VELOCITY = 1.2 +MAX_ACCELERATION = 123.45 +MAX_VELOCITY = 45.67 + +[AXIS_0] +TYPE = LINEAR +HOME = 0.000 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[AXIS_1] +TYPE = LINEAR +HOME = 0.000 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[AXIS_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[EMCIO] +EMCIO = io +CYCLE_TIME = 0.100 +TOOL_TABLE = simpockets.tbl +TOOL_CHANGE_QUILL_UP = 1 +RANDOM_TOOLCHANGER = 0 diff --git a/tests/toolchanger/reload-tool/non-random/test.sh b/tests/toolchanger/reload-tool/non-random/test.sh new file mode 120000 index 00000000000..0b01664e62e --- /dev/null +++ b/tests/toolchanger/reload-tool/non-random/test.sh @@ -0,0 +1 @@ +../shared-test.sh \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/postgui.hal b/tests/toolchanger/reload-tool/postgui.hal new file mode 100644 index 00000000000..0b14c365b89 --- /dev/null +++ b/tests/toolchanger/reload-tool/postgui.hal @@ -0,0 +1,22 @@ + +net tool-change <= iocontrol.0.tool-change +net tool-change => test-ui.tool-change + +net tool-changed <= test-ui.tool-changed +net tool-changed => iocontrol.0.tool-changed + +net tool-prepare <= iocontrol.0.tool-prepare +net tool-prepare => test-ui.tool-prepare + +net tool-prepared <= test-ui.tool-prepared +net tool-prepared => iocontrol.0.tool-prepared + +net tool-number <= iocontrol.0.tool-number +net tool-number => test-ui.tool-number + +net tool-prep-number <= iocontrol.0.tool-prep-number +net tool-prep-number => test-ui.tool-prep-number + +net tool-prep-pocket <= iocontrol.0.tool-prep-pocket +net tool-prep-pocket => test-ui.tool-prep-pocket + diff --git a/tests/toolchanger/reload-tool/random/checkresult b/tests/toolchanger/reload-tool/random/checkresult new file mode 120000 index 00000000000..e826ab2e5b2 --- /dev/null +++ b/tests/toolchanger/reload-tool/random/checkresult @@ -0,0 +1 @@ +../checkresult \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/random/core_sim.hal b/tests/toolchanger/reload-tool/random/core_sim.hal new file mode 120000 index 00000000000..ead32827019 --- /dev/null +++ b/tests/toolchanger/reload-tool/random/core_sim.hal @@ -0,0 +1 @@ +../core_sim.hal \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/random/postgui.hal b/tests/toolchanger/reload-tool/random/postgui.hal new file mode 120000 index 00000000000..d5ae19df5df --- /dev/null +++ b/tests/toolchanger/reload-tool/random/postgui.hal @@ -0,0 +1 @@ +../postgui.hal \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/random/test-ui.py b/tests/toolchanger/reload-tool/random/test-ui.py new file mode 100755 index 00000000000..cf6b76538ae --- /dev/null +++ b/tests/toolchanger/reload-tool/random/test-ui.py @@ -0,0 +1,264 @@ +#!/usr/bin/env python + +import linuxcnc +import hal + +import math +import time +import sys +import subprocess +import os +import signal +import glob +import re + + +def wait_for_linuxcnc_startup(status, timeout=10.0): + + """Poll the Status buffer waiting for it to look initialized, + rather than just allocated (all-zero). Returns on success, throws + RuntimeError on failure.""" + + start_time = time.time() + while time.time() - start_time < timeout: + status.poll() + if (status.angular_units == 0.0) \ + or (status.axes == 0) \ + or (status.axis_mask == 0) \ + or (status.cycle_time == 0.0) \ + or (status.exec_state != linuxcnc.EXEC_DONE) \ + or (status.interp_state != linuxcnc.INTERP_IDLE) \ + or (status.inpos == False) \ + or (status.linear_units == 0.0) \ + or (status.max_acceleration == 0.0) \ + or (status.max_velocity == 0.0) \ + or (status.program_units == 0.0) \ + or (status.rapidrate == 0.0) \ + or (status.state != linuxcnc.STATE_ESTOP) \ + or (status.task_state != linuxcnc.STATE_ESTOP): + time.sleep(0.1) + else: + # looks good + return + + # timeout, throw an exception + raise RuntimeError + + +def wait_for_hal_pin(name, value, timeout=10): + start_time = time.time() + while (time.time() - start_time) < timeout: + if h[name] == value: + return + time.sleep(0.1) + raise RuntimeError("hal pin %s didn't get to %s after %.3f seconds" % (name, value, timeout)) + + +# After doing something that should change the stat buffer, wait this +# long before polling to let the change propagate through. +# FIXME: this is bogus +stat_poll_wait = 0.100 + + +c = linuxcnc.command() +s = linuxcnc.stat() +e = linuxcnc.error_channel() + +h = hal.component("test-ui") + +h.newpin("tool-change", hal.HAL_BIT, hal.HAL_IN) +h.newpin("tool-changed", hal.HAL_BIT, hal.HAL_OUT) +h["tool-changed"] = False + +h.newpin("tool-prepare", hal.HAL_BIT, hal.HAL_IN) +h.newpin("tool-prepared", hal.HAL_BIT, hal.HAL_OUT) +h["tool-prepared"] = False + +h.newpin("tool-number", hal.HAL_S32, hal.HAL_IN) +h.newpin("tool-prep-number", hal.HAL_S32, hal.HAL_IN) +h.newpin("tool-prep-pocket", hal.HAL_S32, hal.HAL_IN) + +h.ready() + +os.system("halcmd source ./postgui.hal") + + +# Wait for LinuxCNC to initialize itself so the Status buffer stabilizes. +wait_for_linuxcnc_startup(s) + +c.state(linuxcnc.STATE_ESTOP_RESET) +c.state(linuxcnc.STATE_ON) +c.home(-1) +c.wait_complete() + +c.mode(linuxcnc.MODE_MDI) + + +# +# At startup tool 3 is in the spindle and no tool prep or change is +# being requested. +# + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 3) +assert(h['tool-prep-number'] == 0) +assert(h['tool-prep-pocket'] == 0) + +s.poll() +assert(s.tool_in_spindle == 3) +assert(s.pocket_prepped == -1) + + +# +# Prepare T2 +# + +c.mdi('t2') +wait_for_hal_pin('tool-prepare', True) + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == True) +assert(h['tool-number'] == 3) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +s.poll() +assert(s.tool_in_spindle == 3) +assert(s.pocket_prepped == -1) + +h['tool-prepared'] = True +wait_for_hal_pin('tool-prepare', False) +h['tool-prepared'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 3) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 3) +assert(s.pocket_prepped == 46) # random tc gives you pocket, which is the same as tool-table-array index + + +# +# Change to T2 +# + +c.mdi('m6') +wait_for_hal_pin('tool-change', True) + +assert(h['tool-change'] == True) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 3) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 46) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 3) +assert(s.pocket_prepped == 46) + +h['tool-changed'] = True +wait_for_hal_pin('tool-change', False) +h['tool-changed'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 0) +assert(h['tool-prep-pocket'] == 0) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == -1) + + +# +# Prepare T12 +# + +c.mdi('t12') +wait_for_hal_pin('tool-prepare', True) + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == True) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 12) +assert(h['tool-prep-pocket'] == 9) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == -1) + +h['tool-prepared'] = True +wait_for_hal_pin('tool-prepare', False) +h['tool-prepared'] = False + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 12) +assert(h['tool-prep-pocket'] == 9) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 9) + + +# +# Prepare T2 +# This tool is already in the spindle. +# + +c.mdi('t2') +try: + wait_for_hal_pin('tool-prepare', True, timeout=5) +except RuntimeError: + # It *should* time out, no tool prep should be performed since the + # requested tool is already in the spindle. + pass + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 0) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 0) + + +# +# Change to prepared tool (T2) +# + +c.mdi('m6') +try: + wait_for_hal_pin('tool-change', True, timeout=5) +except RuntimeError: + # It *should* time out, no tool change should be performed since + # the prepared tool is already in the spindle. + pass + +assert(h['tool-change'] == False) +assert(h['tool-prepare'] == False) +assert(h['tool-number'] == 2) +assert(h['tool-prep-number'] == 2) +assert(h['tool-prep-pocket'] == 0) + +time.sleep(stat_poll_wait) +s.poll() +assert(s.tool_in_spindle == 2) +assert(s.pocket_prepped == 0) + + +sys.exit(0) + diff --git a/tests/toolchanger/reload-tool/random/test.ini b/tests/toolchanger/reload-tool/random/test.ini new file mode 100644 index 00000000000..27ff19b2c68 --- /dev/null +++ b/tests/toolchanger/reload-tool/random/test.ini @@ -0,0 +1,82 @@ +[EMC] +#DEBUG = 0x0 +DEBUG = 0xffffffff + +[DISPLAY] +DISPLAY = ./test-ui.py + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var +USER_M_PATH = ./subs + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +COMM_WAIT = 0.010 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[HAL] +HALFILE = core_sim.hal + +[TRAJ] +NO_FORCE_HOMING=1 +AXES = 3 +COORDINATES = X Y Z +HOME = 0 0 0 +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +CYCLE_TIME = 0.010 +DEFAULT_VELOCITY = 1.2 +MAX_ACCELERATION = 123.45 +MAX_VELOCITY = 45.67 + +[AXIS_0] +TYPE = LINEAR +HOME = 0.000 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[AXIS_1] +TYPE = LINEAR +HOME = 0.000 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[AXIS_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +BACKLASH = 0.000 +INPUT_SCALE = 4000 +OUTPUT_SCALE = 1.000 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[EMCIO] +EMCIO = io +CYCLE_TIME = 0.100 +TOOL_TABLE = simpockets.tbl +TOOL_CHANGE_QUILL_UP = 1 +RANDOM_TOOLCHANGER = 1 diff --git a/tests/toolchanger/reload-tool/random/test.sh b/tests/toolchanger/reload-tool/random/test.sh new file mode 120000 index 00000000000..0b01664e62e --- /dev/null +++ b/tests/toolchanger/reload-tool/random/test.sh @@ -0,0 +1 @@ +../shared-test.sh \ No newline at end of file diff --git a/tests/toolchanger/reload-tool/shared-test.sh b/tests/toolchanger/reload-tool/shared-test.sh new file mode 100755 index 00000000000..d6a1418f77e --- /dev/null +++ b/tests/toolchanger/reload-tool/shared-test.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm -f sim.var +rm -f simpockets.tbl +cp ../simpockets.tbl.save simpockets.tbl +linuxcnc -r test.ini diff --git a/tests/toolchanger/reload-tool/simpockets.tbl.save b/tests/toolchanger/reload-tool/simpockets.tbl.save new file mode 100644 index 00000000000..b568b078932 --- /dev/null +++ b/tests/toolchanger/reload-tool/simpockets.tbl.save @@ -0,0 +1,16 @@ +T3 P0 D2.250000 Z-6.595331 ;2-1/4 face mill +T10 P6 Z-3.406343 ;other big jacobs chuck +T16 P3 ;little jacobs chuck +T12 P9 Z-4.596806 ;1/2 2fl long em +T6 P51 Z-0.950266 ;big jacobs chuck +T2 P46 D0.750000 Z-6.366394 ;3/4 2 flute +T1 P37 D0.750000 Z-5.319396 ;3/4 roughing +T7 P28 Z-2.979905 ;big albrecht drill chuck .25 drill +T11 P19 D0.125000 Z-6.307857 ;1/8 2fl end mill +T15 P5 Z-3.730620 ;little albrecht chuck spot drill +T0 P2 ;no tool +T14 P11 Z-5.305736 ; +T8 P54 Z-7.213145 ;V engraving tool +T9 P44 Z-6.163994 ;90 deg 3/8 mill-drill +T5 P35 Z-2.825524 ;long ER40 collet chuck +T4 P26 D0.375000 Z-5.307185 ;3/8 4fl carbide