From 606313a3d2ff1ad877d380ac4dc35f5783ae24f8 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sun, 20 Sep 2026 17:31:18 +0200 Subject: [PATCH 01/12] add halui tests --- tests/halui/.gitignore | 5 + tests/halui/_lib/coverage.py | 60 +++ tests/halui/_lib/halui_test.py | 347 ++++++++++++++++ tests/halui/_lib/launch.sh | 8 + tests/halui/_lib/tool.tbl | 3 + tests/halui/axes/checkresult | 2 + tests/halui/axes/halui.ini | 100 +++++ tests/halui/axes/test-ui.py | 324 +++++++++++++++ tests/halui/axes/test.sh | 2 + tests/halui/config-9axis/checkresult | 2 + tests/halui/config-9axis/halui.ini | 194 +++++++++ tests/halui/config-9axis/nine.hal | 19 + tests/halui/config-9axis/test-ui.py | 130 ++++++ tests/halui/config-9axis/test.sh | 2 + tests/halui/config-minimal/checkresult | 2 + tests/halui/config-minimal/halui.ini | 74 ++++ tests/halui/config-minimal/minimal.hal | 12 + tests/halui/config-minimal/test-ui.py | 172 ++++++++ tests/halui/config-minimal/test.sh | 2 + tests/halui/joints/checkresult | 2 + tests/halui/joints/halui.ini | 100 +++++ tests/halui/joints/test-ui.py | 442 +++++++++++++++++++++ tests/halui/joints/test.sh | 2 + tests/halui/machine-state/checkresult | 2 + tests/halui/machine-state/halui.ini | 100 +++++ tests/halui/machine-state/test-ui.py | 188 +++++++++ tests/halui/machine-state/test.sh | 2 + tests/halui/mdi-commands/checkresult | 2 + tests/halui/mdi-commands/halui.ini | 102 +++++ tests/halui/mdi-commands/long.ngc | 5 + tests/halui/mdi-commands/test-ui.py | 182 +++++++++ tests/halui/mdi-commands/test.sh | 2 + tests/halui/overrides/checkresult | 2 + tests/halui/overrides/halui.ini | 100 +++++ tests/halui/overrides/test-ui.py | 230 +++++++++++ tests/halui/overrides/test.sh | 2 + tests/halui/program/block-delete.ngc | 4 + tests/halui/program/checkresult | 2 + tests/halui/program/halui.ini | 100 +++++ tests/halui/program/long.ngc | 5 + tests/halui/program/optional-stop.ngc | 5 + tests/halui/program/step.ngc | 5 + tests/halui/program/test-ui.py | 295 ++++++++++++++ tests/halui/program/test.sh | 2 + tests/halui/spindle-coolant/checkresult | 2 + tests/halui/spindle-coolant/halui.ini | 100 +++++ tests/halui/spindle-coolant/test-ui.py | 171 ++++++++ tests/halui/spindle-coolant/test.sh | 2 + tests/halui/startup-halfile/checkresult | 2 + tests/halui/startup-halfile/halui-nets.hal | 7 + tests/halui/startup-halfile/halui.ini | 102 +++++ tests/halui/startup-halfile/test-ui.py | 67 ++++ tests/halui/startup-halfile/test.sh | 2 + tests/halui/tool/checkresult | 2 + tests/halui/tool/halui.ini | 100 +++++ tests/halui/tool/test-ui.py | 112 ++++++ tests/halui/tool/test.sh | 2 + 57 files changed, 4014 insertions(+) create mode 100644 tests/halui/_lib/coverage.py create mode 100644 tests/halui/_lib/halui_test.py create mode 100755 tests/halui/_lib/launch.sh create mode 100644 tests/halui/_lib/tool.tbl create mode 100755 tests/halui/axes/checkresult create mode 100644 tests/halui/axes/halui.ini create mode 100755 tests/halui/axes/test-ui.py create mode 100755 tests/halui/axes/test.sh create mode 100755 tests/halui/config-9axis/checkresult create mode 100644 tests/halui/config-9axis/halui.ini create mode 100644 tests/halui/config-9axis/nine.hal create mode 100755 tests/halui/config-9axis/test-ui.py create mode 100755 tests/halui/config-9axis/test.sh create mode 100755 tests/halui/config-minimal/checkresult create mode 100644 tests/halui/config-minimal/halui.ini create mode 100644 tests/halui/config-minimal/minimal.hal create mode 100755 tests/halui/config-minimal/test-ui.py create mode 100755 tests/halui/config-minimal/test.sh create mode 100755 tests/halui/joints/checkresult create mode 100644 tests/halui/joints/halui.ini create mode 100755 tests/halui/joints/test-ui.py create mode 100755 tests/halui/joints/test.sh create mode 100755 tests/halui/machine-state/checkresult create mode 100644 tests/halui/machine-state/halui.ini create mode 100755 tests/halui/machine-state/test-ui.py create mode 100755 tests/halui/machine-state/test.sh create mode 100755 tests/halui/mdi-commands/checkresult create mode 100644 tests/halui/mdi-commands/halui.ini create mode 100644 tests/halui/mdi-commands/long.ngc create mode 100755 tests/halui/mdi-commands/test-ui.py create mode 100755 tests/halui/mdi-commands/test.sh create mode 100755 tests/halui/overrides/checkresult create mode 100644 tests/halui/overrides/halui.ini create mode 100755 tests/halui/overrides/test-ui.py create mode 100755 tests/halui/overrides/test.sh create mode 100644 tests/halui/program/block-delete.ngc create mode 100755 tests/halui/program/checkresult create mode 100644 tests/halui/program/halui.ini create mode 100644 tests/halui/program/long.ngc create mode 100644 tests/halui/program/optional-stop.ngc create mode 100644 tests/halui/program/step.ngc create mode 100755 tests/halui/program/test-ui.py create mode 100755 tests/halui/program/test.sh create mode 100755 tests/halui/spindle-coolant/checkresult create mode 100644 tests/halui/spindle-coolant/halui.ini create mode 100755 tests/halui/spindle-coolant/test-ui.py create mode 100755 tests/halui/spindle-coolant/test.sh create mode 100755 tests/halui/startup-halfile/checkresult create mode 100644 tests/halui/startup-halfile/halui-nets.hal create mode 100644 tests/halui/startup-halfile/halui.ini create mode 100755 tests/halui/startup-halfile/test-ui.py create mode 100755 tests/halui/startup-halfile/test.sh create mode 100755 tests/halui/tool/checkresult create mode 100644 tests/halui/tool/halui.ini create mode 100755 tests/halui/tool/test-ui.py create mode 100755 tests/halui/tool/test.sh diff --git a/tests/halui/.gitignore b/tests/halui/.gitignore index b23febc81d7..31d40592f97 100644 --- a/tests/halui/.gitignore +++ b/tests/halui/.gitignore @@ -1,2 +1,7 @@ sim.var.bak sim.var +# the halui pin tests copy _lib/tool.tbl in fresh on every run +*/tool.tbl +!_lib/tool.tbl +# per-run list of the halui pins a test touched +*/touched-pins.txt diff --git a/tests/halui/_lib/coverage.py b/tests/halui/_lib/coverage.py new file mode 100644 index 00000000000..8cf13f34b6a --- /dev/null +++ b/tests/halui/_lib/coverage.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Report which halui pins the halui test suite exercises. + +Each test run leaves touched-pins.txt in its directory. This merges them and +matches them against every pin name pattern in halui.cc, so the report stays +honest when halui gains or loses pins. + + python3 tests/halui/_lib/coverage.py +""" + +import glob +import os +import re +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +SUITE = os.path.dirname(HERE) +HALUI_CC = os.path.join(SUITE, '..', '..', 'src', 'emc', 'usr_intf', 'halui.cc') + +SPEC = re.compile(r'%[-+ #0]*\d*(?:\.\d+)?[diouxXcs]') + + +def pattern_regex(pattern): + parts = SPEC.split(pattern) + out = re.escape(parts[0]) + for rest in parts[1:]: + out += r'[A-Za-z0-9_]+' + re.escape(rest) + return re.compile('^' + out + '$') + + +def main(): + with open(HALUI_CC) as f: + patterns = sorted(set(p[len('halui.'):] for p in + re.findall(r'"(halui\.[A-Za-z0-9_.%\-]+)"', f.read()))) + + touched, runs = set(), [] + for path in sorted(glob.glob(os.path.join(SUITE, '*', 'touched-pins.txt'))): + runs.append(os.path.basename(os.path.dirname(path))) + with open(path) as f: + touched.update(line.strip() for line in f if line.strip()) + + if not runs: + print('no touched-pins.txt found; run the halui tests first') + return 1 + + covered = [p for p in patterns if any(pattern_regex(p).match(t) for t in touched)] + missing = [p for p in patterns if p not in covered] + + print('halui pin coverage from %d test runs: %s' % (len(runs), ', '.join(runs))) + print('%d of %d pin patterns exercised (%.0f%%)' + % (len(covered), len(patterns), 100.0 * len(covered) / len(patterns))) + if missing: + print('not exercised:') + for p in missing: + print(' halui.' + p) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tests/halui/_lib/halui_test.py b/tests/halui/_lib/halui_test.py new file mode 100644 index 00000000000..6911f786a02 --- /dev/null +++ b/tests/halui/_lib/halui_test.py @@ -0,0 +1,347 @@ +"""Shared harness for the halui pin tests. + +Each test directory runs linuxcnc with its test-ui.py as the [DISPLAY] +program, so the harness starts once halui and task are both up. It: + + - Finds every pin halui exported and creates a mirror pin with the opposite + direction on its own HAL component, wired straight to it. Tests drive + halui's inputs and read its outputs by suffix: + h.set('machine.on', 1) + h.get('machine.is-on') + + - Talks to task through the stock linuxcnc python module. That is used only + for test setup (opening a program, homing before a jog test, ...) and as + ground truth for what task actually did -- never as the thing under test. + + - Records every check. A failed check is reported and the run carries on, + so one run shows everything that is broken. The process exits non-zero at + the end if anything failed. + +The tests assert what halui does today. Where today's behaviour is a bug, the +check goes through known_bug() with an explanation: the suite is a baseline +that flags any change in behaviour, and fixing one of those bugs has to +update its test deliberately. + +The tests only look at pins and task state, so the same suite applies +whether halui runs as its own process or inside task. +""" + +import math +import os +import sys +import time +import traceback + +import hal +import linuxcnc + +# halui polls its pins and task's status every 20 ms. Holding an input for a +# few of those guarantees halui samples both edges. +HALUI_PERIOD = 0.02 +HOLD = 0.15 +TIMEOUT = 5.0 + +COMP = 'halui-test' + + +class Halui: + + def __init__(self): + self.t0 = time.time() + self.checks = 0 + self.failures = [] + self.known_bugs = [] + self.touched = set() + + # Every pin halui exported, by suffix: {'machine.on': (type, dir)}, + # and the value each input had before we wired it (halui's default). + self.pins = {} + self.defaults = {} + for p in hal.get_info_pins(): + if p['NAME'].startswith('halui.'): + sfx = p['NAME'][len('halui.'):] + self.pins[sfx] = (p['TYPE'], p['DIRECTION']) + if p['DIRECTION'] == hal.HAL_IN: + self.defaults[sfx] = p['VALUE'] + if not self.pins: + raise RuntimeError('no halui pins found -- is halui running?') + + self.comp = hal.component(COMP) + for sfx, (typ, d) in sorted(self.pins.items()): + mirror = hal.HAL_OUT if d == hal.HAL_IN else hal.HAL_IN + self.comp.newpin(sfx, typ, mirror) + # Wiring our output to halui's input makes the signal carry our + # value, so start from halui's own default (scales, deadbands, + # count-enable...) rather than silently replacing it with 0. + if d == hal.HAL_IN: + self.comp[sfx] = self.defaults[sfx] + self.comp.ready() + + # Pins the config already wired elsewhere cannot be driven from here. + self.external = set() + for sfx, (typ, d) in sorted(self.pins.items()): + # hal.connect() does not raise when the link fails: it returns + # True (hal_link() != 0). A failed link here means the config + # already wired this halui pin. + sig = 'ht.' + sfx + hal.new_sig(sig, typ) + if hal.connect('halui.' + sfx, sig): + self.external.add(sfx) + continue + if hal.connect(COMP + '.' + sfx, sig): + raise RuntimeError('could not wire %s.%s' % (COMP, sfx)) + + self.stat = linuxcnc.stat() + self.cmd = linuxcnc.command() + self.errors = linuxcnc.error_channel() + self.poll() + self.log('harness up: %d halui pins, %d wired externally' + % (len(self.pins), len(self.external))) + + # -- reporting --------------------------------------------------------- + + def log(self, msg): + print('%7.3f: %s' % (time.time() - self.t0, msg), flush=True) + + def section(self, name): + self.log('') + self.log('==== %s ====' % name) + + def check(self, name, ok, detail=''): + self.checks += 1 + self.log('%s %s%s' % ('PASS' if ok else 'FAIL', name, + (' -- ' + detail) if detail else '')) + if not ok: + self.failures.append(name) + return ok + + def known_bug(self, name, ok, explanation): + """Assert today's buggy behaviour, and say why it is a bug.""" + self.known_bugs.append(name) + return self.check('KNOWN-BUG ' + name, ok, explanation) + + def finish(self): + here = os.path.dirname(os.path.abspath(sys.argv[0])) + with open(os.path.join(here, 'touched-pins.txt'), 'w') as f: + for p in sorted(self.touched): + f.write(p + '\n') + self.log('') + self.log('%d checks, %d failed, %d known bugs, %d/%d halui pins exercised' + % (self.checks, len(self.failures), len(self.known_bugs), + len(self.touched & set(self.pins)), len(self.pins))) + for f in self.failures: + self.log(' FAILED: ' + f) + sys.exit(1 if self.failures else 0) + + # -- halui pins -------------------------------------------------------- + + def has(self, sfx): + return sfx in self.pins + + def _pin(self, sfx, want_input): + if sfx not in self.pins: + raise KeyError('halui has no pin %r' % sfx) + is_input = self.pins[sfx][1] == hal.HAL_IN + if is_input != want_input: + raise KeyError('halui.%s is an %s pin' % (sfx, 'input' if is_input else 'output')) + self.touched.add(sfx) + + def set(self, sfx, value): + self._pin(sfx, want_input=True) + if sfx in self.external: + raise KeyError('halui.%s is wired by the config; cannot drive it' % sfx) + self.comp[sfx] = value + + def get(self, sfx): + self._pin(sfx, want_input=False) + return self.comp[sfx] + + def default(self, sfx): + """halui's value for an input pin before the harness wired it.""" + self._pin(sfx, want_input=True) + return self.defaults[sfx] + + def pulse(self, sfx, hold=HOLD): + """Rising edge, held long enough for halui to see it, then released.""" + self.set(sfx, 1) + time.sleep(hold) + self.set(sfx, 0) + time.sleep(hold) + + def settle(self, t=HOLD): + time.sleep(t) + + # -- waiting ----------------------------------------------------------- + + def poll(self): + self.stat.poll() + return self.stat + + def wait_for(self, fn, timeout=TIMEOUT): + end = time.time() + timeout + while True: + self.poll() + try: + if fn(): + return True + except Exception: + pass + if time.time() > end: + return False + time.sleep(HALUI_PERIOD / 2) + + def expect(self, name, fn, timeout=TIMEOUT, detail=None): + ok = self.wait_for(fn, timeout) + return self.check(name, ok, detail() if callable(detail) else (detail or '')) + + def stays(self, fn, duration=0.5): + """True if fn holds for the whole duration (records nothing).""" + end = time.time() + duration + while time.time() < end: + self.poll() + if not fn(): + return False + time.sleep(HALUI_PERIOD / 2) + return True + + def expect_steady(self, name, fn, duration=0.5, detail=None): + """fn must stay true for the whole duration.""" + ok = self.stays(fn, duration) + return self.check(name, ok, detail() if callable(detail) else (detail or '')) + + def expect_pin(self, name, sfx, want, timeout=TIMEOUT, tol=1e-6): + is_float = self.pins[sfx][0] == hal.HAL_FLOAT + + def match(): + v = self.get(sfx) + if is_float: + return abs(v - want) <= tol + return v == want + return self.expect(name, match, timeout, + detail=lambda: 'halui.%s = %r, want %r' % (sfx, self.get(sfx), want)) + + def drain_errors(self): + out = [] + while True: + e = self.errors.poll() + if not e: + return out + out.append(e[1]) + + def reset_between_sections(self): + for sfx in sorted(self.touched): + if self.pins[sfx][1] == hal.HAL_IN and sfx not in self.external: + self.comp[sfx] = self.defaults[sfx] + time.sleep(0.3) + self.nml_abort() + + # -- task setup, via NML (not under test) ------------------------------ + + def nml_abort(self): + self.cmd.abort() + self.cmd.wait_complete() + self.wait_for(lambda: self.stat.interp_state == linuxcnc.INTERP_IDLE) + + def nml_state(self, state): + # task has no distinct OFF state: a request for OFF reads back as + # ESTOP_RESET + want = linuxcnc.STATE_ESTOP_RESET if state == linuxcnc.STATE_OFF else state + self.cmd.state(state) + self.cmd.wait_complete() + return self.wait_for(lambda: self.stat.task_state == want) + + def machine_on(self): + if self.poll().task_state == linuxcnc.STATE_ON: + return + if self.stat.task_state == linuxcnc.STATE_ESTOP: + self.nml_state(linuxcnc.STATE_ESTOP_RESET) + if not self.nml_state(linuxcnc.STATE_ON): + raise RuntimeError('setup: could not turn the machine on') + + def machine_estop(self): + self.nml_state(linuxcnc.STATE_ESTOP) + + def nml_mode(self, mode): + self.cmd.mode(mode) + self.cmd.wait_complete() + if not self.wait_for(lambda: self.stat.task_mode == mode): + raise RuntimeError('setup: could not switch to mode %d' % mode) + + def nml_teleop(self, enable): + self.cmd.teleop_enable(enable) + self.cmd.wait_complete() + want = linuxcnc.TRAJ_MODE_TELEOP if enable else linuxcnc.TRAJ_MODE_FREE + if not self.wait_for(lambda: self.stat.motion_mode == want): + raise RuntimeError('setup: could not set teleop=%d' % enable) + + def nml_home_all(self): + # Note: once every joint is homed, task switches an identity-kins + # machine to teleop by itself. + self.nml_mode(linuxcnc.MODE_MANUAL) + self.cmd.home(-1) + self.cmd.wait_complete() + if not self.wait_for(lambda: all(self.stat.homed[:self.stat.joints]), 20): + raise RuntimeError('setup: homing failed') + + def nml_unhome_all(self): + # motion refuses to unhome in teleop ("must be in joint mode or + # disabled to unhome"), which is where homing leaves the machine + self.nml_mode(linuxcnc.MODE_MANUAL) + if self.poll().motion_mode == linuxcnc.TRAJ_MODE_TELEOP: + self.nml_teleop(0) + self.cmd.unhome(-1) + self.cmd.wait_complete() + if not self.wait_for(lambda: not any(self.stat.homed[:self.stat.joints])): + raise RuntimeError('setup: unhoming failed') + + def wait_idle(self, timeout=20): + return self.wait_for(lambda: self.stat.interp_state == linuxcnc.INTERP_IDLE + and self.stat.exec_state == linuxcnc.EXEC_DONE, timeout) + + def nml_mdi(self, code, timeout=20): + self.nml_mode(linuxcnc.MODE_MDI) + self.cmd.mdi(code) + self.cmd.wait_complete() + if not self.wait_idle(timeout): + raise RuntimeError('setup: MDI %r did not finish' % code) + + def joint_pos(self, j): + return self.stat.joint_actual_position[j] + + def axis_pos(self, a): + return self.stat.actual_position['xyzabcuvw'.index(a)] + + def wait_joint_still(self, j, timeout=10): + last = [None] + def still(): + p = self.joint_pos(j) + done = last[0] is not None and abs(p - last[0]) < 1e-9 and self.stat.inpos + last[0] = p + return done + return self.wait_for(still, timeout) + + +def run(*sections): + """Run each section function against one harness; report at the end. + + Between sections every input a test drove goes back to halui's default and + task is aborted, so a section cannot leave a held jog, a paused program or + a half-finished MDI behind for the next one. + """ + h = Halui() + for fn in sections: + h.section(fn.__name__) + try: + fn(h) + except Exception: + h.log(traceback.format_exc()) + h.check('%s ran to completion' % fn.__name__, False, 'exception, see above') + h.reset_between_sections() + h.finish() + + +def close(a, b, tol=1e-6): + return abs(a - b) <= tol + + +INCH_PER_MM = 1 / 25.4 diff --git a/tests/halui/_lib/launch.sh b/tests/halui/_lib/launch.sh new file mode 100755 index 00000000000..abb5f798f01 --- /dev/null +++ b/tests/halui/_lib/launch.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Shared launcher for the halui pin tests. Each test directory's test.sh +# execs this from inside that directory. +# +# task rewrites the tool table (G10 L1, tool changes), so every run starts +# from a fresh copy of the shared one; tool.tbl is ignored by git. +cp ../_lib/tool.tbl tool.tbl +exec linuxcnc -r halui.ini diff --git a/tests/halui/_lib/tool.tbl b/tests/halui/_lib/tool.tbl new file mode 100644 index 00000000000..25496163e24 --- /dev/null +++ b/tests/halui/_lib/tool.tbl @@ -0,0 +1,3 @@ +T1 P1 Z0.5 D0.25 ;tool one +T2 P2 Z1.0 D0.5 ;tool two +T3 P3 Z0.0 D0.125 ;tool three diff --git a/tests/halui/axes/checkresult b/tests/halui/axes/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/axes/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/axes/halui.ini b/tests/halui/axes/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/axes/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/axes/test-ui.py b/tests/halui/axes/test-ui.py new file mode 100755 index 00000000000..83217d91b8d --- /dev/null +++ b/tests/halui/axes/test-ui.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python3 +"""halui: axis selection, teleop jogging and axis positions. + +Pins: axis.L.select, axis.L.is-selected, axis.selected, + axis.jog-speed, axis.jog-deadband, + axis.L.plus, axis.L.minus, axis.L.analog, + axis.L.increment, axis.L.increment-plus, axis.L.increment-minus, + axis.selected.plus, axis.selected.minus, axis.selected.increment, + axis.selected.increment-plus, axis.selected.increment-minus, + axis.L.pos-commanded, axis.L.pos-feedback, axis.L.pos-relative + +The machine is XYZ trivkins, so axis x/y/z is joint 0/1/2 one to one and +axis motion is measured through the joint velocities. Axis jog speed is in +units per minute; halui divides it by 60. +""" + +import math +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + +LETTERS = 'xyzabcuvw' +CONFIGURED = 'xyz' + + +def idx(a): + return LETTERS.index(a) + + +def av(h, a): + return h.stat.joint[idx(a)]['velocity'] + + +def pos(h, a): + return h.stat.actual_position[idx(a)] + + +def expect_velocity(h, a, v, why): + return h.expect('axis %s moves at %+.2f %s' % (a, v, why), + lambda: close(av(h, a), v, 1e-3), + detail=lambda: 'velocity %+.4f' % av(h, a)) + + +def expect_stopped(h, a, why): + h.expect('axis %s stops %s' % (a, why), lambda: close(av(h, a), 0.0, 1e-9) and h.stat.inpos, + detail=lambda: 'velocity %+.4f' % av(h, a)) + + +def expect_not_moving(h, a, why): + h.expect_steady('axis %s does not move %s' % (a, why), + lambda: close(av(h, a), 0.0, 1e-9), + detail=lambda: 'velocity %+.4f' % av(h, a)) + + +def expect_at(h, a, p, why): + return h.expect('axis %s ends at %+.3f %s' % (a, p, why), + lambda: close(pos(h, a), p, 1e-4) and h.stat.inpos, + timeout=10, detail=lambda: 'position %+.4f' % pos(h, a)) + + +def teleop(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + if not all(h.poll().homed[:3]): + h.nml_home_all() + if h.stat.motion_mode != L.TRAJ_MODE_TELEOP: + h.nml_teleop(1) + + +def to_zero(h): + h.machine_on() + if not all(h.poll().homed[:3]): + h.nml_home_all() + h.nml_mdi('G20 G90 G53 G0 X0 Y0 Z0') + teleop(h) + + +def expect_selected(h, a, why): + h.expect_pin('axis.selected is %d (%s) %s' % (idx(a), a, why), 'axis.selected', idx(a)) + for b in CONFIGURED: + h.expect_pin('axis.%s.is-selected is %s %s' % (b, a == b, why), + 'axis.%s.is-selected' % b, a == b) + + +def pins_and_defaults(h): + # input pins exist for all nine axes; status pins only for configured ones + for a in LETTERS: + for p in ('select', 'plus', 'minus', 'analog', 'increment', + 'increment-plus', 'increment-minus'): + if not h.has('axis.%s.%s' % (a, p)): + h.check('axis.%s.%s exists' % (a, p), False) + for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative'): + if h.has('axis.%s.%s' % (a, p)) != (a in CONFIGURED): + h.check('axis.%s.%s exists only if %s is configured' % (a, p, a), False) + h.check('axis input pins exist for all nine axes', True) + h.check('axis.jog-speed defaults to 0', close(h.default('axis.jog-speed'), 0.0)) + h.check('axis.jog-deadband defaults to 0.2', close(h.default('axis.jog-deadband'), 0.2)) + expect_selected(h, 'x', 'at startup') + + +def select(h): + h.pulse('axis.z.select') + expect_selected(h, 'z', 'after axis.z.select') + h.pulse('axis.y.select') + expect_selected(h, 'y', 'after axis.y.select') + h.pulse('axis.a.select') + expect_selected(h, 'y', 'after axis.a.select (A is not configured, ignored)') + h.set('axis.x.select', 1) + expect_selected(h, 'x', 'while axis.x.select is held') + h.pulse('axis.z.select') + expect_selected(h, 'z', 'after axis.z.select while axis.x.select is still held') + h.set('axis.x.select', 0) + h.settle() + expect_selected(h, 'z', 'after releasing axis.x.select') + + +def continuous_jog(h): + to_zero(h) + h.set('axis.jog-speed', 60) + for a in CONFIGURED: + h.set('axis.%s.plus' % a, 1) + expect_velocity(h, a, 1.0, 'while axis.%s.plus is held at jog-speed 60' % a) + h.set('axis.%s.plus' % a, 0) + expect_stopped(h, a, 'when axis.%s.plus is released' % a) + h.set('axis.%s.minus' % a, 1) + expect_velocity(h, a, -1.0, 'while axis.%s.minus is held' % a) + h.set('axis.%s.minus' % a, 0) + expect_stopped(h, a, 'when axis.%s.minus is released' % a) + + to_zero(h) + h.set('axis.jog-speed', 60) + h.set('axis.x.plus', 1) + expect_velocity(h, 'x', 1.0, 'at jog-speed 60') + h.set('axis.jog-speed', 120) + expect_velocity(h, 'x', 2.0, 'after jog-speed changes to 120 mid-jog') + h.set('axis.x.plus', 0) + expect_stopped(h, 'x', 'on release') + h.set('axis.jog-speed', 60) + + # pins for an axis the machine does not have do nothing + h.set('axis.b.plus', 1) + for a in CONFIGURED: + expect_not_moving(h, a, 'while axis.b.plus is held') + h.set('axis.b.plus', 0) + + +def jog_is_gated(h): + to_zero(h) + h.set('axis.jog-speed', 60) + h.nml_teleop(0) + h.set('axis.x.plus', 1) + expect_not_moving(h, 'x', 'in joint (free) mode') + h.set('axis.x.plus', 0) + + h.nml_state(L.STATE_OFF) + h.set('axis.y.plus', 1) + expect_not_moving(h, 'y', 'when the machine is off') + h.set('axis.y.plus', 0) + + +def analog_jog(h): + to_zero(h) + h.set('axis.jog-speed', 60) + h.set('axis.x.analog', 0.5) + expect_velocity(h, 'x', 0.5, 'at analog 0.5') + h.set('axis.x.analog', -0.8) + expect_velocity(h, 'x', -0.8, 'at analog -0.8') + h.set('axis.x.analog', 0.15) + expect_stopped(h, 'x', 'at analog 0.15, inside the 0.2 deadband') + h.set('axis.x.analog', 0.0) + h.set('axis.jog-deadband', 0.6) + h.set('axis.y.analog', 0.5) + expect_not_moving(h, 'y', 'at analog 0.5 with a 0.6 deadband') + h.set('axis.y.analog', 0.9) + expect_velocity(h, 'y', 0.9, 'at analog 0.9 with a 0.6 deadband') + h.set('axis.jog-speed', 30) + expect_velocity(h, 'y', 0.45, 'at analog 0.9 after jog-speed changes to 30') + h.set('axis.y.analog', 0.0) + expect_stopped(h, 'y', 'at analog 0') + h.set('axis.jog-deadband', 0.2) + h.set('axis.jog-speed', 60) + h.set('axis.z.analog', -0.4) + expect_velocity(h, 'z', -0.4, 'at analog -0.4') + h.set('axis.z.analog', 0.0) + expect_stopped(h, 'z', 'at analog 0') + + +def incremental_jog(h): + to_zero(h) + h.set('axis.jog-speed', 60) + for a in CONFIGURED: + h.set('axis.%s.increment' % a, 0.25) + h.pulse('axis.%s.increment-plus' % a) + expect_at(h, a, 0.25, 'after increment-plus') + h.pulse('axis.%s.increment-minus' % a) + expect_at(h, a, 0.0, 'after increment-minus') + + h.pulse('axis.y.select') + h.set('axis.selected.increment', 0.5) + h.pulse('axis.selected.increment-plus') + expect_at(h, 'y', 0.5, 'after axis.selected.increment-plus with y selected') + h.pulse('axis.selected.increment-minus') + expect_at(h, 'y', 0.0, 'after axis.selected.increment-minus') + h.check('the selected increment moved only y', + close(pos(h, 'x'), 0.0, 1e-4) and close(pos(h, 'z'), 0.0, 1e-4), + 'x=%+.4f z=%+.4f' % (pos(h, 'x'), pos(h, 'z'))) + + +def selected_jog(h): + to_zero(h) + h.set('axis.jog-speed', 60) + h.pulse('axis.x.select') + h.set('axis.selected.plus', 1) + expect_velocity(h, 'x', 1.0, 'while axis.selected.plus is held with x selected') + h.set('axis.selected.plus', 0) + expect_stopped(h, 'x', 'on release') + h.set('axis.selected.minus', 1) + expect_velocity(h, 'x', -1.0, 'while axis.selected.minus is held') + h.set('axis.selected.minus', 0) + expect_stopped(h, 'x', 'on release') + + # Changing the selection mid-jog should stop the old axis and start the + # new one, as it does for joints. For axes the restart looks at + # ajog_plus[num_axes] / ajog_minus[num_axes] -- the pins of the axis whose + # index equals the number of configured axes (A on this XYZ machine) -- + # instead of the selected slot ajog_*[EMCMOT_MAX_AXIS]. + h.set('axis.selected.plus', 1) + expect_velocity(h, 'x', 1.0, 'before the selection changes') + h.pulse('axis.y.select') + expect_stopped(h, 'x', 'when the selection moves to y mid-jog') + h.known_bug('a selected jog does not carry over to the newly selected axis', + h.stays(lambda: close(av(h, 'y'), 0.0, 1e-9), 0.8), + 'halui.cc check_hal_changes(): axis reselect reads ajog_plus[num_axes] ' + 'instead of ajog_plus[EMCMOT_MAX_AXIS]; y should be jogging at +1') + h.set('axis.selected.plus', 0) + h.nml_abort() + to_zero(h) + + # the same index error from the other side: A's pin (inert on this + # machine) starts a jog on whichever axis gets selected + h.pulse('axis.x.select') + h.set('axis.a.plus', 1) + expect_not_moving(h, 'x', 'while only axis.a.plus is held (A is not configured)') + h.pulse('axis.z.select') + h.known_bug('holding axis.a.plus makes a newly selected axis jog', + h.wait_for(lambda: close(av(h, 'z'), 1.0, 1e-3), 1.0), + 'same ajog_plus[num_axes] index: num_axes is 3 here, which is axis A; ' + 'z should stay still') + h.set('axis.a.plus', 0) + h.nml_abort() + + +def expected_relative(s): + """halui's own formula (modify_hal_pins) from task's offsets.""" + ax, ay, az = s.actual_position[:3] + g5x, g92, tlo, rot = s.g5x_offset, s.g92_offset, s.tool_offset, s.rotation_xy + x = ax - g5x[0] - tlo[0] + y = ay - g5x[1] - tlo[1] + c, sn = math.cos(-rot * math.pi / 180), math.sin(-rot * math.pi / 180) + return (x * c - y * sn - g92[0], + y * c + x * sn - g92[1], + az - g5x[2] - g92[2] - tlo[2]) + + +def expect_positions(h, machine, relative, why): + for i, a in enumerate(CONFIGURED): + h.expect_pin('axis.%s.pos-commanded is %+.3f %s' % (a, machine[i], why), + 'axis.%s.pos-commanded' % a, machine[i], tol=1e-6) + h.expect_pin('axis.%s.pos-feedback is %+.3f %s' % (a, machine[i], why), + 'axis.%s.pos-feedback' % a, machine[i], tol=1e-6) + h.expect_pin('axis.%s.pos-relative is %+.3f %s' % (a, relative[i], why), + 'axis.%s.pos-relative' % a, relative[i], tol=1e-6) + + +def positions(h): + h.machine_on() + h.nml_home_all() + for code in ('G20 G90 G54', 'G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 R0', 'M61 Q0', + 'G53 G0 X1 Y2 Z0.5'): + h.nml_mdi(code) + expect_positions(h, (1, 2, 0.5), (1, 2, 0.5), 'with no offsets') + + for code in ('G10 L2 P1 X1 Y2 Z0.5 R30', 'M61 Q1', 'G43', 'G53 G0 X3 Y4 Z1', + 'G92 X0.5 Y-0.5'): + h.nml_mdi(code) + s = h.poll() + h.check('setup: task has a G54 offset, G92 offset, rotation and tool offset', + close(s.g5x_offset[0], 1) and close(s.rotation_xy, 30) and close(s.tool_offset[2], 0.5) + and not close(s.g92_offset[0], 0), + 'g5x=%s g92=%s rot=%s tlo=%s' % (s.g5x_offset[:3], s.g92_offset[:3], + s.rotation_xy, s.tool_offset[:3])) + rel = expected_relative(s) + expect_positions(h, (3, 4, 1), rel, 'with G54 + G92 + R30 + G43') + # G92 X0.5 Y-0.5 defines the current point as X0.5 Y-0.5 in program + # coordinates, and Z is machine 1 - G54 0.5 - tool 0.5 = 0 + for a, want in (('x', 0.5), ('y', -0.5), ('z', 0.0)): + h.expect_pin('axis.%s.pos-relative agrees with program coordinates (%+.2f)' % (a, want), + 'axis.%s.pos-relative' % a, want, tol=1e-6) + + # the pins follow motion + teleop(h) + h.set('axis.jog-speed', 60) + h.set('axis.x.increment', 0.5) + h.pulse('axis.x.increment-plus') + expect_at(h, 'x', 3.5, 'after an increment in teleop') + rel = expected_relative(h.poll()) + expect_positions(h, (3.5, 4, 1), rel, 'after moving X by 0.5') + + for code in ('G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 R0', 'M61 Q0'): + h.nml_mdi(code) + + +run(pins_and_defaults, + select, + continuous_jog, + jog_is_gated, + analog_jog, + incremental_jog, + selected_jog, + positions) diff --git a/tests/halui/axes/test.sh b/tests/halui/axes/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/axes/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/config-9axis/checkresult b/tests/halui/config-9axis/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/config-9axis/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/config-9axis/halui.ini b/tests/halui/config-9axis/halui.ini new file mode 100644 index 00000000000..e7501e2a64d --- /dev/null +++ b/tests/halui/config-9axis/halui.ini @@ -0,0 +1,194 @@ +# Nine-axis machine for the halui pin tests: trivkins XYZABCUVW, one joint +# per axis, so every per-axis halui pin exists and does something. + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = nine.hal + +[TRAJ] +COORDINATES = X Y Z A B C U V W +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +MAX_ANGULAR_VELOCITY = 60 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins coordinates=XYZABCUVW +JOINTS = 9 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_A] +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 + +[AXIS_B] +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 + +[AXIS_C] +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 + +[AXIS_U] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_V] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_W] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_3] +TYPE = ANGULAR +HOME = 0.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_4] +TYPE = ANGULAR +HOME = 0.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_5] +TYPE = ANGULAR +HOME = 0.0 +MAX_VELOCITY = 60 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -360.0 +MAX_LIMIT = 360.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_6] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_7] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 + +[JOINT_8] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 1.0 +MIN_FERROR = 0.5 +HOME_SEQUENCE = 0 diff --git a/tests/halui/config-9axis/nine.hal b/tests/halui/config-9axis/nine.hal new file mode 100644 index 00000000000..e90685ec8ab --- /dev/null +++ b/tests/halui/config-9axis/nine.hal @@ -0,0 +1,19 @@ +# nine joints, looped back +loadrt [KINS]KINEMATICS +loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS +addf motion-command-handler servo-thread +addf motion-controller servo-thread + +net j0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb +net j1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb +net j2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb +net j3pos joint.3.motor-pos-cmd => joint.3.motor-pos-fb +net j4pos joint.4.motor-pos-cmd => joint.4.motor-pos-fb +net j5pos joint.5.motor-pos-cmd => joint.5.motor-pos-fb +net j6pos joint.6.motor-pos-cmd => joint.6.motor-pos-fb +net j7pos joint.7.motor-pos-cmd => joint.7.motor-pos-fb +net j8pos joint.8.motor-pos-cmd => joint.8.motor-pos-fb + +net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in +net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared +net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed diff --git a/tests/halui/config-9axis/test-ui.py b/tests/halui/config-9axis/test-ui.py new file mode 100755 index 00000000000..25f33eb7c03 --- /dev/null +++ b/tests/halui/config-9axis/test-ui.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""halui on a nine-axis machine (trivkins XYZABCUVW, joint N drives axis N). + +Every per-axis halui pin exists here, so this covers selection, jogging, +positions and tool length offsets for A, B, C, U, V and W too. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + +LETTERS = 'xyzabcuvw' + + +def jv(h, j): + return h.stat.joint[j]['velocity'] + + +def teleop(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + if not all(h.poll().homed[:9]): + h.nml_home_all() + if h.stat.motion_mode != L.TRAJ_MODE_TELEOP: + h.nml_teleop(1) + + +def pins(h): + missing = ['axis.%s.%s' % (a, p) for a in LETTERS + for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative', + 'select', 'plus', 'minus', 'analog', 'increment', + 'increment-plus', 'increment-minus') + if not h.has('axis.%s.%s' % (a, p))] + h.check('every axis has its full set of pins', not missing, 'missing: %s' % missing) + h.check('joint pins exist for all nine joints', + all(h.has('joint.%d.is-homed' % j) for j in range(9))) + + +def select_every_axis(h): + for i, a in enumerate(LETTERS): + h.pulse('axis.%s.select' % a) + h.expect_pin('axis.selected is %d after axis.%s.select' % (i, a), 'axis.selected', i) + wrong = [b for b in LETTERS if h.get('axis.%s.is-selected' % b) != (a == b)] + h.check('only axis.%s.is-selected is set' % a, not wrong, 'also set/unset: %s' % wrong) + + +def jog_every_axis(h): + teleop(h) + h.set('axis.jog-speed', 60) + for i, a in enumerate(LETTERS): + h.set('axis.%s.plus' % a, 1) + h.expect('axis.%s.plus jogs joint %d' % (a, i), lambda i=i: close(jv(h, i), 1.0, 1e-3), + detail=lambda i=i: 'joint %d velocity %+.4f' % (i, jv(h, i))) + others = [j for j in range(9) if j != i and not close(jv(h, j), 0.0, 1e-9)] + h.check('only joint %d moves' % i, not others, 'also moving: %s' % others) + h.set('axis.%s.plus' % a, 0) + h.expect('axis %s stops on release' % a, + lambda i=i: close(jv(h, i), 0.0, 1e-9) and h.stat.inpos) + + +def reselect_carries_over(h): + # On an XYZ machine this is a known bug (see tests/halui/axes): the + # restart reads ajog_plus[num_axes]. Here num_axes == EMCMOT_MAX_AXIS == 9, + # which happens to be the right slot, so the jog does carry over. + teleop(h) + h.set('axis.jog-speed', 60) + h.pulse('axis.x.select') + h.set('axis.selected.plus', 1) + h.expect('x jogs as the selected axis', lambda: close(jv(h, 0), 1.0, 1e-3)) + h.pulse('axis.y.select') + h.expect('x stops when the selection moves to y', lambda: close(jv(h, 0), 0.0, 1e-9)) + h.expect('y picks up the selected jog (correct only because num_axes is 9 here)', + lambda: close(jv(h, 1), 1.0, 1e-3)) + h.set('axis.selected.plus', 0) + h.expect('y stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) + + +def expect_positions(h, machine, relative, why): + for i, a in enumerate(LETTERS): + h.expect_pin('axis.%s.pos-commanded is %g %s' % (a, machine[i], why), + 'axis.%s.pos-commanded' % a, machine[i], tol=1e-6) + h.expect_pin('axis.%s.pos-feedback is %g %s' % (a, machine[i], why), + 'axis.%s.pos-feedback' % a, machine[i], tol=1e-6) + h.expect_pin('axis.%s.pos-relative is %g %s' % (a, relative[i], why), + 'axis.%s.pos-relative' % a, relative[i], tol=1e-6) + + +def expect_tool_offsets(h, offsets, why): + for i, a in enumerate(LETTERS): + h.expect_pin('tool.length_offset.%s is %g %s' % (a, offsets[i], why), + 'tool.length_offset.' + a, offsets[i], tol=1e-6) + + +def positions_and_offsets(h): + h.machine_on() + h.nml_home_all() + for code in ('G20 G90 G54 G49', 'G92.1', 'G10 L2 P1 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 R0'): + h.nml_mdi(code) + + machine = [i + 2 for i in range(9)] + h.nml_mdi('G53 G0 X2 Y3 Z4 A5 B6 C7 U8 V9 W10') + expect_positions(h, machine, machine, 'with no offsets') + expect_tool_offsets(h, [0] * 9, 'with no tool offset') + + h.nml_mdi('G10 L2 P1 X1 Y2 Z3 A4 B5 C6 U7 V8 W9') + work = [1 + i for i in range(9)] + expect_positions(h, machine, [m - w for m, w in zip(machine, work)], 'with a G54 offset on every axis') + + tlo = [round(0.1 * (i + 1), 1) for i in range(9)] + h.nml_mdi('G43.1 X0.1 Y0.2 Z0.3 A0.4 B0.5 C0.6 U0.7 V0.8 W0.9') + expect_tool_offsets(h, tlo, 'after G43.1 on every axis') + expect_positions(h, machine, [m - w - t for m, w, t in zip(machine, work, tlo)], + 'with G54 and a tool offset on every axis') + + h.nml_mdi('G92 A0 U0 W0') + s = h.poll() + for i, a in ((3, 'a'), (6, 'u'), (8, 'w')): + h.expect_pin('axis.%s.pos-relative is 0 after G92 %s0' % (a, a.upper()), + 'axis.%s.pos-relative' % a, 0.0, tol=1e-6) + h.check('setup: G92 left the other axes alone', close(s.g92_offset[4], 0.0)) + + for code in ('G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 A0 B0 C0 U0 V0 W0'): + h.nml_mdi(code) + + +run(pins, select_every_axis, jog_every_axis, reselect_carries_over, positions_and_offsets) diff --git a/tests/halui/config-9axis/test.sh b/tests/halui/config-9axis/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/config-9axis/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/config-minimal/checkresult b/tests/halui/config-minimal/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/config-minimal/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/config-minimal/halui.ini b/tests/halui/config-minimal/halui.ini new file mode 100644 index 00000000000..f6e70986383 --- /dev/null +++ b/tests/halui/config-minimal/halui.ini @@ -0,0 +1,74 @@ +# Minimal/odd machine for the halui pin tests: two joints driving Y and Z, +# two spindles, no home sequence and no MDI commands -- so halui.home-all, +# halui.halui-mdi-is-running and halui.mdi-command-NN must not exist. + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = minimal.hal + +[TRAJ] +COORDINATES = Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 2 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins coordinates=YZ +JOINTS = 2 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 diff --git a/tests/halui/config-minimal/minimal.hal b/tests/halui/config-minimal/minimal.hal new file mode 100644 index 00000000000..c9cbd1effbf --- /dev/null +++ b/tests/halui/config-minimal/minimal.hal @@ -0,0 +1,12 @@ +# two joints, two spindles, everything looped back +loadrt [KINS]KINEMATICS +loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS num_spindles=[TRAJ]SPINDLES +addf motion-command-handler servo-thread +addf motion-controller servo-thread + +net j0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb +net j1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb + +net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in +net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared +net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed diff --git a/tests/halui/config-minimal/test-ui.py b/tests/halui/config-minimal/test-ui.py new file mode 100755 index 00000000000..69d8488810b --- /dev/null +++ b/tests/halui/config-minimal/test-ui.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +"""halui on a two-joint YZ machine with two spindles, no home sequence and +no MDI commands. + +Checks which pins exist for this configuration, that a second spindle is +driven independently, and how axis selection starts up when the first +configured axis is not X. Joint 0 drives Y and joint 1 drives Z. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + +LETTERS = 'xyzabcuvw' +CONFIGURED = 'yz' +JOINT_OF = {'y': 0, 'z': 1} + + +def jv(h, j): + return h.stat.joint[j]['velocity'] + + +def home_each(h): + # there is no home sequence, so home-all is not an option: one at a time + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + for j in (0, 1): + if not h.poll().homed[j]: + h.cmd.home(j) + h.cmd.wait_complete() + if not h.wait_for(lambda j=j: h.stat.homed[j]): + raise RuntimeError('setup: could not home joint %d' % j) + + +def teleop(h): + home_each(h) + if h.poll().motion_mode != L.TRAJ_MODE_TELEOP: + h.nml_teleop(1) + + +def pins(h): + h.check('no home-all pin without [JOINT_n]HOME_SEQUENCE', not h.has('home-all')) + h.check('no halui-mdi-is-running pin without [HALUI]MDI_COMMAND', + not h.has('halui-mdi-is-running')) + h.check('no mdi-command pins without [HALUI]MDI_COMMAND', + not any(p.startswith('mdi-command-') for p in h.pins)) + h.check('joint pins exist for joints 0 and 1', + all(h.has('joint.%d.%s' % (j, p)) for j in (0, 1) for p in ('home', 'is-homed', 'plus'))) + h.check('no pins for joint 2', not any(p.startswith('joint.2.') for p in h.pins)) + h.check('spindle pins exist for spindles 0 and 1', + all(h.has('spindle.%d.%s' % (s, p)) for s in (0, 1) + for p in ('start', 'is-on', 'brake-on', 'override.value'))) + h.check('no pins for spindle 2', not any(p.startswith('spindle.2.') for p in h.pins)) + wrong = [a for a in LETTERS + for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative') + if h.has('axis.%s.%s' % (a, p)) != (a in CONFIGURED)] + h.check('axis status pins exist only for Y and Z', not wrong, 'wrong: %s' % wrong) + h.check('axis input pins exist for all nine axes', + all(h.has('axis.%s.plus' % a) for a in LETTERS)) + + +def startup_selection(h): + h.expect_pin('joint.0.is-selected is true at startup', 'joint.0.is-selected', True) + h.expect_pin('axis.y.is-selected marks the first configured axis', 'axis.y.is-selected', True) + h.expect_pin('axis.z.is-selected is false at startup', 'axis.z.is-selected', False) + h.known_bug('axis.selected is 0 (X, not on this machine) at startup', + h.get('axis.selected') == 0, + 'hal_init_pins() sets axis_selected to 0 while halui_hal_init() marks the ' + 'first configured axis (Y, index 1) as selected; should be 1') + + teleop(h) + h.set('axis.jog-speed', 60) + h.set('axis.selected.plus', 1) + h.known_bug('axis.selected.plus at startup does not jog the axis shown as selected', + h.stays(lambda: close(jv(h, JOINT_OF['y']), 0.0, 1e-9), 0.8), + 'the jog goes to axis index 0 (X), which halui then drops as not configured') + h.set('axis.selected.plus', 0) + h.settle() + + h.pulse('axis.y.select') + h.expect_pin('pressing axis.y.select makes axis.selected 1', 'axis.selected', 1) + h.set('axis.selected.plus', 1) + h.expect('after that, axis.selected.plus jogs Y', + lambda: close(jv(h, JOINT_OF['y']), 1.0, 1e-3), + detail=lambda: 'joint 0 velocity %+.4f' % jv(h, 0)) + h.set('axis.selected.plus', 0) + h.expect('Y stops on release', lambda: close(jv(h, 0), 0.0, 1e-9) and h.stat.inpos) + + +def second_spindle(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + + def sp(s): + return h.stat.spindle[s] + + h.pulse('spindle.1.start') + h.expect('spindle.1.start turns spindle 1 on', + lambda: sp(1)['enabled'] and sp(1)['speed'] == 1) + h.check('spindle 0 stays off', not sp(0)['enabled']) + h.expect_pin('spindle.1.is-on sets', 'spindle.1.is-on', True) + h.expect_pin('spindle.1.runs-forward sets', 'spindle.1.runs-forward', True) + h.expect_pin('spindle.0.is-on stays false', 'spindle.0.is-on', False) + + h.pulse('spindle.1.reverse') + h.expect('spindle.1.reverse reverses spindle 1', lambda: sp(1)['direction'] == -1) + h.expect_pin('spindle.1.runs-backward sets', 'spindle.1.runs-backward', True) + h.pulse('spindle.1.stop') + h.expect('spindle.1.stop stops spindle 1', lambda: not sp(1)['enabled']) + h.expect_pin('spindle.1.is-on clears', 'spindle.1.is-on', False) + + brake0 = sp(0)['brake'] + h.pulse('spindle.1.brake-on') + h.expect('spindle.1.brake-on engages brake 1', lambda: sp(1)['brake'] == 1) + h.expect_pin('spindle.1.brake-is-on sets', 'spindle.1.brake-is-on', True) + h.check('brake 0 is untouched', sp(0)['brake'] == brake0, + 'brake 0 was %d, now %d' % (brake0, sp(0)['brake'])) + h.pulse('spindle.1.brake-off') + h.expect_pin('spindle.1.brake-is-on clears', 'spindle.1.brake-is-on', False) + + # no [DISPLAY] spindle override limits here: halui clamps to 0 .. 1.0 + h.pulse('spindle.1.override.decrease') + h.expect('spindle.1.override.decrease lowers override 1', + lambda: close(sp(1)['override'], 0.9)) + h.check('override 0 is untouched', close(sp(0)['override'], 1.0)) + h.expect_pin('spindle.1.override.value follows', 'spindle.1.override.value', 0.9) + h.pulse('spindle.1.override.increase') + h.pulse('spindle.1.override.increase') + h.expect('spindle 1 override is clamped at the default maximum of 1.0', + lambda: close(sp(1)['override'], 1.0)) + h.set('spindle.1.override.counts', -3) + h.expect('spindle.1.override.counts moves override 1', lambda: close(sp(1)['override'], 0.7)) + h.pulse('spindle.1.override.reset') + h.expect('spindle.1.override.reset puts it back to 1.0', lambda: close(sp(1)['override'], 1.0)) + + +def motion(h): + home_each(h) + if h.poll().motion_mode != L.TRAJ_MODE_FREE: + h.nml_teleop(0) + h.set('joint.jog-speed', 60) + h.set('joint.1.plus', 1) + h.expect('joint.1.plus jogs joint 1', lambda: close(jv(h, 1), 1.0, 1e-3)) + h.set('joint.1.plus', 0) + h.expect('joint 1 stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) + + teleop(h) + h.set('axis.jog-speed', 60) + h.set('axis.z.plus', 1) + h.expect('axis.z.plus moves joint 1 (Z)', lambda: close(jv(h, 1), 1.0, 1e-3)) + h.set('axis.z.plus', 0) + h.expect('Z stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) + h.set('axis.y.minus', 1) + h.expect('axis.y.minus moves joint 0 (Y) backwards', lambda: close(jv(h, 0), -1.0, 1e-3)) + h.set('axis.y.minus', 0) + h.expect('Y stops on release', lambda: close(jv(h, 0), 0.0, 1e-9) and h.stat.inpos) + + h.set('axis.x.plus', 1) + h.expect_steady('axis.x.plus moves nothing on a machine without X', + lambda: close(jv(h, 0), 0.0, 1e-9) and close(jv(h, 1), 0.0, 1e-9)) + h.set('axis.x.plus', 0) + + h.nml_mdi('G20 G90 G53 G0 Y1.5 Z-0.5') + h.expect_pin('axis.y.pos-feedback shows Y', 'axis.y.pos-feedback', 1.5) + h.expect_pin('axis.z.pos-feedback shows Z', 'axis.z.pos-feedback', -0.5) + + +run(pins, startup_selection, second_spindle, motion) diff --git a/tests/halui/config-minimal/test.sh b/tests/halui/config-minimal/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/config-minimal/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/joints/checkresult b/tests/halui/joints/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/joints/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/joints/halui.ini b/tests/halui/joints/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/joints/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/joints/test-ui.py b/tests/halui/joints/test-ui.py new file mode 100755 index 00000000000..77affb3603f --- /dev/null +++ b/tests/halui/joints/test-ui.py @@ -0,0 +1,442 @@ +#!/usr/bin/env python3 +"""halui: joint selection, homing, joint status and joint jogging. + +Pins: joint.N.select, joint.N.is-selected, joint.selected, + joint.N.home, joint.N.unhome, joint.selected.home, joint.selected.unhome, + home-all, joint.N.is-homed, joint.selected.is-homed, + joint.N.on-{soft,hard}-{min,max}-limit, joint.N.has-fault, + joint.N.override-limits and the joint.selected.* mirrors of those, + joint.jog-speed, joint.jog-deadband, + joint.N.plus, joint.N.minus, joint.N.analog, + joint.N.increment, joint.N.increment-plus, joint.N.increment-minus, + joint.selected.plus, joint.selected.minus, joint.selected.increment, + joint.selected.increment-plus, joint.selected.increment-minus + +Joint jog speed is in units per minute; halui divides it by 60. +""" + +import os +import sys +import time + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import hal # noqa: E402 +import linuxcnc as L # noqa: E402 + +JOINTS = 3 + + +def jv(h, j): + return h.stat.joint[j]['velocity'] + + +def expect_velocity(h, j, v, why): + return h.expect('joint %d moves at %+.2f %s' % (j, v, why), + lambda: close(jv(h, j), v, 1e-3), + detail=lambda: 'velocity %+.4f' % jv(h, j)) + + +def expect_stopped(h, j, why): + # per joint: the global in-position flag stays false while another joint + # is still moving + ok = h.wait_for(lambda: close(jv(h, j), 0.0, 1e-9)) and \ + h.stays(lambda: close(jv(h, j), 0.0, 1e-9), 0.2) + h.check('joint %d stops %s' % (j, why), ok, 'velocity %+.4f' % jv(h, j)) + + +def expect_not_moving(h, j, why): + h.expect_steady('joint %d does not move %s' % (j, why), + lambda: close(jv(h, j), 0.0, 1e-9), + detail=lambda: 'velocity %+.4f' % jv(h, j)) + + +def manual_joint_mode(h, homed=False): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + if homed: + h.nml_home_all() + if h.poll().motion_mode != L.TRAJ_MODE_FREE: + h.nml_teleop(0) + + +def to_zero(h): + manual_joint_mode(h) + h.nml_mdi('G20 G90 G53 G0 X0 Y0 Z0') + h.nml_mode(L.MODE_MANUAL) + if h.poll().motion_mode != L.TRAJ_MODE_FREE: + h.nml_teleop(0) + + +def expect_selected(h, j, why): + h.expect_pin('joint.selected is %d %s' % (j, why), 'joint.selected', j) + for k in range(JOINTS): + h.expect_pin('joint.%d.is-selected is %s %s' % (k, k == j, why), + 'joint.%d.is-selected' % k, k == j) + + +def pins_and_defaults(h): + for j in range(JOINTS): + for p in ('select', 'is-selected', 'home', 'unhome', 'is-homed', 'plus', 'minus', + 'analog', 'increment', 'increment-plus', 'increment-minus', + 'on-soft-min-limit', 'on-soft-max-limit', 'on-hard-min-limit', + 'on-hard-max-limit', 'has-fault', 'override-limits'): + if not h.has('joint.%d.%s' % (j, p)): + h.check('joint.%d.%s exists' % (j, p), False) + h.check('there are no pins for a joint the machine does not have', + not any(s.startswith('joint.%d.' % JOINTS) for s in h.pins)) + h.check('home-all exists because [JOINT_0]HOME_SEQUENCE is set', h.has('home-all')) + h.check('joint.jog-speed defaults to 0', close(h.default('joint.jog-speed'), 0.0)) + h.check('joint.jog-deadband defaults to 0.2', close(h.default('joint.jog-deadband'), 0.2)) + expect_selected(h, 0, 'at startup') + + +def select(h): + h.pulse('joint.2.select') + expect_selected(h, 2, 'after joint.2.select') + h.pulse('joint.1.select') + expect_selected(h, 1, 'after joint.1.select') + + # selection follows the latest rising edge, even while another select is held + h.set('joint.0.select', 1) + expect_selected(h, 0, 'while joint.0.select is held') + h.pulse('joint.2.select') + expect_selected(h, 2, 'after joint.2.select while joint.0.select is still held') + h.set('joint.0.select', 0) + h.settle() + expect_selected(h, 2, 'after releasing joint.0.select (falling edges do nothing)') + + +def homing(h): + manual_joint_mode(h) + h.nml_unhome_all() + for j in range(JOINTS): + h.expect_pin('joint.%d.is-homed is false after unhoming' % j, 'joint.%d.is-homed' % j, False) + + h.pulse('joint.1.home') + h.expect('joint.1.home homes joint 1', lambda: h.stat.homed[1]) + h.expect_pin('joint.1.is-homed sets', 'joint.1.is-homed', True) + h.pulse('joint.1.unhome') + h.expect('joint.1.unhome unhomes joint 1', lambda: not h.stat.homed[1]) + h.expect_pin('joint.1.is-homed clears', 'joint.1.is-homed', False) + + h.pulse('joint.2.select') + h.expect_pin('joint.selected.is-homed is false for unhomed joint 2', + 'joint.selected.is-homed', False) + h.pulse('joint.selected.home') + h.expect('joint.selected.home homes the selected joint (2)', lambda: h.stat.homed[2]) + h.expect_pin('joint.selected.is-homed follows joint 2', 'joint.selected.is-homed', True) + h.pulse('joint.selected.unhome') + h.expect('joint.selected.unhome unhomes the selected joint (2)', lambda: not h.stat.homed[2]) + h.expect_pin('joint.selected.is-homed clears', 'joint.selected.is-homed', False) + + h.pulse('home-all') + h.expect('home-all homes every joint', lambda: all(h.stat.homed[:JOINTS]), timeout=20) + for j in range(JOINTS): + h.expect_pin('joint.%d.is-homed is true after home-all' % j, 'joint.%d.is-homed' % j, True) + h.expect_pin('joint.selected.is-homed is true after home-all', 'joint.selected.is-homed', True) + # task puts an identity-kins machine into teleop once everything is homed + h.expect_pin('mode.is-teleop reports the switch to teleop after homing', 'mode.is-teleop', True) + + # homing is refused while in ESTOP + h.nml_unhome_all() + h.machine_estop() + h.pulse('joint.0.home') + h.expect_steady('joint.0.home in ESTOP does not home', lambda: not h.stat.homed[0]) + h.pulse('home-all') + h.expect_steady('home-all in ESTOP does not home', lambda: not any(h.stat.homed[:JOINTS])) + + +def hard_limits_and_fault(h): + manual_joint_mode(h, homed=True) + h.set('joint.jog-speed', 60) + h.set('joint.0.increment', 0.1) + for kind, motion_pin, key in (('min', 'neg-lim-sw-in', 'min_hard_limit'), + ('max', 'pos-lim-sw-in', 'max_hard_limit')): + manual_joint_mode(h) + h.pulse('joint.0.select') + pin = 'joint.0.on-hard-%s-limit' % kind + sel = 'joint.selected.on-hard-%s-limit' % kind + h.expect_pin('%s is false with the switch open' % pin, pin, False) + hal.set_p('joint.0.' + motion_pin, '1') + h.expect('task sees joint 0 on its hard %s limit' % kind, + lambda k=key: h.stat.joint[0][k]) + h.expect_pin('%s sets' % pin, pin, True) + h.expect_pin('%s follows selected joint 0' % sel, sel, True) + for other in (1, 2): + h.expect_pin('joint.%d.on-hard-%s-limit stays false' % (other, kind), + 'joint.%d.on-hard-%s-limit' % (other, kind), False) + h.pulse('joint.1.select') + h.expect_pin('%s is false while joint 1 is selected' % sel, sel, False) + h.expect_pin('%s is still set for joint 0' % pin, pin, True) + h.pulse('joint.0.select') + h.expect_pin('%s follows joint 0 again once it is reselected' % sel, sel, True) + + # override-limits is a status pin in halui; the override comes over + # NML. task reports one flag for all joints (taskintf.cc: + # overrideLimits = !!overrideLimitMask), so every joint shows it. + h.cmd.override_limits() + h.cmd.wait_complete() + h.expect('task reports the limits overridden', lambda: h.stat.joint[0]['override_limits']) + for j in range(JOINTS): + h.expect_pin('joint.%d.override-limits is set (one flag for all joints)' % j, + 'joint.%d.override-limits' % j, True) + h.expect_pin('joint.selected.override-limits is set', 'joint.selected.override-limits', True) + + hal.set_p('joint.0.' + motion_pin, '0') + h.expect('the hard %s limit clears in task' % kind, lambda k=key: not h.stat.joint[0][k]) + h.expect_pin('%s clears' % pin, pin, False) + h.expect_pin('%s clears' % sel, sel, False) + + # motion drops the override once a jog made while overridden finishes + manual_joint_mode(h) + h.expect_pin('override-limits is still set before any jog', 'joint.0.override-limits', True) + h.pulse('joint.0.increment-plus' if kind == 'min' else 'joint.0.increment-minus') + h.expect('the jog off the switch completes', lambda: h.stat.inpos and close(jv(h, 0), 0.0, 1e-9)) + for j in range(JOINTS): + h.expect_pin('joint.%d.override-limits clears after that jog' % j, + 'joint.%d.override-limits' % j, False) + + manual_joint_mode(h) + h.pulse('joint.2.select') + h.expect_pin('joint.2.has-fault is false', 'joint.2.has-fault', False) + hal.set_p('joint.2.amp-fault-in', '1') + h.expect('task sees the joint 2 amp fault', lambda: h.stat.joint[2]['fault']) + h.expect_pin('joint.2.has-fault sets', 'joint.2.has-fault', True) + h.expect_pin('joint.selected.has-fault follows joint 2', 'joint.selected.has-fault', True) + h.expect_pin('joint.0.has-fault stays false', 'joint.0.has-fault', False) + hal.set_p('joint.2.amp-fault-in', '0') + manual_joint_mode(h) + h.expect('the fault clears in task', lambda: not h.stat.joint[2]['fault']) + h.expect_pin('joint.2.has-fault clears', 'joint.2.has-fault', False) + h.expect_pin('joint.selected.has-fault clears', 'joint.selected.has-fault', False) + + +def soft_limit_pins_never_set(h): + # task never reports per-joint soft limits: taskintf.cc hard-codes + # minSoftLimit/maxSoftLimit to 0 ("soft limits are now applied to the + # command, and should never happen"). motion does still detect a joint + # beyond its soft limit and says so on motion.on-soft-limit. + # + # [JOINT_2] limits are -4 .. 4 and the joint sits at 0. Move the limit + # past the joint through task's ini.N.* pins -- the case motion's own + # comment names as the way this happens. motion then wants the joint + # unhomed before it will move again, so this runs last. + to_zero(h) + manual_joint_mode(h, homed=True) + h.pulse('joint.2.select') + for kind, ini_pin, value in (('min', 'ini.2.min_limit', 1.0), + ('max', 'ini.2.max_limit', -1.0)): + pin = 'joint.2.on-soft-%s-limit' % kind + sel = 'joint.selected.on-soft-%s-limit' % kind + h.expect_pin('%s is false inside the limits' % pin, pin, False) + old = hal.get_value(ini_pin) + hal.set_p(ini_pin, str(value)) + h.expect('motion reports joint 2 beyond its soft %s limit' % kind, + lambda: hal.get_value('motion.on-soft-limit')) + h.known_bug('%s stays false while joint 2 is past that limit' % pin, + h.stays(lambda p=pin, s=sel: not h.get(p) and not h.get(s), 0.5), + 'task hard-codes minSoftLimit/maxSoftLimit to 0 (taskintf.cc), so ' + 'halui.joint.N.on-soft-*-limit and the selected mirrors can never be set') + hal.set_p(ini_pin, str(old)) + h.expect('motion clears on-soft-limit once the limit is restored', + lambda: not hal.get_value('motion.on-soft-limit')) + h.check('the ini limit is back to %g' % old, close(hal.get_value(ini_pin), old)) + h.nml_unhome_all() + + +def continuous_jog(h): + to_zero(h) + h.set('joint.jog-speed', 60) + for j in range(JOINTS): + h.set('joint.%d.plus' % j, 1) + expect_velocity(h, j, 1.0, 'while joint.%d.plus is held at jog-speed 60' % j) + h.set('joint.%d.plus' % j, 0) + expect_stopped(h, j, 'when joint.%d.plus is released' % j) + h.set('joint.%d.minus' % j, 1) + expect_velocity(h, j, -1.0, 'while joint.%d.minus is held' % j) + h.set('joint.%d.minus' % j, 0) + expect_stopped(h, j, 'when joint.%d.minus is released' % j) + + to_zero(h) + h.set('joint.0.plus', 1) + expect_velocity(h, 0, 1.0, 'at jog-speed 60') + h.set('joint.jog-speed', 120) + expect_velocity(h, 0, 2.0, 'after jog-speed changes to 120 mid-jog') + h.set('joint.jog-speed', 30) + expect_velocity(h, 0, 0.5, 'after jog-speed changes to 30 mid-jog') + h.set('joint.0.plus', 0) + expect_stopped(h, 0, 'on release') + + h.set('joint.jog-speed', 60) + h.set('joint.1.plus', 1) + h.set('joint.2.minus', 1) + expect_velocity(h, 1, 1.0, 'together with joint 2') + expect_velocity(h, 2, -1.0, 'together with joint 1') + h.set('joint.1.plus', 0) + expect_stopped(h, 1, 'on release while joint 2 keeps going') + expect_velocity(h, 2, -1.0, 'after joint 1 is released') + h.set('joint.2.minus', 0) + expect_stopped(h, 2, 'on release') + + h.set('joint.jog-speed', 0) + h.set('joint.0.plus', 1) + expect_not_moving(h, 0, 'at jog-speed 0') + h.set('joint.0.plus', 0) + h.set('joint.jog-speed', 60) + + +def jog_is_gated(h): + to_zero(h) + h.set('joint.jog-speed', 60) + + h.nml_state(L.STATE_OFF) + h.set('joint.0.plus', 1) + expect_not_moving(h, 0, 'when the machine is off') + h.set('joint.0.plus', 0) + + manual_joint_mode(h, homed=True) + h.nml_teleop(1) + h.set('joint.0.plus', 1) + expect_not_moving(h, 0, 'in teleop mode') + h.set('joint.0.plus', 0) + h.nml_teleop(0) + + # abort stops a jog; the held input does not restart it + h.set('joint.0.plus', 1) + expect_velocity(h, 0, 1.0, 'before abort') + h.pulse('abort') + expect_stopped(h, 0, 'after abort') + expect_not_moving(h, 0, 'while joint.0.plus is still held after abort') + h.set('joint.0.plus', 0) + + +def analog_jog(h): + to_zero(h) + h.set('joint.jog-speed', 60) + h.set('joint.0.analog', 0.5) + expect_velocity(h, 0, 0.5, 'at analog 0.5') + h.set('joint.0.analog', -0.8) + expect_velocity(h, 0, -0.8, 'at analog -0.8') + h.set('joint.0.analog', 0.1) + expect_stopped(h, 0, 'at analog 0.1, inside the 0.2 deadband') + h.set('joint.0.analog', 0.3) + expect_velocity(h, 0, 0.3, 'at analog 0.3') + h.set('joint.jog-speed', 120) + expect_velocity(h, 0, 0.6, 'at analog 0.3 after jog-speed changes to 120') + h.set('joint.jog-speed', 60) + h.set('joint.0.analog', 0.0) + expect_stopped(h, 0, 'at analog 0') + + h.set('joint.jog-deadband', 0.6) + h.set('joint.0.analog', 0.5) + expect_not_moving(h, 0, 'at analog 0.5 with a 0.6 deadband') + h.set('joint.0.analog', 0.7) + expect_velocity(h, 0, 0.7, 'at analog 0.7 with a 0.6 deadband') + h.set('joint.0.analog', -0.65) + expect_velocity(h, 0, -0.65, 'at analog -0.65 with a 0.6 deadband') + h.set('joint.0.analog', 0.0) + expect_stopped(h, 0, 'at analog 0') + h.set('joint.jog-deadband', 0.2) + + for j in (1, 2): + h.set('joint.%d.analog' % j, -0.4) + expect_velocity(h, j, -0.4, 'at analog -0.4') + h.set('joint.%d.analog' % j, 0.0) + expect_stopped(h, j, 'at analog 0') + + +def expect_at(h, j, pos, why): + return h.expect('joint %d ends at %+.3f %s' % (j, pos, why), + lambda: close(h.joint_pos(j), pos, 1e-4) and h.stat.inpos, + timeout=10, detail=lambda: 'position %+.4f' % h.joint_pos(j)) + + +def incremental_jog(h): + to_zero(h) + h.set('joint.jog-speed', 60) + for j in range(JOINTS): + h.set('joint.%d.increment' % j, 0.25) + h.pulse('joint.%d.increment-plus' % j) + expect_at(h, j, 0.25, 'after increment-plus') + h.pulse('joint.%d.increment-minus' % j) + expect_at(h, j, 0.0, 'after increment-minus') + + h.set('joint.0.increment-plus', 1) + expect_at(h, 0, 0.25, 'while increment-plus is held') + h.expect_steady('a held increment-plus moves only once', + lambda: close(h.joint_pos(0), 0.25, 1e-4), duration=0.6) + h.set('joint.0.increment-plus', 0) + h.settle() + h.expect_steady('releasing increment-plus moves nothing', + lambda: close(h.joint_pos(0), 0.25, 1e-4)) + + h.pulse('joint.1.select') + h.set('joint.selected.increment', 0.5) + h.pulse('joint.selected.increment-plus') + expect_at(h, 1, 0.5, 'after joint.selected.increment-plus with joint 1 selected') + h.pulse('joint.selected.increment-minus') + expect_at(h, 1, 0.0, 'after joint.selected.increment-minus') + h.check('the selected increment did not move joint 0', + close(h.joint_pos(0), 0.25, 1e-4), 'joint 0 at %+.4f' % h.joint_pos(0)) + + h.nml_state(L.STATE_OFF) + h.pulse('joint.2.increment-plus') + h.expect_steady('increment-plus does nothing when the machine is off', + lambda: close(h.joint_pos(2), 0.0, 1e-4)) + + +def selected_jog(h): + to_zero(h) + h.set('joint.jog-speed', 60) + h.pulse('joint.0.select') + + h.set('joint.selected.plus', 1) + expect_velocity(h, 0, 1.0, 'while joint.selected.plus is held') + h.pulse('joint.1.select') + expect_stopped(h, 0, 'when the selection moves to joint 1 mid-jog') + expect_velocity(h, 1, 1.0, 'after being selected mid-jog') + h.set('joint.selected.plus', 0) + expect_stopped(h, 1, 'when joint.selected.plus is released') + + h.set('joint.selected.minus', 1) + expect_velocity(h, 1, -1.0, 'while joint.selected.minus is held') + h.pulse('joint.2.select') + expect_stopped(h, 1, 'when the selection moves to joint 2') + expect_velocity(h, 2, -1.0, 'after being selected during a minus jog') + h.set('joint.selected.minus', 0) + expect_stopped(h, 2, 'on release') + + # a joint jogged on its own pin keeps going when the selection changes + to_zero(h) + h.pulse('joint.0.select') + h.set('joint.2.plus', 1) + h.set('joint.selected.plus', 1) + expect_velocity(h, 0, 1.0, 'as the selected joint') + expect_velocity(h, 2, 1.0, 'on its own pin') + h.pulse('joint.1.select') + expect_stopped(h, 0, 'after the selection moves to joint 1') + expect_velocity(h, 1, 1.0, 'as the newly selected joint') + expect_velocity(h, 2, 1.0, 'still, because its own pin is held') + h.set('joint.selected.plus', 0) + h.set('joint.2.plus', 0) + expect_stopped(h, 1, 'on release') + expect_stopped(h, 2, 'on release') + + # changing the selection when nothing is jogging moves nothing + h.pulse('joint.0.select') + for j in range(JOINTS): + expect_not_moving(h, j, 'after a selection change with no jog active') + + +run(pins_and_defaults, + select, + homing, + hard_limits_and_fault, + continuous_jog, + jog_is_gated, + analog_jog, + incremental_jog, + selected_jog, + soft_limit_pins_never_set) diff --git a/tests/halui/joints/test.sh b/tests/halui/joints/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/joints/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/machine-state/checkresult b/tests/halui/machine-state/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/machine-state/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/machine-state/halui.ini b/tests/halui/machine-state/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/machine-state/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/machine-state/test-ui.py b/tests/halui/machine-state/test-ui.py new file mode 100755 index 00000000000..e2d00e1300f --- /dev/null +++ b/tests/halui/machine-state/test-ui.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python3 +"""halui: estop, machine power, task mode and motion mode. + +Pins: estop.activate, estop.reset, estop.is-activated, + machine.on, machine.off, machine.is-on, machine.units-per-mm, + mode.manual, mode.auto, mode.mdi, mode.teleop, mode.joint, + mode.is-manual, mode.is-auto, mode.is-mdi, mode.is-teleop, mode.is-joint +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, INCH_PER_MM # noqa: E402 + +import linuxcnc as L # noqa: E402 + +# task has no distinct OFF state: it reports ESTOP_RESET when the machine is +# neither estopped nor enabled (emctask.cc, emcTaskSetState) +POWERED_OFF = L.STATE_ESTOP_RESET + +MODE_PINS = {L.MODE_MANUAL: 'mode.is-manual', + L.MODE_AUTO: 'mode.is-auto', + L.MODE_MDI: 'mode.is-mdi'} + + +def startup_status(h): + h.expect('task starts in ESTOP', lambda: h.stat.task_state == L.STATE_ESTOP) + h.expect_pin('estop.is-activated reflects startup ESTOP', 'estop.is-activated', True) + h.expect_pin('machine.is-on is false at startup', 'machine.is-on', False) + # linear units are units per mm; this is an inch machine + h.expect_pin('machine.units-per-mm is published once task is up', + 'machine.units-per-mm', INCH_PER_MM, tol=1e-9) + + +def estop_and_power(h): + h.pulse('estop.reset') + h.expect('estop.reset -> task ESTOP_RESET', + lambda: h.stat.task_state == L.STATE_ESTOP_RESET) + h.expect_pin('estop.is-activated clears on reset', 'estop.is-activated', False) + h.expect_pin('machine.is-on stays false after reset', 'machine.is-on', False) + + h.pulse('machine.on') + h.expect('machine.on -> task ON', lambda: h.stat.task_state == L.STATE_ON) + h.expect_pin('machine.is-on sets', 'machine.is-on', True) + + h.pulse('machine.off') + h.expect('machine.off powers down (task reads back ESTOP_RESET)', + lambda: h.stat.task_state == POWERED_OFF) + h.expect_pin('machine.is-on clears on OFF', 'machine.is-on', False) + h.expect_pin('estop.is-activated stays clear on OFF', 'estop.is-activated', False) + + h.pulse('machine.on') + h.expect('machine.on from OFF -> task ON', lambda: h.stat.task_state == L.STATE_ON) + + h.pulse('estop.activate') + h.expect('estop.activate from ON -> task ESTOP', lambda: h.stat.task_state == L.STATE_ESTOP) + h.expect_pin('estop.is-activated sets', 'estop.is-activated', True) + h.expect_pin('machine.is-on clears on ESTOP', 'machine.is-on', False) + + +def power_on_refused_in_estop(h): + # task refuses ON straight from ESTOP; halui passes the request on and + # does not try to work around it + h.machine_estop() + h.pulse('machine.on') + h.expect_steady('machine.on while in ESTOP is refused by task', + lambda: h.stat.task_state == L.STATE_ESTOP) + h.expect_pin('machine.is-on stays false', 'machine.is-on', False) + + +def inputs_are_edge_triggered(h): + h.machine_estop() + h.nml_state(L.STATE_ESTOP_RESET) + h.set('machine.on', 1) + h.expect('rising edge on machine.on powers on', lambda: h.stat.task_state == L.STATE_ON) + h.nml_state(L.STATE_OFF) + h.expect_steady('a held machine.on does not power on again', + lambda: h.stat.task_state == POWERED_OFF, duration=0.6) + h.set('machine.on', 0) + h.expect_steady('the falling edge of machine.on does nothing', + lambda: h.stat.task_state == POWERED_OFF, duration=0.4) + + h.nml_state(L.STATE_ON) + h.set('estop.activate', 1) + h.expect('rising edge on estop.activate estops', lambda: h.stat.task_state == L.STATE_ESTOP) + h.nml_state(L.STATE_ESTOP_RESET) + h.expect_steady('a held estop.activate does not estop again', + lambda: h.stat.task_state == L.STATE_ESTOP_RESET, duration=0.6) + h.set('estop.activate', 0) + + +def status_follows_other_clients(h): + # output pins mirror task state no matter who changed it + h.machine_estop() + h.expect_pin('estop.is-activated follows an NML estop', 'estop.is-activated', True) + h.machine_on() + h.expect_pin('machine.is-on follows an NML power-on', 'machine.is-on', True) + h.expect_pin('estop.is-activated follows an NML reset', 'estop.is-activated', False) + + +def expect_task_mode_pins(h, want, why): + for mode, pin in MODE_PINS.items(): + h.expect_pin('%s is %s %s' % (pin, mode == want, why), pin, mode == want) + + +def task_modes(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + for request, mode, label in (('mode.mdi', L.MODE_MDI, 'MDI'), + ('mode.auto', L.MODE_AUTO, 'AUTO'), + ('mode.manual', L.MODE_MANUAL, 'MANUAL')): + h.pulse(request) + h.expect('%s -> task %s' % (request, label), lambda m=mode: h.stat.task_mode == m) + expect_task_mode_pins(h, mode, 'after ' + request) + + # asking for the mode task is already in sends nothing at all + for request, mode in (('mode.manual', L.MODE_MANUAL), + ('mode.auto', L.MODE_AUTO), + ('mode.mdi', L.MODE_MDI)): + h.nml_mode(mode) + h.settle(0.1) + serial = h.poll().echo_serial_number + h.pulse(request) + h.settle(0.3) + h.check('%s while already in that mode sends no command' % request, + h.poll().echo_serial_number == serial, + 'echo_serial_number %d -> %d' % (serial, h.stat.echo_serial_number)) + + # status pins follow a mode change made by another client + h.nml_mode(L.MODE_AUTO) + expect_task_mode_pins(h, L.MODE_AUTO, 'after an NML mode change') + h.nml_mode(L.MODE_MANUAL) + + +def task_mode_while_not_on(h): + for state, label in ((L.STATE_ESTOP, 'ESTOP'), (L.STATE_OFF, 'OFF')): + if state == L.STATE_ESTOP: + h.machine_estop() + else: + h.machine_on() + h.nml_state(L.STATE_OFF) + h.nml_mode(L.MODE_MANUAL) + h.pulse('mode.mdi') + h.expect('mode.mdi is accepted while in %s' % label, + lambda: h.stat.task_mode == L.MODE_MDI) + h.pulse('mode.manual') + h.expect('mode.manual is accepted while in %s' % label, + lambda: h.stat.task_mode == L.MODE_MANUAL) + + +def motion_modes(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + h.nml_home_all() + + h.pulse('mode.teleop') + h.expect('mode.teleop -> motion TELEOP', lambda: h.stat.motion_mode == L.TRAJ_MODE_TELEOP) + h.expect_pin('mode.is-teleop sets', 'mode.is-teleop', True) + h.expect_pin('mode.is-joint clears in teleop', 'mode.is-joint', False) + + h.pulse('mode.joint') + h.expect('mode.joint -> motion FREE', lambda: h.stat.motion_mode == L.TRAJ_MODE_FREE) + h.expect_pin('mode.is-joint sets', 'mode.is-joint', True) + h.expect_pin('mode.is-teleop clears in joint mode', 'mode.is-teleop', False) + + # in MDI, motion is in coordinated mode: neither teleop nor joint + h.nml_mode(L.MODE_MDI) + h.expect('MDI puts motion in COORD', lambda: h.stat.motion_mode == L.TRAJ_MODE_COORD) + h.expect_pin('mode.is-joint is false in COORD', 'mode.is-joint', False) + h.expect_pin('mode.is-teleop is false in COORD', 'mode.is-teleop', False) + + # status follows another client switching to teleop + h.nml_mode(L.MODE_MANUAL) + h.nml_teleop(1) + h.expect_pin('mode.is-teleop follows an NML teleop enable', 'mode.is-teleop', True) + h.nml_teleop(0) + h.expect_pin('mode.is-joint follows an NML teleop disable', 'mode.is-joint', True) + + +run(startup_status, + estop_and_power, + power_on_refused_in_estop, + inputs_are_edge_triggered, + status_follows_other_clients, + task_modes, + task_mode_while_not_on, + motion_modes) diff --git a/tests/halui/machine-state/test.sh b/tests/halui/machine-state/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/machine-state/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/mdi-commands/checkresult b/tests/halui/mdi-commands/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/mdi-commands/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/mdi-commands/halui.ini b/tests/halui/mdi-commands/halui.ini new file mode 100644 index 00000000000..b7ddfc5ab00 --- /dev/null +++ b/tests/halui/mdi-commands/halui.ini @@ -0,0 +1,102 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G20 G90 G0 X1 +MDI_COMMAND = G20 G90 G0 X0 +MDI_COMMAND = G20 G90 G1 X2 F60 +MDI_COMMAND = G20 G90 G1 X0 F60 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/mdi-commands/long.ngc b/tests/halui/mdi-commands/long.ngc new file mode 100644 index 00000000000..cac45d6b3e7 --- /dev/null +++ b/tests/halui/mdi-commands/long.ngc @@ -0,0 +1,5 @@ +(six seconds out along X, six back: long enough to pause, resume and stop) +G20 G90 G17 +G1 X3 F30 +G1 X0 F30 +M2 diff --git a/tests/halui/mdi-commands/test-ui.py b/tests/halui/mdi-commands/test-ui.py new file mode 100755 index 00000000000..89516f9c54b --- /dev/null +++ b/tests/halui/mdi-commands/test-ui.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +"""halui: [HALUI]MDI_COMMAND buttons. + +Pins: mdi-command-NN, halui-mdi-is-running + +halui switches task to MDI, runs the command, and switches back to the mode +it found once task reports DONE. tests/halui/mdi covers the basic round trip; +this covers the running flag, queueing, and the paths where task refuses. + +MDI_COMMAND 00: G0 X1 01: G0 X0 + 02: G1 X2 F60 03: G1 X0 F60 (two seconds each) +""" + +import os +import sys +import time + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + +MODES = {L.MODE_MANUAL: 'MANUAL', L.MODE_AUTO: 'AUTO', L.MODE_MDI: 'MDI'} + + +def x(h): + return h.stat.actual_position[0] + + +def expect_x(h, want, why, timeout=10): + return h.expect('X reaches %g %s' % (want, why), + lambda: close(x(h), want, 1e-4) and h.stat.inpos, timeout, + detail=lambda: 'X=%.4f' % x(h)) + + +def expect_mode(h, mode, why, timeout=5): + return h.expect('task is back in %s %s' % (MODES[mode], why), + lambda: h.stat.task_mode == mode, timeout, + detail=lambda: 'mode=%s' % MODES.get(h.stat.task_mode, h.stat.task_mode)) + + +def at_x0(h, mode): + h.machine_on() + h.nml_mdi('G20 G90 G0 X0 Y0 Z0') + h.nml_mode(mode) + + +def pins(h): + for n in range(4): + h.check('mdi-command-%02d exists' % n, h.has('mdi-command-%02d' % n)) + h.check('there is no pin beyond the configured commands', not h.has('mdi-command-04')) + h.check('halui-mdi-is-running exists because MDI commands are configured', + h.has('halui-mdi-is-running')) + h.expect_pin('halui-mdi-is-running is false at startup', 'halui-mdi-is-running', False) + + +def round_trip_from_each_mode(h): + for mode in (L.MODE_MANUAL, L.MODE_AUTO, L.MODE_MDI): + at_x0(h, mode) + h.pulse('mdi-command-00') + expect_x(h, 1, 'after mdi-command-00 from %s' % MODES[mode]) + expect_mode(h, mode, 'after the command') + h.expect_pin('halui-mdi-is-running clears after the command from %s' % MODES[mode], + 'halui-mdi-is-running', False) + + +def running_flag(h): + at_x0(h, L.MODE_MANUAL) + h.pulse('mdi-command-02') + h.expect('task switches to MDI for the command', lambda: h.stat.task_mode == L.MODE_MDI) + h.expect_pin('halui-mdi-is-running sets while the command runs', 'halui-mdi-is-running', True) + h.expect('the command is moving X', lambda: 0.2 < x(h) < 1.8) + h.check('task is still in MDI mid-command', h.stat.task_mode == L.MODE_MDI) + expect_x(h, 2, 'at the end of mdi-command-02') + expect_mode(h, L.MODE_MANUAL, 'once the command is done') + h.expect_pin('halui-mdi-is-running clears when it is done', 'halui-mdi-is-running', False) + + +def queued_commands(h): + at_x0(h, L.MODE_MANUAL) + h.pulse('mdi-command-02') + h.expect('first command under way', lambda: x(h) > 0.2) + h.pulse('mdi-command-03') + furthest = 0.0 + end = time.time() + 10 + while time.time() < end: + h.poll() + furthest = max(furthest, x(h)) + if h.stat.task_mode != L.MODE_MDI: + break + time.sleep(0.01) + h.check('both queued commands ran in order (X went to 2 and back to 0)', + furthest > 1.99 and close(x(h), 0, 1e-4), + 'furthest X=%.4f, final X=%.4f' % (furthest, x(h))) + h.check('the mode is restored only after the whole queue is done', + close(x(h), 0, 1e-4), 'mode left MDI at X=%.4f' % x(h)) + expect_mode(h, L.MODE_MANUAL, 'after the queue') + h.expect_pin('halui-mdi-is-running clears after the queue', 'halui-mdi-is-running', False) + + +def edge_only(h): + at_x0(h, L.MODE_MANUAL) + h.set('mdi-command-00', 1) + expect_x(h, 1, 'while mdi-command-00 is held') + expect_mode(h, L.MODE_MANUAL, 'while it is still held') + h.nml_mdi('G0 X0') + h.nml_mode(L.MODE_MANUAL) + h.expect_steady('a held mdi-command-00 does not run again', + lambda: close(x(h), 0, 1e-4) and h.stat.task_mode == L.MODE_MANUAL, + duration=0.8) + h.set('mdi-command-00', 0) + + +def refused_by_task(h): + # In ESTOP task accepts the switch to MDI but refuses the command itself. + at_x0(h, L.MODE_MANUAL) + h.machine_estop() + h.nml_mode(L.MODE_MANUAL) + h.drain_errors() + h.pulse('mdi-command-00') + h.settle(1.0) + s = h.poll() + h.log('mdi-command-00 in ESTOP: mode=%s status=%d X=%.4f is-running=%s errors=%r' + % (MODES.get(s.task_mode), s.state, x(h), h.get('halui-mdi-is-running'), + h.drain_errors())) + h.check('the command does not move anything in ESTOP', close(x(h), 0, 1e-4)) + h.check('task reports the refused command as an error', s.state == L.RCS_ERROR, + 'status=%d' % s.state) + # halui restores the old mode only on RCS DONE (modify_hal_pins). The + # refused command leaves task in ERROR, so nothing is restored and the + # running flag never drops. + h.known_bug('task is left in MDI after an MDI button is refused', + h.stays(lambda: h.stat.task_mode == L.MODE_MDI, 1.0), + 'halui only restores the previous mode when task status is DONE; ' + 'on ERROR it waits forever. Should be back in MANUAL') + h.known_bug('halui-mdi-is-running stays true after the refused command', + h.stays(lambda: h.get('halui-mdi-is-running'), 1.0), + 'halui_sent_mdi is cleared only on DONE; should be false') + + # The stale state resolves on the next command that finishes with DONE, + # whatever it is. Here that is powering the machine on, which therefore + # also switches task out of MDI -- long after the button press. + h.machine_on() + h.known_bug('turning the machine on later switches task back to MANUAL', + h.wait_for(lambda: h.stat.task_mode == L.MODE_MANUAL), + 'the delayed restore from the refused MDI button fires on the next DONE, ' + 'from an unrelated command') + h.expect_pin('halui-mdi-is-running clears after that', 'halui-mdi-is-running', False) + + +def while_program_runs(h): + # task refuses the switch to MDI while a program runs + at_x0(h, L.MODE_AUTO) + here = os.path.dirname(os.path.abspath(__file__)) + h.cmd.program_open(os.path.join(here, 'long.ngc')) + h.cmd.wait_complete() + h.cmd.auto(L.AUTO_RUN, 0) + h.expect('the program is running', lambda: x(h) > 0.2) + h.pulse('mdi-command-00') + h.settle(0.5) + running_flag = h.get('halui-mdi-is-running') + h.log('mdi-command-00 while a program runs: mode=%s is-running=%s' + % (MODES.get(h.poll().task_mode), running_flag)) + h.check('task stays in AUTO', h.stat.task_mode == L.MODE_AUTO) + h.known_bug('halui-mdi-is-running is true although no MDI command was sent', + running_flag, + 'sendMdiCommand() sets halui_sent_mdi before task has refused the ' + 'switch to MDI; should stay false') + h.check('the program keeps running', h.stat.interp_state != L.INTERP_IDLE) + h.nml_abort() + h.expect_pin('halui-mdi-is-running is clear once the program is gone', + 'halui-mdi-is-running', False) + h.check('task is still in AUTO afterwards', h.poll().task_mode == L.MODE_AUTO) + + +run(pins, + round_trip_from_each_mode, + running_flag, + queued_commands, + edge_only, + refused_by_task, + while_program_runs) diff --git a/tests/halui/mdi-commands/test.sh b/tests/halui/mdi-commands/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/mdi-commands/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/overrides/checkresult b/tests/halui/overrides/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/overrides/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/overrides/halui.ini b/tests/halui/overrides/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/overrides/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/overrides/test-ui.py b/tests/halui/overrides/test-ui.py new file mode 100755 index 00000000000..25840468ee0 --- /dev/null +++ b/tests/halui/overrides/test-ui.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +"""halui: feed, rapid, spindle and max-velocity overrides. + +For each override: counts (relative and direct-value), count-enable, scale, +increase, decrease, reset, value -- and the clamping halui applies. + +Limits in halui.ini: [DISPLAY]MAX_FEED_OVERRIDE = 1.5, +MIN_SPINDLE_OVERRIDE = 0.5, MAX_SPINDLE_OVERRIDE = 1.2, +[TRAJ]MAX_LINEAR_VELOCITY = 4. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + + +class Model: + """What halui should ask for: last value +/- steps, clamped.""" + + def __init__(self, value, lo, hi): + self.value, self.lo, self.hi, self.counts = value, lo, hi, 0 + + def clamp(self, v): + return max(self.lo, min(self.hi, v)) + + def relative(self, counts, scale): + self.value = self.clamp(self.value + (counts - self.counts) * scale) + self.counts = counts + + def direct(self, counts, scale): + self.value = self.clamp(counts * scale) + self.counts = counts + + def ignored(self, counts): + self.counts = counts + + def set(self, v): + self.value = self.clamp(v) + + +def exercise(h, label, pfx, read, lo, hi, has_reset=True): + def P(s): + return pfx + '.' + s + + m = Model(read(h.poll()), lo, hi) + + def expect(why): + # When a step leaves the value unchanged (already at a limit) the + # check below passes at once, so give halui time to sample the input + # before the next one arrives -- otherwise two steps look like one. + h.settle() + want = m.value + h.expect('%s is %.3f %s' % (label, want, why), + lambda: close(read(h.stat), want, 1e-6), + detail=lambda: 'task has %.4f' % read(h.stat)) + h.expect_pin('%s.value is %.3f %s' % (pfx, want, why), P('value'), want, tol=1e-6) + + h.check('%s.scale defaults to 0.1' % pfx, close(h.default(P('scale')), 0.1), + 'default %r' % h.default(P('scale'))) + h.check('%s.count-enable defaults to on' % pfx, h.default(P('count-enable')) is True, + 'default %r' % h.default(P('count-enable'))) + expect('at startup') + + scale = 0.1 + for c in (1, 4, 20, 19, -40, -38): + h.set(P('counts'), c) + m.relative(c, scale) + expect('after counts -> %d (relative)' % c) + + h.set(P('count-enable'), 0) + h.set(P('counts'), -30) + m.ignored(-30) + h.expect_steady('%s ignores counts while count-enable is off' % pfx, + lambda: close(read(h.stat), m.value, 1e-6)) + h.set(P('count-enable'), 1) + h.set(P('counts'), -29) + m.relative(-29, scale) + expect('after re-enabling: one count, no jump from the ignored ones') + + h.pulse(P('increase')) + m.set(m.value + scale) + expect('after increase') + h.pulse(P('decrease')) + m.set(m.value - scale) + expect('after decrease') + + h.set(P('increase'), 1) + h.settle(0.3) + m.set(m.value + scale) + expect('while increase is held (one step per edge)') + h.set(P('increase'), 0) + h.settle() + + scale = 0.25 + h.set(P('scale'), scale) + h.pulse(P('increase')) + m.set(m.value + scale) + expect('after increase with scale 0.25') + for _ in range(8): + h.pulse(P('increase')) + m.set(m.value + scale) + expect('after increasing past the upper limit') + for _ in range(12): + h.pulse(P('decrease')) + m.set(m.value - scale) + expect('after decreasing past the lower limit') + + if has_reset: + h.pulse(P('reset')) + m.set(1.0) + expect('after reset') + else: + h.check('%s has no reset pin' % pfx, not h.has(P('reset'))) + + scale = 0.1 + h.set(P('scale'), scale) + h.set(P('direct-value'), 1) + for c in (7, 30, -1, 9): + h.set(P('counts'), c) + m.direct(c, scale) + expect('after counts -> %d (direct-value)' % c) + h.set(P('direct-value'), 0) + h.set(P('counts'), 10) + m.relative(10, scale) + expect('after counts -> 10 (relative again)') + return m + + +def feed_override(h): + h.machine_on() + exercise(h, 'task feed override', 'feed-override', lambda s: s.feedrate, 0.0, 1.5) + h.cmd.feedrate(0.7) + h.expect_pin('feed-override.value follows an NML change', 'feed-override.value', 0.7) + + +def rapid_override(h): + h.machine_on() + # halui hard-codes the rapid override ceiling at 1.0 + exercise(h, 'task rapid override', 'rapid-override', lambda s: s.rapidrate, 0.0, 1.0) + h.cmd.rapidrate(0.3) + h.expect_pin('rapid-override.value follows an NML change', 'rapid-override.value', 0.3) + + +def spindle_override(h): + h.machine_on() + exercise(h, 'task spindle 0 override', 'spindle.0.override', + lambda s: s.spindle[0]['override'], 0.5, 1.2) + h.cmd.spindleoverride(0.8, 0) + h.expect_pin('spindle.0.override.value follows an NML change', + 'spindle.0.override.value', 0.8) + + +def max_velocity(h): + h.machine_on() + start = h.poll().max_velocity + h.check('task starts at [TRAJ]MAX_LINEAR_VELOCITY', close(start, 4.0), 'max_velocity=%.3f' % start) + h.expect_pin('max-velocity.value shows it', 'max-velocity.value', 4.0) + h.check('max-velocity.scale defaults to 0 (halui never initialises it)', + close(h.default('max-velocity.scale'), 0.0), 'default %r' % h.default('max-velocity.scale')) + h.check('max-velocity.count-enable defaults to on', h.default('max-velocity.count-enable') is True) + + h.set('max-velocity.scale', 0.5) + h.pulse('max-velocity.decrease') + h.known_bug('max-velocity.decrease from 4.0 lands on 1.0 instead of 3.5', + h.wait_for(lambda: close(h.stat.max_velocity, 1.0)), + 'every request is clamped to 1.0: iniLoad() no longer reads ' + '[TRAJ]MAX_LINEAR_VELOCITY into maxMaxVelocity since 2f57090adb ' + '(new ini parser); intended ceiling here is 4.0') + h.expect_pin('max-velocity.value follows the clamped value', 'max-velocity.value', 1.0) + + # inside [0, 1.0] the override behaves as intended + m = Model(1.0, 0.0, 1.0) + + def expect(why): + h.settle() + want = m.value + h.expect('task max velocity is %.3f %s' % (want, why), + lambda: close(h.stat.max_velocity, want, 1e-6), + detail=lambda: 'task has %.4f' % h.stat.max_velocity) + h.expect_pin('max-velocity.value is %.3f %s' % (want, why), 'max-velocity.value', want) + + h.pulse('max-velocity.decrease') + m.set(0.5) + expect('after decrease') + h.pulse('max-velocity.increase') + m.set(1.0) + expect('after increase') + h.pulse('max-velocity.increase') + expect('after increasing past the (buggy) 1.0 ceiling') + for c in (-1, -5, -3): + h.set('max-velocity.counts', c) + m.relative(c, 0.5) + expect('after counts -> %d (relative)' % c) + + h.set('max-velocity.count-enable', 0) + h.set('max-velocity.counts', 5) + m.ignored(5) + h.expect_steady('max-velocity ignores counts while count-enable is off', + lambda: close(h.stat.max_velocity, m.value, 1e-6)) + h.set('max-velocity.count-enable', 1) + + h.set('max-velocity.direct-value', 1) + h.set('max-velocity.counts', 1) + m.direct(1, 0.5) + expect('after counts -> 1 (direct-value)') + h.set('max-velocity.counts', 6) + h.known_bug('max-velocity direct-value 3.0 lands on 1.0', + h.wait_for(lambda: close(h.stat.max_velocity, 1.0)), + 'same maxMaxVelocity clamp; intended result is 3.0') + h.set('max-velocity.direct-value', 0) + h.check('max-velocity has no reset pin', not h.has('max-velocity.reset')) + + h.cmd.maxvel(2.5) + h.expect_pin('max-velocity.value follows an NML change', 'max-velocity.value', 2.5) + + +def not_on(h): + # overrides are immediate commands: task accepts them even when not ON + h.machine_estop() + h.cmd.feedrate(1.0) + h.cmd.wait_complete() + h.pulse('feed-override.decrease') + h.expect('feed override changes while in ESTOP', lambda: close(h.stat.feedrate, 0.9)) + + +run(feed_override, rapid_override, spindle_override, max_velocity, not_on) diff --git a/tests/halui/overrides/test.sh b/tests/halui/overrides/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/overrides/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/program/block-delete.ngc b/tests/halui/program/block-delete.ngc new file mode 100644 index 00000000000..ccec84254ac --- /dev/null +++ b/tests/halui/program/block-delete.ngc @@ -0,0 +1,4 @@ +G20 G90 +G0 Z0 +/G0 Z-1 +M2 diff --git a/tests/halui/program/checkresult b/tests/halui/program/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/program/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/program/halui.ini b/tests/halui/program/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/program/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/program/long.ngc b/tests/halui/program/long.ngc new file mode 100644 index 00000000000..cac45d6b3e7 --- /dev/null +++ b/tests/halui/program/long.ngc @@ -0,0 +1,5 @@ +(six seconds out along X, six back: long enough to pause, resume and stop) +G20 G90 G17 +G1 X3 F30 +G1 X0 F30 +M2 diff --git a/tests/halui/program/optional-stop.ngc b/tests/halui/program/optional-stop.ngc new file mode 100644 index 00000000000..563612d0428 --- /dev/null +++ b/tests/halui/program/optional-stop.ngc @@ -0,0 +1,5 @@ +G20 G90 +G0 X0 +M1 +G0 X0.5 +M2 diff --git a/tests/halui/program/step.ngc b/tests/halui/program/step.ngc new file mode 100644 index 00000000000..111479bd529 --- /dev/null +++ b/tests/halui/program/step.ngc @@ -0,0 +1,5 @@ +(every line moves, so each step is visible as a change in X) +G20 G90 G0 X0.1 +G0 X0.2 +G0 X0.3 +M2 diff --git a/tests/halui/program/test-ui.py b/tests/halui/program/test-ui.py new file mode 100755 index 00000000000..dc5fe39abb6 --- /dev/null +++ b/tests/halui/program/test-ui.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python3 +"""halui: program control and program status. + +Pins: program.run, program.pause, program.resume, program.step, program.stop, + program.optional-stop.on, program.optional-stop.off, + program.optional-stop.is-on, + program.block-delete.on, program.block-delete.off, + program.block-delete.is-on, + program.is-idle, program.is-running, program.is-paused, abort + +halui cannot open a program, so opening one is done over NML as setup. +""" + +import os +import sys +import time + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.join(HERE, '..', '_lib')) +from halui_test import run, close # noqa: E402 + +import linuxcnc as L # noqa: E402 + + +def running(h): + return h.stat.interp_state in (L.INTERP_READING, L.INTERP_WAITING) + + +def paused(h): + return h.stat.interp_state == L.INTERP_PAUSED + + +def idle(h): + return h.stat.interp_state == L.INTERP_IDLE + + +def x(h): + return h.poll().actual_position[0] + + +def expect_program_pins(h, is_idle, is_running, is_paused, why): + h.expect_pin('program.is-idle is %s %s' % (is_idle, why), 'program.is-idle', is_idle) + h.expect_pin('program.is-running is %s %s' % (is_running, why), 'program.is-running', is_running) + h.expect_pin('program.is-paused is %s %s' % (is_paused, why), 'program.is-paused', is_paused) + + +def to_origin(h): + h.machine_on() + h.nml_mdi('G20 G90 G0 X0 Y0 Z0') + + +def open_program(h, name): + h.nml_mode(L.MODE_AUTO) + h.cmd.program_open(os.path.join(HERE, name)) + h.cmd.wait_complete() + if not h.wait_for(lambda: h.stat.file.endswith(name)): + raise RuntimeError('setup: could not open ' + name) + + +def nml_run(h): + # wait_complete() on a run only returns once the program has finished, + # so for a short program just wait for task to take the command + h.cmd.auto(L.AUTO_RUN, 0) + if not h.wait_for(lambda: h.stat.echo_serial_number >= h.cmd.serial): + raise RuntimeError('setup: task did not take the run command') + + +def expect_still(h, name): + h.settle(0.3) + a = x(h) + h.settle(0.4) + b = x(h) + return h.check(name, close(a, b, 1e-6), 'X %.5f -> %.5f' % (a, b)) + + +def run_without_a_program(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + h.check('no program is open at startup', h.poll().file == '', 'file=%r' % h.stat.file) + expect_program_pins(h, True, False, False, 'at startup') + serial = h.poll().echo_serial_number + h.pulse('program.run') + h.settle(0.3) + h.check('program.run with no program open sends nothing', + h.poll().echo_serial_number == serial, + 'echo_serial_number %d -> %d' % (serial, h.stat.echo_serial_number)) + h.check('program.run with no program open leaves task in MANUAL', + h.stat.task_mode == L.MODE_MANUAL, 'mode=%d' % h.stat.task_mode) + + +def run_pause_resume_stop(h): + to_origin(h) + open_program(h, 'long.ngc') + h.nml_mode(L.MODE_MANUAL) + + h.pulse('program.run') + h.expect('program.run switches task to AUTO by itself', + lambda: h.stat.task_mode == L.MODE_AUTO) + h.expect('program.run starts the program', lambda: running(h)) + h.expect('the program moves X', lambda: h.stat.actual_position[0] > 0.2) + expect_program_pins(h, False, True, False, 'while running') + + h.pulse('program.pause') + h.expect('program.pause pauses the program', lambda: paused(h)) + expect_program_pins(h, False, False, True, 'while paused') + expect_still(h, 'motion stops while paused') + + h.pulse('program.pause') + h.expect_steady('program.pause while paused keeps it paused', lambda: paused(h), duration=0.4) + + here = x(h) + h.pulse('program.resume') + h.expect('program.resume resumes the program', lambda: running(h)) + h.expect('motion continues after resume', lambda: h.stat.actual_position[0] > here + 0.05) + expect_program_pins(h, False, True, False, 'after resume') + + h.pulse('program.resume') + h.expect_steady('program.resume while running keeps it running', lambda: running(h), duration=0.4) + + h.pulse('program.stop') + h.expect('program.stop ends the program', lambda: idle(h)) + expect_program_pins(h, True, False, False, 'after program.stop') + expect_still(h, 'motion stops after program.stop') + + +def run_while_already_in_auto(h): + to_origin(h) + open_program(h, 'long.ngc') + h.pulse('program.run') + h.expect('program.run from AUTO starts the program', lambda: running(h)) + h.pulse('program.stop') + h.expect('program.stop ends it', lambda: idle(h)) + + +def pause_when_idle(h): + # task accepts a pause with a program open but not running, and reports + # the interpreter as PAUSED. That is task behaviour, not halui's; halui + # passes the request on and its status pins report what task says. + to_origin(h) + open_program(h, 'long.ngc') + h.pulse('program.pause') + h.expect('program.pause with nothing running puts task in PAUSED', lambda: paused(h)) + expect_program_pins(h, False, False, True, 'after a pause while idle') + h.pulse('program.stop') + h.expect('program.stop leaves that paused state', lambda: idle(h)) + expect_program_pins(h, True, False, False, 'after stopping it') + + +def abort_pin(h): + to_origin(h) + open_program(h, 'long.ngc') + nml_run(h) + h.expect('the program runs (started over NML)', lambda: h.stat.actual_position[0] > 0.2) + expect_program_pins(h, False, True, False, 'while a program started over NML runs') + h.pulse('abort') + h.expect('abort ends a running program', lambda: idle(h)) + expect_program_pins(h, True, False, False, 'after abort') + expect_still(h, 'motion stops after abort') + + # abort also stops a paused program + to_origin(h) + open_program(h, 'long.ngc') + nml_run(h) + h.cmd.auto(L.AUTO_PAUSE) + h.cmd.wait_complete() + h.wait_for(lambda: paused(h)) + h.pulse('abort') + h.expect('abort ends a paused program', lambda: idle(h)) + expect_program_pins(h, True, False, False, 'after aborting a paused program') + + # and an MDI move + to_origin(h) + h.nml_mode(L.MODE_MDI) + h.cmd.mdi('G1 X3 F30') + h.expect('an MDI move is under way', lambda: h.stat.actual_position[0] > 0.1) + h.pulse('abort') + h.expect('abort ends an MDI move', lambda: idle(h)) + expect_still(h, 'motion stops after aborting MDI') + + +def step_trace(h, do_step, steps=8): + """Step through step.ngc, recording (X, interpreter state) after each step.""" + to_origin(h) + open_program(h, 'step.ngc') + trace = [] + for _ in range(steps): + do_step() + h.settle(0.6) + s = h.poll() + trace.append((round(s.actual_position[0], 4), s.interp_state)) + return trace + + +def step(h): + # How far one step gets is task's business (it lags the presses while the + # program starts up). halui's job is to turn each rising edge into exactly + # one step, so compare it with stepping over NML. + def nml_step(): + h.cmd.auto(L.AUTO_STEP) + h.cmd.wait_complete() + + reference = step_trace(h, nml_step) + h.nml_abort() + via_pin = step_trace(h, lambda: h.pulse('program.step')) + h.check('program.step steps exactly like an NML step, press for press', + via_pin == reference, 'NML %s / pin %s' % (reference, via_pin)) + + xs = [x for x, _ in via_pin] + h.check('stepping walks through the whole program', 0.3 in xs, 'X after each step: %s' % xs) + h.check('no step moves more than one line', + all(b - a <= 0.1 + 1e-6 for a, b in zip([0.0] + xs, xs)), 'X after each step: %s' % xs) + + h.pulse('program.stop') + h.expect('program.stop ends a stepped program', lambda: idle(h)) + + +def optional_stop(h): + h.machine_on() + h.pulse('program.optional-stop.on') + h.expect('optional-stop.on turns optional stop on in task', lambda: h.stat.optional_stop) + h.expect_pin('optional-stop.is-on sets', 'program.optional-stop.is-on', True) + + to_origin(h) + h.nml_mdi('G0 X0') + open_program(h, 'optional-stop.ngc') + nml_run(h) + h.expect('with optional stop on, M1 pauses the program', lambda: paused(h)) + h.check('the move after M1 has not happened', close(x(h), 0.0, 1e-4), 'X=%.4f' % x(h)) + h.pulse('program.resume') + h.expect('program.resume continues past M1', + lambda: idle(h) and close(h.stat.actual_position[0], 0.5, 1e-4)) + + h.pulse('program.optional-stop.off') + h.expect('optional-stop.off turns optional stop off in task', lambda: not h.stat.optional_stop) + h.expect_pin('optional-stop.is-on clears', 'program.optional-stop.is-on', False) + + to_origin(h) + open_program(h, 'optional-stop.ngc') + saw_pause = False + nml_run(h) + end = time.time() + 10 + while time.time() < end: + h.poll() + saw_pause = saw_pause or paused(h) + if idle(h): + break + time.sleep(0.01) + h.check('with optional stop off, M1 is skipped', not saw_pause and idle(h) + and close(h.stat.actual_position[0], 0.5, 1e-4), + 'paused=%s X=%.4f' % (saw_pause, h.stat.actual_position[0])) + + h.cmd.set_optional_stop(1) + h.expect_pin('optional-stop.is-on follows an NML change', 'program.optional-stop.is-on', True) + h.cmd.set_optional_stop(0) + h.expect_pin('optional-stop.is-on follows it back', 'program.optional-stop.is-on', False) + + +def block_delete(h): + h.machine_on() + h.pulse('program.block-delete.on') + h.expect('block-delete.on turns block delete on in task', lambda: h.stat.block_delete) + h.expect_pin('block-delete.is-on sets', 'program.block-delete.is-on', True) + + to_origin(h) + open_program(h, 'block-delete.ngc') + nml_run(h) + h.wait_idle() + h.check('with block delete on, the "/" line is skipped', + close(h.poll().actual_position[2], 0.0, 1e-4), 'Z=%.4f' % h.stat.actual_position[2]) + + h.pulse('program.block-delete.off') + h.expect('block-delete.off turns block delete off in task', lambda: not h.stat.block_delete) + h.expect_pin('block-delete.is-on clears', 'program.block-delete.is-on', False) + + to_origin(h) + open_program(h, 'block-delete.ngc') + nml_run(h) + h.wait_idle() + h.check('with block delete off, the "/" line runs', + close(h.poll().actual_position[2], -1.0, 1e-4), 'Z=%.4f' % h.stat.actual_position[2]) + + h.cmd.set_block_delete(1) + h.expect_pin('block-delete.is-on follows an NML change', 'program.block-delete.is-on', True) + h.cmd.set_block_delete(0) + h.expect_pin('block-delete.is-on follows it back', 'program.block-delete.is-on', False) + + +run(run_without_a_program, + run_pause_resume_stop, + run_while_already_in_auto, + pause_when_idle, + abort_pin, + step, + optional_stop, + block_delete) diff --git a/tests/halui/program/test.sh b/tests/halui/program/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/program/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/spindle-coolant/checkresult b/tests/halui/spindle-coolant/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/spindle-coolant/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/spindle-coolant/halui.ini b/tests/halui/spindle-coolant/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/spindle-coolant/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/spindle-coolant/test-ui.py b/tests/halui/spindle-coolant/test-ui.py new file mode 100755 index 00000000000..f1daa19269b --- /dev/null +++ b/tests/halui/spindle-coolant/test-ui.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +"""halui: spindle control, spindle brake, mist and flood. + +Pins: spindle.0.start, stop, forward, reverse, increase, decrease, + brake-on, brake-off, is-on, runs-forward, runs-backward, brake-is-on, + mist.on, mist.off, mist.is-on, flood.on, flood.off, flood.is-on +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run # noqa: E402 + +import linuxcnc as L # noqa: E402 + +SP = 'spindle.0.' + + +def sp(h): + return h.stat.spindle[0] + + +def expect_spindle(h, speed, why): + direction = (speed > 0) - (speed < 0) + h.expect('spindle 0 runs at %g %s' % (speed, why), + lambda: sp(h)['speed'] == speed and sp(h)['direction'] == direction + and bool(sp(h)['enabled']) == (speed != 0), + detail=lambda: 'speed=%g direction=%d enabled=%d' + % (sp(h)['speed'], sp(h)['direction'], sp(h)['enabled'])) + h.expect_pin(SP + 'is-on is %s %s' % (speed != 0, why), SP + 'is-on', speed != 0) + h.expect_pin(SP + 'runs-forward is %s %s' % (speed > 0, why), SP + 'runs-forward', speed > 0) + h.expect_pin(SP + 'runs-backward is %s %s' % (speed < 0, why), SP + 'runs-backward', speed < 0) + + +def expect_speed_steady(h, speed, why): + h.expect_steady('spindle 0 stays at %g %s' % (speed, why), + lambda: sp(h)['speed'] == speed, + detail=lambda: 'speed=%g' % sp(h)['speed']) + + +def without_s_word(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + expect_spindle(h, 0, 'at startup') + # with no S word active, halui asks for speed +/-1 + h.pulse(SP + 'start') + expect_spindle(h, 1, 'after start with no S word') + h.pulse(SP + 'stop') + expect_spindle(h, 0, 'after stop') + h.pulse(SP + 'reverse') + expect_spindle(h, -1, 'after reverse with no S word') + h.pulse(SP + 'forward') + expect_spindle(h, 1, 'after forward with no S word') + h.pulse(SP + 'stop') + expect_spindle(h, 0, 'after stop') + + +def with_s_word(h): + h.machine_on() + h.nml_mdi('S500') + h.nml_mode(L.MODE_MANUAL) + h.pulse(SP + 'forward') + expect_spindle(h, 500, 'after forward with S500') + h.pulse(SP + 'reverse') + expect_spindle(h, -500, 'after reverse with S500') + h.pulse(SP + 'start') + expect_spindle(h, 500, 'after start with S500 (start is forward)') + + # each rising edge steps by [SPINDLE_0]INCREMENT (default 100); + # the falling edge sends SPINDLE_CONSTANT, which keeps the speed + h.set(SP + 'increase', 1) + expect_spindle(h, 600, 'on the rising edge of increase') + expect_speed_steady(h, 600, 'while increase is held') + h.set(SP + 'increase', 0) + expect_speed_steady(h, 600, 'after increase is released') + + h.set(SP + 'decrease', 1) + expect_spindle(h, 500, 'on the rising edge of decrease') + h.set(SP + 'decrease', 0) + expect_speed_steady(h, 500, 'after decrease is released') + + h.pulse(SP + 'reverse') + expect_spindle(h, -500, 'after reverse') + h.pulse(SP + 'increase') + expect_spindle(h, -600, 'after increase while in reverse (magnitude grows)') + h.pulse(SP + 'decrease') + expect_spindle(h, -500, 'after decrease while in reverse') + + h.pulse(SP + 'stop') + expect_spindle(h, 0, 'after stop') + h.pulse(SP + 'increase') + expect_spindle(h, 0, 'after increase while stopped (does nothing)') + h.pulse(SP + 'decrease') + expect_spindle(h, 0, 'after decrease while stopped (does nothing)') + + +def brake(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + h.pulse(SP + 'brake-on') + h.expect('brake-on engages the brake', lambda: sp(h)['brake'] == 1) + h.expect_pin(SP + 'brake-is-on sets', SP + 'brake-is-on', True) + h.pulse(SP + 'brake-off') + h.expect('brake-off releases the brake', lambda: sp(h)['brake'] == 0) + h.expect_pin(SP + 'brake-is-on clears', SP + 'brake-is-on', False) + + h.cmd.brake(L.BRAKE_ENGAGE, 0) + h.expect_pin(SP + 'brake-is-on follows an NML brake engage', SP + 'brake-is-on', True) + h.cmd.brake(L.BRAKE_RELEASE, 0) + h.expect_pin(SP + 'brake-is-on follows an NML brake release', SP + 'brake-is-on', False) + + +def status_follows_other_clients(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + h.cmd.spindle(L.SPINDLE_FORWARD, 300, 0) + expect_spindle(h, 300, 'after an NML spindle forward') + h.cmd.spindle(L.SPINDLE_REVERSE, 300, 0) + expect_spindle(h, -300, 'after an NML spindle reverse') + h.cmd.spindle(L.SPINDLE_OFF, 0) + expect_spindle(h, 0, 'after an NML spindle off') + + +def spindle_when_not_on(h): + h.machine_estop() + h.pulse(SP + 'start') + expect_speed_steady(h, 0, 'when start is pressed in ESTOP') + h.expect_pin(SP + 'is-on stays false in ESTOP', SP + 'is-on', False) + + +def coolant(h): + h.machine_on() + h.nml_mode(L.MODE_MANUAL) + for kind in ('mist', 'flood'): + read = (lambda s: s.mist) if kind == 'mist' else (lambda s: s.flood) + h.pulse(kind + '.on') + h.expect('%s.on turns %s on' % (kind, kind), lambda r=read: r(h.stat)) + h.expect_pin('%s.is-on sets' % kind, kind + '.is-on', True) + h.pulse(kind + '.off') + h.expect('%s.off turns %s off' % (kind, kind), lambda r=read: not r(h.stat)) + h.expect_pin('%s.is-on clears' % kind, kind + '.is-on', False) + + h.cmd.mist(L.MIST_ON) + h.expect_pin('mist.is-on follows an NML mist on', 'mist.is-on', True) + h.cmd.flood(L.FLOOD_ON) + h.expect_pin('flood.is-on follows an NML flood on', 'flood.is-on', True) + h.cmd.mist(L.MIST_OFF) + h.cmd.flood(L.FLOOD_OFF) + h.expect_pin('mist.is-on follows an NML mist off', 'mist.is-on', False) + h.expect_pin('flood.is-on follows an NML flood off', 'flood.is-on', False) + + +def machine_off_stops_flood(h): + # task turns flood off whenever the machine is turned on or off + # (emcTaskSetState); flood.is-on has to follow that + h.machine_on() + h.pulse('flood.on') + h.expect_pin('flood is on', 'flood.is-on', True) + h.pulse('machine.off') + h.expect('machine.off turns flood off in task', lambda: not h.stat.flood) + h.expect_pin('flood.is-on follows task turning flood off', 'flood.is-on', False) + + +run(without_s_word, + with_s_word, + brake, + status_follows_other_clients, + spindle_when_not_on, + coolant, + machine_off_stops_flood) diff --git a/tests/halui/spindle-coolant/test.sh b/tests/halui/spindle-coolant/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/spindle-coolant/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/startup-halfile/checkresult b/tests/halui/startup-halfile/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/startup-halfile/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/startup-halfile/halui-nets.hal b/tests/halui/startup-halfile/halui-nets.hal new file mode 100644 index 00000000000..bf0bcf2c075 --- /dev/null +++ b/tests/halui/startup-halfile/halui-nets.hal @@ -0,0 +1,7 @@ +# halui pins wired from a regular HALFILE. The startup script runs HAL files +# only after halui is ready, and configs rely on that: this must keep loading +# if halui ever moves into task. +net machine-is-on-led halui.machine.is-on +net remote-estop halui.estop.activate +net remote-estop-reset halui.estop.reset +net remote-mode-mdi halui.mode.mdi diff --git a/tests/halui/startup-halfile/halui.ini b/tests/halui/startup-halfile/halui.ini new file mode 100644 index 00000000000..901508b390c --- /dev/null +++ b/tests/halui/startup-halfile/halui.ini @@ -0,0 +1,102 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal +# halui pins wired in a regular HALFILE, not POSTGUI_HALFILE +HALFILE = halui-nets.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/startup-halfile/test-ui.py b/tests/halui/startup-halfile/test-ui.py new file mode 100755 index 00000000000..c07b51daac6 --- /dev/null +++ b/tests/halui/startup-halfile/test-ui.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""halui pins wired from a regular HALFILE. + +The startup script runs HAL files only after halui is ready, and configs +rely on that ordering. This config nets halui pins in a HALFILE (see +halui-nets.hal); if halui's pins did not exist yet, linuxcnc would not get +as far as running this script. +""" + +import os +import sys +import time + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) +from halui_test import run, HOLD # noqa: E402 + +import hal # noqa: E402 +import linuxcnc as L # noqa: E402 + +NETTED = {'machine.is-on', 'estop.activate', 'estop.reset', 'mode.mdi'} + + +def pulse_signal(h, sig, pin): + h.touched.add(pin) + hal.set_s(sig, True) + time.sleep(HOLD) + hal.set_s(sig, False) + time.sleep(HOLD) + + +def wiring(h): + h.check('linuxcnc started with halui pins netted from a HALFILE', True) + h.check('exactly the netted pins are wired outside the harness', + h.external == NETTED, 'external: %s' % sorted(h.external)) + + +def netted_pins_work(h): + h.expect('the machine-is-on-led signal is false in ESTOP', + lambda: not hal.get_value('machine-is-on-led')) + + pulse_signal(h, 'remote-estop-reset', 'estop.reset') + h.expect('a pulse on the netted estop.reset resets estop', + lambda: h.stat.task_state == L.STATE_ESTOP_RESET) + + h.machine_on() + h.expect('the machine-is-on-led signal follows the machine turning on', + lambda: hal.get_value('machine-is-on-led')) + + h.nml_mode(L.MODE_MANUAL) + pulse_signal(h, 'remote-mode-mdi', 'mode.mdi') + h.expect('a pulse on the netted mode.mdi switches task to MDI', + lambda: h.stat.task_mode == L.MODE_MDI) + + pulse_signal(h, 'remote-estop', 'estop.activate') + h.expect('a pulse on the netted estop.activate estops the machine', + lambda: h.stat.task_state == L.STATE_ESTOP) + h.expect('the machine-is-on-led signal drops with it', + lambda: not hal.get_value('machine-is-on-led')) + + try: + h.set('estop.activate', 1) + h.check('the harness refuses to drive a pin the config wired', False) + except KeyError: + h.check('the harness refuses to drive a pin the config wired', True) + + +run(wiring, netted_pins_work) diff --git a/tests/halui/startup-halfile/test.sh b/tests/halui/startup-halfile/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/startup-halfile/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh diff --git a/tests/halui/tool/checkresult b/tests/halui/tool/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/tool/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/tool/halui.ini b/tests/halui/tool/halui.ini new file mode 100644 index 00000000000..4d21b0429ec --- /dev/null +++ b/tests/halui/tool/halui.ini @@ -0,0 +1,100 @@ +# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, +# a tool table, a home sequence (so halui.home-all exists) and two MDI +# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). + +[EMC] +VERSION = 1.1 +DEBUG = 0 + +[DISPLAY] +DISPLAY = ./test-ui.py +MAX_FEED_OVERRIDE = 1.5 +MIN_SPINDLE_OVERRIDE = 0.5 +MAX_SPINDLE_OVERRIDE = 1.2 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 + +[RS274NGC] +PARAMETER_FILE = sim.var + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[EMCIO] +TOOL_TABLE = tool.tbl + +[HAL] +HALFILE = LIB:core_sim.hal + +[HALUI] +MDI_COMMAND = G0 X1 Y0 Z0 +MDI_COMMAND = G0 X0 Y0 Z0 + +[TRAJ] +COORDINATES = X Y Z +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 +SPINDLES = 1 +NO_FORCE_HOMING = 1 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[AXIS_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_0] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_1] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 + +[JOINT_2] +TYPE = LINEAR +HOME = 0.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 +HOME_SEQUENCE = 0 diff --git a/tests/halui/tool/test-ui.py b/tests/halui/tool/test-ui.py new file mode 100755 index 00000000000..5c0f4d9d6c0 --- /dev/null +++ b/tests/halui/tool/test-ui.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +"""halui: tool status. + +Pins: tool.number, tool.diameter, + tool.length_offset.x/y/z/a/b/c/u/v/w + +tool.tbl: T1 Z0.5 D0.25, T2 Z1.0 D0.5, T3 Z0 D0.125. test.sh copies it +fresh from ../_lib before every run, because G10 L1 rewrites it. +""" + +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.join(HERE, '..', '_lib')) +from halui_test import run # noqa: E402 + +import linuxcnc as L # noqa: E402 + +OFFSET_LETTERS = 'xyzabcuvw' + + +def mdi(h, *codes): + h.machine_on() + for c in codes: + h.nml_mdi(c) + + +def expect_tool(h, number, diameter, why): + h.expect('task has tool %d in the spindle %s' % (number, why), + lambda: h.stat.tool_in_spindle == number, + detail=lambda: 'tool_in_spindle=%d' % h.stat.tool_in_spindle) + h.expect_pin('tool.number is %d %s' % (number, why), 'tool.number', number) + h.expect_pin('tool.diameter is %g %s' % (diameter, why), 'tool.diameter', diameter, tol=1e-6) + + +def expect_offsets(h, offsets, why): + for i, a in enumerate(OFFSET_LETTERS): + want = offsets.get(a, 0.0) + h.expect('task tool offset %s is %g %s' % (a, want, why), + lambda i=i, w=want: abs(h.stat.tool_offset[i] - w) < 1e-6, + detail=lambda i=i: 'tool_offset[%d]=%g' % (i, h.stat.tool_offset[i])) + h.expect_pin('tool.length_offset.%s is %g %s' % (a, want, why), + 'tool.length_offset.' + a, want, tol=1e-6) + + +def startup(h): + expect_tool(h, 0, 0.0, 'at startup') + expect_offsets(h, {}, 'at startup') + + +def tool_changes(h): + mdi(h, 'G20 G90 G49', 'M61 Q2') + expect_tool(h, 2, 0.5, 'after M61 Q2') + expect_offsets(h, {}, 'before G43') + + mdi(h, 'G43') + expect_offsets(h, {'z': 1.0}, 'after G43 with tool 2') + + mdi(h, 'M61 Q1', 'G43') + expect_tool(h, 1, 0.25, 'after M61 Q1') + expect_offsets(h, {'z': 0.5}, 'after G43 with tool 1') + + mdi(h, 'T3 M6') + expect_tool(h, 3, 0.125, 'after T3 M6') + mdi(h, 'G43') + expect_offsets(h, {'z': 0.0}, 'after G43 with tool 3') + + mdi(h, 'G43.1 X0.1 Y0.2 Z0.3') + expect_offsets(h, {'x': 0.1, 'y': 0.2, 'z': 0.3}, 'after G43.1 X0.1 Y0.2 Z0.3') + + mdi(h, 'G49') + expect_offsets(h, {}, 'after G49') + + mdi(h, 'M61 Q0') + expect_tool(h, 0, 0.0, 'after M61 Q0 (empty spindle)') + + +def status_follows_table_edits(h): + mdi(h, 'G20 G90 M61 Q2') + expect_tool(h, 2, 0.5, 'before the table edit') + mdi(h, 'G10 L1 P2 R0.4') + expect_tool(h, 2, 0.8, 'after G10 L1 P2 R0.4 (radius 0.4)') + mdi(h, 'G10 L1 P2 Z1.25', 'G43') + expect_offsets(h, {'z': 1.25}, 'after G10 L1 P2 Z1.25 and G43') + mdi(h, 'G49', 'M61 Q0') + + +def unknown_tool(h): + # modify_hal_pins() has a latent bug: its "tool not found" test compares + # the loop index with CANON_POCKETS_MAX, but the loop stops after the last + # used index, so a tool missing from the table would leave the previous + # diameter on the pin. It cannot be reached this way: task refuses M61 for + # a tool that is not in the table, and on a non-random changer index 0 + # always mirrors the loaded tool. + mdi(h, 'G20 G90 M61 Q3') + expect_tool(h, 3, 0.125, 'before asking for an unknown tool') + h.drain_errors() + h.nml_mode(L.MODE_MDI) + h.cmd.mdi('M61 Q99') + h.cmd.wait_complete() + h.wait_idle() + h.settle(0.3) + errors = h.drain_errors() + h.check('task refuses M61 for a tool that is not in the table', + h.poll().tool_in_spindle == 3 and any('99' in e for e in errors), + 'tool_in_spindle=%d errors=%r' % (h.stat.tool_in_spindle, errors)) + expect_tool(h, 3, 0.125, 'after the refused M61 Q99') + mdi(h, 'M61 Q0') + + +run(startup, tool_changes, status_follows_table_edits, unknown_tool) diff --git a/tests/halui/tool/test.sh b/tests/halui/tool/test.sh new file mode 100755 index 00000000000..fd122f82169 --- /dev/null +++ b/tests/halui/tool/test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec ../_lib/launch.sh From cb04d862f4b546fda2aa1c196354f12861245563 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sun, 20 Sep 2026 17:33:30 +0200 Subject: [PATCH 02/12] remove halui from example configs --- configs/attic/dallur-thc/dallur-advanced.ini | 3 --- configs/by_interface/mesa/plasma-5i20/plasma-5i20.ini | 1 - configs/by_interface/mesa/plasma-5i20/plasma-demo.ini | 1 - configs/by_interface/parport/gantry/gantry.ini | 1 - configs/by_interface/parport/gantry/gantry_joints.ini | 1 - configs/by_interface/parport/plasma-thc-sim/plasma_mm.ini | 3 --- configs/by_interface/parport/stepper-gantry/stepper_mm.ini | 3 --- configs/by_machine/scorbot-er-3/scorbot-er-3.ini | 2 -- configs/by_machine/smithy/1034gecko.ini | 1 - configs/by_machine/smithy/1240.ini | 1 - configs/by_machine/smithy/1240_4axis.ini | 1 - configs/by_machine/smithy/1240combined.ini | 1 - configs/by_machine/smithy/1240combined_4axis.ini | 1 - configs/by_machine/smithy/1240combined_mm.ini | 1 - configs/by_machine/smithy/1240gecko.ini | 1 - configs/by_machine/smithy/1240rutex.ini | 1 - configs/by_machine/smithy/1240rutex_4axis.ini | 1 - configs/by_machine/smithy/1315.ini | 1 - configs/by_machine/smithy/516gecko.ini | 1 - configs/by_machine/smithy/622.ini | 1 - configs/by_machine/smithy/622_4axis.ini | 1 - configs/by_machine/smithy/622gecko.ini | 1 - configs/by_machine/smithy/622keyence.ini | 1 - configs/by_machine/smithy/622leadshine.ini | 1 - configs/by_machine/smithy/622leadshine_4axis.ini | 1 - configs/by_machine/smithy/924.ini | 1 - configs/sim/axis/anglejog/anglejog.ini | 1 - configs/sim/axis/axis.ini | 2 -- configs/sim/axis/axis_9axis.ini | 1 - configs/sim/axis/axis_9axis_scurve.ini | 1 - configs/sim/axis/axis_mm.ini | 2 -- configs/sim/axis/axis_mm_scurve.ini | 1 - configs/sim/axis/canterp.ini | 1 - configs/sim/axis/external_offsets/dynamic_offsets.ini | 1 - configs/sim/axis/external_offsets/eoffsets.ini | 1 - configs/sim/axis/external_offsets/jwp_z.ini | 1 - configs/sim/axis/external_offsets/opa.ini | 1 - configs/sim/axis/extrajoints/12extrajoints.ini | 1 - configs/sim/axis/extrajoints/1extrajoint.ini | 1 - configs/sim/axis/extrajoints/2extrajoints.ini | 1 - configs/sim/axis/foam/axis_foam.ini | 1 - configs/sim/axis/gantry/gantry_mm.ini | 1 - configs/sim/axis/gladevcp/gladevcp_panel.ini | 1 - configs/sim/axis/gladevcp/gladevcp_panel_tester.ini | 1 - configs/sim/axis/gladevcp/gladevcp_tab.ini | 1 - configs/sim/axis/gladevcp/probe.ini | 1 - configs/sim/axis/gladevcp/set-param-from-ini.ini | 1 - configs/sim/axis/halui_pyvcp/halui.ini | 1 - configs/sim/axis/histogram_demo.ini | 1 - configs/sim/axis/home_is_shared/home_is_shared.ini | 1 - configs/sim/axis/ini_hal_demo.ini | 1 - configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini | 1 - configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini | 1 - configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini | 1 - configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini | 1 - configs/sim/axis/laser/laser.ini | 1 - configs/sim/axis/lathe.ini | 1 - configs/sim/axis/moveoff/1_onpause_local.ini | 1 - configs/sim/axis/moveoff/2_onpause_external.ini | 1 - configs/sim/axis/moveoff/3_always_local.ini | 1 - configs/sim/axis/moveoff/4_always_external.ini | 1 - configs/sim/axis/moveoff/5_no_gui.ini | 1 - configs/sim/axis/moveoff/6_zretract.ini | 1 - configs/sim/axis/moveoff/7_pyvcp.ini | 1 - configs/sim/axis/moveoff/8_gladevcp.ini | 1 - configs/sim/axis/mtconnect/example.ini | 1 - configs/sim/axis/ngcgui/ngcgui.ini | 1 - configs/sim/axis/ngcgui/ngcgui_gcmc.ini | 1 - configs/sim/axis/ngcgui/ngcgui_lathe.ini | 1 - configs/sim/axis/ngcgui/ngcgui_simple.ini | 1 - configs/sim/axis/ngcgui/pyngcgui_axis.ini | 1 - configs/sim/axis/pentapod/pentapod.ini | 1 - configs/sim/axis/plasma/imperial.ini | 1 - configs/sim/axis/plasma/metric.ini | 1 - configs/sim/axis/profile_axis.ini | 1 - configs/sim/axis/qtvcp/qtvcp_tab.ini | 1 - configs/sim/axis/qtvcp/qtvismach_tab.ini | 1 - configs/sim/axis/random_tc.ini | 1 - configs/sim/axis/remap/cycle/cycle.ini | 1 - configs/sim/axis/remap/extend-builtins/extend-builtins.ini | 1 - configs/sim/axis/remap/getting-started/demo.ini | 1 - .../manualtoolchange.ini | 1 - configs/sim/axis/remap/rack-toolchange/racktoolchange.ini | 1 - configs/sim/axis/remap/stop-lookahead/demo.ini | 1 - configs/sim/axis/rose_engine/rose_engine.ini | 1 - configs/sim/axis/spindle_orient/orient.ini | 1 - configs/sim/axis/twopass/twopass.ini | 1 - configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini | 2 -- configs/sim/axis/vismach/5axis/bridgemill/5axis.ini | 1 - configs/sim/axis/vismach/5axis/max5/max5kins.ini | 1 - configs/sim/axis/vismach/5axis/max5/max5triv.ini | 1 - configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini | 1 - .../sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini | 1 - .../sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini | 1 - .../xyzacb-trsrn_twp/xyzacb-trsrn.ini | 1 - .../xyzbca-trsrn_twp/xyzbca-trsrn.ini | 1 - configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini | 1 - configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini | 1 - configs/sim/axis/vismach/delta/ldelta.ini | 1 - configs/sim/axis/vismach/delta/ldelta_demo.ini | 1 - configs/sim/axis/vismach/delta/rdelta.ini | 1 - configs/sim/axis/vismach/hbm/hbm.ini | 1 - configs/sim/axis/vismach/hexapod-sim/hexapod.ini | 1 - .../vismach/melfa-sim/melfa-sim-genser/melfa-sim-genser.ini | 1 - .../sim/axis/vismach/melfa-sim/melfa-sim-three21/melfa_321.ini | 1 - configs/sim/axis/vismach/millturn/millturn.ini | 1 - configs/sim/axis/vismach/puma/puma.ini | 1 - configs/sim/axis/vismach/puma/puma560.ini | 1 - configs/sim/axis/vismach/puma/puma560_uvw.ini | 1 - configs/sim/axis/vismach/puma/puma_cube.ini | 1 - configs/sim/axis/vismach/scara/scara.ini | 1 - configs/sim/axis/wrapped_rotary/wrapped_rotary.ini | 1 - configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini | 1 - configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini | 1 - configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini | 1 - configs/sim/gmoccapy/6_axis.ini | 1 - configs/sim/gmoccapy/7_axis.ini | 1 - configs/sim/gmoccapy/7_axis_tool.ini | 1 - configs/sim/gmoccapy/8_axis.ini | 1 - configs/sim/gmoccapy/9_axis.ini | 1 - configs/sim/gmoccapy/gmoccapy.ini | 2 -- configs/sim/gmoccapy/gmoccapy_4_axis.ini | 2 -- configs/sim/gmoccapy/gmoccapy_800x600.ini | 2 -- configs/sim/gmoccapy/gmoccapy_XYZAB.ini | 2 -- configs/sim/gmoccapy/gmoccapy_XYZAC.ini | 2 -- configs/sim/gmoccapy/gmoccapy_XYZCW.ini | 2 -- configs/sim/gmoccapy/gmoccapy_blockdelete.ini | 2 -- configs/sim/gmoccapy/gmoccapy_left_panel.ini | 2 -- configs/sim/gmoccapy/gmoccapy_messages.ini | 2 -- configs/sim/gmoccapy/gmoccapy_pedant.ini | 2 -- configs/sim/gmoccapy/gmoccapy_pyngcgui.ini | 2 -- configs/sim/gmoccapy/gmoccapy_pyngcgui_gcmc.ini | 2 -- configs/sim/gmoccapy/gmoccapy_qt_messages.ini | 2 -- configs/sim/gmoccapy/gmoccapy_right_panel.ini | 2 -- configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini | 2 -- configs/sim/gmoccapy/gmoccapy_tool_sensor.ini | 2 -- configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe_C.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe_CW.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini | 2 -- configs/sim/gmoccapy/lathe_configs/lathe_macros.ini | 2 -- .../sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini | 1 - configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini | 1 - .../non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini | 1 - configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini | 2 -- configs/sim/gscreen/gscreen.ini | 2 -- configs/sim/gscreen/gscreen_custom/9axis.ini | 2 -- configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini | 2 -- configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini | 2 -- configs/sim/gscreen/gscreen_custom/industrial.ini | 2 -- configs/sim/gscreen/gscreen_custom/tester.ini | 2 -- configs/sim/gscreen/gscreen_custom/tester_metric.ini | 2 -- configs/sim/gscreen/gscreen_lathe.ini | 1 - configs/sim/gscreen/gscreen_mm.ini | 2 -- .../gscreen/industrial_lathe_wear/industrial_lathe_wear.ini | 1 - configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini | 1 - configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini | 1 - configs/sim/gscreen/silverdragon/silverdragon.ini | 1 - configs/sim/gscreen/spartan/spartan.ini | 1 - configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini | 2 -- configs/sim/pyvcp_demo/pyvcp_demo1.ini | 2 -- configs/sim/pyvcp_demo/pyvcp_embed_tab.ini | 2 -- configs/sim/qtaxis/non-trivial/scara/scara.ini | 1 - configs/sim/qtaxis/xyz/qtaxis.ini | 2 -- configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini | 1 - configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyzw.ini | 1 - configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini | 1 - configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini | 1 - configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_yyxz.ini | 1 - .../qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini | 1 - configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini | 1 - configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini | 1 - configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric_debug.ini | 1 - configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini | 1 - configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini | 1 - configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini | 1 - configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini | 1 - .../sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini | 1 - .../qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical_xyza.ini | 1 - configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini | 1 - configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini | 1 - configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini | 1 - configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini | 1 - configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_next_xyz.ini | 1 - .../qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini | 1 - configs/sim/qtdragon_lathe/basic_xz_lathe/lathe.ini | 1 - configs/sim/qttouchy/qttouchy.ini | 2 -- configs/sim/qtvcp_screens/blender.ini | 2 -- .../industrial_lathe_wear/industrial_lathe_wear.ini | 1 - configs/sim/qtvcp_screens/non-trivial/scara/scara.ini | 1 - configs/sim/qtvcp_screens/qt_800x600.ini | 2 -- configs/sim/qtvcp_screens/qtaxis.ini | 2 -- configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini | 2 -- configs/sim/qtvcp_screens/qtaxis_mpg.ini | 2 -- configs/sim/qtvcp_screens/qtdefault.ini | 2 -- configs/sim/qtvcp_screens/qtdefault_9axis.ini | 1 - configs/sim/qtvcp_screens/qtdefault_mm.ini | 2 -- configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini | 1 - configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini | 2 -- configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini | 2 -- .../qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini | 2 -- configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini | 2 -- configs/sim/qtvcp_screens/qtx1mill.ini | 2 -- configs/sim/qtvcp_screens/tester.ini | 2 -- configs/sim/tklinuxcnc/ldelta.ini | 1 - configs/sim/touchy/ngcgui/pyngcgui_touchy.ini | 1 - configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini | 1 - configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini | 1 - configs/sim/woodpecker/woodpecker.ini | 1 - configs/sim/woodpecker/woodpecker_auto_tool_probe.ini | 1 - configs/sim/woodpecker/woodpecker_xyz.ini | 1 - configs/sim/woodpecker/woodpecker_xyza.ini | 1 - configs/sim/woodpecker/woodpecker_xyzab.ini | 1 - configs/sim/woodpecker/woodpecker_xyzy.ini | 1 - configs/sim/woodpecker/woodpecker_xyzya.ini | 1 - 217 files changed, 277 deletions(-) diff --git a/configs/attic/dallur-thc/dallur-advanced.ini b/configs/attic/dallur-thc/dallur-advanced.ini index 29c669589d4..17391f89e8a 100644 --- a/configs/attic/dallur-thc/dallur-advanced.ini +++ b/configs/attic/dallur-thc/dallur-advanced.ini @@ -79,9 +79,6 @@ CYCLE_TIME = 0.010 # The run script first uses halcmd to execute any HALFILE # files, and then to execute any individual HALCMD commands. # -# HALUI to interact with NML -# Run before any other HALFILE -HALUI=halui # list of hal config files to run through halcmd # files are executed in the order in which they appear HALFILE = dallur-core_stepper.hal diff --git a/configs/by_interface/mesa/plasma-5i20/plasma-5i20.ini b/configs/by_interface/mesa/plasma-5i20/plasma-5i20.ini index 665749f493d..05893701472 100644 --- a/configs/by_interface/mesa/plasma-5i20/plasma-5i20.ini +++ b/configs/by_interface/mesa/plasma-5i20/plasma-5i20.ini @@ -52,7 +52,6 @@ CYCLE_TIME = 0.010 # files are executed in the order in which they appear HALFILE = plasma-5i20.hal POSTGUI_HALFILE = postgui.hal -HALUI = halui # list of halcmd commands to execute # commands are executed in the order in which they appear #HALCMD = save neta diff --git a/configs/by_interface/mesa/plasma-5i20/plasma-demo.ini b/configs/by_interface/mesa/plasma-5i20/plasma-demo.ini index 227b53a8c42..50ce08897fc 100644 --- a/configs/by_interface/mesa/plasma-5i20/plasma-demo.ini +++ b/configs/by_interface/mesa/plasma-5i20/plasma-demo.ini @@ -43,7 +43,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = plasma-demo.hal POSTGUI_HALFILE = postgui.hal diff --git a/configs/by_interface/parport/gantry/gantry.ini b/configs/by_interface/parport/gantry/gantry.ini index efef5faf1f6..9940e23fc40 100644 --- a/configs/by_interface/parport/gantry/gantry.ini +++ b/configs/by_interface/parport/gantry/gantry.ini @@ -51,7 +51,6 @@ BASE_PERIOD = 30000 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = gantry.hal #HALFILE = custom.hal #POSTGUI_HALFILE = postgui_call_list.hal diff --git a/configs/by_interface/parport/gantry/gantry_joints.ini b/configs/by_interface/parport/gantry/gantry_joints.ini index 6e8d83daa12..f249d65e20b 100644 --- a/configs/by_interface/parport/gantry/gantry_joints.ini +++ b/configs/by_interface/parport/gantry/gantry_joints.ini @@ -51,7 +51,6 @@ BASE_PERIOD = 30000 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = gantry.hal [HALUI] diff --git a/configs/by_interface/parport/plasma-thc-sim/plasma_mm.ini b/configs/by_interface/parport/plasma-thc-sim/plasma_mm.ini index db1c400a957..56884b5fc77 100644 --- a/configs/by_interface/parport/plasma-thc-sim/plasma_mm.ini +++ b/configs/by_interface/parport/plasma-thc-sim/plasma_mm.ini @@ -104,9 +104,6 @@ CYCLE_TIME = 0.100 # The run script first uses halcmd to execute any HALFILE # files, and then to execute any individual HALCMD commands. # -# HALUI to interact with NML -# Run before any other HALFILE -HALUI = halui # list of hal config files to run through halcmd #+ files are executed in the order in which they appear HALFILE = kinematics.hal diff --git a/configs/by_interface/parport/stepper-gantry/stepper_mm.ini b/configs/by_interface/parport/stepper-gantry/stepper_mm.ini index d8fc9c20233..801ef71b72b 100644 --- a/configs/by_interface/parport/stepper-gantry/stepper_mm.ini +++ b/configs/by_interface/parport/stepper-gantry/stepper_mm.ini @@ -96,9 +96,6 @@ CYCLE_TIME = 0.100 # The run script first uses halcmd to execute any HALFILE # files, and then to execute any individual HALCMD commands. # -# HALUI to interact with NML -# Run before any other HALFILE -HALUI = halui # list of hal config files to run through halcmd #+ files are executed in the order in which they appear HALFILE = kinematics.hal diff --git a/configs/by_machine/scorbot-er-3/scorbot-er-3.ini b/configs/by_machine/scorbot-er-3/scorbot-er-3.ini index 3ba8fea37ae..71911f9215a 100644 --- a/configs/by_machine/scorbot-er-3/scorbot-er-3.ini +++ b/configs/by_machine/scorbot-er-3/scorbot-er-3.ini @@ -73,8 +73,6 @@ HALFILE = scorbot-er-3.hal #HALFILE = shuttlexpress-customization.hal POSTGUI_HALFILE = pyvcp.hal -HALUI = halui - [HALUI] #No Content diff --git a/configs/by_machine/smithy/1034gecko.ini b/configs/by_machine/smithy/1034gecko.ini index 71ac255c449..56468417b47 100644 --- a/configs/by_machine/smithy/1034gecko.ini +++ b/configs/by_machine/smithy/1034gecko.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 1240gecko.hal EZTROL_HALFILE = eztrol.hal HALFILE = axis_manualtoolchange.hal diff --git a/configs/by_machine/smithy/1240.ini b/configs/by_machine/smithy/1240.ini index a5301550bd5..3763cc7282a 100644 --- a/configs/by_machine/smithy/1240.ini +++ b/configs/by_machine/smithy/1240.ini @@ -88,7 +88,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 1240.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/1240_4axis.ini b/configs/by_machine/smithy/1240_4axis.ini index 07f326a7977..a9a53f169f5 100644 --- a/configs/by_machine/smithy/1240_4axis.ini +++ b/configs/by_machine/smithy/1240_4axis.ini @@ -88,7 +88,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 1240_4axis.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/1240combined.ini b/configs/by_machine/smithy/1240combined.ini index fe808dd5564..10241ccea9b 100644 --- a/configs/by_machine/smithy/1240combined.ini +++ b/configs/by_machine/smithy/1240combined.ini @@ -91,7 +91,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 1240combined.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/1240combined_4axis.ini b/configs/by_machine/smithy/1240combined_4axis.ini index a9600f508ab..b26588e6ed2 100644 --- a/configs/by_machine/smithy/1240combined_4axis.ini +++ b/configs/by_machine/smithy/1240combined_4axis.ini @@ -91,7 +91,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 1240combined_4axis.hal #HALFILE = naiky_4axis.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/1240combined_mm.ini b/configs/by_machine/smithy/1240combined_mm.ini index e04e4edfee5..a497764d694 100644 --- a/configs/by_machine/smithy/1240combined_mm.ini +++ b/configs/by_machine/smithy/1240combined_mm.ini @@ -89,7 +89,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 1240combined.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/1240gecko.ini b/configs/by_machine/smithy/1240gecko.ini index 05d87c39a63..34cca4694b6 100644 --- a/configs/by_machine/smithy/1240gecko.ini +++ b/configs/by_machine/smithy/1240gecko.ini @@ -88,7 +88,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 1240gecko.hal EZTROL_HALFILE = eztrol.hal POSTGUI_HALFILE = gecko_postgui.hal diff --git a/configs/by_machine/smithy/1240rutex.ini b/configs/by_machine/smithy/1240rutex.ini index ab8906feb24..c5af47baf79 100644 --- a/configs/by_machine/smithy/1240rutex.ini +++ b/configs/by_machine/smithy/1240rutex.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 1240rutex.hal EZTROL_HALFILE = eztrol.hal HALFILE = axis_manualtoolchange.hal diff --git a/configs/by_machine/smithy/1240rutex_4axis.ini b/configs/by_machine/smithy/1240rutex_4axis.ini index a92967300e0..e4c04bc0001 100644 --- a/configs/by_machine/smithy/1240rutex_4axis.ini +++ b/configs/by_machine/smithy/1240rutex_4axis.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 1240rutex_4axis.hal EZTROL_HALFILE = eztrol.hal HALFILE = axis_manualtoolchange.hal diff --git a/configs/by_machine/smithy/1315.ini b/configs/by_machine/smithy/1315.ini index 695a2a71d84..992758019ad 100644 --- a/configs/by_machine/smithy/1315.ini +++ b/configs/by_machine/smithy/1315.ini @@ -67,7 +67,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 1315.hal #HALFILE = naiky.hal POSTGUI_HALFILE = 1315postgui.hal diff --git a/configs/by_machine/smithy/516gecko.ini b/configs/by_machine/smithy/516gecko.ini index 09e46aef400..f3c8d942464 100644 --- a/configs/by_machine/smithy/516gecko.ini +++ b/configs/by_machine/smithy/516gecko.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 622gecko.hal EZTROL_HALFILE = eztrol.hal HALFILE = axis_manualtoolchange.hal diff --git a/configs/by_machine/smithy/622.ini b/configs/by_machine/smithy/622.ini index eea966b8284..b390d6b0f5d 100644 --- a/configs/by_machine/smithy/622.ini +++ b/configs/by_machine/smithy/622.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 622.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/622_4axis.ini b/configs/by_machine/smithy/622_4axis.ini index 88b085909d8..2bb26ee3bc6 100644 --- a/configs/by_machine/smithy/622_4axis.ini +++ b/configs/by_machine/smithy/622_4axis.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 622_4axis.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/622gecko.ini b/configs/by_machine/smithy/622gecko.ini index edd1a34409a..fdc8a35727e 100644 --- a/configs/by_machine/smithy/622gecko.ini +++ b/configs/by_machine/smithy/622gecko.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = 622gecko.hal EZTROL_HALFILE = eztrol.hal HALFILE = axis_manualtoolchange.hal diff --git a/configs/by_machine/smithy/622keyence.ini b/configs/by_machine/smithy/622keyence.ini index b3a955910bf..7c16c57da94 100644 --- a/configs/by_machine/smithy/622keyence.ini +++ b/configs/by_machine/smithy/622keyence.ini @@ -88,7 +88,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 622keyence.hal #HALFILE = naiky.hal EZTROL_HALFILE = 622eztrol-leadshine.hal diff --git a/configs/by_machine/smithy/622leadshine.ini b/configs/by_machine/smithy/622leadshine.ini index a23e2a29735..e5b0449c486 100644 --- a/configs/by_machine/smithy/622leadshine.ini +++ b/configs/by_machine/smithy/622leadshine.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 622leadshine.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/622leadshine_4axis.ini b/configs/by_machine/smithy/622leadshine_4axis.ini index 21c1c44340b..7b56be52200 100644 --- a/configs/by_machine/smithy/622leadshine_4axis.ini +++ b/configs/by_machine/smithy/622leadshine_4axis.ini @@ -87,7 +87,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 622leadshine_4axis.hal #HALFILE = naiky.hal EZTROL_HALFILE = 5i20eztrol.hal diff --git a/configs/by_machine/smithy/924.ini b/configs/by_machine/smithy/924.ini index c4092c0a83e..684ddc663db 100644 --- a/configs/by_machine/smithy/924.ini +++ b/configs/by_machine/smithy/924.ini @@ -72,7 +72,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = 924.hal #HALFILE = naiky.hal diff --git a/configs/sim/axis/anglejog/anglejog.ini b/configs/sim/axis/anglejog/anglejog.ini index 696f6188bb2..17196bfe235 100644 --- a/configs/sim/axis/anglejog/anglejog.ini +++ b/configs/sim/axis/anglejog/anglejog.ini @@ -30,7 +30,6 @@ SERVO_PERIOD = 1000000 CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl -no_sim_spindle -no_use_hal_manualtoolchange # all provisions for anglejog: POSTGUI_HALFILE = anglejog_postgui.hal diff --git a/configs/sim/axis/axis.ini b/configs/sim/axis/axis.ini index 534604ef150..4945eafc986 100644 --- a/configs/sim/axis/axis.ini +++ b/configs/sim/axis/axis.ini @@ -124,8 +124,6 @@ HALFILE = cooling.hal # AXIS at this time (only AXIS creates a HAL component of its own) #POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] COORDINATES = X Y Z diff --git a/configs/sim/axis/axis_9axis.ini b/configs/sim/axis/axis_9axis.ini index ff220c27567..103baf9c510 100644 --- a/configs/sim/axis/axis_9axis.ini +++ b/configs/sim/axis/axis_9axis.ini @@ -45,7 +45,6 @@ SERVO_PERIOD = 1000000 TOOL_CHANGE_POSITION = 0 0 2 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = locking_indexer.hal diff --git a/configs/sim/axis/axis_9axis_scurve.ini b/configs/sim/axis/axis_9axis_scurve.ini index 39c082a442b..24bc30f8012 100644 --- a/configs/sim/axis/axis_9axis_scurve.ini +++ b/configs/sim/axis/axis_9axis_scurve.ini @@ -47,7 +47,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = axis_9axis_scurve.hal [TRAJ] diff --git a/configs/sim/axis/axis_mm.ini b/configs/sim/axis/axis_mm.ini index df209baf313..1efb1d7dee4 100644 --- a/configs/sim/axis/axis_mm.ini +++ b/configs/sim/axis/axis_mm.ini @@ -115,8 +115,6 @@ HALFILE = cooling.hal # AXIS at this time (only AXIS creates a HAL component of its own) #POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] COORDINATES = X Y Z diff --git a/configs/sim/axis/axis_mm_scurve.ini b/configs/sim/axis/axis_mm_scurve.ini index 13a3e803bbd..0f69e88d20c 100644 --- a/configs/sim/axis/axis_mm_scurve.ini +++ b/configs/sim/axis/axis_mm_scurve.ini @@ -47,7 +47,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = axis_mm_scurve.hal [TRAJ] diff --git a/configs/sim/axis/canterp.ini b/configs/sim/axis/canterp.ini index 1fc4c1ab779..c34f3c67fa1 100644 --- a/configs/sim/axis/canterp.ini +++ b/configs/sim/axis/canterp.ini @@ -32,7 +32,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/external_offsets/dynamic_offsets.ini b/configs/sim/axis/external_offsets/dynamic_offsets.ini index b07b103c737..6b0fd9969fd 100644 --- a/configs/sim/axis/external_offsets/dynamic_offsets.ini +++ b/configs/sim/axis/external_offsets/dynamic_offsets.ini @@ -4,7 +4,6 @@ DELAY = 5 APP = halscope -i dynamic_offsets.halscope [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl -no_sim_spindle POSTGUI_HALFILE = dynamic_offsets_panel.hal diff --git a/configs/sim/axis/external_offsets/eoffsets.ini b/configs/sim/axis/external_offsets/eoffsets.ini index 0542f67c902..6559b3364f8 100644 --- a/configs/sim/axis/external_offsets/eoffsets.ini +++ b/configs/sim/axis/external_offsets/eoffsets.ini @@ -18,7 +18,6 @@ APP = sim_pin --title "MPG Simulator" \ APP = eoffsets_monitor.tcl [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl -no_use_hal_manualtoolchange HALFILE = eoffsets.hal POSTGUI_HALFILE = eoffsets_panel.hal diff --git a/configs/sim/axis/external_offsets/jwp_z.ini b/configs/sim/axis/external_offsets/jwp_z.ini index d99db80c758..0c6853d4965 100644 --- a/configs/sim/axis/external_offsets/jwp_z.ini +++ b/configs/sim/axis/external_offsets/jwp_z.ini @@ -10,7 +10,6 @@ [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = jwp_z_panel.hal diff --git a/configs/sim/axis/external_offsets/opa.ini b/configs/sim/axis/external_offsets/opa.ini index 2301b15c977..87b68605f48 100644 --- a/configs/sim/axis/external_offsets/opa.ini +++ b/configs/sim/axis/external_offsets/opa.ini @@ -5,7 +5,6 @@ DELAY = 3 APP = sim_pin ini.x.max_acceleration ini.x.max_velocity [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = opa.hal POSTGUI_HALFILE = opa_panel.hal diff --git a/configs/sim/axis/extrajoints/12extrajoints.ini b/configs/sim/axis/extrajoints/12extrajoints.ini index ff8f8f02c39..96ec281db6f 100644 --- a/configs/sim/axis/extrajoints/12extrajoints.ini +++ b/configs/sim/axis/extrajoints/12extrajoints.ini @@ -26,7 +26,6 @@ SERVO_PERIOD = 1000000 TWOPASS = on HALFILE = LIB:basic_sim.tcl HALFILE = ./extrajoints.tcl -HALUI = halui [DISPLAY] DISPLAY = axis diff --git a/configs/sim/axis/extrajoints/1extrajoint.ini b/configs/sim/axis/extrajoints/1extrajoint.ini index 38c17ad9da2..bdbb4358c2d 100644 --- a/configs/sim/axis/extrajoints/1extrajoint.ini +++ b/configs/sim/axis/extrajoints/1extrajoint.ini @@ -27,7 +27,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = 1extrajoint.hal -HALUI = halui [DISPLAY] diff --git a/configs/sim/axis/extrajoints/2extrajoints.ini b/configs/sim/axis/extrajoints/2extrajoints.ini index fee8ff15c41..21a7b8b7f10 100644 --- a/configs/sim/axis/extrajoints/2extrajoints.ini +++ b/configs/sim/axis/extrajoints/2extrajoints.ini @@ -31,7 +31,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = LIB:basic_sim.tcl HALFILE = ./2extrajoints.hal -HALUI = halui [DISPLAY] DISPLAY = axis diff --git a/configs/sim/axis/foam/axis_foam.ini b/configs/sim/axis/foam/axis_foam.ini index db93a5f2849..96961c0b731 100644 --- a/configs/sim/axis/foam/axis_foam.ini +++ b/configs/sim/axis/foam/axis_foam.ini @@ -41,7 +41,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/gantry/gantry_mm.ini b/configs/sim/axis/gantry/gantry_mm.ini index 52e01d21bfb..51b029ffb28 100644 --- a/configs/sim/axis/gantry/gantry_mm.ini +++ b/configs/sim/axis/gantry/gantry_mm.ini @@ -39,7 +39,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = gantry_mm.hal -HALUI = halui [KINS] KINEMATICS = trivkins coordinates=xyyz kinstype=BOTH diff --git a/configs/sim/axis/gladevcp/gladevcp_panel.ini b/configs/sim/axis/gladevcp/gladevcp_panel.ini index a8f477b8ade..64b95bad2e4 100644 --- a/configs/sim/axis/gladevcp/gladevcp_panel.ini +++ b/configs/sim/axis/gladevcp/gladevcp_panel.ini @@ -44,7 +44,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE= manual-example.hal diff --git a/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini b/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini index 26b292677c7..caedbd799c8 100644 --- a/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini +++ b/configs/sim/axis/gladevcp/gladevcp_panel_tester.ini @@ -44,7 +44,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl #POSTGUI_HALFILE= manual-example.hal diff --git a/configs/sim/axis/gladevcp/gladevcp_tab.ini b/configs/sim/axis/gladevcp/gladevcp_tab.ini index 4395c542d52..4b16152efd2 100644 --- a/configs/sim/axis/gladevcp/gladevcp_tab.ini +++ b/configs/sim/axis/gladevcp/gladevcp_tab.ini @@ -48,7 +48,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = manual-example.hal diff --git a/configs/sim/axis/gladevcp/probe.ini b/configs/sim/axis/gladevcp/probe.ini index 635f6424b62..e0d878d0e66 100644 --- a/configs/sim/axis/gladevcp/probe.ini +++ b/configs/sim/axis/gladevcp/probe.ini @@ -46,7 +46,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/gladevcp/set-param-from-ini.ini b/configs/sim/axis/gladevcp/set-param-from-ini.ini index 43da20df92f..998a660657e 100644 --- a/configs/sim/axis/gladevcp/set-param-from-ini.ini +++ b/configs/sim/axis/gladevcp/set-param-from-ini.ini @@ -44,7 +44,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/halui_pyvcp/halui.ini b/configs/sim/axis/halui_pyvcp/halui.ini index 4eaef32e8da..7e62a514a6a 100644 --- a/configs/sim/axis/halui_pyvcp/halui.ini +++ b/configs/sim/axis/halui_pyvcp/halui.ini @@ -33,7 +33,6 @@ CYCLE_TIME = 0.010 HALFILE = core_sim.hal HALFILE = pyvcp.hal HALFILE = simulated_home.hal -HALUI = halui [HALUI] MDI_COMMAND = G0 G53 Z0 diff --git a/configs/sim/axis/histogram_demo.ini b/configs/sim/axis/histogram_demo.ini index 615f01859fe..c6221ef9b75 100644 --- a/configs/sim/axis/histogram_demo.ini +++ b/configs/sim/axis/histogram_demo.ini @@ -45,7 +45,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/home_is_shared/home_is_shared.ini b/configs/sim/axis/home_is_shared/home_is_shared.ini index e80bf812c76..5503aa51163 100644 --- a/configs/sim/axis/home_is_shared/home_is_shared.ini +++ b/configs/sim/axis/home_is_shared/home_is_shared.ini @@ -99,7 +99,6 @@ TOOL_CHANGE_QUILL_UP = 1 [HAL] HALFILE = core_sim.hal HALFILE = simulated_home_is_shared.hal -HALUI = halui # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/configs/sim/axis/ini_hal_demo.ini b/configs/sim/axis/ini_hal_demo.ini index 75c5992b7f9..486d3f939d5 100644 --- a/configs/sim/axis/ini_hal_demo.ini +++ b/configs/sim/axis/ini_hal_demo.ini @@ -47,7 +47,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = postgui_calib_helper.hal diff --git a/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini b/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini index bce8ab912bc..c3ef01710a6 100644 --- a/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini +++ b/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini @@ -20,7 +20,6 @@ JOINTS = 5 KINEMATICS = trivkins coordinates=xyyzb kinstype=both [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:wheeljogpins.tcl 0.1 diff --git a/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini b/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini index 8cc06b086f2..6e9838b1985 100644 --- a/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini +++ b/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini @@ -13,7 +13,6 @@ JOINTS = 4 KINEMATICS = trivkins coordinates=xyzb [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:wheeljogpins.tcl 0.1 diff --git a/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini b/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini index 8918f2f36ae..548ba7b8b15 100644 --- a/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini +++ b/configs/sim/axis/ja_tests/xyzx_mpg/xyzx-xhc-hb04.ini @@ -5,7 +5,6 @@ APP = halshow xyzx.halshow [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:xhc-hb04.tcl diff --git a/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini b/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini index 997ab73cc95..ec873a69d30 100644 --- a/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini +++ b/configs/sim/axis/ja_tests/xyzx_mpg/xyzx.ini @@ -11,7 +11,6 @@ APP = sim_pin \ APP = halshow xyzx.halshow [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = ./xyzx_jog.hal diff --git a/configs/sim/axis/laser/laser.ini b/configs/sim/axis/laser/laser.ini index 9ca8259791b..cb43697088a 100644 --- a/configs/sim/axis/laser/laser.ini +++ b/configs/sim/axis/laser/laser.ini @@ -13,7 +13,6 @@ LINEAR_UNITS = mm ANGULAR_UNITS = degree [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = laser.hal POSTGUI_HALFILE = postgui.hal diff --git a/configs/sim/axis/lathe.ini b/configs/sim/axis/lathe.ini index dcbfba03341..47cb37b0514 100644 --- a/configs/sim/axis/lathe.ini +++ b/configs/sim/axis/lathe.ini @@ -40,7 +40,6 @@ SERVO_PERIOD = 1000000 CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = lathe_postgui.hal diff --git a/configs/sim/axis/moveoff/1_onpause_local.ini b/configs/sim/axis/moveoff/1_onpause_local.ini index b6cf30a605a..4892c9bdeba 100644 --- a/configs/sim/axis/moveoff/1_onpause_local.ini +++ b/configs/sim/axis/moveoff/1_onpause_local.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,onpause,local [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/2_onpause_external.ini b/configs/sim/axis/moveoff/2_onpause_external.ini index 46c594a7d8d..6bf8dfe081c 100644 --- a/configs/sim/axis/moveoff/2_onpause_external.ini +++ b/configs/sim/axis/moveoff/2_onpause_external.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,onpause,external [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/3_always_local.ini b/configs/sim/axis/moveoff/3_always_local.ini index eedd656d649..bf8b53e8698 100644 --- a/configs/sim/axis/moveoff/3_always_local.ini +++ b/configs/sim/axis/moveoff/3_always_local.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,always,local [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/4_always_external.ini b/configs/sim/axis/moveoff/4_always_external.ini index 635bc49ce4f..2cf8283178e 100644 --- a/configs/sim/axis/moveoff/4_always_external.ini +++ b/configs/sim/axis/moveoff/4_always_external.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,always,external [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/5_no_gui.ini b/configs/sim/axis/moveoff/5_no_gui.ini index 45c1ba29823..1d6aa1f06e1 100644 --- a/configs/sim/axis/moveoff/5_no_gui.ini +++ b/configs/sim/axis/moveoff/5_no_gui.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,no_gui [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:hookup_moveoff.tcl diff --git a/configs/sim/axis/moveoff/6_zretract.ini b/configs/sim/axis/moveoff/6_zretract.ini index a26f98bb48b..dd8996cb2b0 100644 --- a/configs/sim/axis/moveoff/6_zretract.ini +++ b/configs/sim/axis/moveoff/6_zretract.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff zretract demo [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/7_pyvcp.ini b/configs/sim/axis/moveoff/7_pyvcp.ini index 191a2b7fe17..852895b3621 100644 --- a/configs/sim/axis/moveoff/7_pyvcp.ini +++ b/configs/sim/axis/moveoff/7_pyvcp.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,onpause,external [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/moveoff/8_gladevcp.ini b/configs/sim/axis/moveoff/8_gladevcp.ini index 1c61c46b552..787c807baf4 100644 --- a/configs/sim/axis/moveoff/8_gladevcp.ini +++ b/configs/sim/axis/moveoff/8_gladevcp.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = moveoff,onpause,external [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl # hookup a moveoff component: diff --git a/configs/sim/axis/mtconnect/example.ini b/configs/sim/axis/mtconnect/example.ini index 0ee7838cf6b..b39ad50015a 100644 --- a/configs/sim/axis/mtconnect/example.ini +++ b/configs/sim/axis/mtconnect/example.ini @@ -97,7 +97,6 @@ HALFILE = check_xyz_constraints.hal HALFILE = ../cooling.hal # Load the MTConnect agent as a userspace HAL component (see mtconnect.hal). HALFILE = mtconnect.hal -HALUI = halui [TRAJ] COORDINATES = X Y Z diff --git a/configs/sim/axis/ngcgui/ngcgui.ini b/configs/sim/axis/ngcgui/ngcgui.ini index 538017966e6..ac3e15f5f43 100644 --- a/configs/sim/axis/ngcgui/ngcgui.ini +++ b/configs/sim/axis/ngcgui/ngcgui.ini @@ -81,7 +81,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/ngcgui/ngcgui_gcmc.ini b/configs/sim/axis/ngcgui/ngcgui_gcmc.ini index 9139f793ee4..6625d08060e 100644 --- a/configs/sim/axis/ngcgui/ngcgui_gcmc.ini +++ b/configs/sim/axis/ngcgui/ngcgui_gcmc.ini @@ -85,7 +85,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/ngcgui/ngcgui_lathe.ini b/configs/sim/axis/ngcgui/ngcgui_lathe.ini index dff7147df02..7655af01c3e 100644 --- a/configs/sim/axis/ngcgui/ngcgui_lathe.ini +++ b/configs/sim/axis/ngcgui/ngcgui_lathe.ini @@ -67,7 +67,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/ngcgui/ngcgui_simple.ini b/configs/sim/axis/ngcgui/ngcgui_simple.ini index ccb896d7e1f..95a47a195f3 100644 --- a/configs/sim/axis/ngcgui/ngcgui_simple.ini +++ b/configs/sim/axis/ngcgui/ngcgui_simple.ini @@ -68,7 +68,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/ngcgui/pyngcgui_axis.ini b/configs/sim/axis/ngcgui/pyngcgui_axis.ini index 8cab0e77f10..3388435615d 100644 --- a/configs/sim/axis/ngcgui/pyngcgui_axis.ini +++ b/configs/sim/axis/ngcgui/pyngcgui_axis.ini @@ -82,7 +82,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/pentapod/pentapod.ini b/configs/sim/axis/pentapod/pentapod.ini index 943a62c0c2d..0f91e195476 100644 --- a/configs/sim/axis/pentapod/pentapod.ini +++ b/configs/sim/axis/pentapod/pentapod.ini @@ -42,7 +42,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = kinematics.hal POSTGUI_HALFILE = pentapod_postgui.hal diff --git a/configs/sim/axis/plasma/imperial.ini b/configs/sim/axis/plasma/imperial.ini index a86417ab27d..3b2d1092fdb 100644 --- a/configs/sim/axis/plasma/imperial.ini +++ b/configs/sim/axis/plasma/imperial.ini @@ -20,7 +20,6 @@ TWOPASS = ON HALFILE = plasmac2/lib/sim/sim_stepgen.tcl HALFILE = qtplasmac_comp.hal HALFILE = custom.hal -HALUI = halui [DISPLAY] DISPLAY = axis diff --git a/configs/sim/axis/plasma/metric.ini b/configs/sim/axis/plasma/metric.ini index d9d7d8ad745..a3b1d0e91eb 100644 --- a/configs/sim/axis/plasma/metric.ini +++ b/configs/sim/axis/plasma/metric.ini @@ -20,7 +20,6 @@ TWOPASS = ON HALFILE = plasmac2/lib/sim/sim_stepgen.tcl HALFILE = qtplasmac_comp.hal HALFILE = custom.hal -HALUI = halui [DISPLAY] DISPLAY = axis diff --git a/configs/sim/axis/profile_axis.ini b/configs/sim/axis/profile_axis.ini index e43ef4f7946..03cea494693 100644 --- a/configs/sim/axis/profile_axis.ini +++ b/configs/sim/axis/profile_axis.ini @@ -42,7 +42,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/qtvcp/qtvcp_tab.ini b/configs/sim/axis/qtvcp/qtvcp_tab.ini index 7822089cb27..edf508783a0 100644 --- a/configs/sim/axis/qtvcp/qtvcp_tab.ini +++ b/configs/sim/axis/qtvcp/qtvcp_tab.ini @@ -51,7 +51,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/qtvcp/qtvismach_tab.ini b/configs/sim/axis/qtvcp/qtvismach_tab.ini index 561c9b4c2a2..f00dc83969f 100644 --- a/configs/sim/axis/qtvcp/qtvismach_tab.ini +++ b/configs/sim/axis/qtvcp/qtvismach_tab.ini @@ -45,7 +45,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/random_tc.ini b/configs/sim/axis/random_tc.ini index 442449ee371..2c1bd8f1b55 100644 --- a/configs/sim/axis/random_tc.ini +++ b/configs/sim/axis/random_tc.ini @@ -42,7 +42,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/remap/cycle/cycle.ini b/configs/sim/axis/remap/cycle/cycle.ini index 6f3ebe6e5de..dcfe73aba97 100644 --- a/configs/sim/axis/remap/cycle/cycle.ini +++ b/configs/sim/axis/remap/cycle/cycle.ini @@ -50,7 +50,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = locking_indexer.hal diff --git a/configs/sim/axis/remap/extend-builtins/extend-builtins.ini b/configs/sim/axis/remap/extend-builtins/extend-builtins.ini index 67634a009a1..3e2ff851f2a 100644 --- a/configs/sim/axis/remap/extend-builtins/extend-builtins.ini +++ b/configs/sim/axis/remap/extend-builtins/extend-builtins.ini @@ -83,7 +83,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = gladevcp.hal diff --git a/configs/sim/axis/remap/getting-started/demo.ini b/configs/sim/axis/remap/getting-started/demo.ini index e2e7ac32dc0..baf1cf305e9 100644 --- a/configs/sim/axis/remap/getting-started/demo.ini +++ b/configs/sim/axis/remap/getting-started/demo.ini @@ -132,7 +132,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini b/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini index 20fc4388e68..483ac90d5e1 100644 --- a/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini +++ b/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/manualtoolchange.ini @@ -56,7 +56,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE= gladevcp.hal diff --git a/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini b/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini index 659bda067c3..dd1b7c86721 100644 --- a/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini +++ b/configs/sim/axis/remap/rack-toolchange/racktoolchange.ini @@ -54,7 +54,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = racktoolchange.hal POSTGUI_HALFILE= gladevcp.hal diff --git a/configs/sim/axis/remap/stop-lookahead/demo.ini b/configs/sim/axis/remap/stop-lookahead/demo.ini index 43aade97169..91d1c790b46 100644 --- a/configs/sim/axis/remap/stop-lookahead/demo.ini +++ b/configs/sim/axis/remap/stop-lookahead/demo.ini @@ -50,7 +50,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/rose_engine/rose_engine.ini b/configs/sim/axis/rose_engine/rose_engine.ini index 7ad0172a7bd..1fbddfe4df9 100644 --- a/configs/sim/axis/rose_engine/rose_engine.ini +++ b/configs/sim/axis/rose_engine/rose_engine.ini @@ -1,7 +1,6 @@ [APPLICATIONS] APP = halshow rose_engine.halshow [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/axis/spindle_orient/orient.ini b/configs/sim/axis/spindle_orient/orient.ini index 148bf9935e5..7c281375fbb 100644 --- a/configs/sim/axis/spindle_orient/orient.ini +++ b/configs/sim/axis/spindle_orient/orient.ini @@ -46,7 +46,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = axis_manualtoolchange.hal HALFILE = simulated_home.hal diff --git a/configs/sim/axis/twopass/twopass.ini b/configs/sim/axis/twopass/twopass.ini index b944fe09c1e..fa136a0fa74 100644 --- a/configs/sim/axis/twopass/twopass.ini +++ b/configs/sim/axis/twopass/twopass.ini @@ -43,7 +43,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui # options available are: on,verbose,nodelete TWOPASS = on HALFILE = core_sim.hal diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini index 7e2dfcc4d1f..ead951a340c 100644 --- a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini +++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini @@ -112,8 +112,6 @@ HALFILE = 3axis-tutorial.hal # AXIS at this time (only AXIS creates a HAL component of its own) #POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini b/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini index 38e706fac22..2707f631b70 100644 --- a/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini +++ b/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini @@ -38,7 +38,6 @@ SERVO_PERIOD = 1000000 CYCLE_TIME = 0.010 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = 5axisgui.hal POSTGUI_HALFILE = 5axis_postgui.hal diff --git a/configs/sim/axis/vismach/5axis/max5/max5kins.ini b/configs/sim/axis/vismach/5axis/max5/max5kins.ini index b2d77aaf046..957798018a6 100644 --- a/configs/sim/axis/vismach/5axis/max5/max5kins.ini +++ b/configs/sim/axis/vismach/5axis/max5/max5kins.ini @@ -6,7 +6,6 @@ JOINTS = 6 [HAL] HALFILE = max5kins.hal -HALUI = halui [EMC] VERSION = 1.1 diff --git a/configs/sim/axis/vismach/5axis/max5/max5triv.ini b/configs/sim/axis/vismach/5axis/max5/max5triv.ini index 005c3627ad2..9c466209942 100644 --- a/configs/sim/axis/vismach/5axis/max5/max5triv.ini +++ b/configs/sim/axis/vismach/5axis/max5/max5triv.ini @@ -6,7 +6,6 @@ JOINTS = 6 [HAL] HALFILE = max5triv.hal -HALUI = halui [EMC] VERSION = 1.1 diff --git a/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini b/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini index bd6dc79e82a..d526e341f63 100644 --- a/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini +++ b/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini @@ -32,7 +32,6 @@ KINEMATICS = xyzab_tdr_kins JOINTS = 5 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = xyzab-tdr-postgui.hal diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini index 9c2bc00e33e..1436f780f3f 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini @@ -44,7 +44,6 @@ KINEMATICS = xyzac-trt-kins sparm=identityfirst JOINTS = 5 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = switchkins_postgui.hal diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini index 45d780a251c..278b8aa1262 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini @@ -44,7 +44,6 @@ KINEMATICS = xyzbc-trt-kins sparm=identityfirst JOINTS = 5 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = switchkins_postgui.hal diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini index 2be585e6ef8..c9bcb54ce49 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini @@ -70,7 +70,6 @@ PRIMARY = C SECONDARY = B [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = xyzacb-trsrn_postgui.hal diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini index d3032855aee..ef3e476225d 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini @@ -70,7 +70,6 @@ PRIMARY = C SECONDARY = A [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = xyzbca-trsrn_postgui.hal diff --git a/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini b/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini index 35ee95f4ab3..da6425d924c 100644 --- a/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini +++ b/configs/sim/axis/vismach/VMC_toolchange/vmc_graycode.ini @@ -30,7 +30,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = vmc.hal HALFILE = sim_vmc.hal HALFILE = spindle.hal diff --git a/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini b/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini index 323b7eab813..b4783e494e2 100644 --- a/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini +++ b/configs/sim/axis/vismach/VMC_toolchange/vmc_index.ini @@ -30,7 +30,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = vmc.hal HALFILE = sim_vmc.hal HALFILE = spindle.hal diff --git a/configs/sim/axis/vismach/delta/ldelta.ini b/configs/sim/axis/vismach/delta/ldelta.ini index a6c95c302fa..fb1393a589f 100644 --- a/configs/sim/axis/vismach/delta/ldelta.ini +++ b/configs/sim/axis/vismach/delta/ldelta.ini @@ -46,7 +46,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = sim_ldelta.hal HALFILE = axis_manualtoolchange.hal -HALUI = halui [TRAJ] COORDINATES = X Y Z A diff --git a/configs/sim/axis/vismach/delta/ldelta_demo.ini b/configs/sim/axis/vismach/delta/ldelta_demo.ini index 8c72659967b..e45ac7d05d6 100644 --- a/configs/sim/axis/vismach/delta/ldelta_demo.ini +++ b/configs/sim/axis/vismach/delta/ldelta_demo.ini @@ -46,7 +46,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = sim_ldelta.hal HALFILE = axis_manualtoolchange.hal -HALUI = halui HALCMD = setp joint.0.jog-enable 1 HALCMD = setp joint.1.jog-enable 1 diff --git a/configs/sim/axis/vismach/delta/rdelta.ini b/configs/sim/axis/vismach/delta/rdelta.ini index e40defb1c41..17d83eaafc1 100644 --- a/configs/sim/axis/vismach/delta/rdelta.ini +++ b/configs/sim/axis/vismach/delta/rdelta.ini @@ -46,7 +46,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = sim_rdelta.hal HALFILE = axis_manualtoolchange.hal -HALUI = halui [TRAJ] COORDINATES = X Y Z A B C U V W diff --git a/configs/sim/axis/vismach/hbm/hbm.ini b/configs/sim/axis/vismach/hbm/hbm.ini index 231778a5009..ae108d96559 100644 --- a/configs/sim/axis/vismach/hbm/hbm.ini +++ b/configs/sim/axis/vismach/hbm/hbm.ini @@ -28,7 +28,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = hbm.hal [TRAJ] diff --git a/configs/sim/axis/vismach/hexapod-sim/hexapod.ini b/configs/sim/axis/vismach/hexapod-sim/hexapod.ini index f42a14799a0..65543c7a8bd 100644 --- a/configs/sim/axis/vismach/hexapod-sim/hexapod.ini +++ b/configs/sim/axis/vismach/hexapod-sim/hexapod.ini @@ -36,7 +36,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = kinematics.hal HALCMD = loadusr -W ./hexagui.py diff --git a/configs/sim/axis/vismach/melfa-sim/melfa-sim-genser/melfa-sim-genser.ini b/configs/sim/axis/vismach/melfa-sim/melfa-sim-genser/melfa-sim-genser.ini index cfea9e01701..59221f236fb 100644 --- a/configs/sim/axis/vismach/melfa-sim/melfa-sim-genser/melfa-sim-genser.ini +++ b/configs/sim/axis/vismach/melfa-sim/melfa-sim-genser/melfa-sim-genser.ini @@ -8,7 +8,6 @@ KINEMATICS= genserkins JOINTS= 6 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = melfa_mdh.hal HALCMD = loadusr -W ../melfagui.py diff --git a/configs/sim/axis/vismach/melfa-sim/melfa-sim-three21/melfa_321.ini b/configs/sim/axis/vismach/melfa-sim/melfa-sim-three21/melfa_321.ini index 5a8ba9d4787..495a214a855 100644 --- a/configs/sim/axis/vismach/melfa-sim/melfa-sim-three21/melfa_321.ini +++ b/configs/sim/axis/vismach/melfa-sim/melfa-sim-three21/melfa_321.ini @@ -8,7 +8,6 @@ KINEMATICS= three21kins JOINTS= 6 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = melfa_dh.hal HALCMD = loadusr -W ../melfagui.py diff --git a/configs/sim/axis/vismach/millturn/millturn.ini b/configs/sim/axis/vismach/millturn/millturn.ini index 575947d9dce..9d5ea62d3eb 100644 --- a/configs/sim/axis/vismach/millturn/millturn.ini +++ b/configs/sim/axis/vismach/millturn/millturn.ini @@ -11,7 +11,6 @@ KINEMATICS = millturn JOINTS= 4 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = millturn.hal POSTGUI_HALFILE = millturn-postgui.hal diff --git a/configs/sim/axis/vismach/puma/puma.ini b/configs/sim/axis/vismach/puma/puma.ini index 99c0fa33112..c9eee69634a 100644 --- a/configs/sim/axis/vismach/puma/puma.ini +++ b/configs/sim/axis/vismach/puma/puma.ini @@ -8,7 +8,6 @@ KINEMATICS = pumakins JOINTS = 6 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = puma_dh.hal HALCMD = loadusr -W ./pumagui.py diff --git a/configs/sim/axis/vismach/puma/puma560.ini b/configs/sim/axis/vismach/puma/puma560.ini index 046f5d118d5..31ca764725d 100644 --- a/configs/sim/axis/vismach/puma/puma560.ini +++ b/configs/sim/axis/vismach/puma/puma560.ini @@ -12,7 +12,6 @@ JOINTS= 6 KINEMATICS= genserkins [HAL] -HALUI = halui HALCMD = loadusr -W ./puma560gui.py HALFILE = LIB:basic_sim.tcl HALFILE = puma560_dh.hal diff --git a/configs/sim/axis/vismach/puma/puma560_uvw.ini b/configs/sim/axis/vismach/puma/puma560_uvw.ini index a6b9f8544e9..df96788061d 100644 --- a/configs/sim/axis/vismach/puma/puma560_uvw.ini +++ b/configs/sim/axis/vismach/puma/puma560_uvw.ini @@ -12,7 +12,6 @@ JOINTS= 9 KINEMATICS= genserkins [HAL] -HALUI = halui HALCMD = loadusr -W ./puma560gui.py HALFILE = LIB:basic_sim.tcl HALFILE = puma560_dh.hal diff --git a/configs/sim/axis/vismach/puma/puma_cube.ini b/configs/sim/axis/vismach/puma/puma_cube.ini index 8397ce3ea7a..d40a54428fc 100644 --- a/configs/sim/axis/vismach/puma/puma_cube.ini +++ b/configs/sim/axis/vismach/puma/puma_cube.ini @@ -99,7 +99,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = puma_dh.hal HALCMD = loadusr -W ./pumagui.py diff --git a/configs/sim/axis/vismach/scara/scara.ini b/configs/sim/axis/vismach/scara/scara.ini index 23323fdc8bf..9daec89d7d5 100644 --- a/configs/sim/axis/vismach/scara/scara.ini +++ b/configs/sim/axis/vismach/scara/scara.ini @@ -55,7 +55,6 @@ JOINTS = 6 KINEMATICS = scarakins coordinates=xyzcab [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALCMD = loadusr -W ./scaragui.py POSTGUI_HALFILE = scara_postgui.hal diff --git a/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini b/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini index 4d2bc2673ec..0c5d7c296c0 100644 --- a/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini +++ b/configs/sim/axis/wrapped_rotary/wrapped_rotary.ini @@ -39,7 +39,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = wrapped_rotary.hal -HALUI = halui [KINS] KINEMATICS = trivkins coordinates=xyza kinstype=BOTH diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini index f57619ca97a..65147e531cd 100644 --- a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini +++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini @@ -9,7 +9,6 @@ MACHINE = xhc-hb04 layout1 demo [HAL] HALFILE = LIB:basic_sim.tcl HALFILE = LIB:xhc-hb04.tcl -HALUI = halui [XHC_HB04_CONFIG] # specify layout = n for LIB:xhc-hb04-layout{n}.cfg files diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini index eba145fc3fb..f64e9ce1441 100644 --- a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini +++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini @@ -9,7 +9,6 @@ MACHINE = xhc-hb04 layout2 demo [HAL] HALFILE = LIB:basic_sim.tcl HALFILE = LIB:xhc-hb04.tcl -HALUI = halui [XHC_HB04_CONFIG] # specify layout = n for LIB:xhc-hb04-layout{n}.cfg files diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini index 820f965f002..3bf3077f039 100644 --- a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini +++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_mm.ini @@ -7,7 +7,6 @@ VERSION = 1.1 MACHINE = xhc-hb04 layout2 mm demo [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:xhc-hb04.tcl diff --git a/configs/sim/gmoccapy/6_axis.ini b/configs/sim/gmoccapy/6_axis.ini index 4a1a0179f8c..7431a17fc2e 100644 --- a/configs/sim/gmoccapy/6_axis.ini +++ b/configs/sim/gmoccapy/6_axis.ini @@ -59,7 +59,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = core_sim_6.hal #HALFILE = simulated_home_9.hal diff --git a/configs/sim/gmoccapy/7_axis.ini b/configs/sim/gmoccapy/7_axis.ini index e5d25e7fddb..2f0186f8c1a 100644 --- a/configs/sim/gmoccapy/7_axis.ini +++ b/configs/sim/gmoccapy/7_axis.ini @@ -59,7 +59,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = core_sim_7.hal #HALFILE = simulated_home_9.hal diff --git a/configs/sim/gmoccapy/7_axis_tool.ini b/configs/sim/gmoccapy/7_axis_tool.ini index 62c9b2578a3..71aa1abba3b 100644 --- a/configs/sim/gmoccapy/7_axis_tool.ini +++ b/configs/sim/gmoccapy/7_axis_tool.ini @@ -59,7 +59,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = core_sim_7.hal #HALFILE = simulated_home_9.hal diff --git a/configs/sim/gmoccapy/8_axis.ini b/configs/sim/gmoccapy/8_axis.ini index bbfd5b65dde..19410a0c3b9 100644 --- a/configs/sim/gmoccapy/8_axis.ini +++ b/configs/sim/gmoccapy/8_axis.ini @@ -62,7 +62,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = core_sim_8.hal # Single file that is executed after the GUI has started. diff --git a/configs/sim/gmoccapy/9_axis.ini b/configs/sim/gmoccapy/9_axis.ini index 33fac9bce8d..61791bbb4a1 100644 --- a/configs/sim/gmoccapy/9_axis.ini +++ b/configs/sim/gmoccapy/9_axis.ini @@ -59,7 +59,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = core_sim_9.hal #HALFILE = simulated_home_9.hal diff --git a/configs/sim/gmoccapy/gmoccapy.ini b/configs/sim/gmoccapy/gmoccapy.ini index 217ae378d61..6b64f9bc4a4 100644 --- a/configs/sim/gmoccapy/gmoccapy.ini +++ b/configs/sim/gmoccapy/gmoccapy.ini @@ -96,8 +96,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_4_axis.ini b/configs/sim/gmoccapy/gmoccapy_4_axis.ini index 34e0bd18085..0d34ad8171e 100644 --- a/configs/sim/gmoccapy/gmoccapy_4_axis.ini +++ b/configs/sim/gmoccapy/gmoccapy_4_axis.ini @@ -69,8 +69,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_800x600.ini b/configs/sim/gmoccapy/gmoccapy_800x600.ini index 8c2f29bdca9..95be38c3068 100644 --- a/configs/sim/gmoccapy/gmoccapy_800x600.ini +++ b/configs/sim/gmoccapy/gmoccapy_800x600.ini @@ -87,8 +87,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_XYZAB.ini b/configs/sim/gmoccapy/gmoccapy_XYZAB.ini index 75c0997fcd4..d69347ad008 100644 --- a/configs/sim/gmoccapy/gmoccapy_XYZAB.ini +++ b/configs/sim/gmoccapy/gmoccapy_XYZAB.ini @@ -99,8 +99,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_XYZAC.ini b/configs/sim/gmoccapy/gmoccapy_XYZAC.ini index 1b9348e4742..c67346b2dc6 100644 --- a/configs/sim/gmoccapy/gmoccapy_XYZAC.ini +++ b/configs/sim/gmoccapy/gmoccapy_XYZAC.ini @@ -88,8 +88,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_XYZCW.ini b/configs/sim/gmoccapy/gmoccapy_XYZCW.ini index 9fbb984d4f7..74c66acb95c 100644 --- a/configs/sim/gmoccapy/gmoccapy_XYZCW.ini +++ b/configs/sim/gmoccapy/gmoccapy_XYZCW.ini @@ -84,8 +84,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_blockdelete.ini b/configs/sim/gmoccapy/gmoccapy_blockdelete.ini index 4043aa966d9..bfb3dbd7e86 100644 --- a/configs/sim/gmoccapy/gmoccapy_blockdelete.ini +++ b/configs/sim/gmoccapy/gmoccapy_blockdelete.ini @@ -85,8 +85,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_left_panel.ini b/configs/sim/gmoccapy/gmoccapy_left_panel.ini index 52c9d8b3a30..47e096e3f5e 100644 --- a/configs/sim/gmoccapy/gmoccapy_left_panel.ini +++ b/configs/sim/gmoccapy/gmoccapy_left_panel.ini @@ -78,8 +78,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_messages.ini b/configs/sim/gmoccapy/gmoccapy_messages.ini index 705f051028f..1cf69d4c015 100644 --- a/configs/sim/gmoccapy/gmoccapy_messages.ini +++ b/configs/sim/gmoccapy/gmoccapy_messages.ini @@ -111,8 +111,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_pedant.ini b/configs/sim/gmoccapy/gmoccapy_pedant.ini index 8ca75a3fd8c..2f13186e4f1 100644 --- a/configs/sim/gmoccapy/gmoccapy_pedant.ini +++ b/configs/sim/gmoccapy/gmoccapy_pedant.ini @@ -79,8 +79,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini b/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini index 6bfc5c446a9..dffaee23f46 100644 --- a/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini +++ b/configs/sim/gmoccapy/gmoccapy_pyngcgui.ini @@ -114,8 +114,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_pyngcgui_gcmc.ini b/configs/sim/gmoccapy/gmoccapy_pyngcgui_gcmc.ini index de4a5e50836..303fe9156ea 100644 --- a/configs/sim/gmoccapy/gmoccapy_pyngcgui_gcmc.ini +++ b/configs/sim/gmoccapy/gmoccapy_pyngcgui_gcmc.ini @@ -115,8 +115,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_qt_messages.ini b/configs/sim/gmoccapy/gmoccapy_qt_messages.ini index d15480633da..e77de499b01 100644 --- a/configs/sim/gmoccapy/gmoccapy_qt_messages.ini +++ b/configs/sim/gmoccapy/gmoccapy_qt_messages.ini @@ -109,8 +109,6 @@ POSTGUI_HALFILE = gmoccapy_postgui.hal POSTGUI_HALCMD = loadusr -Wn ini_dialogs qtvcp --ini gmoccapy_qt_messages.ini -q ini_dialogs POSTGUI_HALCMD = setp ini_dialogs.VFD 1 -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_right_panel.ini b/configs/sim/gmoccapy/gmoccapy_right_panel.ini index 62213d687d5..35130499f47 100644 --- a/configs/sim/gmoccapy/gmoccapy_right_panel.ini +++ b/configs/sim/gmoccapy/gmoccapy_right_panel.ini @@ -74,8 +74,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini b/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini index 704e64d796d..6f5f225cd5b 100644 --- a/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini +++ b/configs/sim/gmoccapy/gmoccapy_sim_hardware_button.ini @@ -82,8 +82,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini b/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini index 37daf107549..6f607735a8d 100644 --- a/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini +++ b/configs/sim/gmoccapy/gmoccapy_tool_sensor.ini @@ -104,8 +104,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini b/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini index 9ac53efa54b..2a186a7145d 100644 --- a/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini +++ b/configs/sim/gmoccapy/gmoccapy_with_user_tabs.ini @@ -99,8 +99,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe.ini b/configs/sim/gmoccapy/lathe_configs/lathe.ini index 71da9ff283d..4df6ba4e8d6 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe.ini @@ -76,8 +76,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe_C.ini b/configs/sim/gmoccapy/lathe_configs/lathe_C.ini index b47ec8d569d..96c75824987 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe_C.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe_C.ini @@ -77,8 +77,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini b/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini index e5bd6640c33..05a775972f8 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe_CW.ini @@ -77,8 +77,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini b/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini index b49ae755431..6859eb479e8 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe_backtool.ini @@ -77,8 +77,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini b/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini index e95ffdd29ac..1b600a31078 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe_imperial.ini @@ -77,8 +77,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini b/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini index c3a49f61433..198ccbb5995 100644 --- a/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini +++ b/configs/sim/gmoccapy/lathe_configs/lathe_macros.ini @@ -82,8 +82,6 @@ HALFILE = simulated_home_lathe.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = ./gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini b/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini index 979e8775798..f5a577d52e8 100644 --- a/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini +++ b/configs/sim/gmoccapy/non_trivial_kinematics/Gantry/gantry_mm.ini @@ -54,7 +54,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = gantry_mm.hal -HALUI = halui # Single file that is executed after the GUI has started. #POSTGUI_HALFILE = gmoccapy_postgui.hal diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini b/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini index 37b2ad9a241..9120639155a 100644 --- a/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini +++ b/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara.ini @@ -44,7 +44,6 @@ SERVO_PERIOD = 1000000 TRAJ_PERIOD = 10000000 [HAL] -HALUI = halui HALFILE = scara_sim_4.hal POSTGUI_HALFILE = postgui.hal diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini b/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini index ad1ea4a3877..50f5888fc8a 100644 --- a/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini +++ b/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini @@ -31,7 +31,6 @@ TOPLEVEL = ../../python/toplevel.py LOG_LEVEL = 0 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl -no_use_hal_manualtoolchange # vismach xyzac-trt-gui items diff --git a/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini b/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini index 5e0dffb5895..6037033e80b 100644 --- a/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini +++ b/configs/sim/gmoccapy/plasma_config/gmoccapy_plasma.ini @@ -79,8 +79,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gmoccapy_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen.ini b/configs/sim/gscreen/gscreen.ini index 42b90a1c5f5..b1232f673dc 100644 --- a/configs/sim/gscreen/gscreen.ini +++ b/configs/sim/gscreen/gscreen.ini @@ -132,8 +132,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) # POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/9axis.ini b/configs/sim/gscreen/gscreen_custom/9axis.ini index 89ff1072083..7f88fa8c9d3 100644 --- a/configs/sim/gscreen/gscreen_custom/9axis.ini +++ b/configs/sim/gscreen/gscreen_custom/9axis.ini @@ -102,8 +102,6 @@ HALFILE = locking_indexer.hal # Single file that is executed after the GUI has started. #POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini b/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini index e91dd76845b..b7f485284c9 100644 --- a/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini +++ b/configs/sim/gscreen/gscreen_custom/gaxis_no_plot.ini @@ -99,8 +99,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gaxis_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini b/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini index d27ba0bd229..c2abe2d8f28 100644 --- a/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini +++ b/configs/sim/gscreen/gscreen_custom/gscreen_gaxis.ini @@ -99,8 +99,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = gaxis_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/industrial.ini b/configs/sim/gscreen/gscreen_custom/industrial.ini index 0aa100bbfd8..ca2d99900a0 100644 --- a/configs/sim/gscreen/gscreen_custom/industrial.ini +++ b/configs/sim/gscreen/gscreen_custom/industrial.ini @@ -101,8 +101,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = industrial_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/tester.ini b/configs/sim/gscreen/gscreen_custom/tester.ini index 3b6f6145815..6924beacf6e 100644 --- a/configs/sim/gscreen/gscreen_custom/tester.ini +++ b/configs/sim/gscreen/gscreen_custom/tester.ini @@ -90,8 +90,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = tester_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_custom/tester_metric.ini b/configs/sim/gscreen/gscreen_custom/tester_metric.ini index e9d51848396..f313e40a46e 100644 --- a/configs/sim/gscreen/gscreen_custom/tester_metric.ini +++ b/configs/sim/gscreen/gscreen_custom/tester_metric.ini @@ -102,8 +102,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = tester_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/gscreen_lathe.ini b/configs/sim/gscreen/gscreen_lathe.ini index b219e1e5931..23b5e756339 100644 --- a/configs/sim/gscreen/gscreen_lathe.ini +++ b/configs/sim/gscreen/gscreen_lathe.ini @@ -42,7 +42,6 @@ SERVO_PERIOD = 1000000 CYCLE_TIME = 0.001 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = lathe_postgui.hal diff --git a/configs/sim/gscreen/gscreen_mm.ini b/configs/sim/gscreen/gscreen_mm.ini index fb27c3da7c8..af7a205c95f 100644 --- a/configs/sim/gscreen/gscreen_mm.ini +++ b/configs/sim/gscreen/gscreen_mm.ini @@ -103,8 +103,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) #POSTGUI_HALFILE = test_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] #No Content diff --git a/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini b/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini index a18d281d567..9032cffcfe2 100644 --- a/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini +++ b/configs/sim/gscreen/industrial_lathe_wear/industrial_lathe_wear.ini @@ -44,7 +44,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = lathe_postgui.hal diff --git a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini index bbc2903e276..5ad0a976566 100644 --- a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini +++ b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen.ini @@ -91,7 +91,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini index cba1b603180..d4c922f9b96 100644 --- a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini +++ b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard.ini @@ -88,7 +88,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/gscreen/silverdragon/silverdragon.ini b/configs/sim/gscreen/silverdragon/silverdragon.ini index fe2e27123d9..c7932c2b49e 100644 --- a/configs/sim/gscreen/silverdragon/silverdragon.ini +++ b/configs/sim/gscreen/silverdragon/silverdragon.ini @@ -77,7 +77,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. #POSTGUI_HALFILE = silverdragon_postgui.hal -HALUI = halui # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/gscreen/spartan/spartan.ini b/configs/sim/gscreen/spartan/spartan.ini index dbdc9baa8b8..1de14983b2e 100644 --- a/configs/sim/gscreen/spartan/spartan.ini +++ b/configs/sim/gscreen/spartan/spartan.ini @@ -43,7 +43,6 @@ TASK = milltask CYCLE_TIME = 0.010 [HAL] -HALUI = halui HALFILE = spartan.hal HALFILE = simulated_home.hal HALFILE = custom.hal diff --git a/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini b/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini index ea8520ed706..07d9fb0e31b 100644 --- a/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini +++ b/configs/sim/pyvcp_demo/pyvcp_bottom_panel.ini @@ -117,8 +117,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = pyvcp_bottom_panel.hal -HALUI = halui - [HALUI] # add halui MDI commands here (max 64) diff --git a/configs/sim/pyvcp_demo/pyvcp_demo1.ini b/configs/sim/pyvcp_demo/pyvcp_demo1.ini index 57be35b0ef0..076710de532 100644 --- a/configs/sim/pyvcp_demo/pyvcp_demo1.ini +++ b/configs/sim/pyvcp_demo/pyvcp_demo1.ini @@ -114,8 +114,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = custom.hal -HALUI = halui - [HALUI] # add halui MDI commands here (max 64) diff --git a/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini b/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini index 1895448e577..80574f49fd3 100644 --- a/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini +++ b/configs/sim/pyvcp_demo/pyvcp_embed_tab.ini @@ -118,8 +118,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = pyvcp_embed_tab.hal -HALUI = halui - [HALUI] # add halui MDI commands here (max 64) diff --git a/configs/sim/qtaxis/non-trivial/scara/scara.ini b/configs/sim/qtaxis/non-trivial/scara/scara.ini index 00ea3d2a1ca..041ae255c34 100644 --- a/configs/sim/qtaxis/non-trivial/scara/scara.ini +++ b/configs/sim/qtaxis/non-trivial/scara/scara.ini @@ -119,7 +119,6 @@ JOINTS = 6 KINEMATICS = scarakins coordinates=xyzcab [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [HALUI] diff --git a/configs/sim/qtaxis/xyz/qtaxis.ini b/configs/sim/qtaxis/xyz/qtaxis.ini index 12cf1911843..2f9dcb2afa7 100644 --- a/configs/sim/qtaxis/xyz/qtaxis.ini +++ b/configs/sim/qtaxis/xyz/qtaxis.ini @@ -177,8 +177,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini index 8c16d5e1d20..d84babffac8 100644 --- a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini +++ b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini @@ -120,7 +120,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyzw.ini b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyzw.ini index b3614ef512a..791aefecd93 100644 --- a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyzw.ini +++ b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyzw.ini @@ -122,7 +122,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini index 1430466c4dc..f76d1d3d9a4 100644 --- a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini +++ b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzy.ini @@ -120,7 +120,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini index e37a803deae..10bb8a88291 100644 --- a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini +++ b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyzya.ini @@ -124,7 +124,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_yyxz.ini b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_yyxz.ini index 54631bbbfd8..cc39f30a238 100644 --- a/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_yyxz.ini +++ b/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_yyxz.ini @@ -120,7 +120,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini b/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini index cd8c1cd4ae7..109740b4e3d 100644 --- a/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini +++ b/configs/sim/qtdragon/qtdragon_tool_probe/qtdragon_auto_tool_probe.ini @@ -144,7 +144,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge HALFILE = core_sim.hal diff --git a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini index 4be20c9b004..f4a3cf65d14 100644 --- a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini +++ b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini @@ -153,7 +153,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini index c246e1d6845..561179e06ac 100644 --- a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini +++ b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric.ini @@ -150,7 +150,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric_debug.ini b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric_debug.ini index b2bb0b8ddd2..347ebd1ff4d 100644 --- a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric_debug.ini +++ b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_metric_debug.ini @@ -158,7 +158,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini index 466f0e98085..8eabb84c516 100644 --- a/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini +++ b/configs/sim/qtdragon/qtdragon_xyz/qtdragon_xyza.ini @@ -129,7 +129,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui # loads the HAL machine simulation HALFILE = gantrysim.hal HALFILE = simulated-gantry-home.hal diff --git a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini index 59e43f1cb63..0477fec4d1c 100644 --- a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini +++ b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini @@ -125,7 +125,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini index 41dbf6364b5..59ac96fee1e 100644 --- a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini +++ b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzab.ini @@ -125,7 +125,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini index 01fc99beefe..70857afcdf4 100644 --- a/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini +++ b/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyzac.ini @@ -125,7 +125,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini index 605f9700ce1..22d30d42e14 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini @@ -128,7 +128,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge HALFILE = core_sim.hal diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical_xyza.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical_xyza.ini index d8e88f3b704..e412ddcec3b 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical_xyza.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical_xyza.ini @@ -131,7 +131,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini index 25283374243..c3d249406bd 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyz.ini @@ -126,7 +126,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge HALFILE = core_sim.hal diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini index b206ed1a7db..20e593a5275 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyza.ini @@ -128,7 +128,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini index a489db176c6..660227adaa2 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzab.ini @@ -125,7 +125,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini index 2d2c97b1e17..70e904de811 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_xyzac.ini @@ -125,7 +125,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge # loads the HAL machine simulation diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_next_xyz.ini b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_next_xyz.ini index aaf67603a23..b99a925b8d9 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_next_xyz.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_next_xyz.ini @@ -120,7 +120,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = simulated_home.hal # this file is loaded after qtdragon has made it's HAl pins diff --git a/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini b/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini index 274443940af..1e25dd5e056 100644 --- a/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini +++ b/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini @@ -120,7 +120,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALBRIDGE = hal_bridge HALFILE = core_sim.hal diff --git a/configs/sim/qtdragon_lathe/basic_xz_lathe/lathe.ini b/configs/sim/qtdragon_lathe/basic_xz_lathe/lathe.ini index 6d5a04b2c14..1c810b286ee 100644 --- a/configs/sim/qtdragon_lathe/basic_xz_lathe/lathe.ini +++ b/configs/sim/qtdragon_lathe/basic_xz_lathe/lathe.ini @@ -56,7 +56,6 @@ SERVO_PERIOD = 1000000 CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALBRIDGE = hal_bridge HALFILE = LIB:basic_sim.tcl diff --git a/configs/sim/qttouchy/qttouchy.ini b/configs/sim/qttouchy/qttouchy.ini index ef616ba42fd..5690b1cae85 100644 --- a/configs/sim/qttouchy/qttouchy.ini +++ b/configs/sim/qttouchy/qttouchy.ini @@ -158,8 +158,6 @@ HALFILE = simulated_home.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/blender.ini b/configs/sim/qtvcp_screens/blender.ini index 6e091cd644b..4ebdd924f49 100644 --- a/configs/sim/qtvcp_screens/blender.ini +++ b/configs/sim/qtvcp_screens/blender.ini @@ -167,8 +167,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini b/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini index 12effa9efe5..992f211af75 100644 --- a/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini +++ b/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini @@ -64,7 +64,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl -no_use_hal_manualtoolchange POSTGUI_HALFILE = qtvcp_postgui.hal diff --git a/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini b/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini index 97f588c2e34..d786c83435c 100644 --- a/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini +++ b/configs/sim/qtvcp_screens/non-trivial/scara/scara.ini @@ -120,7 +120,6 @@ JOINTS = 6 KINEMATICS = scarakins coordinates=xyzcab [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [HALUI] diff --git a/configs/sim/qtvcp_screens/qt_800x600.ini b/configs/sim/qtvcp_screens/qt_800x600.ini index ff78136c0b7..2def79cb40b 100644 --- a/configs/sim/qtvcp_screens/qt_800x600.ini +++ b/configs/sim/qtvcp_screens/qt_800x600.ini @@ -124,8 +124,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtaxis.ini b/configs/sim/qtvcp_screens/qtaxis.ini index c023a0607a8..bc4fe148af4 100644 --- a/configs/sim/qtvcp_screens/qtaxis.ini +++ b/configs/sim/qtvcp_screens/qtaxis.ini @@ -180,8 +180,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini b/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini index 0876cac83cc..54ce1466385 100644 --- a/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini +++ b/configs/sim/qtvcp_screens/qtaxis_lathe/qtaxis_lathe.ini @@ -154,8 +154,6 @@ POSTGUI_HALFILE = qtvcp_postgui.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - [TRAJ] diff --git a/configs/sim/qtvcp_screens/qtaxis_mpg.ini b/configs/sim/qtvcp_screens/qtaxis_mpg.ini index e5bb171e719..bbcc52ad9c1 100644 --- a/configs/sim/qtvcp_screens/qtaxis_mpg.ini +++ b/configs/sim/qtvcp_screens/qtaxis_mpg.ini @@ -207,8 +207,6 @@ POSTGUI_HALCMD = setp qtaxis.mpg-enable 1 #POSTGUI_HALCMD = net mpg-enable qtaxis.mpg-enable sim_panel.selectscroll POSTGUI_HALCMD = net mpg qtaxis.mpg-in sim_panel.MPG-s -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtdefault.ini b/configs/sim/qtvcp_screens/qtdefault.ini index 78061f39987..cb378c86c02 100644 --- a/configs/sim/qtvcp_screens/qtdefault.ini +++ b/configs/sim/qtvcp_screens/qtdefault.ini @@ -170,8 +170,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtdefault_9axis.ini b/configs/sim/qtvcp_screens/qtdefault_9axis.ini index dad0c31c2e6..419615a9615 100644 --- a/configs/sim/qtvcp_screens/qtdefault_9axis.ini +++ b/configs/sim/qtvcp_screens/qtdefault_9axis.ini @@ -56,7 +56,6 @@ SERVO_PERIOD = 1000000 TOOL_CHANGE_POSITION = 0 0 2 [HAL] - HALUI = halui HALFILE = LIB:basic_sim.tcl -no_use_hal_manualtoolchange HALFILE = locking_indexer.hal diff --git a/configs/sim/qtvcp_screens/qtdefault_mm.ini b/configs/sim/qtvcp_screens/qtdefault_mm.ini index a696d4597e4..de74d574c11 100644 --- a/configs/sim/qtvcp_screens/qtdefault_mm.ini +++ b/configs/sim/qtvcp_screens/qtdefault_mm.ini @@ -110,8 +110,6 @@ HALFILE = simulated_home.hal # Single file that is executed after the GUI has started. POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] COORDINATES = X Y Z diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini b/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini index a28b0a1e885..534757ff6bc 100644 --- a/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini +++ b/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini @@ -110,7 +110,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = simulated_home.hal #HALFILE = custom.hal diff --git a/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini b/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini index 0372ad865c1..0aa0ece3706 100644 --- a/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini +++ b/configs/sim/qtvcp_screens/qtvcp_custom/qtdefault_ngc.ini @@ -189,8 +189,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini index 0270b000131..39961324f7d 100644 --- a/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini +++ b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini @@ -192,8 +192,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini index 14820649397..dbcab0b5d15 100644 --- a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini +++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini @@ -192,8 +192,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini index 0372ad865c1..0aa0ece3706 100644 --- a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini +++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini @@ -189,8 +189,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/qtx1mill.ini b/configs/sim/qtvcp_screens/qtx1mill.ini index 0e3a2d3c334..b9aa6c59dec 100644 --- a/configs/sim/qtvcp_screens/qtx1mill.ini +++ b/configs/sim/qtvcp_screens/qtx1mill.ini @@ -174,8 +174,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/qtvcp_screens/tester.ini b/configs/sim/qtvcp_screens/tester.ini index 4cec31b24f5..4b3b493e67b 100644 --- a/configs/sim/qtvcp_screens/tester.ini +++ b/configs/sim/qtvcp_screens/tester.ini @@ -144,8 +144,6 @@ HALFILE = check_constraints.hal # AXIS at this time (only AXIS creates a HAL component of its own) #POSTGUI_HALFILE = qtvcp_postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [HALUI] diff --git a/configs/sim/tklinuxcnc/ldelta.ini b/configs/sim/tklinuxcnc/ldelta.ini index c2222ff791e..b2ca19f0afd 100644 --- a/configs/sim/tklinuxcnc/ldelta.ini +++ b/configs/sim/tklinuxcnc/ldelta.ini @@ -46,7 +46,6 @@ SERVO_PERIOD = 1000000 [HAL] HALFILE = sim_ldelta.hal HALFILE = axis_manualtoolchange.hal -HALUI = halui [TRAJ] COORDINATES = X Y Z A diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini b/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini index 1297e290e42..858c181fa9c 100644 --- a/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini +++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy.ini @@ -54,7 +54,6 @@ CYCLE_TIME = 0.001 [HAL] HALFILE = LIB:basic_sim.tcl -HALUI = halui [TRAJ] COORDINATES = X Y Z diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini b/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini index 90918ec728c..3eba2ab765e 100644 --- a/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini +++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe.ini @@ -64,7 +64,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl [TRAJ] diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini index 500bf37ed1c..15b52e9c096 100644 --- a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini +++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.ini @@ -54,7 +54,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = LIB:hookup_moveoff.tcl diff --git a/configs/sim/woodpecker/woodpecker.ini b/configs/sim/woodpecker/woodpecker.ini index fc6b389dc99..fd46471f057 100644 --- a/configs/sim/woodpecker/woodpecker.ini +++ b/configs/sim/woodpecker/woodpecker.ini @@ -78,7 +78,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = simulated_home.hal #HALFILE = custom.hal diff --git a/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini b/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini index e8fe3935119..07748d5ace9 100644 --- a/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini +++ b/configs/sim/woodpecker/woodpecker_auto_tool_probe.ini @@ -100,7 +100,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = simulated_home.hal POSTGUI_HALFILE = woodpecker_postgui.hal diff --git a/configs/sim/woodpecker/woodpecker_xyz.ini b/configs/sim/woodpecker/woodpecker_xyz.ini index 911f2c576b0..1631c202240 100644 --- a/configs/sim/woodpecker/woodpecker_xyz.ini +++ b/configs/sim/woodpecker/woodpecker_xyz.ini @@ -87,7 +87,6 @@ SPINDLES = 1 NO_FORCE_HOMING = 1 [HAL] -HALUI = halui HALFILE = core_sim.hal HALFILE = simulated_home.hal #HALFILE = custom.hal diff --git a/configs/sim/woodpecker/woodpecker_xyza.ini b/configs/sim/woodpecker/woodpecker_xyza.ini index 1226c5e7e00..6d2fb66c3b3 100644 --- a/configs/sim/woodpecker/woodpecker_xyza.ini +++ b/configs/sim/woodpecker/woodpecker_xyza.ini @@ -116,7 +116,6 @@ POSITION_FILE = position.txt #NO_FORCE_HOMING = 1 [HAL] -HALUI = halui #HALFILE = core_sim.hal HALFILE = gantrysim.hal HALFILE = simulated-gantry-home.hal diff --git a/configs/sim/woodpecker/woodpecker_xyzab.ini b/configs/sim/woodpecker/woodpecker_xyzab.ini index d6229b133c6..67f1e0f788d 100644 --- a/configs/sim/woodpecker/woodpecker_xyzab.ini +++ b/configs/sim/woodpecker/woodpecker_xyzab.ini @@ -102,7 +102,6 @@ POSITION_FILE = position.txt SPINDLES = 1 [HAL] -HALUI = halui HALFILE = gantrysim-xyzab.hal HALFILE = simulated-gantry-xyzab-home.hal #HALFILE = mpg.hal diff --git a/configs/sim/woodpecker/woodpecker_xyzy.ini b/configs/sim/woodpecker/woodpecker_xyzy.ini index 18f793993f4..bbd8f63a620 100644 --- a/configs/sim/woodpecker/woodpecker_xyzy.ini +++ b/configs/sim/woodpecker/woodpecker_xyzy.ini @@ -84,7 +84,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui #HALFILE = core_sim.hal HALFILE = gantrysim.hal HALFILE = simulated-gantry-home.hal diff --git a/configs/sim/woodpecker/woodpecker_xyzya.ini b/configs/sim/woodpecker/woodpecker_xyzya.ini index 3f0ba0c3b57..87ea1220a07 100644 --- a/configs/sim/woodpecker/woodpecker_xyzya.ini +++ b/configs/sim/woodpecker/woodpecker_xyzya.ini @@ -87,7 +87,6 @@ DEFAULT_LINEAR_VELOCITY = 50.00 SPINDLES = 1 [HAL] -HALUI = halui #HALFILE = core_sim.hal HALFILE = gantrysim.hal HALFILE = simulated-gantry-home.hal From fb2ddb5d8fa81dd529477282220047674621e172 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sun, 20 Sep 2026 17:34:39 +0200 Subject: [PATCH 03/12] remove halui from test configs --- tests/abort/feed-rate/test.ini | 1 - tests/abort/g64/test.ini | 1 - tests/ccomp/early-exit/test.ini | 1 - tests/halui/jogging/halui.ini | 1 - tests/halui/mdi/halui.ini | 1 - tests/interp/g28.2/flush-order/test.ini | 1 - tests/interp/g28.2/home-all-sequence/test.ini | 1 - tests/interp/g28.2/immediate-mode-guard/test.ini | 1 - tests/interp/g28.2/invalid-pword/test.ini | 1 - tests/interp/g28.2/position-model/test.ini | 1 - tests/interp/g28.2/sequencing/test.ini | 1 - tests/interp/mdi-oword-m66/interp.ini | 1 - tests/interp/oword-mdi-sub-update/interp.ini | 1 - tests/interp/subroutine-return/interp.ini | 1 - tests/interp_initcode/test.ini | 1 - tests/matrixkins/test.ini | 1 - tests/maxkins/test.ini | 1 - tests/mdi-queue-length/test.ini | 1 - tests/mdi-while-queuebuster-waitflag/test.ini | 1 - tests/mqtt/simulator.ini | 1 - tests/remap/remap-io/test-ngc.ini | 1 - tests/remap/remap-io/test-py.ini | 1 - tests/remap/remap-reentry/test.ini | 1 - tests/rs274ngc-startup/test.ini | 1 - tests/startup-state/test.ini | 1 - tests/statbuffer-g5x-abort/test.ini | 1 - tests/tlo/g43-test.ini | 1 - tests/tool-info/non-random/test.ini | 1 - tests/tool-info/random-no-startup-tool/test.ini | 1 - tests/tool-info/random-with-startup-tool/test.ini | 1 - tests/toolchanger/abort-during-change/abort-test.ini | 1 - tests/toolchanger/m61/m61-test.ini | 1 - tests/trajectory-planner/circular-arcs/configs/9axis.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XY.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XYZ.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XYZ_fast.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XYZ_medium.ini | 2 -- .../trajectory-planner/circular-arcs/configs/XYZ_nospindle.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XYZ_uneven.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XY_slowZ.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/XZ.ini | 2 -- tests/trajectory-planner/circular-arcs/configs/axis_mm.ini | 2 -- 42 files changed, 52 deletions(-) diff --git a/tests/abort/feed-rate/test.ini b/tests/abort/feed-rate/test.ini index d8acfe5dff9..36b3c1ca150 100644 --- a/tests/abort/feed-rate/test.ini +++ b/tests/abort/feed-rate/test.ini @@ -30,7 +30,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/abort/g64/test.ini b/tests/abort/g64/test.ini index f8dee4fe1ad..051ba44990f 100644 --- a/tests/abort/g64/test.ini +++ b/tests/abort/g64/test.ini @@ -28,7 +28,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = motion-test.hal diff --git a/tests/ccomp/early-exit/test.ini b/tests/ccomp/early-exit/test.ini index 44e664dc5a0..db7340ab5a7 100644 --- a/tests/ccomp/early-exit/test.ini +++ b/tests/ccomp/early-exit/test.ini @@ -28,7 +28,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/halui/jogging/halui.ini b/tests/halui/jogging/halui.ini index 4fcd2b2b88f..acc1e1a6f94 100644 --- a/tests/halui/jogging/halui.ini +++ b/tests/halui/jogging/halui.ini @@ -22,7 +22,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/halui/mdi/halui.ini b/tests/halui/mdi/halui.ini index 052cd84a331..b55b8215f1b 100644 --- a/tests/halui/mdi/halui.ini +++ b/tests/halui/mdi/halui.ini @@ -22,7 +22,6 @@ CYCLE_TIME = 0.001 MDI_QUEUED_COMMANDS=10000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/interp/g28.2/flush-order/test.ini b/tests/interp/g28.2/flush-order/test.ini index 38b6a739acb..8edb313dd14 100644 --- a/tests/interp/g28.2/flush-order/test.ini +++ b/tests/interp/g28.2/flush-order/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal [TRAJ] diff --git a/tests/interp/g28.2/home-all-sequence/test.ini b/tests/interp/g28.2/home-all-sequence/test.ini index b55ba992d9b..2cb34a6e528 100644 --- a/tests/interp/g28.2/home-all-sequence/test.ini +++ b/tests/interp/g28.2/home-all-sequence/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal [TRAJ] diff --git a/tests/interp/g28.2/immediate-mode-guard/test.ini b/tests/interp/g28.2/immediate-mode-guard/test.ini index eb1ecd04ca9..95e2516ac87 100644 --- a/tests/interp/g28.2/immediate-mode-guard/test.ini +++ b/tests/interp/g28.2/immediate-mode-guard/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal [TRAJ] diff --git a/tests/interp/g28.2/invalid-pword/test.ini b/tests/interp/g28.2/invalid-pword/test.ini index c0b3db5b31a..d3b47c68490 100644 --- a/tests/interp/g28.2/invalid-pword/test.ini +++ b/tests/interp/g28.2/invalid-pword/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal [TRAJ] diff --git a/tests/interp/g28.2/position-model/test.ini b/tests/interp/g28.2/position-model/test.ini index c725f5bf718..1f63941b0ab 100644 --- a/tests/interp/g28.2/position-model/test.ini +++ b/tests/interp/g28.2/position-model/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = sim_extra.hal diff --git a/tests/interp/g28.2/sequencing/test.ini b/tests/interp/g28.2/sequencing/test.ini index eb1ecd04ca9..95e2516ac87 100644 --- a/tests/interp/g28.2/sequencing/test.ini +++ b/tests/interp/g28.2/sequencing/test.ini @@ -19,7 +19,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal [TRAJ] diff --git a/tests/interp/mdi-oword-m66/interp.ini b/tests/interp/mdi-oword-m66/interp.ini index f6eaa099929..ff1128df8d5 100644 --- a/tests/interp/mdi-oword-m66/interp.ini +++ b/tests/interp/mdi-oword-m66/interp.ini @@ -23,7 +23,6 @@ CYCLE_TIME = 0.001 MDI_QUEUED_COMMANDS=10000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/interp/oword-mdi-sub-update/interp.ini b/tests/interp/oword-mdi-sub-update/interp.ini index 0774aa13db5..50f99de9258 100644 --- a/tests/interp/oword-mdi-sub-update/interp.ini +++ b/tests/interp/oword-mdi-sub-update/interp.ini @@ -22,7 +22,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/interp/subroutine-return/interp.ini b/tests/interp/subroutine-return/interp.ini index 18c4e6cb673..3ad89829196 100644 --- a/tests/interp/subroutine-return/interp.ini +++ b/tests/interp/subroutine-return/interp.ini @@ -23,7 +23,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/interp_initcode/test.ini b/tests/interp_initcode/test.ini index d183d9276b9..7e37f25610b 100644 --- a/tests/interp_initcode/test.ini +++ b/tests/interp_initcode/test.ini @@ -29,7 +29,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = LIB:simulated_home.hal HALFILE = LIB:lathe.hal diff --git a/tests/matrixkins/test.ini b/tests/matrixkins/test.ini index 662138a46a7..98be460a21b 100644 --- a/tests/matrixkins/test.ini +++ b/tests/matrixkins/test.ini @@ -27,7 +27,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/maxkins/test.ini b/tests/maxkins/test.ini index 7cf23c05738..8b28d176c3c 100644 --- a/tests/maxkins/test.ini +++ b/tests/maxkins/test.ini @@ -30,7 +30,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/mdi-queue-length/test.ini b/tests/mdi-queue-length/test.ini index c3c867680f3..fbda0260e13 100644 --- a/tests/mdi-queue-length/test.ini +++ b/tests/mdi-queue-length/test.ini @@ -21,7 +21,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [TRAJ] diff --git a/tests/mdi-while-queuebuster-waitflag/test.ini b/tests/mdi-while-queuebuster-waitflag/test.ini index 574763d8bee..32816c58090 100644 --- a/tests/mdi-while-queuebuster-waitflag/test.ini +++ b/tests/mdi-while-queuebuster-waitflag/test.ini @@ -22,7 +22,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [TRAJ] diff --git a/tests/mqtt/simulator.ini b/tests/mqtt/simulator.ini index ba7f9fc0232..aa8d6494263 100644 --- a/tests/mqtt/simulator.ini +++ b/tests/mqtt/simulator.ini @@ -25,7 +25,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = simulator.hal [HALUI] diff --git a/tests/remap/remap-io/test-ngc.ini b/tests/remap/remap-io/test-ngc.ini index 4ece72c8ff0..5d5250015dd 100644 --- a/tests/remap/remap-io/test-ngc.ini +++ b/tests/remap/remap-io/test-ngc.ini @@ -35,7 +35,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/remap/remap-io/test-py.ini b/tests/remap/remap-io/test-py.ini index d4d110f9948..fe94ace845d 100644 --- a/tests/remap/remap-io/test-py.ini +++ b/tests/remap/remap-io/test-py.ini @@ -35,7 +35,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/remap/remap-reentry/test.ini b/tests/remap/remap-reentry/test.ini index 1dc3cbe953a..46f82e8d21a 100644 --- a/tests/remap/remap-reentry/test.ini +++ b/tests/remap/remap-reentry/test.ini @@ -21,7 +21,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [TRAJ] diff --git a/tests/rs274ngc-startup/test.ini b/tests/rs274ngc-startup/test.ini index 93bb8db533a..fbb0442d7dc 100644 --- a/tests/rs274ngc-startup/test.ini +++ b/tests/rs274ngc-startup/test.ini @@ -29,7 +29,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/startup-state/test.ini b/tests/startup-state/test.ini index eb6773fbb25..303de104ca4 100644 --- a/tests/startup-state/test.ini +++ b/tests/startup-state/test.ini @@ -28,7 +28,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/statbuffer-g5x-abort/test.ini b/tests/statbuffer-g5x-abort/test.ini index ef2be910f43..80768c3a642 100644 --- a/tests/statbuffer-g5x-abort/test.ini +++ b/tests/statbuffer-g5x-abort/test.ini @@ -28,7 +28,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/tlo/g43-test.ini b/tests/tlo/g43-test.ini index 0b6d9beaa80..b56bb9923d2 100644 --- a/tests/tlo/g43-test.ini +++ b/tests/tlo/g43-test.ini @@ -21,7 +21,6 @@ CYCLE_TIME = 0.001 MDI_QUEUED_COMMANDS=10000 [HAL] -HALUI = halui HALFILE = mod_core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/tool-info/non-random/test.ini b/tests/tool-info/non-random/test.ini index 654191fb3f1..a0d34221906 100644 --- a/tests/tool-info/non-random/test.ini +++ b/tests/tool-info/non-random/test.ini @@ -24,7 +24,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/tool-info/random-no-startup-tool/test.ini b/tests/tool-info/random-no-startup-tool/test.ini index c002e1f8b36..a55d6fc7c02 100644 --- a/tests/tool-info/random-no-startup-tool/test.ini +++ b/tests/tool-info/random-no-startup-tool/test.ini @@ -24,7 +24,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/tool-info/random-with-startup-tool/test.ini b/tests/tool-info/random-with-startup-tool/test.ini index c002e1f8b36..a55d6fc7c02 100644 --- a/tests/tool-info/random-with-startup-tool/test.ini +++ b/tests/tool-info/random-with-startup-tool/test.ini @@ -24,7 +24,6 @@ TASK = milltask CYCLE_TIME = 0.001 [HAL] -HALUI = halui HALFILE = core_sim.hal [HALUI] diff --git a/tests/toolchanger/abort-during-change/abort-test.ini b/tests/toolchanger/abort-during-change/abort-test.ini index 3d7fc19cd75..0ee237cc8e6 100644 --- a/tests/toolchanger/abort-during-change/abort-test.ini +++ b/tests/toolchanger/abort-during-change/abort-test.ini @@ -20,7 +20,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = mod_core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/toolchanger/m61/m61-test.ini b/tests/toolchanger/m61/m61-test.ini index e3ad9deae49..68e1303ff48 100644 --- a/tests/toolchanger/m61/m61-test.ini +++ b/tests/toolchanger/m61/m61-test.ini @@ -21,7 +21,6 @@ BASE_PERIOD = 0 SERVO_PERIOD = 1000000 [HAL] -HALUI = halui HALFILE = mod_core_sim.hal POSTGUI_HALFILE = postgui.hal diff --git a/tests/trajectory-planner/circular-arcs/configs/9axis.ini b/tests/trajectory-planner/circular-arcs/configs/9axis.ini index 13aa2b2fcd6..c3d93cb363f 100644 --- a/tests/trajectory-planner/circular-arcs/configs/9axis.ini +++ b/tests/trajectory-planner/circular-arcs/configs/9axis.ini @@ -104,8 +104,6 @@ HALFILE = constraint_check_9axis.tcl # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui_9axis.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XY.ini b/tests/trajectory-planner/circular-arcs/configs/XY.ini index bd8095ee093..b0b89ef41df 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XY.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XY.ini @@ -112,8 +112,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XYZ.ini b/tests/trajectory-planner/circular-arcs/configs/XYZ.ini index 9af90c0fc52..06ae2217483 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XYZ.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XYZ.ini @@ -111,8 +111,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XYZ_fast.ini b/tests/trajectory-planner/circular-arcs/configs/XYZ_fast.ini index 6927d4f0381..c65bae120fd 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XYZ_fast.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XYZ_fast.ini @@ -111,8 +111,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XYZ_medium.ini b/tests/trajectory-planner/circular-arcs/configs/XYZ_medium.ini index 6996743b6c7..072755a022b 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XYZ_medium.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XYZ_medium.ini @@ -112,8 +112,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XYZ_nospindle.ini b/tests/trajectory-planner/circular-arcs/configs/XYZ_nospindle.ini index fb102d8b355..59728db01bd 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XYZ_nospindle.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XYZ_nospindle.ini @@ -97,8 +97,6 @@ HALFILE = test_status.tcl # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XYZ_uneven.ini b/tests/trajectory-planner/circular-arcs/configs/XYZ_uneven.ini index 9969e362ffd..0b2e550e3cd 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XYZ_uneven.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XYZ_uneven.ini @@ -111,8 +111,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XY_slowZ.ini b/tests/trajectory-planner/circular-arcs/configs/XY_slowZ.ini index 7970522cceb..6e3beb171a8 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XY_slowZ.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XY_slowZ.ini @@ -111,8 +111,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/XZ.ini b/tests/trajectory-planner/circular-arcs/configs/XZ.ini index 376a5f786f1..866a1245b20 100644 --- a/tests/trajectory-planner/circular-arcs/configs/XZ.ini +++ b/tests/trajectory-planner/circular-arcs/configs/XZ.ini @@ -112,8 +112,6 @@ HALFILE = sim_spindle_encoder.hal # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] diff --git a/tests/trajectory-planner/circular-arcs/configs/axis_mm.ini b/tests/trajectory-planner/circular-arcs/configs/axis_mm.ini index a87b6f8f398..7c8d8f6a644 100644 --- a/tests/trajectory-planner/circular-arcs/configs/axis_mm.ini +++ b/tests/trajectory-planner/circular-arcs/configs/axis_mm.ini @@ -107,8 +107,6 @@ HALFILE = test_status.tcl # AXIS at this time (only AXIS creates a HAL component of its own) POSTGUI_HALFILE = postgui.hal -HALUI = halui - # Trajectory planner section -------------------------------------------------- [TRAJ] From 99b51400e2d265b418eb257f49a0c6bd063bad03 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sun, 20 Sep 2026 17:41:22 +0200 Subject: [PATCH 04/12] move halui to task --- debian/linuxcnc.install.in | 1 - docs/src/config/ini-config.adoc | 2 - docs/src/config/moveoff.adoc | 5 +- docs/src/gui/halui.adoc | 21 +- docs/src/hal/basic-hal.adoc | 2 +- docs/src/hal/halui-examples.adoc | 7 +- docs/src/hal/twopass.adoc | 1 - docs/src/man/man1/halui.1.adoc | 27 +- docs/src/man/man1/moveoff_gui.1.adoc | 7 - docs/src/plasma/qtplasmac.adoc | 1 - scripts/linuxcnc.in | 15 - src/emc/task/Submakefile | 2 + src/emc/task/cmd_queue.cc | 109 +++++ src/emc/task/cmd_queue.hh | 74 ++++ src/emc/task/emctaskmain.cc | 40 ++ src/emc/{usr_intf => task}/halui.cc | 560 ++++++++++--------------- src/emc/task/halui.hh | 30 ++ src/emc/usr_intf/Submakefile | 10 +- src/emc/usr_intf/pncconf/build_INI.py | 1 - src/emc/usr_intf/stepconf/build_INI.py | 2 - 20 files changed, 493 insertions(+), 424 deletions(-) create mode 100644 src/emc/task/cmd_queue.cc create mode 100644 src/emc/task/cmd_queue.hh rename src/emc/{usr_intf => task}/halui.cc (89%) create mode 100644 src/emc/task/halui.hh diff --git a/debian/linuxcnc.install.in b/debian/linuxcnc.install.in index d66045b43a5..80b405ddf5d 100644 --- a/debian/linuxcnc.install.in +++ b/debian/linuxcnc.install.in @@ -28,7 +28,6 @@ usr/bin/halscope usr/bin/halshow usr/bin/halstreamer usr/bin/haltcl -usr/bin/halui usr/bin/hbmgui usr/bin/hexagui usr/bin/hy_gt_vfd diff --git a/docs/src/config/ini-config.adoc b/docs/src/config/ini-config.adoc index 4980de30b1d..c019009d7de 100644 --- a/docs/src/config/ini-config.adoc +++ b/docs/src/config/ini-config.adoc @@ -778,8 +778,6 @@ For more information see the <> chapter. Some GUIs create HAL pins and support the use of a postgui halfile to use them. GUIs that support postgui HAL files include Touchy, AXIS, Gscreen, and GMOCCAPY. + See section <> for more information. -* `HALUI = halui` - adds the HAL user interface pins. + - For more information see the <> chapter. [[sub:ini:sec:halui]] === [HALUI] section(((INI File,Sections,[HALUI] Section))) diff --git a/docs/src/config/moveoff.adoc b/docs/src/config/moveoff.adoc index 81e1bb7d605..ed57ccc3079 100644 --- a/docs/src/config/moveoff.adoc +++ b/docs/src/config/moveoff.adoc @@ -114,8 +114,7 @@ to the corresponding joint. Modify an existing configuration as follows: -Make sure there is an INI file entry for `[HAL]HALUI` and create a new -`[HAL]HALFILE` entry for LIB:hookup_moveoff.tcl. +Create a new `[HAL]HALFILE` entry for LIB:hookup_moveoff.tcl. The entry for LIB:hookup_moveoff.tcl should follow all `HALFILE=` entries for HAL files that connect the pins for `joint.N.motor-pos-cmd`, `joint.N.motor-pos-fb`, and any components connected to these pins @@ -124,7 +123,6 @@ for HAL files that connect the pins for `joint.N.motor-pos-cmd`, [source,ini] ---- [HAL] -HALUI = halui HALFILE = existing_configuration_halfile_1 # ... HALFILE = existing_configuration_halfile_n @@ -216,7 +214,6 @@ and mv.bactrack-enable pins to signals: [source,ini] ---- [HAL] -HALUI = halui # ... HALFILE = LIB:hookup_moveoff.tcl HALFILE = LIB:moveoff_external.hal diff --git a/docs/src/gui/halui.adoc b/docs/src/gui/halui.adoc index e9c87f8c1ae..d7f501298a8 100644 --- a/docs/src/gui/halui.adoc +++ b/docs/src/gui/halui.adoc @@ -9,25 +9,12 @@ == Introduction Halui is a HAL based user interface for LinuxCNC, it connects HAL pins to -NML commands. Most of the functionality (buttons, indicators etc.) that +machine commands. Most of the functionality (buttons, indicators etc.) that is provided by a traditional GUI (AXIS, GMOCCAPY, QtDragon, etc.), is provided by HAL pins in Halui. -The easiest way to add halui is to add the following to the [HAL] -section of the INI file: - -[source,ini] ----- -[HAL] -HALUI = halui ----- - -An alternate way to invoke it (specially if you generate the configuration with StepConf) is to include the following in your `custom.hal` file. + -Make sure you use the correct path to your INI file. - -[source,hal] ----- -loadusr halui -ini /path/to/inifile.ini ----- +There is nothing to set up: the pins exist in every configuration, created +by the task controller before the HAL files are read, so a HAL file can +connect them straight away. Pins nobody connects cost nothing. == MDI diff --git a/docs/src/hal/basic-hal.adoc b/docs/src/hal/basic-hal.adoc index 0c800c56c9a..73166bd7c55 100644 --- a/docs/src/hal/basic-hal.adoc +++ b/docs/src/hal/basic-hal.adoc @@ -137,7 +137,7 @@ Flags may be one or more of the following: [source,hal] ---- loadusr -loadusr halui +loadusr hal_input loadusr -Wn spindle gs2_vfd -n spindle ---- diff --git a/docs/src/hal/halui-examples.adoc b/docs/src/hal/halui-examples.adoc index 2f237cc14cb..f0f7daab4ad 100644 --- a/docs/src/hal/halui-examples.adoc +++ b/docs/src/hal/halui-examples.adoc @@ -5,12 +5,7 @@ = Halui Examples (((Halui Examples))) -For any Halui examples to work you need to add the following line to the [HAL] section of the INI file. - -[source,ini] ----- -HALUI = halui ----- +The Halui pins are always available, so these examples work as they stand. [[sec:halui-remote-start]] == Remote Start diff --git a/docs/src/hal/twopass.adoc b/docs/src/hal/twopass.adoc index 7fdc48fae2c..fd50a15d5da 100644 --- a/docs/src/hal/twopass.adoc +++ b/docs/src/hal/twopass.adoc @@ -120,7 +120,6 @@ HALFILE = simulated_home.hal HALFILE = load_for_postgui.hal <- loadrt lines for components in postgui.hal POSTGUI_HALFILE = postgui.hal -HALUI = halui ---- == Post GUI diff --git a/docs/src/man/man1/halui.1.adoc b/docs/src/man/man1/halui.1.adoc index 861abcd04c0..d4244078d71 100644 --- a/docs/src/man/man1/halui.1.adoc +++ b/docs/src/man/man1/halui.1.adoc @@ -2,29 +2,24 @@ == NAME -halui - observe HAL pins and command LinuxCNC through NML - -== SYNOPSIS - -*halui* [*-ini* __] +halui - HAL pins to observe and command LinuxCNC == DESCRIPTION -The program *halui* is used to build a User Interface using hardware knobs and switches. -It exports a big number of pins, and acts accordingly when these change. - -== OPTIONS +*halui* is used to build a User Interface using hardware knobs and switches. +It provides a large number of HAL pins, and acts accordingly when these +change. -*-ini* _filename_:: - Use the _filename_ as the configuration file. Note: halui must find - the nml file specified in the INI, usually that file is in the same - folder as the INI, so it makes sense to run halui from that folder. +The pins are part of the LinuxCNC task controller and exist in every +configuration. There is nothing to load and nothing to configure: connect +the pins you want in a HAL file. Earlier versions ran halui as a separate +program, selected with *[HAL]HALUI* in the INI file; that setting is no +longer read. == USAGE -When run, *halui* will export a large number of pins. A user can connect -those to his physical knobs & switches & leds, and when a change is -noticed halui triggers an appropriate event. +A user can connect the pins to his physical knobs & switches & leds, and +when a change is noticed halui triggers an appropriate event. Caveat, *halui* expects the signals to be debounced, so if needed (bad knob contact) connect the physical button to a HAL debounce filter first. diff --git a/docs/src/man/man1/moveoff_gui.1.adoc b/docs/src/man/man1/moveoff_gui.1.adoc index 042b2aead0f..dd82617a6b9 100644 --- a/docs/src/man/man1/moveoff_gui.1.adoc +++ b/docs/src/man/man1/moveoff_gui.1.adoc @@ -73,12 +73,6 @@ These options are available for special cases: LinuxCNC must be running. -Halui must be loaded, typical INI file setting: ----- -[HAL] -HALUI = halui ----- - The moveoff component must be loaded with the name 'mv' as: + **loadrt moveoff names=**_mv **personality=**_number_of_axes_ @@ -107,7 +101,6 @@ HALFILE *hookup_moveoff.tcl* as illustrated below: ---- [HAL] -HALUI = halui HALFILE = user_halfile_1 etc ... HALFILE = user_halfile_n diff --git a/docs/src/plasma/qtplasmac.adoc b/docs/src/plasma/qtplasmac.adoc index bc68a12556c..7a852b00098 100644 --- a/docs/src/plasma/qtplasmac.adoc +++ b/docs/src/plasma/qtplasmac.adoc @@ -570,7 +570,6 @@ These variables are mandatory. [source,ini] ---- -HALUI = halui (required) HALFILE = __.hal (the machine HAL file) HALFILE = plasmac.tcl (the standard QtPlasmaC HAL file) HALFILE = custom.hal (Users custom HAL commands) diff --git a/scripts/linuxcnc.in b/scripts/linuxcnc.in index 3ab645da498..05e028f0d52 100644 --- a/scripts/linuxcnc.in +++ b/scripts/linuxcnc.in @@ -528,10 +528,6 @@ if [ "$EMCTASK" = emctask ]; then EMCTASK=linuxcnctask; fi # so it needs to start by default, as the first process EMCSERVER=linuxcncsvr -# 2.7. get halui information -GetFromIniQuiet HALUI HAL -HALUI=$retval - # 2.7.1 get halbridge info from INI GetFromIniQuiet HALBRIDGE HAL HALBRIDGE=$retval @@ -830,17 +826,6 @@ fi halcmd loadusr -Wn inihal "$EMCTASK" -ini "$INIFILE" -# 4.3.5. Run halui in background, if necessary -if [ -n "$HALUI" ] ; then - echo "Starting HAL User Interface program: $HALUI" >> "$PRINT_FILE" - if ! program_available "$HALUI" ; then - echo "Can't execute halui program $HALUI" - Cleanup - exit 1 - fi - $HALCMD loadusr -Wn halui "$HALUI" -ini "$INIFILE" -fi - # run hal bridge program IF requested if [ -n "$HALBRIDGE" ] ; then echo "Starting HAL User Interface program: $HALBRIDGE" >> "$PRINT_FILE" diff --git a/src/emc/task/Submakefile b/src/emc/task/Submakefile index 9fdab7004d6..3892cdeb7eb 100644 --- a/src/emc/task/Submakefile +++ b/src/emc/task/Submakefile @@ -23,6 +23,8 @@ MILLTASKSRCS := \ emc/motion/stashf.c \ emc/task/taskclass.cc \ emc/task/backtrace.cc \ + emc/task/cmd_queue.cc \ + emc/task/halui.cc \ emc/usr_intf/mapini.cc USERSRCS += $(MILLTASKSRCS) diff --git a/src/emc/task/cmd_queue.cc b/src/emc/task/cmd_queue.cc new file mode 100644 index 00000000000..2ba477d4c1a --- /dev/null +++ b/src/emc/task/cmd_queue.cc @@ -0,0 +1,109 @@ +/******************************************************************** +* Description: cmd_queue.cc +* Command injection point for task-internal command producers. +* See cmd_queue.hh for what it is for. +* +* License: GPL Version 2 +********************************************************************/ + +#include "cmd_queue.hh" + +#include "nml_intf/emc.hh" +#include "nml_intf/emc_nml.hh" + +#include +#include +#include +#include + +namespace { + +struct Entry { + std::vector data; /* the message, byte for byte */ + taskcmd::Ticket ticket = 0; + unsigned long key = 0; /* 0: never superseded */ +}; + +std::mutex g_mu; /* guards everything below */ +std::deque g_queue; +Entry g_current; /* keeps the popped message alive */ +taskcmd::Ticket g_next_ticket = 1; + +/* A backlog this long means the producer is far ahead of task and the + commands are stale anyway; dropping is better than growing without + bound. Jogs coalesce, so reaching this takes a genuine flood. */ +const size_t MAX_QUEUED = 64; + +} // namespace + +taskcmd::Ticket taskcmd::pushRaw(const void *cmd, size_t size, + unsigned long coalesce_key) +{ + if (cmd == NULL || size == 0 || size > MAX_CMD_SIZE) { + return 0; + } + + std::lock_guard lk(g_mu); + + const Ticket ticket = g_next_ticket++; + + if (coalesce_key != 0) { + for (Entry &e : g_queue) { + if (e.key != coalesce_key) { + continue; + } + /* Supersede in place: the newer command takes the older one's + turn, so ordering against other commands is unchanged. */ + e.data.assign(static_cast(cmd), + static_cast(cmd) + size); + e.ticket = ticket; + return ticket; + } + } + + if (g_queue.size() >= MAX_QUEUED) { + return 0; + } + + Entry e; + e.data.assign(static_cast(cmd), + static_cast(cmd) + size); + e.ticket = ticket; + e.key = coalesce_key; + g_queue.push_back(std::move(e)); + + return ticket; +} + +bool taskcmd::pending(Ticket ticket) +{ + if (ticket == 0) { + return false; + } + + std::lock_guard lk(g_mu); + for (const Entry &e : g_queue) { + if (e.ticket == ticket) { + return true; + } + } + return false; +} + +RCS_CMD_MSG *taskcmd::next(int echo_serial_number) +{ + std::lock_guard lk(g_mu); + + if (g_queue.empty()) { + return NULL; + } + + g_current = std::move(g_queue.front()); + g_queue.pop_front(); + + /* Task treats a command as new when its serial differs from the one it + last echoed, so hand it the next serial along. */ + RCS_CMD_MSG *msg = reinterpret_cast(g_current.data.data()); + msg->serial_number = echo_serial_number + 1; + return msg; +} diff --git a/src/emc/task/cmd_queue.hh b/src/emc/task/cmd_queue.hh new file mode 100644 index 00000000000..6e490d0dea4 --- /dev/null +++ b/src/emc/task/cmd_queue.hh @@ -0,0 +1,74 @@ +/******************************************************************** +* Description: cmd_queue.hh +* Command injection point for everything inside task that issues NML +* commands without going through the NML command channel. +* +* Task executes one command per cycle, taken either from the NML command +* buffer or from this queue. A command placed here is therefore judged by +* emcTaskPlan() exactly like one that arrived over NML: same mode and +* state gating, same serial-number echo, same error reporting. +* +* Two producers use it: +* - ws_server.cc, from the websocket server thread +* - halui.cc, from the task thread +* +* License: GPL Version 2 +********************************************************************/ +#ifndef TASK_CMD_QUEUE_HH +#define TASK_CMD_QUEUE_HH + +#include + +class RCS_CMD_MSG; + +namespace taskcmd { + +/* Biggest NML command that can be queued. EMC_TASK_PLAN_OPEN is the large + one (a LINELEN path plus a 4k remote transfer buffer). */ +const size_t MAX_CMD_SIZE = 8192; + +/* Identifies one queued command, so a producer can tell whether task has + taken it yet. Zero is never a valid ticket: push() returns 0 when the + queue is full, and pending(0) is false. */ +typedef unsigned long Ticket; + +/* Queue a copy of a command message. Thread safe. + + coalesce_key, when non-zero, means "this command supersedes any command + still queued under the same key": the pending one is overwritten in + place, keeping its position in the queue. It is for commands that carry + a state rather than an action -- a continuous jog is the case that + matters, where a producer running faster than task drains the queue + would otherwise build a backlog of stale velocities. Never use it for a + command that must happen exactly once, such as an incremental jog. + + The superseded command's ticket stops being pending without ever having + been executed, so a producer that watches a ticket must pass key 0. */ +Ticket pushRaw(const void *cmd, size_t size, unsigned long coalesce_key); + +template +Ticket push(const T &cmd, unsigned long coalesce_key = 0) +{ + static_assert(sizeof(T) <= MAX_CMD_SIZE, "NML command too large to queue"); + return pushRaw(&cmd, sizeof(T), coalesce_key); +} + +/* True while the command is still waiting. False once task has taken it -- + which, for a caller running in the task loop after the status update, + means the command has been issued and the status reflects it. */ +bool pending(Ticket ticket); + +/* Pop the next command, or NULL if none is waiting. Task loop only. + + The returned message stays valid until the next call and is meant to be + consumed exactly like one freshly read from NML. echo_serial_number is + the serial task last echoed; the message gets echo_serial_number + 1 so + that task's "is this a new command?" test fires. Task puts the serial + back afterwards without echoing it: an NML serial is the command + buffer's write id, and echoing one of those here would make task drop + the next command an NML client writes. */ +RCS_CMD_MSG *next(int echo_serial_number); + +} // namespace taskcmd + +#endif /* TASK_CMD_QUEUE_HH */ diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index 96fa4951eab..559c53293c5 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -86,6 +86,8 @@ fpu_control_t __fpu_control = _FPU_IEEE & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_M #include "taskclass.hh" #include "motion/motion.h" // EMCMOT_ORIENT_* #include "ini/inihal.hh" +#include "halui.hh" // the HAL user interface, in task +#include "cmd_queue.hh" // commands from ws_server and halui using namespace linuxcnc; using namespace std::chrono_literals; @@ -108,6 +110,9 @@ static RCS_CMD_MSG *emcCommand = NULL; // global EMC status EMC_STAT *emcStatus = NULL; +// set while emcCommand points at a command from inside task (the websocket +// server or halui) rather than at the NML command buffer +static bool emcCommandInternal = false; // timer stuff static linuxcnc::CyclicTimer *timer = NULL; @@ -3352,6 +3357,9 @@ static int emctask_shutdown(void) delete timer; timer = NULL; } + // release the halui HAL component + haluiExit(); + // delete the NML channels if (NULL != emcErrorBuffer) { @@ -3523,6 +3531,15 @@ int main(int argc, char *argv[]) exit(1); } + // Create the halui pins before emctask_startup() readies the inihal + // component: halcmd is waiting on that and runs the HAL files next, + // and those may connect halui pins. + if (0 != haluiInit(emc_inifile)) { + log_error("can't initialize halui\n"); + emctask_shutdown(); + exit(1); + } + // initialize everything if (0 != emctask_startup()) { emctask_shutdown(); @@ -3560,6 +3577,17 @@ int main(int argc, char *argv[]) // read command if (0 != emcCommandBuffer->read()) { // got a new command, so clear out errors + emcCommand = emcCommandBuffer->get_address(); + emcCommandInternal = false; + taskPlanError = 0; + taskExecuteError = 0; + } else if (RCS_CMD_MSG *queued = + taskcmd::next(emcStatus->echo_serial_number)) { + // A command came from inside task -- the websocket server or + // halui. Point emcCommand at it and the rest of the loop treats + // it exactly like one read from NML. + emcCommand = queued; + emcCommandInternal = true; taskPlanError = 0; taskExecuteError = 0; } @@ -3703,6 +3731,16 @@ int main(int argc, char *argv[]) // handle RCS_STAT_MSG base class members explicitly, since this // is not an NML_MODULE and they won't be set automatically + // A command from inside task must not consume a serial number. An + // NML serial is the command buffer's write id, so echoing "one past + // the last NML command" is echoing the id the next NML client write + // will get, and task would then drop that command as one it has + // already seen. Leave the echo where the last NML command put it, + // and mark the internal message as seen so that emcTaskPlan() does + // not dispatch it again next cycle. + if (emcCommandInternal) { + emcCommand->serial_number = emcStatus->echo_serial_number; + } else { // do task emcStatus->task.command_type = emcCommand->_type; emcStatus->task.echo_serial_number = emcCommand->serial_number; @@ -3710,6 +3748,7 @@ int main(int argc, char *argv[]) // do top level emcStatus->command_type = emcCommand->_type; emcStatus->echo_serial_number = emcCommand->serial_number; + } if (taskPlanError || taskExecuteError || emcStatus->task.execState == EMC_TASK_EXEC::ERROR || @@ -3737,6 +3776,7 @@ int main(int argc, char *argv[]) // will be updated in the _update() functions above. There's // no need to call the individual functions on all WM items. emcStatusBuffer->write(emcStatus); + haluiUpdate(); // wait on timer cycle, if specified, or calculate actual // interval if INI file says to run full out via diff --git a/src/emc/usr_intf/halui.cc b/src/emc/task/halui.cc similarity index 89% rename from src/emc/usr_intf/halui.cc rename to src/emc/task/halui.cc index c40e2831e73..cfbf16166ee 100644 --- a/src/emc/usr_intf/halui.cc +++ b/src/emc/task/halui.cc @@ -1,19 +1,38 @@ /******************************************************************** -* Description: halui.cc -* HAL User-Interface component. -* This file exports various UI related hal pins, and communicates -* with EMC through NML messages +* Description: halui.cc (task) +* The HAL user interface, running inside task. * -* Derived from a work by Fred Proctor & Will Shackleford (emcsh.cc) -* some of the functions (sendFooBar() are adapted from there) +* This was the standalone halui program (src/emc/usr_intf/halui.cc, now +* deleted) with its NML transport taken out. The pin table, the edge +* detection in check_hal_changes() and the status mirroring in +* modify_hal_pins() are the same code, so that behaviour -- including the +* quirks the tests in tests/halui pin down -- is unchanged. * -* Author: Alex Joni -* License: GPL Version 2 -* System: Linux +* What is different, and why: +* +* - No NML. Commands go into the task-internal queue (cmd_queue.hh), so +* they pass through emcTaskPlan() exactly like a command from a UI. +* Nothing waits for an echo: inside task, waiting for task to answer +* is a deadlock, since it is this thread that would have to answer. +* +* - MDI commands become a state machine, see sendMdiCommand() below. +* +* - Status is read straight out of the live EMC_STAT. halui sees it after +* task has finished the cycle's status update, which is the same +* picture an NML client gets, one cycle earlier. +* +* - The pin scan still runs at 20 ms, the standalone halui's loop period. +* The task cycle is typically 1 ms, and jog pins send a command per +* change, so running the whole scan every cycle would put up to a +* thousand commands a second through task's single command slot. +* estop-activate, machine-off, abort and program-stop are checked every +* cycle regardless. * -* Copyright (c) 2006 All rights reserved. +* halui is always there: there is nothing to switch on, and a machine +* that connects none of the pins pays for a pin scan every 20 ms. * -* Last change: +* Derived from the standalone halui.cc by Alex Joni, which this replaces. +* License: GPL Version 2 ********************************************************************/ #include "logutil.hh" @@ -22,9 +41,10 @@ #include #include #include -#include #include +#include + #include /* access to HAL functions/definitions */ #include /* rtapi_print_msg */ #include "rcs_status.hh" @@ -34,15 +54,16 @@ #include "nml_intf/emcglb.h" // EMC_NMLFILE, TRAJ_MAX_VELOCITY, etc. #include "nml_intf/emccfg.h" // DEFAULT_TRAJ_MAX_VELOCITY #include -#include "libnml/nml/nml_oi.hh" #include "timeutil.hh" #include #include "tooldata/tooldata.hh" -#include "mapini.hh" -#include "unitenum.hh" +#include "usr_intf/mapini.hh" +#include "usr_intf/unitenum.hh" + +#include "halui.hh" +#include "cmd_queue.hh" using namespace linuxcnc; -using namespace std::chrono_literals; /* Using halui: see the man page */ @@ -236,7 +257,7 @@ static char *mdi_commands[MDI_MAX]; static int num_mdi_commands=0; static int have_home_all = 0; -static int comp_id, done; /* component ID, main while loop */ +static int comp_id = -1; /* HAL component ID */ static int num_axes = 0; //number of axes, taken from the INI [TRAJ] section static int num_joints = 3; //number of joints, taken from the INI [KINS] section @@ -249,220 +270,38 @@ static double maxSpindleOverride=1.0; static EMC_TASK_MODE halui_old_mode = EMC_TASK_MODE::MANUAL; static int halui_sent_mdi = 0; -// the NML channels to the EMC task -static RCS_CMD_CHANNEL *emcCommandBuffer = NULL; -static RCS_STAT_CHANNEL *emcStatusBuffer = NULL; -EMC_STAT *emcStatus = NULL; - -// the NML channel for errors -static NML *emcErrorBuffer = NULL; - -// the serial number to use. -static int emcCommandSerialNumber = 0; - -// how long to wait for Task to report that it has received our command -static double receiveTimeout = 10.0; - -// how long to wait for Task to finish running our command -static double doneTimeout = 60.; - -static void quit(int /*sig*/) -{ - done = 1; -} - -static int emcTaskNmlGet() -{ - int retval = 0; - - // try to connect to EMC cmd - if (emcCommandBuffer == NULL) { - emcCommandBuffer = - new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "xemc", - emc_nmlfile); - if (!emcCommandBuffer->valid()) { - delete emcCommandBuffer; - emcCommandBuffer = NULL; - retval = -1; - } - } - // try to connect to EMC status - if (emcStatusBuffer == NULL) { - emcStatusBuffer = - new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "xemc", - emc_nmlfile); - if (!emcStatusBuffer->valid()) { - delete emcStatusBuffer; - emcStatusBuffer = NULL; - emcStatus = NULL; - retval = -1; - } else { - emcStatus = reinterpret_cast(emcStatusBuffer->get_address()); - } - } - - return retval; -} - -static int emcErrorNmlGet() -{ - int retval = 0; - - if (emcErrorBuffer == NULL) { - emcErrorBuffer = - new NML(nmlErrorFormat, "emcError", "xemc", emc_nmlfile); - if (!emcErrorBuffer->valid()) { - delete emcErrorBuffer; - emcErrorBuffer = NULL; - retval = -1; - } - } - - return retval; -} - -static int tryNml() -{ - std::chrono::seconds end; - int good; -constexpr auto RETRY_TIME = 10s; // wait for subsystems to come up -constexpr auto RETRY_INTERVAL = 1s; // between wait tries for a subsystem - - end = RETRY_TIME; - good = 0; - do { - if (0 == emcTaskNmlGet()) { - good = 1; - break; - } - esleep(RETRY_INTERVAL); - end -= RETRY_INTERVAL; - } while (end > 0s); - - if (!good) { - return -1; - } - end = RETRY_TIME; - good = 0; - do { - if (0 == emcErrorNmlGet()) { - good = 1; - break; - } - esleep(RETRY_INTERVAL); - end -= RETRY_INTERVAL; - } while (end > 0s); +// How often the pin scan runs, the standalone halui's loop period. +static const double HALUI_PERIOD = 0.020; - if (!good) { - return -1; - } - - return 0; +static double last_pass = 0.0; -} +// MDI state machine, see sendMdiCommand() +static std::deque mdi_pending; +static taskcmd::Ticket mdi_mode_ticket = 0; +static taskcmd::Ticket mdi_exec_ticket = 0; -static int updateStatus() +// Queue a command for task to execute on one of the next cycles. This is +// where the standalone halui wrote to the NML command channel and then +// waited for task to echo the serial number back. +// +// coalesce_key is passed for jogs only: see cmd_queue.hh. Returns 0 like +// the NML send it replaces, -1 if the queue is full. +template +static int emcCommandSend(const T &cmd, unsigned long coalesce_key = 0) { - NMLTYPE type; - - if (NULL == emcStatus || NULL == emcStatusBuffer) { - rtapi_print("halui: %s: no status buffer\n", __func__); + if (taskcmd::push(cmd, coalesce_key) == 0) { + rtapi_print("halui: %s: command queue full, dropping a command\n", __func__); return -1; } - - if (!emcStatusBuffer->valid()) { - rtapi_print("halui: %s: status buffer is not valid\n", __func__); - return -1; - } - - switch (type = emcStatusBuffer->peek()) { - case -1: - // error on CMS channel - rtapi_print("halui: %s: error peeking status buffer\n", __func__); - return -1; - break; - - case 0: // no new data - case EMC_STAT_TYPE: // new data - break; - - default: - rtapi_print("halui: %s: unknown error peeking status buffer\n", __func__); - return -1; - break; - } - return 0; } - -constexpr auto EMC_COMMAND_DELAY = 100ms; // how long to sleep between checks - -static int emcCommandWaitDone() -{ - for (auto end = 0ms; end < std::chrono::duration(doneTimeout); - end += EMC_COMMAND_DELAY) { - updateStatus(); - int serial_diff = emcStatus->echo_serial_number - emcCommandSerialNumber; - - if (serial_diff < 0) { - continue; - } - - if (serial_diff > 0) { - return 0; - } - - if (emcStatus->status == RCS_STATUS::DONE) { - return 0; - } - - if (emcStatus->status == RCS_STATUS::ERROR) { - return -1; - } - - esleep(EMC_COMMAND_DELAY); - } - - return -1; -} - -static int emcCommandSend(RCS_CMD_MSG & cmd) -{ - // write command - if (emcCommandBuffer->write(&cmd)) { - rtapi_print("halui: %s: error writing to Task\n", __func__); - return -1; - } - emcCommandSerialNumber = cmd.serial_number; - - // wait for receive - for (auto end = 0ms; end < std::chrono::duration(receiveTimeout); - end += EMC_COMMAND_DELAY) { - updateStatus(); - int serial_diff = emcStatus->echo_serial_number - emcCommandSerialNumber; - - if (serial_diff >= 0) { - return 0; - } - - esleep(EMC_COMMAND_DELAY); - } - - rtapi_print("halui: %s: no echo from Task after %.3f seconds\n", __func__, receiveTimeout); - return -1; -} - -static void thisQuit() +// One key per jog target, so that a new jog for a joint or axis replaces +// the one still waiting for it rather than queueing behind it. +static unsigned long jog_key(int ja, int jjogmode) { - //don't forget the big HAL sin ;) - hal_exit(comp_id); - - if(emcCommandBuffer) { delete emcCommandBuffer; emcCommandBuffer = NULL; } - if(emcStatusBuffer) { delete emcStatusBuffer; emcStatusBuffer = NULL; } - if(emcErrorBuffer) { delete emcErrorBuffer; emcErrorBuffer = NULL; } - exit(0); + return 1 + (unsigned long)(jjogmode ? 1 : 0) * 1024 + (unsigned long)ja; } static LINEAR_UNIT_CONVERSION linearUnitConversion = LINEAR_UNITS_AUTO; @@ -831,61 +670,95 @@ static int sendMdi() return emcCommandSend(mode_msg); } -static int sendMdiCommand(int n) +// Start an [HALUI]MDI_COMMAND. The standalone halui could block here: it +// sent the switch to MDI, waited for task to echo it, checked the mode and +// only then sent the command itself. Inside task nothing may block, so the +// sequence becomes a state machine, driven by service_mdi() below: +// +// press -> queue SET_MODE(MDI) -> task reaches MDI -> queue EXECUTE +// +// What the pins do is unchanged, including the two known quirks the tests +// pin down: halui-mdi-is-running goes true at the press, before task has +// accepted anything, and a command task refuses leaves it stuck until the +// next command finishes DONE. +static void sendMdiCommand(int n) { - EMC_TASK_PLAN_EXECUTE emc_task_plan_execute_msg; - - if (updateStatus()) { - return -1; - } - if (!halui_sent_mdi) { // There is currently no MDI command from halui executing, we're // currently starting the first one. Record what the Task mode is, // so we can restore it when all the MDI commands finish. halui_old_mode = emcStatus->task.mode; } - + halui_sent_mdi = 1; - if (num_mdi_commands>0){ - hal_set_bool(halui_data->halui_mdi_is_running, halui_sent_mdi); - updateStatus(); + if (num_mdi_commands > 0) { + hal_set_bool(halui_data->halui_mdi_is_running, halui_sent_mdi); } - + + mdi_pending.push_back(n); + // switch to MDI mode if needed - if (emcStatus->task.mode != EMC_TASK_MODE::MDI) { - if (sendMdi() != 0) { - rtapi_print("halui: %s: failed to Set Mode MDI\n", __func__); - return -1; - } - if (updateStatus() != 0) { - rtapi_print("halui: %s: failed to update status\n", __func__); - return -1; - } - if (emcStatus->task.mode != EMC_TASK_MODE::MDI) { - rtapi_print("halui: %s: switched mode, but got %d instead of mdi\n", __func__, (int)emcStatus->task.mode); - return -1; - } + if (emcStatus->task.mode != EMC_TASK_MODE::MDI && mdi_mode_ticket == 0) { + EMC_TASK_SET_MODE mode_msg; + mode_msg.mode = EMC_TASK_MODE::MDI; + mdi_mode_ticket = taskcmd::push(mode_msg); } - rtapi_strxcpy(emc_task_plan_execute_msg.command, mdi_commands[n]); - if (emcCommandSend(emc_task_plan_execute_msg)) { - rtapi_print("halui: %s: failed to send mdi command %d\n", __func__, n); - return -1; +} + +// Issue the MDI commands waiting for task to be in MDI mode, or give up on +// them if task did not go there. Runs every task cycle. +static void service_mdi() +{ + if (mdi_pending.empty()) { + return; } - return 0; + if (emcStatus->task.mode == EMC_TASK_MODE::MDI) { + mdi_mode_ticket = 0; + while (!mdi_pending.empty()) { + EMC_TASK_PLAN_EXECUTE emc_task_plan_execute_msg; + rtapi_strxcpy(emc_task_plan_execute_msg.command, + mdi_commands[mdi_pending.front()]); + mdi_exec_ticket = taskcmd::push(emc_task_plan_execute_msg); + mdi_pending.pop_front(); + } + return; + } + + if (!taskcmd::pending(mdi_mode_ticket)) { + // Task has been through the mode change and is not in MDI, so it + // refused it -- while a program runs, for instance. Drop the + // commands, exactly as the standalone halui did when its mode + // check failed. halui_sent_mdi deliberately stays set: the pins + // recover on the next command that ends DONE. + rtapi_print("halui: %s: could not switch task to mdi, dropping %d command(s)\n", + __func__, (int)mdi_pending.size()); + mdi_pending.clear(); + mdi_mode_ticket = 0; + } } +// True once the MDI command halui started has actually been issued by task +// (not merely queued), which is what the standalone halui knew by waiting +// for the echo before it returned from sendMdiCommand(). +static bool mdi_settled() +{ + return halui_sent_mdi + && mdi_pending.empty() + && !taskcmd::pending(mdi_mode_ticket) + && !taskcmd::pending(mdi_exec_ticket); +} + +// The standalone halui waited here for task to finish the mode change, +// up to 60 seconds. Inside task that wait is the deadlock it sounds like: +// task cannot finish anything while halui holds the loop. static int sendTeleop() { EMC_TRAJ_SET_TELEOP_ENABLE emc_set_teleop_enable_msg; emc_set_teleop_enable_msg.enable = 1; - if (emcCommandSend(emc_set_teleop_enable_msg)) { - return -1; - } - return emcCommandWaitDone(); + return emcCommandSend(emc_set_teleop_enable_msg); } static int sendJoint() @@ -893,10 +766,7 @@ static int sendJoint() EMC_TRAJ_SET_TELEOP_ENABLE emc_set_teleop_enable_msg; emc_set_teleop_enable_msg.enable = 0; - if (emcCommandSend(emc_set_teleop_enable_msg)) { - return -1; - } - return emcCommandWaitDone(); + return emcCommandSend(emc_set_teleop_enable_msg); } static int sendMistOn() @@ -935,8 +805,6 @@ static int sendProgramRun(int line) { EMC_TASK_PLAN_RUN emc_task_plan_run_msg; - updateStatus(); - if (0 == emcStatus->task.file[0]) { return -1; // no program open } @@ -1093,7 +961,7 @@ static void sendJogStop(int ja, int jjogmode) emc_jog_stop_msg.jjogmode = jjogmode; emc_jog_stop_msg.joint_or_axis = ja; - emcCommandSend(emc_jog_stop_msg); + emcCommandSend(emc_jog_stop_msg, jog_key(ja, jjogmode)); } @@ -1116,7 +984,7 @@ static void sendJogCont(int ja, double speed, int jjogmode) emc_jog_cont_msg.joint_or_axis = ja; emc_jog_cont_msg.vel = speed / 60.0; - emcCommandSend(emc_jog_cont_msg); + emcCommandSend(emc_jog_cont_msg, jog_key(ja, jjogmode)); } static void sendJogIncr(int ja, double speed, double incr, int jjogmode) @@ -1207,7 +1075,7 @@ static int sendSpindleOverride(int spindle, double override) return emcCommandSend(emc_traj_set_spindle_scale_msg); } -static int iniLoad(const char *filename) +static int haluiIniLoad(const char *filename) { IniFile inifile(filename); @@ -1215,24 +1083,6 @@ static int iniLoad(const char *filename) return -1; } - // EMC debugging flags - emc_debug = (unsigned)inifile.findUIntV("DEBUG", "EMC", 0); - - if (emc_debug & EMC_DEBUG_CONFIG) { - std::string version = inifile.findStringV("VERSION", "EMC", ""); - std::string machine = inifile.findStringV("MACHINE", "EMC", ""); - extern char *program_invocation_short_name; - log_info( - "{} ({}) halui: machine '{}' version '{}'\n", - program_invocation_short_name, getpid(), machine, version - ); - } - - if (auto inistring = inifile.findString("NML_FILE", "EMC")) { - // copy to global - rtapi_strxcpy(emc_nmlfile, inistring->c_str()); - } // else not found, use default - if (auto inival = inifile.findReal("MAX_FEED_OVERRIDE", "DISPLAY")) { if (*inival > 0.0) { maxFeedOverride = *inival; @@ -1423,6 +1273,28 @@ static bool jogging_selected_axis(local_halui_str &hal) { } +// The pins where a 20 ms sampling period is the wrong answer. They are +// checked every task cycle; check_bit_changed() updates old_halui_data, so +// the full pass below does not see the same edge a second time. +static void check_safety_pins() +{ + if (check_bit_changed(hal_get_bool(halui_data->estop_activate), + old_halui_data.estop_activate) != 0) + sendEstop(); + + if (check_bit_changed(hal_get_bool(halui_data->machine_off), + old_halui_data.machine_off) != 0) + sendMachineOff(); + + if (check_bit_changed(hal_get_bool(halui_data->abort), + old_halui_data.abort) != 0) + sendAbort(); + + if (check_bit_changed(hal_get_bool(halui_data->program_stop), + old_halui_data.program_stop) != 0) + sendAbort(); +} + // this function looks if any of the hal pins has changed // and sends appropriate messages if so static void check_hal_changes() @@ -1907,10 +1779,10 @@ static void modify_hal_pins() hal_set_bool(halui_data->estop_is_activated, emcStatus->task.state == EMC_TASK_STATE::ESTOP); // Decide once whether an ongoing halui MDI command has finished: the mode - // restore below refreshes emcStatus, and Task may echo it while still EXEC. - bool mdi_finished = halui_sent_mdi && emcStatus->status == RCS_STATUS::DONE; + // restore below may refresh emcStatus, and Task may echo it while still EXEC. + bool mdi_finished = mdi_settled() && emcStatus->status == RCS_STATUS::DONE; - if (halui_sent_mdi) { // we have an ongoing MDI command + if (mdi_settled()) { // we have an ongoing MDI command if (mdi_finished) { //which seems to have finished switch (halui_old_mode) { case EMC_TASK_MODE::MANUAL: sendManual();break; @@ -1935,12 +1807,12 @@ static void modify_hal_pins() if (num_mdi_commands>0){ // we wants initialize program_is_idle and mode_is_mdi before halui_sent_mdi - if (halui_sent_mdi) { // we have an ongoing MDI command + if (mdi_settled()) { // we have an ongoing MDI command if (mdi_finished) { //which seems to have finished halui_sent_mdi = 0; - esleep(20ms); //sleep for a while - updateStatus(); - esleep(20ms); //sleep for a while + mdi_exec_ticket = 0; + // the standalone halui slept 2x20ms around a status + // re-read here; in task the status is already current } } hal_set_bool(halui_data->halui_mdi_is_running, halui_sent_mdi); @@ -2097,68 +1969,74 @@ static void modify_hal_pins() -int main(int argc, char *argv[]) -{ - // process command line args - if (0 != emcGetArgs(argc, argv)) { - log_error("error in argument list\n"); - exit(1); - } - // get configuration information - if (0 != iniLoad(emc_inifile)) { - log_error("iniLoad error\n"); - exit(2); +/******************************************************************** +* +* The three entry points task uses. See halui.hh. +* +********************************************************************/ + +int haluiInit(const char *filename) +{ + if (0 != haluiIniLoad(filename)) { + log_error("halui: iniLoad error\n"); + return -1; } - //init HAL and export pins if (0 != halui_hal_init()) { - log_error("hal_init error\n"); - exit(1); + log_error("halui: hal_init error\n"); + // the export helpers hal_exit() the component themselves + comp_id = -1; + return -1; } - //initialize safe values hal_init_pins(); + return 0; +} - // init NML - if (0 != tryNml()) { - log_error("can't connect to emc\n"); - thisQuit(); - exit(1); - } - -#ifdef TOOL_NML //{ - //fprintf(stderr,"%8d HALUI REGISTER %p\n",getpid(), - tool_nml_register((CANON_TOOL_TABLE*)&emcStatus->io.tool.toolTable); -#else //}{ - tool_mmap_user(); -#endif //} - - // get current serial number, and save it for restoring when we quit - // so as not to interfere with real operator interface - updateStatus(); - - done = 0; - /* Register the routine that catches the SIGINT signal */ - signal(SIGINT, quit); - /* catch SIGTERM too - the run script uses it to shut things down */ - signal(SIGTERM, quit); - - while (!done) { - static bool task_start_synced = 0; - if (!task_start_synced) { - // wait for task to establish nonzero linearUnits - if (emcStatus->motion.traj.linearUnits != 0) { - // set once at startup, no changes are expected: - hal_set_real(halui_data->units_per_mm, emcStatus->motion.traj.linearUnits); - task_start_synced = 1; - } +void haluiUpdate(void) +{ + if (comp_id < 0) { + return; + } + + static bool task_start_synced = false; + if (!task_start_synced) { + // wait for task to establish nonzero linearUnits + if (emcStatus->motion.traj.linearUnits != 0) { + // set once at startup, no changes are expected: + hal_set_real(halui_data->units_per_mm, emcStatus->motion.traj.linearUnits); + task_start_synced = true; } - check_hal_changes(); //if anything changed send NML messages + } + + // every cycle: the pins that should not wait for the next pass + check_safety_pins(); + + const double now = etime(); + const bool due = (now - last_pass) >= HALUI_PERIOD; + + if (due) { + last_pass = now; + check_hal_changes(); //if anything changed send commands + } + + // every cycle, and after check_hal_changes() so that a button pressed + // in this pass is acted on in it + service_mdi(); + + if (due) { modify_hal_pins(); //if status changed modify HAL too - esleep(20ms); //sleep for a while - updateStatus(); } - thisQuit(); - return 0; +} + +void haluiExit(void) +{ + if (comp_id < 0) { + return; + } + + //don't forget the big HAL sin ;) + hal_exit(comp_id); + comp_id = -1; } diff --git a/src/emc/task/halui.hh b/src/emc/task/halui.hh new file mode 100644 index 00000000000..c825b70dd75 --- /dev/null +++ b/src/emc/task/halui.hh @@ -0,0 +1,30 @@ +/******************************************************************** +* Description: halui.hh +* The HAL user interface, running inside task. +* +* This is the whole interface task sees; everything else lives in +* halui.cc, the way ws_server.cc holds the websocket transport. +* +* License: GPL Version 2 +********************************************************************/ +#ifndef TASK_HALUI_HH +#define TASK_HALUI_HH + +/* Create the halui HAL component and its pins. Returns 0, or -1 on + failure. There is nothing to configure: the pins are always there, and + cost nothing to a machine that connects none of them. + + Call this before ini_hal_init(): halcmd's "loadusr -Wn inihal" returns as + soon as the inihal component is ready, and the HAL files -- which may + well "net" halui pins -- run immediately afterwards. */ +int haluiInit(const char *inifile); + +/* Read the input pins, write the status pins. Called once per task cycle. + Most of the work is internally rate limited to 20 ms, which was the + standalone halui's loop period. */ +void haluiUpdate(void); + +/* Release the HAL component. Safe to call if haluiInit() never ran. */ +void haluiExit(void); + +#endif /* TASK_HALUI_HH */ diff --git a/src/emc/usr_intf/Submakefile b/src/emc/usr_intf/Submakefile index 33c030bea38..121bcfe3b0a 100644 --- a/src/emc/usr_intf/Submakefile +++ b/src/emc/usr_intf/Submakefile @@ -13,10 +13,7 @@ EMCLCDSRCS := emc/usr_intf/emclcd.cc \ emc/usr_intf/shcom.cc \ emc/usr_intf/sockets.cc -HALUISRCS := emc/usr_intf/halui.cc \ - emc/usr_intf/mapini.cc - -USERSRCS += $(EMCSHSRCS) $(EMCRSHSRCS) $(EMCSCHEDSRCS) $(EMCLCDSRCS) $(USRMOTSRCS) $(HALUISRCS) +USERSRCS += $(EMCSHSRCS) $(EMCRSHSRCS) $(EMCSCHEDSRCS) $(EMCLCDSRCS) $(USRMOTSRCS) $(call TOOBJSDEPS, $(EMCSHSRCS)) : EXTRAFLAGS = $(ULFLAGS) $(TCL_CFLAGS) -fPIC @@ -41,8 +38,3 @@ TARGETS += ../bin/schedrmt $(ECHO) Linking $(notdir $@) $(Q)$(CXX) -o $@ $(ULFLAGS) $^ -lfmt $(LDFLAGS) TARGETS += ../bin/linuxcnclcd - -../bin/halui: $(call TOOBJS, $(HALUISRCS)) ../lib/liblinuxcnc.a ../lib/liblinuxcncini.so.1 ../lib/libnml.so.0 ../lib/liblinuxcnchal.so.0 ../lib/libtooldata.so.0 - $(ECHO) Linking $(notdir $@) - $(Q)$(CXX) $(CXXFLAGS) -o $@ $(ULFLAGS) $^ -lfmt $(LDFLAGS) -TARGETS += ../bin/halui diff --git a/src/emc/usr_intf/pncconf/build_INI.py b/src/emc/usr_intf/pncconf/build_INI.py index 379978a4cff..b2529e683c6 100644 --- a/src/emc/usr_intf/pncconf/build_INI.py +++ b/src/emc/usr_intf/pncconf/build_INI.py @@ -267,7 +267,6 @@ def write_inifile(self, base): print("%s=%s"%(a,b), file=file) print(file=file) print("[HAL]", file=file) - print("HALUI = halui", file=file) print("HALFILE = %s.hal" % self.d.machinename, file=file) # qtplasmac requires the qtplasmac_comp file to connect the plasmac component if self.d.frontend == _PD._QTPLASMAC: diff --git a/src/emc/usr_intf/stepconf/build_INI.py b/src/emc/usr_intf/stepconf/build_INI.py index 6bf173b3ce8..0bfb550a1cc 100644 --- a/src/emc/usr_intf/stepconf/build_INI.py +++ b/src/emc/usr_intf/stepconf/build_INI.py @@ -212,8 +212,6 @@ def write_inifile(self, base): print(file=file) print("[HAL]", file=file) - if self.d.halui or self.d.select_qtplasmac: - print("HALUI = halui", file=file) print("HALFILE = %s.hal" % self.d.machinename, file=file) # qtplasmac requires custom, custom_postgui and shutdown hal files if self.d.select_qtplasmac: From bdf222d4b4f53e76e0eab95ba1a7f210be777e4b Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sun, 20 Sep 2026 18:44:00 +0200 Subject: [PATCH 05/12] remove halui from ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d412317f24f..12bcaf82254 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,7 @@ jobs: fi done for f in scripts/linuxcnc scripts/halrun bin/linuxcncrsh bin/linuxcncsvr \ - bin/halcmd bin/halui bin/mdi bin/linuxcnctop; do + bin/halcmd bin/mdi bin/linuxcnctop; do if test ! -x "$f"; then echo "error: missing headless artifact: $f" exit 1 From 02f1522052bdef87be96fb344e8e9c6c72aa1b59 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Mon, 21 Sep 2026 12:16:17 +0200 Subject: [PATCH 06/12] fix halui tests --- tests/halui/_lib/halui_test.py | 36 +++++++++++++++++++++++++++------- tests/halui/axes/test-ui.py | 16 +++++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/tests/halui/_lib/halui_test.py b/tests/halui/_lib/halui_test.py index 6911f786a02..6a4fd54c465 100644 --- a/tests/halui/_lib/halui_test.py +++ b/tests/halui/_lib/halui_test.py @@ -40,6 +40,14 @@ HALUI_PERIOD = 0.02 HOLD = 0.15 TIMEOUT = 5.0 +# Per-attempt wait for a task_state change, and how many times to reissue it. +# The transition normally lands well under a second, but the first one after +# startup can be refused outright: task is still coming up while the harness +# is still enumerating and wiring halui's ~250 pins, so nothing has settled +# by the time the first section runs. ui-smoke's ensure_state() reissues for +# the same reason (see tests/ui-smoke/_lib/drive.py). +STATE_ATTEMPT_TIMEOUT = 3.0 +STATE_RETRY_BUDGET = 6 COMP = 'halui-test' @@ -95,8 +103,14 @@ def __init__(self): self.cmd = linuxcnc.command() self.errors = linuxcnc.error_channel() self.poll() - self.log('harness up: %d halui pins, %d wired externally' - % (len(self.pins), len(self.external))) + # Until task publishes its first status, task_state reads 0, which is + # not STATE_ESTOP and not STATE_ON -- branching on it would skip the + # estop clear below and leave every later state(ON) refused. The + # harness can be up 4ms after launch, so this is reached routinely. + if not self.wait_for(lambda: self.stat.task_state != 0): + raise RuntimeError('setup: task never published a state') + self.log('harness up: %d halui pins, %d wired externally, task_state=%d' + % (len(self.pins), len(self.external), self.stat.task_state)) # -- reporting --------------------------------------------------------- @@ -246,15 +260,23 @@ def nml_state(self, state): # task has no distinct OFF state: a request for OFF reads back as # ESTOP_RESET want = linuxcnc.STATE_ESTOP_RESET if state == linuxcnc.STATE_OFF else state - self.cmd.state(state) - self.cmd.wait_complete() - return self.wait_for(lambda: self.stat.task_state == want) + for attempt in range(1, STATE_RETRY_BUDGET + 1): + self.cmd.state(state) + self.cmd.wait_complete() + if self.wait_for(lambda: self.stat.task_state == want, + timeout=STATE_ATTEMPT_TIMEOUT): + return True + self.log('task_state %d not reached on attempt %d, retrying' + % (want, attempt)) + return False def machine_on(self): if self.poll().task_state == linuxcnc.STATE_ON: return - if self.stat.task_state == linuxcnc.STATE_ESTOP: - self.nml_state(linuxcnc.STATE_ESTOP_RESET) + # Unconditional: a machine that is not ON may be in estop whatever the + # last poll said, and STATE_ON is refused until estop is cleared. + if not self.nml_state(linuxcnc.STATE_ESTOP_RESET): + raise RuntimeError('setup: could not clear estop') if not self.nml_state(linuxcnc.STATE_ON): raise RuntimeError('setup: could not turn the machine on') diff --git a/tests/halui/axes/test-ui.py b/tests/halui/axes/test-ui.py index 83217d91b8d..034580b0ef4 100755 --- a/tests/halui/axes/test-ui.py +++ b/tests/halui/axes/test-ui.py @@ -254,9 +254,17 @@ def selected_jog(h): h.nml_abort() -def expected_relative(s): - """halui's own formula (modify_hal_pins) from task's offsets.""" - ax, ay, az = s.actual_position[:3] +def expected_relative(s, machine=None): + """halui's own formula (modify_hal_pins) from task's offsets. + + `machine` is the machine position to model from. Pass the position the + caller has just asserted rather than letting it default: a move is only + confirmed to expect_at()'s 1e-4, so actual_position can still be settling + by that much, while expect_positions() compares the result at 1e-6. Under + load that gap shows up as a ~5e-5 miss on pos-relative alone -- the + commanded/feedback checks compare against exact literals and pass. + """ + ax, ay, az = machine if machine is not None else s.actual_position[:3] g5x, g92, tlo, rot = s.g5x_offset, s.g92_offset, s.tool_offset, s.rotation_xy x = ax - g5x[0] - tlo[0] y = ay - g5x[1] - tlo[1] @@ -307,7 +315,7 @@ def positions(h): h.set('axis.x.increment', 0.5) h.pulse('axis.x.increment-plus') expect_at(h, 'x', 3.5, 'after an increment in teleop') - rel = expected_relative(h.poll()) + rel = expected_relative(h.poll(), (3.5, 4, 1)) expect_positions(h, (3.5, 4, 1), rel, 'after moving X by 0.5') for code in ('G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 R0', 'M61 Q0'): From 3c5ccb07fd37deadef4846901556e161083a76e2 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Fri, 16 Oct 2026 11:12:00 +0200 Subject: [PATCH 07/12] remove remaining HALUI settings from configs and tests --- configs/sim/axis/db_demo/base.inc | 1 - configs/sim/axis/ini_with_includes/hal.inc | 1 - configs/sim/axis/ja_tests/xz/xzbase.inc | 1 - configs/sim/axis/xhc-hb04/README | 1 - configs/sim/qtplasmac/qtplasmac_imperial_ini.inc | 1 - configs/sim/qtplasmac/qtplasmac_metric_ini.inc | 1 - configs/sim/tklinuxcnc/trivkins/xzbase.inc | 1 - configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt | 1 - configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt | 1 - tests/workplane-preview/test.ini | 1 - tests/workplane-retain/clear.ini | 1 - tests/workplane-retain/test.ini | 1 - 12 files changed, 12 deletions(-) diff --git a/configs/sim/axis/db_demo/base.inc b/configs/sim/axis/db_demo/base.inc index 8330fee7eb5..142df4c93e4 100644 --- a/configs/sim/axis/db_demo/base.inc +++ b/configs/sim/axis/db_demo/base.inc @@ -20,7 +20,6 @@ EMCMOT = motmod SERVO_PERIOD = 1000000 [HAL] -HALUI=halui HALFILE = LIB:basic_sim.tcl -no_use_hal_manualtoolchange POSTGUI_HALFILE = db_postgui.hal diff --git a/configs/sim/axis/ini_with_includes/hal.inc b/configs/sim/axis/ini_with_includes/hal.inc index f627913c476..25843406070 100644 --- a/configs/sim/axis/ini_with_includes/hal.inc +++ b/configs/sim/axis/ini_with_includes/hal.inc @@ -5,4 +5,3 @@ # list of hal config files to run through halcmd # files are executed in the order in which they appear HALFILE = LIB:basic_sim.tcl -HALUI = halui diff --git a/configs/sim/axis/ja_tests/xz/xzbase.inc b/configs/sim/axis/ja_tests/xz/xzbase.inc index 0ed6ec2841a..bf35154d4a3 100644 --- a/configs/sim/axis/ja_tests/xz/xzbase.inc +++ b/configs/sim/axis/ja_tests/xz/xzbase.inc @@ -1,6 +1,5 @@ [HAL] HALFILE = LIB:basic_sim.tcl - HALUI = halui [TRAJ] COORDINATES = XZ diff --git a/configs/sim/axis/xhc-hb04/README b/configs/sim/axis/xhc-hb04/README index 6b7aba395c3..8468387af72 100644 --- a/configs/sim/axis/xhc-hb04/README +++ b/configs/sim/axis/xhc-hb04/README @@ -162,7 +162,6 @@ For example, the organization for the xhc-hb04-layout2.ini file is: ... | HALFILE = | HALFILE = LIB:xhc-hb04.tcl | xhc-hb04 configuration script - HALUI = halui | Halui specifier [XHC_HB04_CONFIG] | All config items used by LIB:xhc-hb04.tcl layout = | diff --git a/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc b/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc index 23f990a8d0e..881a6872d59 100644 --- a/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc +++ b/configs/sim/qtplasmac/qtplasmac_imperial_ini.inc @@ -19,7 +19,6 @@ HALFILE = qtplasmac_comp.hal HALFILE = custom.hal POSTGUI_HALFILE = custom_postgui.hal POSTGUI_HALFILE = sim_postgui.hal -HALUI = halui [EMC] VERSION = 1.1 diff --git a/configs/sim/qtplasmac/qtplasmac_metric_ini.inc b/configs/sim/qtplasmac/qtplasmac_metric_ini.inc index 12e6c3fb39e..82f0df7c161 100644 --- a/configs/sim/qtplasmac/qtplasmac_metric_ini.inc +++ b/configs/sim/qtplasmac/qtplasmac_metric_ini.inc @@ -19,7 +19,6 @@ HALFILE = qtplasmac_comp.hal HALFILE = custom.hal POSTGUI_HALFILE = custom_postgui.hal POSTGUI_HALFILE = sim_postgui.hal -HALUI = halui [EMC] VERSION = 1.1 diff --git a/configs/sim/tklinuxcnc/trivkins/xzbase.inc b/configs/sim/tklinuxcnc/trivkins/xzbase.inc index b78b08f35f5..6bb1b111101 100644 --- a/configs/sim/tklinuxcnc/trivkins/xzbase.inc +++ b/configs/sim/tklinuxcnc/trivkins/xzbase.inc @@ -1,6 +1,5 @@ [HAL] HALFILE = LIB:basic_sim.tcl - HALUI = halui [TRAJ] COORDINATES = XZ diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt index df58dc90c87..8154e407807 100644 --- a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt +++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff.txt @@ -5,7 +5,6 @@ modifies pyngcgui_touchy.ini to use: [HAL] ... HALFILE = hookup_move.tcl -HALUI = halui APP = moveoff_gui \ -size 20 -loc center \ diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt index 4c920b3708e..84b30d69da0 100644 --- a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt +++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt @@ -5,7 +5,6 @@ modifica pyngcgui_touchy.ini para usar: [HAL] ... HALFILE = hookup_move.tcl -HALUI = halui APP = moveoff_gui \ -size 20 -loc center \ diff --git a/tests/workplane-preview/test.ini b/tests/workplane-preview/test.ini index 51a235f0cff..1f8daf8cb04 100644 --- a/tests/workplane-preview/test.ini +++ b/tests/workplane-preview/test.ini @@ -29,7 +29,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = LIB:simulated_home.hal HALFILE = LIB:lathe.hal diff --git a/tests/workplane-retain/clear.ini b/tests/workplane-retain/clear.ini index 891b931cef0..cd41d92f2c4 100644 --- a/tests/workplane-retain/clear.ini +++ b/tests/workplane-retain/clear.ini @@ -29,7 +29,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = LIB:simulated_home.hal HALFILE = LIB:lathe.hal diff --git a/tests/workplane-retain/test.ini b/tests/workplane-retain/test.ini index 2fd2850e903..e58fa29def4 100644 --- a/tests/workplane-retain/test.ini +++ b/tests/workplane-retain/test.ini @@ -30,7 +30,6 @@ TOOL_TABLE = tool.tbl TOOL_CHANGE_POSITION = 0 0 2 [HAL] -HALUI = halui HALFILE = LIB:core_sim.hal HALFILE = LIB:simulated_home.hal HALFILE = LIB:lathe.hal From 235032b01c9e6c4057777c72487f8ab2331cb6d3 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Fri, 16 Oct 2026 11:12:00 +0200 Subject: [PATCH 08/12] halui: fix comments and docs Drop references to a websocket server that is not in the tree, list the INI settings halui still reads, and state the cost of unused pins consistently. --- docs/src/gui/halui.adoc | 9 +++++++-- docs/src/man/man1/halui.1.adoc | 22 ++++++++++++++++++---- src/emc/task/cmd_queue.hh | 6 +++--- src/emc/task/emctaskmain.cc | 12 ++++++------ src/emc/task/halui.hh | 7 ++++--- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/docs/src/gui/halui.adoc b/docs/src/gui/halui.adoc index d7f501298a8..18d287ac60b 100644 --- a/docs/src/gui/halui.adoc +++ b/docs/src/gui/halui.adoc @@ -12,9 +12,14 @@ Halui is a HAL based user interface for LinuxCNC, it connects HAL pins to machine commands. Most of the functionality (buttons, indicators etc.) that is provided by a traditional GUI (AXIS, GMOCCAPY, QtDragon, etc.), is provided by HAL pins in Halui. -There is nothing to set up: the pins exist in every configuration, created +There is nothing to load: the pins exist in every configuration, created by the task controller before the HAL files are read, so a HAL file can -connect them straight away. Pins nobody connects cost nothing. +connect them straight away. A configuration that connects none of them +pays only for a pin scan every 20 ms. + +Earlier versions ran halui as a separate program, started with +`[HAL]HALUI = halui` in the INI file or `loadusr halui` in a HAL file. +Neither is needed any more; remove them from existing configurations. == MDI diff --git a/docs/src/man/man1/halui.1.adoc b/docs/src/man/man1/halui.1.adoc index d4244078d71..8f3fdc853c6 100644 --- a/docs/src/man/man1/halui.1.adoc +++ b/docs/src/man/man1/halui.1.adoc @@ -11,10 +11,24 @@ It provides a large number of HAL pins, and acts accordingly when these change. The pins are part of the LinuxCNC task controller and exist in every -configuration. There is nothing to load and nothing to configure: connect -the pins you want in a HAL file. Earlier versions ran halui as a separate -program, selected with *[HAL]HALUI* in the INI file; that setting is no -longer read. +configuration. There is nothing to load: connect the pins you want in a +HAL file. Earlier versions ran halui as a separate program, selected with +*[HAL]HALUI* in the INI file or started with *loadusr halui*; neither is +needed any more. + +== INI FILE + +halui still reads these INI settings: + +*[HALUI]MDI_COMMAND*:: + An MDI command to run when the matching *halui.mdi-command-NN* pin goes + true. May be given up to 64 times. +*[DISPLAY]MAX_FEED_OVERRIDE*:: + Upper limit for the feed override set through halui. +*[DISPLAY]MIN_SPINDLE_OVERRIDE*, *[DISPLAY]MAX_SPINDLE_OVERRIDE*:: + Limits for the spindle override set through halui. +*[TRAJ]COORDINATES*:: + Which *halui.axis.L.\** pins are created. == USAGE diff --git a/src/emc/task/cmd_queue.hh b/src/emc/task/cmd_queue.hh index 6e490d0dea4..d05f6f6f493 100644 --- a/src/emc/task/cmd_queue.hh +++ b/src/emc/task/cmd_queue.hh @@ -8,9 +8,9 @@ * emcTaskPlan() exactly like one that arrived over NML: same mode and * state gating, same serial-number echo, same error reporting. * -* Two producers use it: -* - ws_server.cc, from the websocket server thread -* - halui.cc, from the task thread +* halui.cc, running in the task thread, is the only producer today. +* push() is thread safe, so a transport running in its own thread can +* use it too. * * License: GPL Version 2 ********************************************************************/ diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index 559c53293c5..bbe9a8b2cc7 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -87,7 +87,7 @@ fpu_control_t __fpu_control = _FPU_IEEE & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_M #include "motion/motion.h" // EMCMOT_ORIENT_* #include "ini/inihal.hh" #include "halui.hh" // the HAL user interface, in task -#include "cmd_queue.hh" // commands from ws_server and halui +#include "cmd_queue.hh" // commands from inside task (halui) using namespace linuxcnc; using namespace std::chrono_literals; @@ -110,8 +110,8 @@ static RCS_CMD_MSG *emcCommand = NULL; // global EMC status EMC_STAT *emcStatus = NULL; -// set while emcCommand points at a command from inside task (the websocket -// server or halui) rather than at the NML command buffer +// set while emcCommand points at a command from inside task (halui) +// rather than at the NML command buffer static bool emcCommandInternal = false; // timer stuff @@ -3583,9 +3583,9 @@ int main(int argc, char *argv[]) taskExecuteError = 0; } else if (RCS_CMD_MSG *queued = taskcmd::next(emcStatus->echo_serial_number)) { - // A command came from inside task -- the websocket server or - // halui. Point emcCommand at it and the rest of the loop treats - // it exactly like one read from NML. + // A command came from inside task (halui). Point emcCommand at + // it and the rest of the loop treats it exactly like one read + // from NML. emcCommand = queued; emcCommandInternal = true; taskPlanError = 0; diff --git a/src/emc/task/halui.hh b/src/emc/task/halui.hh index c825b70dd75..7a64e5d1f55 100644 --- a/src/emc/task/halui.hh +++ b/src/emc/task/halui.hh @@ -3,7 +3,7 @@ * The HAL user interface, running inside task. * * This is the whole interface task sees; everything else lives in -* halui.cc, the way ws_server.cc holds the websocket transport. +* halui.cc. * * License: GPL Version 2 ********************************************************************/ @@ -11,8 +11,9 @@ #define TASK_HALUI_HH /* Create the halui HAL component and its pins. Returns 0, or -1 on - failure. There is nothing to configure: the pins are always there, and - cost nothing to a machine that connects none of them. + failure. There is nothing to load: the pins are always there, and a + machine that connects none of them pays only for a pin scan every + 20 ms. Call this before ini_hal_init(): halcmd's "loadusr -Wn inihal" returns as soon as the inihal component is ready, and the HAL files -- which may From 355af12c91918671a7c9d9aae639ad7152d961ff Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Fri, 16 Oct 2026 11:12:00 +0200 Subject: [PATCH 09/12] halui: keep a compatibility stub and warn about [HAL]HALUI Configurations that still run 'loadusr halui' would fail to start now that the program is gone. Install a halui stub that prints a warning and exits successfully, warn at startup when [HAL]HALUI is set, and add a migration note to the update docs. --- debian/linuxcnc.install.in | 1 + docs/src/getting-started/updating-linuxcnc.adoc | 15 +++++++++++++++ scripts/halui | 9 +++++++++ scripts/linuxcnc.in | 7 +++++++ src/Makefile | 1 + 5 files changed, 33 insertions(+) create mode 100755 scripts/halui diff --git a/debian/linuxcnc.install.in b/debian/linuxcnc.install.in index 80b405ddf5d..d66045b43a5 100644 --- a/debian/linuxcnc.install.in +++ b/debian/linuxcnc.install.in @@ -28,6 +28,7 @@ usr/bin/halscope usr/bin/halshow usr/bin/halstreamer usr/bin/haltcl +usr/bin/halui usr/bin/hbmgui usr/bin/hexagui usr/bin/hy_gt_vfd diff --git a/docs/src/getting-started/updating-linuxcnc.adoc b/docs/src/getting-started/updating-linuxcnc.adoc index 63decc6e5e2..2f9e5960909 100644 --- a/docs/src/getting-started/updating-linuxcnc.adoc +++ b/docs/src/getting-started/updating-linuxcnc.adoc @@ -232,6 +232,21 @@ link:../man/man1/mesambccc.1.html[mesambccc(1)]. The 2.9 release retains the framework, so its documentation remains available in the http://linuxcnc.org/docs/2.9/html/drivers/mesa_modbus.html[2.9 docs]. +=== halui is part of the task controller + +halui is no longer a separate program. Its pins are created by the task +controller in every configuration, before the HAL files are read, so +there is nothing to start. Remove these from existing configurations: + +* `HALUI = halui` in the `[HAL]` section of the INI file. It is no longer + read; LinuxCNC prints a warning at startup while it is still there. +* `loadusr halui` (with or without `-W`/`-Wn halui` and `-ini ...`) in a + HAL file. A compatibility `halui` stub still accepts this and prints a + warning; it will be removed in a later release. + +The pins, `[HALUI]MDI_COMMAND` and the `[DISPLAY]` override limits work +as before, see link:../gui/halui.html[HAL User Interface]. + == Preview renderer now requires OpenGL 3.3 core diff --git a/scripts/halui b/scripts/halui new file mode 100755 index 00000000000..15921048e43 --- /dev/null +++ b/scripts/halui @@ -0,0 +1,9 @@ +#!/bin/sh +# halui used to be a separate program. Its pins are now created by the task +# controller in every configuration, so there is nothing left to start. +# This stub keeps configurations that still run "loadusr halui" working, +# and tells their owners to remove that line. +echo "halui: the halui pins are built into the task controller now;" \ + "remove 'loadusr halui' from your HAL file (and [HAL]HALUI from" \ + "your INI file). This compatibility stub will be removed." >&2 +exit 0 diff --git a/scripts/linuxcnc.in b/scripts/linuxcnc.in index 05e028f0d52..5edb0990ba4 100644 --- a/scripts/linuxcnc.in +++ b/scripts/linuxcnc.in @@ -528,6 +528,13 @@ if [ "$EMCTASK" = emctask ]; then EMCTASK=linuxcnctask; fi # so it needs to start by default, as the first process EMCSERVER=linuxcncsvr +# 2.7. halui is part of task now; [HAL]HALUI is no longer read +GetFromIniQuiet HALUI HAL +if [ -n "$retval" ] ; then + echo "Warning: [HAL]HALUI is no longer needed, the halui pins are built" \ + "into the task controller. Remove it from $INIFILE." >&2 +fi + # 2.7.1 get halbridge info from INI GetFromIniQuiet HALBRIDGE HAL HALBRIDGE=$retval diff --git a/src/Makefile b/src/Makefile index df19b0c3dc7..3bd45ec6775 100644 --- a/src/Makefile +++ b/src/Makefile @@ -664,6 +664,7 @@ endif $(EXE) ../scripts/latency-plot $(DESTDIR)$(bindir) $(EXE) ../scripts/latency-histogram $(DESTDIR)$(bindir) $(EXE) ../scripts/moveoff_gui $(DESTDIR)$(bindir) + $(EXE) ../scripts/halui $(DESTDIR)$(bindir) $(EXE) ../scripts/hal-histogram $(DESTDIR)$(bindir) $(EXE) ../scripts/xhc-hb04-accels $(DESTDIR)$(bindir) $(EXE) ../scripts/pyvcp_demo $(DESTDIR)$(bindir) From 77a491fdb36218c4b0f6c8a17c1e6512915908b7 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Fri, 16 Oct 2026 11:58:34 +0200 Subject: [PATCH 10/12] tests: remove the halui move verification tests They pinned down halui's behaviour so the move into task could be checked for changes. That is done; the pre-existing halui/jogging and halui/mdi tests stay. --- tests/halui/.gitignore | 5 - tests/halui/_lib/coverage.py | 60 --- tests/halui/_lib/halui_test.py | 369 ----------------- tests/halui/_lib/launch.sh | 8 - tests/halui/_lib/tool.tbl | 3 - tests/halui/axes/checkresult | 2 - tests/halui/axes/halui.ini | 100 ----- tests/halui/axes/test-ui.py | 332 ---------------- tests/halui/axes/test.sh | 2 - tests/halui/config-9axis/checkresult | 2 - tests/halui/config-9axis/halui.ini | 194 --------- tests/halui/config-9axis/nine.hal | 19 - tests/halui/config-9axis/test-ui.py | 130 ------ tests/halui/config-9axis/test.sh | 2 - tests/halui/config-minimal/checkresult | 2 - tests/halui/config-minimal/halui.ini | 74 ---- tests/halui/config-minimal/minimal.hal | 12 - tests/halui/config-minimal/test-ui.py | 172 -------- tests/halui/config-minimal/test.sh | 2 - tests/halui/joints/checkresult | 2 - tests/halui/joints/halui.ini | 100 ----- tests/halui/joints/test-ui.py | 442 --------------------- tests/halui/joints/test.sh | 2 - tests/halui/machine-state/checkresult | 2 - tests/halui/machine-state/halui.ini | 100 ----- tests/halui/machine-state/test-ui.py | 188 --------- tests/halui/machine-state/test.sh | 2 - tests/halui/mdi-commands/checkresult | 2 - tests/halui/mdi-commands/halui.ini | 102 ----- tests/halui/mdi-commands/long.ngc | 5 - tests/halui/mdi-commands/test-ui.py | 182 --------- tests/halui/mdi-commands/test.sh | 2 - tests/halui/overrides/checkresult | 2 - tests/halui/overrides/halui.ini | 100 ----- tests/halui/overrides/test-ui.py | 230 ----------- tests/halui/overrides/test.sh | 2 - tests/halui/program/block-delete.ngc | 4 - tests/halui/program/checkresult | 2 - tests/halui/program/halui.ini | 100 ----- tests/halui/program/long.ngc | 5 - tests/halui/program/optional-stop.ngc | 5 - tests/halui/program/step.ngc | 5 - tests/halui/program/test-ui.py | 295 -------------- tests/halui/program/test.sh | 2 - tests/halui/spindle-coolant/checkresult | 2 - tests/halui/spindle-coolant/halui.ini | 100 ----- tests/halui/spindle-coolant/test-ui.py | 171 -------- tests/halui/spindle-coolant/test.sh | 2 - tests/halui/startup-halfile/checkresult | 2 - tests/halui/startup-halfile/halui-nets.hal | 7 - tests/halui/startup-halfile/halui.ini | 102 ----- tests/halui/startup-halfile/test-ui.py | 67 ---- tests/halui/startup-halfile/test.sh | 2 - tests/halui/tool/checkresult | 2 - tests/halui/tool/halui.ini | 100 ----- tests/halui/tool/test-ui.py | 112 ------ tests/halui/tool/test.sh | 2 - 57 files changed, 4044 deletions(-) delete mode 100644 tests/halui/_lib/coverage.py delete mode 100644 tests/halui/_lib/halui_test.py delete mode 100755 tests/halui/_lib/launch.sh delete mode 100644 tests/halui/_lib/tool.tbl delete mode 100755 tests/halui/axes/checkresult delete mode 100644 tests/halui/axes/halui.ini delete mode 100755 tests/halui/axes/test-ui.py delete mode 100755 tests/halui/axes/test.sh delete mode 100755 tests/halui/config-9axis/checkresult delete mode 100644 tests/halui/config-9axis/halui.ini delete mode 100644 tests/halui/config-9axis/nine.hal delete mode 100755 tests/halui/config-9axis/test-ui.py delete mode 100755 tests/halui/config-9axis/test.sh delete mode 100755 tests/halui/config-minimal/checkresult delete mode 100644 tests/halui/config-minimal/halui.ini delete mode 100644 tests/halui/config-minimal/minimal.hal delete mode 100755 tests/halui/config-minimal/test-ui.py delete mode 100755 tests/halui/config-minimal/test.sh delete mode 100755 tests/halui/joints/checkresult delete mode 100644 tests/halui/joints/halui.ini delete mode 100755 tests/halui/joints/test-ui.py delete mode 100755 tests/halui/joints/test.sh delete mode 100755 tests/halui/machine-state/checkresult delete mode 100644 tests/halui/machine-state/halui.ini delete mode 100755 tests/halui/machine-state/test-ui.py delete mode 100755 tests/halui/machine-state/test.sh delete mode 100755 tests/halui/mdi-commands/checkresult delete mode 100644 tests/halui/mdi-commands/halui.ini delete mode 100644 tests/halui/mdi-commands/long.ngc delete mode 100755 tests/halui/mdi-commands/test-ui.py delete mode 100755 tests/halui/mdi-commands/test.sh delete mode 100755 tests/halui/overrides/checkresult delete mode 100644 tests/halui/overrides/halui.ini delete mode 100755 tests/halui/overrides/test-ui.py delete mode 100755 tests/halui/overrides/test.sh delete mode 100644 tests/halui/program/block-delete.ngc delete mode 100755 tests/halui/program/checkresult delete mode 100644 tests/halui/program/halui.ini delete mode 100644 tests/halui/program/long.ngc delete mode 100644 tests/halui/program/optional-stop.ngc delete mode 100644 tests/halui/program/step.ngc delete mode 100755 tests/halui/program/test-ui.py delete mode 100755 tests/halui/program/test.sh delete mode 100755 tests/halui/spindle-coolant/checkresult delete mode 100644 tests/halui/spindle-coolant/halui.ini delete mode 100755 tests/halui/spindle-coolant/test-ui.py delete mode 100755 tests/halui/spindle-coolant/test.sh delete mode 100755 tests/halui/startup-halfile/checkresult delete mode 100644 tests/halui/startup-halfile/halui-nets.hal delete mode 100644 tests/halui/startup-halfile/halui.ini delete mode 100755 tests/halui/startup-halfile/test-ui.py delete mode 100755 tests/halui/startup-halfile/test.sh delete mode 100755 tests/halui/tool/checkresult delete mode 100644 tests/halui/tool/halui.ini delete mode 100755 tests/halui/tool/test-ui.py delete mode 100755 tests/halui/tool/test.sh diff --git a/tests/halui/.gitignore b/tests/halui/.gitignore index 31d40592f97..b23febc81d7 100644 --- a/tests/halui/.gitignore +++ b/tests/halui/.gitignore @@ -1,7 +1,2 @@ sim.var.bak sim.var -# the halui pin tests copy _lib/tool.tbl in fresh on every run -*/tool.tbl -!_lib/tool.tbl -# per-run list of the halui pins a test touched -*/touched-pins.txt diff --git a/tests/halui/_lib/coverage.py b/tests/halui/_lib/coverage.py deleted file mode 100644 index 8cf13f34b6a..00000000000 --- a/tests/halui/_lib/coverage.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python3 -"""Report which halui pins the halui test suite exercises. - -Each test run leaves touched-pins.txt in its directory. This merges them and -matches them against every pin name pattern in halui.cc, so the report stays -honest when halui gains or loses pins. - - python3 tests/halui/_lib/coverage.py -""" - -import glob -import os -import re -import sys - -HERE = os.path.dirname(os.path.abspath(__file__)) -SUITE = os.path.dirname(HERE) -HALUI_CC = os.path.join(SUITE, '..', '..', 'src', 'emc', 'usr_intf', 'halui.cc') - -SPEC = re.compile(r'%[-+ #0]*\d*(?:\.\d+)?[diouxXcs]') - - -def pattern_regex(pattern): - parts = SPEC.split(pattern) - out = re.escape(parts[0]) - for rest in parts[1:]: - out += r'[A-Za-z0-9_]+' + re.escape(rest) - return re.compile('^' + out + '$') - - -def main(): - with open(HALUI_CC) as f: - patterns = sorted(set(p[len('halui.'):] for p in - re.findall(r'"(halui\.[A-Za-z0-9_.%\-]+)"', f.read()))) - - touched, runs = set(), [] - for path in sorted(glob.glob(os.path.join(SUITE, '*', 'touched-pins.txt'))): - runs.append(os.path.basename(os.path.dirname(path))) - with open(path) as f: - touched.update(line.strip() for line in f if line.strip()) - - if not runs: - print('no touched-pins.txt found; run the halui tests first') - return 1 - - covered = [p for p in patterns if any(pattern_regex(p).match(t) for t in touched)] - missing = [p for p in patterns if p not in covered] - - print('halui pin coverage from %d test runs: %s' % (len(runs), ', '.join(runs))) - print('%d of %d pin patterns exercised (%.0f%%)' - % (len(covered), len(patterns), 100.0 * len(covered) / len(patterns))) - if missing: - print('not exercised:') - for p in missing: - print(' halui.' + p) - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tests/halui/_lib/halui_test.py b/tests/halui/_lib/halui_test.py deleted file mode 100644 index 6a4fd54c465..00000000000 --- a/tests/halui/_lib/halui_test.py +++ /dev/null @@ -1,369 +0,0 @@ -"""Shared harness for the halui pin tests. - -Each test directory runs linuxcnc with its test-ui.py as the [DISPLAY] -program, so the harness starts once halui and task are both up. It: - - - Finds every pin halui exported and creates a mirror pin with the opposite - direction on its own HAL component, wired straight to it. Tests drive - halui's inputs and read its outputs by suffix: - h.set('machine.on', 1) - h.get('machine.is-on') - - - Talks to task through the stock linuxcnc python module. That is used only - for test setup (opening a program, homing before a jog test, ...) and as - ground truth for what task actually did -- never as the thing under test. - - - Records every check. A failed check is reported and the run carries on, - so one run shows everything that is broken. The process exits non-zero at - the end if anything failed. - -The tests assert what halui does today. Where today's behaviour is a bug, the -check goes through known_bug() with an explanation: the suite is a baseline -that flags any change in behaviour, and fixing one of those bugs has to -update its test deliberately. - -The tests only look at pins and task state, so the same suite applies -whether halui runs as its own process or inside task. -""" - -import math -import os -import sys -import time -import traceback - -import hal -import linuxcnc - -# halui polls its pins and task's status every 20 ms. Holding an input for a -# few of those guarantees halui samples both edges. -HALUI_PERIOD = 0.02 -HOLD = 0.15 -TIMEOUT = 5.0 -# Per-attempt wait for a task_state change, and how many times to reissue it. -# The transition normally lands well under a second, but the first one after -# startup can be refused outright: task is still coming up while the harness -# is still enumerating and wiring halui's ~250 pins, so nothing has settled -# by the time the first section runs. ui-smoke's ensure_state() reissues for -# the same reason (see tests/ui-smoke/_lib/drive.py). -STATE_ATTEMPT_TIMEOUT = 3.0 -STATE_RETRY_BUDGET = 6 - -COMP = 'halui-test' - - -class Halui: - - def __init__(self): - self.t0 = time.time() - self.checks = 0 - self.failures = [] - self.known_bugs = [] - self.touched = set() - - # Every pin halui exported, by suffix: {'machine.on': (type, dir)}, - # and the value each input had before we wired it (halui's default). - self.pins = {} - self.defaults = {} - for p in hal.get_info_pins(): - if p['NAME'].startswith('halui.'): - sfx = p['NAME'][len('halui.'):] - self.pins[sfx] = (p['TYPE'], p['DIRECTION']) - if p['DIRECTION'] == hal.HAL_IN: - self.defaults[sfx] = p['VALUE'] - if not self.pins: - raise RuntimeError('no halui pins found -- is halui running?') - - self.comp = hal.component(COMP) - for sfx, (typ, d) in sorted(self.pins.items()): - mirror = hal.HAL_OUT if d == hal.HAL_IN else hal.HAL_IN - self.comp.newpin(sfx, typ, mirror) - # Wiring our output to halui's input makes the signal carry our - # value, so start from halui's own default (scales, deadbands, - # count-enable...) rather than silently replacing it with 0. - if d == hal.HAL_IN: - self.comp[sfx] = self.defaults[sfx] - self.comp.ready() - - # Pins the config already wired elsewhere cannot be driven from here. - self.external = set() - for sfx, (typ, d) in sorted(self.pins.items()): - # hal.connect() does not raise when the link fails: it returns - # True (hal_link() != 0). A failed link here means the config - # already wired this halui pin. - sig = 'ht.' + sfx - hal.new_sig(sig, typ) - if hal.connect('halui.' + sfx, sig): - self.external.add(sfx) - continue - if hal.connect(COMP + '.' + sfx, sig): - raise RuntimeError('could not wire %s.%s' % (COMP, sfx)) - - self.stat = linuxcnc.stat() - self.cmd = linuxcnc.command() - self.errors = linuxcnc.error_channel() - self.poll() - # Until task publishes its first status, task_state reads 0, which is - # not STATE_ESTOP and not STATE_ON -- branching on it would skip the - # estop clear below and leave every later state(ON) refused. The - # harness can be up 4ms after launch, so this is reached routinely. - if not self.wait_for(lambda: self.stat.task_state != 0): - raise RuntimeError('setup: task never published a state') - self.log('harness up: %d halui pins, %d wired externally, task_state=%d' - % (len(self.pins), len(self.external), self.stat.task_state)) - - # -- reporting --------------------------------------------------------- - - def log(self, msg): - print('%7.3f: %s' % (time.time() - self.t0, msg), flush=True) - - def section(self, name): - self.log('') - self.log('==== %s ====' % name) - - def check(self, name, ok, detail=''): - self.checks += 1 - self.log('%s %s%s' % ('PASS' if ok else 'FAIL', name, - (' -- ' + detail) if detail else '')) - if not ok: - self.failures.append(name) - return ok - - def known_bug(self, name, ok, explanation): - """Assert today's buggy behaviour, and say why it is a bug.""" - self.known_bugs.append(name) - return self.check('KNOWN-BUG ' + name, ok, explanation) - - def finish(self): - here = os.path.dirname(os.path.abspath(sys.argv[0])) - with open(os.path.join(here, 'touched-pins.txt'), 'w') as f: - for p in sorted(self.touched): - f.write(p + '\n') - self.log('') - self.log('%d checks, %d failed, %d known bugs, %d/%d halui pins exercised' - % (self.checks, len(self.failures), len(self.known_bugs), - len(self.touched & set(self.pins)), len(self.pins))) - for f in self.failures: - self.log(' FAILED: ' + f) - sys.exit(1 if self.failures else 0) - - # -- halui pins -------------------------------------------------------- - - def has(self, sfx): - return sfx in self.pins - - def _pin(self, sfx, want_input): - if sfx not in self.pins: - raise KeyError('halui has no pin %r' % sfx) - is_input = self.pins[sfx][1] == hal.HAL_IN - if is_input != want_input: - raise KeyError('halui.%s is an %s pin' % (sfx, 'input' if is_input else 'output')) - self.touched.add(sfx) - - def set(self, sfx, value): - self._pin(sfx, want_input=True) - if sfx in self.external: - raise KeyError('halui.%s is wired by the config; cannot drive it' % sfx) - self.comp[sfx] = value - - def get(self, sfx): - self._pin(sfx, want_input=False) - return self.comp[sfx] - - def default(self, sfx): - """halui's value for an input pin before the harness wired it.""" - self._pin(sfx, want_input=True) - return self.defaults[sfx] - - def pulse(self, sfx, hold=HOLD): - """Rising edge, held long enough for halui to see it, then released.""" - self.set(sfx, 1) - time.sleep(hold) - self.set(sfx, 0) - time.sleep(hold) - - def settle(self, t=HOLD): - time.sleep(t) - - # -- waiting ----------------------------------------------------------- - - def poll(self): - self.stat.poll() - return self.stat - - def wait_for(self, fn, timeout=TIMEOUT): - end = time.time() + timeout - while True: - self.poll() - try: - if fn(): - return True - except Exception: - pass - if time.time() > end: - return False - time.sleep(HALUI_PERIOD / 2) - - def expect(self, name, fn, timeout=TIMEOUT, detail=None): - ok = self.wait_for(fn, timeout) - return self.check(name, ok, detail() if callable(detail) else (detail or '')) - - def stays(self, fn, duration=0.5): - """True if fn holds for the whole duration (records nothing).""" - end = time.time() + duration - while time.time() < end: - self.poll() - if not fn(): - return False - time.sleep(HALUI_PERIOD / 2) - return True - - def expect_steady(self, name, fn, duration=0.5, detail=None): - """fn must stay true for the whole duration.""" - ok = self.stays(fn, duration) - return self.check(name, ok, detail() if callable(detail) else (detail or '')) - - def expect_pin(self, name, sfx, want, timeout=TIMEOUT, tol=1e-6): - is_float = self.pins[sfx][0] == hal.HAL_FLOAT - - def match(): - v = self.get(sfx) - if is_float: - return abs(v - want) <= tol - return v == want - return self.expect(name, match, timeout, - detail=lambda: 'halui.%s = %r, want %r' % (sfx, self.get(sfx), want)) - - def drain_errors(self): - out = [] - while True: - e = self.errors.poll() - if not e: - return out - out.append(e[1]) - - def reset_between_sections(self): - for sfx in sorted(self.touched): - if self.pins[sfx][1] == hal.HAL_IN and sfx not in self.external: - self.comp[sfx] = self.defaults[sfx] - time.sleep(0.3) - self.nml_abort() - - # -- task setup, via NML (not under test) ------------------------------ - - def nml_abort(self): - self.cmd.abort() - self.cmd.wait_complete() - self.wait_for(lambda: self.stat.interp_state == linuxcnc.INTERP_IDLE) - - def nml_state(self, state): - # task has no distinct OFF state: a request for OFF reads back as - # ESTOP_RESET - want = linuxcnc.STATE_ESTOP_RESET if state == linuxcnc.STATE_OFF else state - for attempt in range(1, STATE_RETRY_BUDGET + 1): - self.cmd.state(state) - self.cmd.wait_complete() - if self.wait_for(lambda: self.stat.task_state == want, - timeout=STATE_ATTEMPT_TIMEOUT): - return True - self.log('task_state %d not reached on attempt %d, retrying' - % (want, attempt)) - return False - - def machine_on(self): - if self.poll().task_state == linuxcnc.STATE_ON: - return - # Unconditional: a machine that is not ON may be in estop whatever the - # last poll said, and STATE_ON is refused until estop is cleared. - if not self.nml_state(linuxcnc.STATE_ESTOP_RESET): - raise RuntimeError('setup: could not clear estop') - if not self.nml_state(linuxcnc.STATE_ON): - raise RuntimeError('setup: could not turn the machine on') - - def machine_estop(self): - self.nml_state(linuxcnc.STATE_ESTOP) - - def nml_mode(self, mode): - self.cmd.mode(mode) - self.cmd.wait_complete() - if not self.wait_for(lambda: self.stat.task_mode == mode): - raise RuntimeError('setup: could not switch to mode %d' % mode) - - def nml_teleop(self, enable): - self.cmd.teleop_enable(enable) - self.cmd.wait_complete() - want = linuxcnc.TRAJ_MODE_TELEOP if enable else linuxcnc.TRAJ_MODE_FREE - if not self.wait_for(lambda: self.stat.motion_mode == want): - raise RuntimeError('setup: could not set teleop=%d' % enable) - - def nml_home_all(self): - # Note: once every joint is homed, task switches an identity-kins - # machine to teleop by itself. - self.nml_mode(linuxcnc.MODE_MANUAL) - self.cmd.home(-1) - self.cmd.wait_complete() - if not self.wait_for(lambda: all(self.stat.homed[:self.stat.joints]), 20): - raise RuntimeError('setup: homing failed') - - def nml_unhome_all(self): - # motion refuses to unhome in teleop ("must be in joint mode or - # disabled to unhome"), which is where homing leaves the machine - self.nml_mode(linuxcnc.MODE_MANUAL) - if self.poll().motion_mode == linuxcnc.TRAJ_MODE_TELEOP: - self.nml_teleop(0) - self.cmd.unhome(-1) - self.cmd.wait_complete() - if not self.wait_for(lambda: not any(self.stat.homed[:self.stat.joints])): - raise RuntimeError('setup: unhoming failed') - - def wait_idle(self, timeout=20): - return self.wait_for(lambda: self.stat.interp_state == linuxcnc.INTERP_IDLE - and self.stat.exec_state == linuxcnc.EXEC_DONE, timeout) - - def nml_mdi(self, code, timeout=20): - self.nml_mode(linuxcnc.MODE_MDI) - self.cmd.mdi(code) - self.cmd.wait_complete() - if not self.wait_idle(timeout): - raise RuntimeError('setup: MDI %r did not finish' % code) - - def joint_pos(self, j): - return self.stat.joint_actual_position[j] - - def axis_pos(self, a): - return self.stat.actual_position['xyzabcuvw'.index(a)] - - def wait_joint_still(self, j, timeout=10): - last = [None] - def still(): - p = self.joint_pos(j) - done = last[0] is not None and abs(p - last[0]) < 1e-9 and self.stat.inpos - last[0] = p - return done - return self.wait_for(still, timeout) - - -def run(*sections): - """Run each section function against one harness; report at the end. - - Between sections every input a test drove goes back to halui's default and - task is aborted, so a section cannot leave a held jog, a paused program or - a half-finished MDI behind for the next one. - """ - h = Halui() - for fn in sections: - h.section(fn.__name__) - try: - fn(h) - except Exception: - h.log(traceback.format_exc()) - h.check('%s ran to completion' % fn.__name__, False, 'exception, see above') - h.reset_between_sections() - h.finish() - - -def close(a, b, tol=1e-6): - return abs(a - b) <= tol - - -INCH_PER_MM = 1 / 25.4 diff --git a/tests/halui/_lib/launch.sh b/tests/halui/_lib/launch.sh deleted file mode 100755 index abb5f798f01..00000000000 --- a/tests/halui/_lib/launch.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Shared launcher for the halui pin tests. Each test directory's test.sh -# execs this from inside that directory. -# -# task rewrites the tool table (G10 L1, tool changes), so every run starts -# from a fresh copy of the shared one; tool.tbl is ignored by git. -cp ../_lib/tool.tbl tool.tbl -exec linuxcnc -r halui.ini diff --git a/tests/halui/_lib/tool.tbl b/tests/halui/_lib/tool.tbl deleted file mode 100644 index 25496163e24..00000000000 --- a/tests/halui/_lib/tool.tbl +++ /dev/null @@ -1,3 +0,0 @@ -T1 P1 Z0.5 D0.25 ;tool one -T2 P2 Z1.0 D0.5 ;tool two -T3 P3 Z0.0 D0.125 ;tool three diff --git a/tests/halui/axes/checkresult b/tests/halui/axes/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/axes/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/axes/halui.ini b/tests/halui/axes/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/axes/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/axes/test-ui.py b/tests/halui/axes/test-ui.py deleted file mode 100755 index 034580b0ef4..00000000000 --- a/tests/halui/axes/test-ui.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env python3 -"""halui: axis selection, teleop jogging and axis positions. - -Pins: axis.L.select, axis.L.is-selected, axis.selected, - axis.jog-speed, axis.jog-deadband, - axis.L.plus, axis.L.minus, axis.L.analog, - axis.L.increment, axis.L.increment-plus, axis.L.increment-minus, - axis.selected.plus, axis.selected.minus, axis.selected.increment, - axis.selected.increment-plus, axis.selected.increment-minus, - axis.L.pos-commanded, axis.L.pos-feedback, axis.L.pos-relative - -The machine is XYZ trivkins, so axis x/y/z is joint 0/1/2 one to one and -axis motion is measured through the joint velocities. Axis jog speed is in -units per minute; halui divides it by 60. -""" - -import math -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - -LETTERS = 'xyzabcuvw' -CONFIGURED = 'xyz' - - -def idx(a): - return LETTERS.index(a) - - -def av(h, a): - return h.stat.joint[idx(a)]['velocity'] - - -def pos(h, a): - return h.stat.actual_position[idx(a)] - - -def expect_velocity(h, a, v, why): - return h.expect('axis %s moves at %+.2f %s' % (a, v, why), - lambda: close(av(h, a), v, 1e-3), - detail=lambda: 'velocity %+.4f' % av(h, a)) - - -def expect_stopped(h, a, why): - h.expect('axis %s stops %s' % (a, why), lambda: close(av(h, a), 0.0, 1e-9) and h.stat.inpos, - detail=lambda: 'velocity %+.4f' % av(h, a)) - - -def expect_not_moving(h, a, why): - h.expect_steady('axis %s does not move %s' % (a, why), - lambda: close(av(h, a), 0.0, 1e-9), - detail=lambda: 'velocity %+.4f' % av(h, a)) - - -def expect_at(h, a, p, why): - return h.expect('axis %s ends at %+.3f %s' % (a, p, why), - lambda: close(pos(h, a), p, 1e-4) and h.stat.inpos, - timeout=10, detail=lambda: 'position %+.4f' % pos(h, a)) - - -def teleop(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - if not all(h.poll().homed[:3]): - h.nml_home_all() - if h.stat.motion_mode != L.TRAJ_MODE_TELEOP: - h.nml_teleop(1) - - -def to_zero(h): - h.machine_on() - if not all(h.poll().homed[:3]): - h.nml_home_all() - h.nml_mdi('G20 G90 G53 G0 X0 Y0 Z0') - teleop(h) - - -def expect_selected(h, a, why): - h.expect_pin('axis.selected is %d (%s) %s' % (idx(a), a, why), 'axis.selected', idx(a)) - for b in CONFIGURED: - h.expect_pin('axis.%s.is-selected is %s %s' % (b, a == b, why), - 'axis.%s.is-selected' % b, a == b) - - -def pins_and_defaults(h): - # input pins exist for all nine axes; status pins only for configured ones - for a in LETTERS: - for p in ('select', 'plus', 'minus', 'analog', 'increment', - 'increment-plus', 'increment-minus'): - if not h.has('axis.%s.%s' % (a, p)): - h.check('axis.%s.%s exists' % (a, p), False) - for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative'): - if h.has('axis.%s.%s' % (a, p)) != (a in CONFIGURED): - h.check('axis.%s.%s exists only if %s is configured' % (a, p, a), False) - h.check('axis input pins exist for all nine axes', True) - h.check('axis.jog-speed defaults to 0', close(h.default('axis.jog-speed'), 0.0)) - h.check('axis.jog-deadband defaults to 0.2', close(h.default('axis.jog-deadband'), 0.2)) - expect_selected(h, 'x', 'at startup') - - -def select(h): - h.pulse('axis.z.select') - expect_selected(h, 'z', 'after axis.z.select') - h.pulse('axis.y.select') - expect_selected(h, 'y', 'after axis.y.select') - h.pulse('axis.a.select') - expect_selected(h, 'y', 'after axis.a.select (A is not configured, ignored)') - h.set('axis.x.select', 1) - expect_selected(h, 'x', 'while axis.x.select is held') - h.pulse('axis.z.select') - expect_selected(h, 'z', 'after axis.z.select while axis.x.select is still held') - h.set('axis.x.select', 0) - h.settle() - expect_selected(h, 'z', 'after releasing axis.x.select') - - -def continuous_jog(h): - to_zero(h) - h.set('axis.jog-speed', 60) - for a in CONFIGURED: - h.set('axis.%s.plus' % a, 1) - expect_velocity(h, a, 1.0, 'while axis.%s.plus is held at jog-speed 60' % a) - h.set('axis.%s.plus' % a, 0) - expect_stopped(h, a, 'when axis.%s.plus is released' % a) - h.set('axis.%s.minus' % a, 1) - expect_velocity(h, a, -1.0, 'while axis.%s.minus is held' % a) - h.set('axis.%s.minus' % a, 0) - expect_stopped(h, a, 'when axis.%s.minus is released' % a) - - to_zero(h) - h.set('axis.jog-speed', 60) - h.set('axis.x.plus', 1) - expect_velocity(h, 'x', 1.0, 'at jog-speed 60') - h.set('axis.jog-speed', 120) - expect_velocity(h, 'x', 2.0, 'after jog-speed changes to 120 mid-jog') - h.set('axis.x.plus', 0) - expect_stopped(h, 'x', 'on release') - h.set('axis.jog-speed', 60) - - # pins for an axis the machine does not have do nothing - h.set('axis.b.plus', 1) - for a in CONFIGURED: - expect_not_moving(h, a, 'while axis.b.plus is held') - h.set('axis.b.plus', 0) - - -def jog_is_gated(h): - to_zero(h) - h.set('axis.jog-speed', 60) - h.nml_teleop(0) - h.set('axis.x.plus', 1) - expect_not_moving(h, 'x', 'in joint (free) mode') - h.set('axis.x.plus', 0) - - h.nml_state(L.STATE_OFF) - h.set('axis.y.plus', 1) - expect_not_moving(h, 'y', 'when the machine is off') - h.set('axis.y.plus', 0) - - -def analog_jog(h): - to_zero(h) - h.set('axis.jog-speed', 60) - h.set('axis.x.analog', 0.5) - expect_velocity(h, 'x', 0.5, 'at analog 0.5') - h.set('axis.x.analog', -0.8) - expect_velocity(h, 'x', -0.8, 'at analog -0.8') - h.set('axis.x.analog', 0.15) - expect_stopped(h, 'x', 'at analog 0.15, inside the 0.2 deadband') - h.set('axis.x.analog', 0.0) - h.set('axis.jog-deadband', 0.6) - h.set('axis.y.analog', 0.5) - expect_not_moving(h, 'y', 'at analog 0.5 with a 0.6 deadband') - h.set('axis.y.analog', 0.9) - expect_velocity(h, 'y', 0.9, 'at analog 0.9 with a 0.6 deadband') - h.set('axis.jog-speed', 30) - expect_velocity(h, 'y', 0.45, 'at analog 0.9 after jog-speed changes to 30') - h.set('axis.y.analog', 0.0) - expect_stopped(h, 'y', 'at analog 0') - h.set('axis.jog-deadband', 0.2) - h.set('axis.jog-speed', 60) - h.set('axis.z.analog', -0.4) - expect_velocity(h, 'z', -0.4, 'at analog -0.4') - h.set('axis.z.analog', 0.0) - expect_stopped(h, 'z', 'at analog 0') - - -def incremental_jog(h): - to_zero(h) - h.set('axis.jog-speed', 60) - for a in CONFIGURED: - h.set('axis.%s.increment' % a, 0.25) - h.pulse('axis.%s.increment-plus' % a) - expect_at(h, a, 0.25, 'after increment-plus') - h.pulse('axis.%s.increment-minus' % a) - expect_at(h, a, 0.0, 'after increment-minus') - - h.pulse('axis.y.select') - h.set('axis.selected.increment', 0.5) - h.pulse('axis.selected.increment-plus') - expect_at(h, 'y', 0.5, 'after axis.selected.increment-plus with y selected') - h.pulse('axis.selected.increment-minus') - expect_at(h, 'y', 0.0, 'after axis.selected.increment-minus') - h.check('the selected increment moved only y', - close(pos(h, 'x'), 0.0, 1e-4) and close(pos(h, 'z'), 0.0, 1e-4), - 'x=%+.4f z=%+.4f' % (pos(h, 'x'), pos(h, 'z'))) - - -def selected_jog(h): - to_zero(h) - h.set('axis.jog-speed', 60) - h.pulse('axis.x.select') - h.set('axis.selected.plus', 1) - expect_velocity(h, 'x', 1.0, 'while axis.selected.plus is held with x selected') - h.set('axis.selected.plus', 0) - expect_stopped(h, 'x', 'on release') - h.set('axis.selected.minus', 1) - expect_velocity(h, 'x', -1.0, 'while axis.selected.minus is held') - h.set('axis.selected.minus', 0) - expect_stopped(h, 'x', 'on release') - - # Changing the selection mid-jog should stop the old axis and start the - # new one, as it does for joints. For axes the restart looks at - # ajog_plus[num_axes] / ajog_minus[num_axes] -- the pins of the axis whose - # index equals the number of configured axes (A on this XYZ machine) -- - # instead of the selected slot ajog_*[EMCMOT_MAX_AXIS]. - h.set('axis.selected.plus', 1) - expect_velocity(h, 'x', 1.0, 'before the selection changes') - h.pulse('axis.y.select') - expect_stopped(h, 'x', 'when the selection moves to y mid-jog') - h.known_bug('a selected jog does not carry over to the newly selected axis', - h.stays(lambda: close(av(h, 'y'), 0.0, 1e-9), 0.8), - 'halui.cc check_hal_changes(): axis reselect reads ajog_plus[num_axes] ' - 'instead of ajog_plus[EMCMOT_MAX_AXIS]; y should be jogging at +1') - h.set('axis.selected.plus', 0) - h.nml_abort() - to_zero(h) - - # the same index error from the other side: A's pin (inert on this - # machine) starts a jog on whichever axis gets selected - h.pulse('axis.x.select') - h.set('axis.a.plus', 1) - expect_not_moving(h, 'x', 'while only axis.a.plus is held (A is not configured)') - h.pulse('axis.z.select') - h.known_bug('holding axis.a.plus makes a newly selected axis jog', - h.wait_for(lambda: close(av(h, 'z'), 1.0, 1e-3), 1.0), - 'same ajog_plus[num_axes] index: num_axes is 3 here, which is axis A; ' - 'z should stay still') - h.set('axis.a.plus', 0) - h.nml_abort() - - -def expected_relative(s, machine=None): - """halui's own formula (modify_hal_pins) from task's offsets. - - `machine` is the machine position to model from. Pass the position the - caller has just asserted rather than letting it default: a move is only - confirmed to expect_at()'s 1e-4, so actual_position can still be settling - by that much, while expect_positions() compares the result at 1e-6. Under - load that gap shows up as a ~5e-5 miss on pos-relative alone -- the - commanded/feedback checks compare against exact literals and pass. - """ - ax, ay, az = machine if machine is not None else s.actual_position[:3] - g5x, g92, tlo, rot = s.g5x_offset, s.g92_offset, s.tool_offset, s.rotation_xy - x = ax - g5x[0] - tlo[0] - y = ay - g5x[1] - tlo[1] - c, sn = math.cos(-rot * math.pi / 180), math.sin(-rot * math.pi / 180) - return (x * c - y * sn - g92[0], - y * c + x * sn - g92[1], - az - g5x[2] - g92[2] - tlo[2]) - - -def expect_positions(h, machine, relative, why): - for i, a in enumerate(CONFIGURED): - h.expect_pin('axis.%s.pos-commanded is %+.3f %s' % (a, machine[i], why), - 'axis.%s.pos-commanded' % a, machine[i], tol=1e-6) - h.expect_pin('axis.%s.pos-feedback is %+.3f %s' % (a, machine[i], why), - 'axis.%s.pos-feedback' % a, machine[i], tol=1e-6) - h.expect_pin('axis.%s.pos-relative is %+.3f %s' % (a, relative[i], why), - 'axis.%s.pos-relative' % a, relative[i], tol=1e-6) - - -def positions(h): - h.machine_on() - h.nml_home_all() - for code in ('G20 G90 G54', 'G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 R0', 'M61 Q0', - 'G53 G0 X1 Y2 Z0.5'): - h.nml_mdi(code) - expect_positions(h, (1, 2, 0.5), (1, 2, 0.5), 'with no offsets') - - for code in ('G10 L2 P1 X1 Y2 Z0.5 R30', 'M61 Q1', 'G43', 'G53 G0 X3 Y4 Z1', - 'G92 X0.5 Y-0.5'): - h.nml_mdi(code) - s = h.poll() - h.check('setup: task has a G54 offset, G92 offset, rotation and tool offset', - close(s.g5x_offset[0], 1) and close(s.rotation_xy, 30) and close(s.tool_offset[2], 0.5) - and not close(s.g92_offset[0], 0), - 'g5x=%s g92=%s rot=%s tlo=%s' % (s.g5x_offset[:3], s.g92_offset[:3], - s.rotation_xy, s.tool_offset[:3])) - rel = expected_relative(s) - expect_positions(h, (3, 4, 1), rel, 'with G54 + G92 + R30 + G43') - # G92 X0.5 Y-0.5 defines the current point as X0.5 Y-0.5 in program - # coordinates, and Z is machine 1 - G54 0.5 - tool 0.5 = 0 - for a, want in (('x', 0.5), ('y', -0.5), ('z', 0.0)): - h.expect_pin('axis.%s.pos-relative agrees with program coordinates (%+.2f)' % (a, want), - 'axis.%s.pos-relative' % a, want, tol=1e-6) - - # the pins follow motion - teleop(h) - h.set('axis.jog-speed', 60) - h.set('axis.x.increment', 0.5) - h.pulse('axis.x.increment-plus') - expect_at(h, 'x', 3.5, 'after an increment in teleop') - rel = expected_relative(h.poll(), (3.5, 4, 1)) - expect_positions(h, (3.5, 4, 1), rel, 'after moving X by 0.5') - - for code in ('G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 R0', 'M61 Q0'): - h.nml_mdi(code) - - -run(pins_and_defaults, - select, - continuous_jog, - jog_is_gated, - analog_jog, - incremental_jog, - selected_jog, - positions) diff --git a/tests/halui/axes/test.sh b/tests/halui/axes/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/axes/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/config-9axis/checkresult b/tests/halui/config-9axis/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/config-9axis/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/config-9axis/halui.ini b/tests/halui/config-9axis/halui.ini deleted file mode 100644 index e7501e2a64d..00000000000 --- a/tests/halui/config-9axis/halui.ini +++ /dev/null @@ -1,194 +0,0 @@ -# Nine-axis machine for the halui pin tests: trivkins XYZABCUVW, one joint -# per axis, so every per-axis halui pin exists and does something. - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = nine.hal - -[TRAJ] -COORDINATES = X Y Z A B C U V W -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -MAX_ANGULAR_VELOCITY = 60 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins coordinates=XYZABCUVW -JOINTS = 9 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_A] -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 - -[AXIS_B] -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 - -[AXIS_C] -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 - -[AXIS_U] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_V] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_W] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_3] -TYPE = ANGULAR -HOME = 0.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_4] -TYPE = ANGULAR -HOME = 0.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_5] -TYPE = ANGULAR -HOME = 0.0 -MAX_VELOCITY = 60 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -360.0 -MAX_LIMIT = 360.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_6] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_7] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 - -[JOINT_8] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 1.0 -MIN_FERROR = 0.5 -HOME_SEQUENCE = 0 diff --git a/tests/halui/config-9axis/nine.hal b/tests/halui/config-9axis/nine.hal deleted file mode 100644 index e90685ec8ab..00000000000 --- a/tests/halui/config-9axis/nine.hal +++ /dev/null @@ -1,19 +0,0 @@ -# nine joints, looped back -loadrt [KINS]KINEMATICS -loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS -addf motion-command-handler servo-thread -addf motion-controller servo-thread - -net j0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb -net j1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb -net j2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb -net j3pos joint.3.motor-pos-cmd => joint.3.motor-pos-fb -net j4pos joint.4.motor-pos-cmd => joint.4.motor-pos-fb -net j5pos joint.5.motor-pos-cmd => joint.5.motor-pos-fb -net j6pos joint.6.motor-pos-cmd => joint.6.motor-pos-fb -net j7pos joint.7.motor-pos-cmd => joint.7.motor-pos-fb -net j8pos joint.8.motor-pos-cmd => joint.8.motor-pos-fb - -net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in -net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared -net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed diff --git a/tests/halui/config-9axis/test-ui.py b/tests/halui/config-9axis/test-ui.py deleted file mode 100755 index 25f33eb7c03..00000000000 --- a/tests/halui/config-9axis/test-ui.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -"""halui on a nine-axis machine (trivkins XYZABCUVW, joint N drives axis N). - -Every per-axis halui pin exists here, so this covers selection, jogging, -positions and tool length offsets for A, B, C, U, V and W too. -""" - -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - -LETTERS = 'xyzabcuvw' - - -def jv(h, j): - return h.stat.joint[j]['velocity'] - - -def teleop(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - if not all(h.poll().homed[:9]): - h.nml_home_all() - if h.stat.motion_mode != L.TRAJ_MODE_TELEOP: - h.nml_teleop(1) - - -def pins(h): - missing = ['axis.%s.%s' % (a, p) for a in LETTERS - for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative', - 'select', 'plus', 'minus', 'analog', 'increment', - 'increment-plus', 'increment-minus') - if not h.has('axis.%s.%s' % (a, p))] - h.check('every axis has its full set of pins', not missing, 'missing: %s' % missing) - h.check('joint pins exist for all nine joints', - all(h.has('joint.%d.is-homed' % j) for j in range(9))) - - -def select_every_axis(h): - for i, a in enumerate(LETTERS): - h.pulse('axis.%s.select' % a) - h.expect_pin('axis.selected is %d after axis.%s.select' % (i, a), 'axis.selected', i) - wrong = [b for b in LETTERS if h.get('axis.%s.is-selected' % b) != (a == b)] - h.check('only axis.%s.is-selected is set' % a, not wrong, 'also set/unset: %s' % wrong) - - -def jog_every_axis(h): - teleop(h) - h.set('axis.jog-speed', 60) - for i, a in enumerate(LETTERS): - h.set('axis.%s.plus' % a, 1) - h.expect('axis.%s.plus jogs joint %d' % (a, i), lambda i=i: close(jv(h, i), 1.0, 1e-3), - detail=lambda i=i: 'joint %d velocity %+.4f' % (i, jv(h, i))) - others = [j for j in range(9) if j != i and not close(jv(h, j), 0.0, 1e-9)] - h.check('only joint %d moves' % i, not others, 'also moving: %s' % others) - h.set('axis.%s.plus' % a, 0) - h.expect('axis %s stops on release' % a, - lambda i=i: close(jv(h, i), 0.0, 1e-9) and h.stat.inpos) - - -def reselect_carries_over(h): - # On an XYZ machine this is a known bug (see tests/halui/axes): the - # restart reads ajog_plus[num_axes]. Here num_axes == EMCMOT_MAX_AXIS == 9, - # which happens to be the right slot, so the jog does carry over. - teleop(h) - h.set('axis.jog-speed', 60) - h.pulse('axis.x.select') - h.set('axis.selected.plus', 1) - h.expect('x jogs as the selected axis', lambda: close(jv(h, 0), 1.0, 1e-3)) - h.pulse('axis.y.select') - h.expect('x stops when the selection moves to y', lambda: close(jv(h, 0), 0.0, 1e-9)) - h.expect('y picks up the selected jog (correct only because num_axes is 9 here)', - lambda: close(jv(h, 1), 1.0, 1e-3)) - h.set('axis.selected.plus', 0) - h.expect('y stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) - - -def expect_positions(h, machine, relative, why): - for i, a in enumerate(LETTERS): - h.expect_pin('axis.%s.pos-commanded is %g %s' % (a, machine[i], why), - 'axis.%s.pos-commanded' % a, machine[i], tol=1e-6) - h.expect_pin('axis.%s.pos-feedback is %g %s' % (a, machine[i], why), - 'axis.%s.pos-feedback' % a, machine[i], tol=1e-6) - h.expect_pin('axis.%s.pos-relative is %g %s' % (a, relative[i], why), - 'axis.%s.pos-relative' % a, relative[i], tol=1e-6) - - -def expect_tool_offsets(h, offsets, why): - for i, a in enumerate(LETTERS): - h.expect_pin('tool.length_offset.%s is %g %s' % (a, offsets[i], why), - 'tool.length_offset.' + a, offsets[i], tol=1e-6) - - -def positions_and_offsets(h): - h.machine_on() - h.nml_home_all() - for code in ('G20 G90 G54 G49', 'G92.1', 'G10 L2 P1 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 R0'): - h.nml_mdi(code) - - machine = [i + 2 for i in range(9)] - h.nml_mdi('G53 G0 X2 Y3 Z4 A5 B6 C7 U8 V9 W10') - expect_positions(h, machine, machine, 'with no offsets') - expect_tool_offsets(h, [0] * 9, 'with no tool offset') - - h.nml_mdi('G10 L2 P1 X1 Y2 Z3 A4 B5 C6 U7 V8 W9') - work = [1 + i for i in range(9)] - expect_positions(h, machine, [m - w for m, w in zip(machine, work)], 'with a G54 offset on every axis') - - tlo = [round(0.1 * (i + 1), 1) for i in range(9)] - h.nml_mdi('G43.1 X0.1 Y0.2 Z0.3 A0.4 B0.5 C0.6 U0.7 V0.8 W0.9') - expect_tool_offsets(h, tlo, 'after G43.1 on every axis') - expect_positions(h, machine, [m - w - t for m, w, t in zip(machine, work, tlo)], - 'with G54 and a tool offset on every axis') - - h.nml_mdi('G92 A0 U0 W0') - s = h.poll() - for i, a in ((3, 'a'), (6, 'u'), (8, 'w')): - h.expect_pin('axis.%s.pos-relative is 0 after G92 %s0' % (a, a.upper()), - 'axis.%s.pos-relative' % a, 0.0, tol=1e-6) - h.check('setup: G92 left the other axes alone', close(s.g92_offset[4], 0.0)) - - for code in ('G92.1', 'G49', 'G10 L2 P1 X0 Y0 Z0 A0 B0 C0 U0 V0 W0'): - h.nml_mdi(code) - - -run(pins, select_every_axis, jog_every_axis, reselect_carries_over, positions_and_offsets) diff --git a/tests/halui/config-9axis/test.sh b/tests/halui/config-9axis/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/config-9axis/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/config-minimal/checkresult b/tests/halui/config-minimal/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/config-minimal/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/config-minimal/halui.ini b/tests/halui/config-minimal/halui.ini deleted file mode 100644 index f6e70986383..00000000000 --- a/tests/halui/config-minimal/halui.ini +++ /dev/null @@ -1,74 +0,0 @@ -# Minimal/odd machine for the halui pin tests: two joints driving Y and Z, -# two spindles, no home sequence and no MDI commands -- so halui.home-all, -# halui.halui-mdi-is-running and halui.mdi-command-NN must not exist. - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = minimal.hal - -[TRAJ] -COORDINATES = Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 2 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins coordinates=YZ -JOINTS = 2 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 diff --git a/tests/halui/config-minimal/minimal.hal b/tests/halui/config-minimal/minimal.hal deleted file mode 100644 index c9cbd1effbf..00000000000 --- a/tests/halui/config-minimal/minimal.hal +++ /dev/null @@ -1,12 +0,0 @@ -# two joints, two spindles, everything looped back -loadrt [KINS]KINEMATICS -loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS num_spindles=[TRAJ]SPINDLES -addf motion-command-handler servo-thread -addf motion-controller servo-thread - -net j0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb -net j1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb - -net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in -net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared -net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed diff --git a/tests/halui/config-minimal/test-ui.py b/tests/halui/config-minimal/test-ui.py deleted file mode 100755 index 69d8488810b..00000000000 --- a/tests/halui/config-minimal/test-ui.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env python3 -"""halui on a two-joint YZ machine with two spindles, no home sequence and -no MDI commands. - -Checks which pins exist for this configuration, that a second spindle is -driven independently, and how axis selection starts up when the first -configured axis is not X. Joint 0 drives Y and joint 1 drives Z. -""" - -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - -LETTERS = 'xyzabcuvw' -CONFIGURED = 'yz' -JOINT_OF = {'y': 0, 'z': 1} - - -def jv(h, j): - return h.stat.joint[j]['velocity'] - - -def home_each(h): - # there is no home sequence, so home-all is not an option: one at a time - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - for j in (0, 1): - if not h.poll().homed[j]: - h.cmd.home(j) - h.cmd.wait_complete() - if not h.wait_for(lambda j=j: h.stat.homed[j]): - raise RuntimeError('setup: could not home joint %d' % j) - - -def teleop(h): - home_each(h) - if h.poll().motion_mode != L.TRAJ_MODE_TELEOP: - h.nml_teleop(1) - - -def pins(h): - h.check('no home-all pin without [JOINT_n]HOME_SEQUENCE', not h.has('home-all')) - h.check('no halui-mdi-is-running pin without [HALUI]MDI_COMMAND', - not h.has('halui-mdi-is-running')) - h.check('no mdi-command pins without [HALUI]MDI_COMMAND', - not any(p.startswith('mdi-command-') for p in h.pins)) - h.check('joint pins exist for joints 0 and 1', - all(h.has('joint.%d.%s' % (j, p)) for j in (0, 1) for p in ('home', 'is-homed', 'plus'))) - h.check('no pins for joint 2', not any(p.startswith('joint.2.') for p in h.pins)) - h.check('spindle pins exist for spindles 0 and 1', - all(h.has('spindle.%d.%s' % (s, p)) for s in (0, 1) - for p in ('start', 'is-on', 'brake-on', 'override.value'))) - h.check('no pins for spindle 2', not any(p.startswith('spindle.2.') for p in h.pins)) - wrong = [a for a in LETTERS - for p in ('is-selected', 'pos-commanded', 'pos-feedback', 'pos-relative') - if h.has('axis.%s.%s' % (a, p)) != (a in CONFIGURED)] - h.check('axis status pins exist only for Y and Z', not wrong, 'wrong: %s' % wrong) - h.check('axis input pins exist for all nine axes', - all(h.has('axis.%s.plus' % a) for a in LETTERS)) - - -def startup_selection(h): - h.expect_pin('joint.0.is-selected is true at startup', 'joint.0.is-selected', True) - h.expect_pin('axis.y.is-selected marks the first configured axis', 'axis.y.is-selected', True) - h.expect_pin('axis.z.is-selected is false at startup', 'axis.z.is-selected', False) - h.known_bug('axis.selected is 0 (X, not on this machine) at startup', - h.get('axis.selected') == 0, - 'hal_init_pins() sets axis_selected to 0 while halui_hal_init() marks the ' - 'first configured axis (Y, index 1) as selected; should be 1') - - teleop(h) - h.set('axis.jog-speed', 60) - h.set('axis.selected.plus', 1) - h.known_bug('axis.selected.plus at startup does not jog the axis shown as selected', - h.stays(lambda: close(jv(h, JOINT_OF['y']), 0.0, 1e-9), 0.8), - 'the jog goes to axis index 0 (X), which halui then drops as not configured') - h.set('axis.selected.plus', 0) - h.settle() - - h.pulse('axis.y.select') - h.expect_pin('pressing axis.y.select makes axis.selected 1', 'axis.selected', 1) - h.set('axis.selected.plus', 1) - h.expect('after that, axis.selected.plus jogs Y', - lambda: close(jv(h, JOINT_OF['y']), 1.0, 1e-3), - detail=lambda: 'joint 0 velocity %+.4f' % jv(h, 0)) - h.set('axis.selected.plus', 0) - h.expect('Y stops on release', lambda: close(jv(h, 0), 0.0, 1e-9) and h.stat.inpos) - - -def second_spindle(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - - def sp(s): - return h.stat.spindle[s] - - h.pulse('spindle.1.start') - h.expect('spindle.1.start turns spindle 1 on', - lambda: sp(1)['enabled'] and sp(1)['speed'] == 1) - h.check('spindle 0 stays off', not sp(0)['enabled']) - h.expect_pin('spindle.1.is-on sets', 'spindle.1.is-on', True) - h.expect_pin('spindle.1.runs-forward sets', 'spindle.1.runs-forward', True) - h.expect_pin('spindle.0.is-on stays false', 'spindle.0.is-on', False) - - h.pulse('spindle.1.reverse') - h.expect('spindle.1.reverse reverses spindle 1', lambda: sp(1)['direction'] == -1) - h.expect_pin('spindle.1.runs-backward sets', 'spindle.1.runs-backward', True) - h.pulse('spindle.1.stop') - h.expect('spindle.1.stop stops spindle 1', lambda: not sp(1)['enabled']) - h.expect_pin('spindle.1.is-on clears', 'spindle.1.is-on', False) - - brake0 = sp(0)['brake'] - h.pulse('spindle.1.brake-on') - h.expect('spindle.1.brake-on engages brake 1', lambda: sp(1)['brake'] == 1) - h.expect_pin('spindle.1.brake-is-on sets', 'spindle.1.brake-is-on', True) - h.check('brake 0 is untouched', sp(0)['brake'] == brake0, - 'brake 0 was %d, now %d' % (brake0, sp(0)['brake'])) - h.pulse('spindle.1.brake-off') - h.expect_pin('spindle.1.brake-is-on clears', 'spindle.1.brake-is-on', False) - - # no [DISPLAY] spindle override limits here: halui clamps to 0 .. 1.0 - h.pulse('spindle.1.override.decrease') - h.expect('spindle.1.override.decrease lowers override 1', - lambda: close(sp(1)['override'], 0.9)) - h.check('override 0 is untouched', close(sp(0)['override'], 1.0)) - h.expect_pin('spindle.1.override.value follows', 'spindle.1.override.value', 0.9) - h.pulse('spindle.1.override.increase') - h.pulse('spindle.1.override.increase') - h.expect('spindle 1 override is clamped at the default maximum of 1.0', - lambda: close(sp(1)['override'], 1.0)) - h.set('spindle.1.override.counts', -3) - h.expect('spindle.1.override.counts moves override 1', lambda: close(sp(1)['override'], 0.7)) - h.pulse('spindle.1.override.reset') - h.expect('spindle.1.override.reset puts it back to 1.0', lambda: close(sp(1)['override'], 1.0)) - - -def motion(h): - home_each(h) - if h.poll().motion_mode != L.TRAJ_MODE_FREE: - h.nml_teleop(0) - h.set('joint.jog-speed', 60) - h.set('joint.1.plus', 1) - h.expect('joint.1.plus jogs joint 1', lambda: close(jv(h, 1), 1.0, 1e-3)) - h.set('joint.1.plus', 0) - h.expect('joint 1 stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) - - teleop(h) - h.set('axis.jog-speed', 60) - h.set('axis.z.plus', 1) - h.expect('axis.z.plus moves joint 1 (Z)', lambda: close(jv(h, 1), 1.0, 1e-3)) - h.set('axis.z.plus', 0) - h.expect('Z stops on release', lambda: close(jv(h, 1), 0.0, 1e-9) and h.stat.inpos) - h.set('axis.y.minus', 1) - h.expect('axis.y.minus moves joint 0 (Y) backwards', lambda: close(jv(h, 0), -1.0, 1e-3)) - h.set('axis.y.minus', 0) - h.expect('Y stops on release', lambda: close(jv(h, 0), 0.0, 1e-9) and h.stat.inpos) - - h.set('axis.x.plus', 1) - h.expect_steady('axis.x.plus moves nothing on a machine without X', - lambda: close(jv(h, 0), 0.0, 1e-9) and close(jv(h, 1), 0.0, 1e-9)) - h.set('axis.x.plus', 0) - - h.nml_mdi('G20 G90 G53 G0 Y1.5 Z-0.5') - h.expect_pin('axis.y.pos-feedback shows Y', 'axis.y.pos-feedback', 1.5) - h.expect_pin('axis.z.pos-feedback shows Z', 'axis.z.pos-feedback', -0.5) - - -run(pins, startup_selection, second_spindle, motion) diff --git a/tests/halui/config-minimal/test.sh b/tests/halui/config-minimal/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/config-minimal/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/joints/checkresult b/tests/halui/joints/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/joints/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/joints/halui.ini b/tests/halui/joints/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/joints/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/joints/test-ui.py b/tests/halui/joints/test-ui.py deleted file mode 100755 index 77affb3603f..00000000000 --- a/tests/halui/joints/test-ui.py +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/env python3 -"""halui: joint selection, homing, joint status and joint jogging. - -Pins: joint.N.select, joint.N.is-selected, joint.selected, - joint.N.home, joint.N.unhome, joint.selected.home, joint.selected.unhome, - home-all, joint.N.is-homed, joint.selected.is-homed, - joint.N.on-{soft,hard}-{min,max}-limit, joint.N.has-fault, - joint.N.override-limits and the joint.selected.* mirrors of those, - joint.jog-speed, joint.jog-deadband, - joint.N.plus, joint.N.minus, joint.N.analog, - joint.N.increment, joint.N.increment-plus, joint.N.increment-minus, - joint.selected.plus, joint.selected.minus, joint.selected.increment, - joint.selected.increment-plus, joint.selected.increment-minus - -Joint jog speed is in units per minute; halui divides it by 60. -""" - -import os -import sys -import time - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import hal # noqa: E402 -import linuxcnc as L # noqa: E402 - -JOINTS = 3 - - -def jv(h, j): - return h.stat.joint[j]['velocity'] - - -def expect_velocity(h, j, v, why): - return h.expect('joint %d moves at %+.2f %s' % (j, v, why), - lambda: close(jv(h, j), v, 1e-3), - detail=lambda: 'velocity %+.4f' % jv(h, j)) - - -def expect_stopped(h, j, why): - # per joint: the global in-position flag stays false while another joint - # is still moving - ok = h.wait_for(lambda: close(jv(h, j), 0.0, 1e-9)) and \ - h.stays(lambda: close(jv(h, j), 0.0, 1e-9), 0.2) - h.check('joint %d stops %s' % (j, why), ok, 'velocity %+.4f' % jv(h, j)) - - -def expect_not_moving(h, j, why): - h.expect_steady('joint %d does not move %s' % (j, why), - lambda: close(jv(h, j), 0.0, 1e-9), - detail=lambda: 'velocity %+.4f' % jv(h, j)) - - -def manual_joint_mode(h, homed=False): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - if homed: - h.nml_home_all() - if h.poll().motion_mode != L.TRAJ_MODE_FREE: - h.nml_teleop(0) - - -def to_zero(h): - manual_joint_mode(h) - h.nml_mdi('G20 G90 G53 G0 X0 Y0 Z0') - h.nml_mode(L.MODE_MANUAL) - if h.poll().motion_mode != L.TRAJ_MODE_FREE: - h.nml_teleop(0) - - -def expect_selected(h, j, why): - h.expect_pin('joint.selected is %d %s' % (j, why), 'joint.selected', j) - for k in range(JOINTS): - h.expect_pin('joint.%d.is-selected is %s %s' % (k, k == j, why), - 'joint.%d.is-selected' % k, k == j) - - -def pins_and_defaults(h): - for j in range(JOINTS): - for p in ('select', 'is-selected', 'home', 'unhome', 'is-homed', 'plus', 'minus', - 'analog', 'increment', 'increment-plus', 'increment-minus', - 'on-soft-min-limit', 'on-soft-max-limit', 'on-hard-min-limit', - 'on-hard-max-limit', 'has-fault', 'override-limits'): - if not h.has('joint.%d.%s' % (j, p)): - h.check('joint.%d.%s exists' % (j, p), False) - h.check('there are no pins for a joint the machine does not have', - not any(s.startswith('joint.%d.' % JOINTS) for s in h.pins)) - h.check('home-all exists because [JOINT_0]HOME_SEQUENCE is set', h.has('home-all')) - h.check('joint.jog-speed defaults to 0', close(h.default('joint.jog-speed'), 0.0)) - h.check('joint.jog-deadband defaults to 0.2', close(h.default('joint.jog-deadband'), 0.2)) - expect_selected(h, 0, 'at startup') - - -def select(h): - h.pulse('joint.2.select') - expect_selected(h, 2, 'after joint.2.select') - h.pulse('joint.1.select') - expect_selected(h, 1, 'after joint.1.select') - - # selection follows the latest rising edge, even while another select is held - h.set('joint.0.select', 1) - expect_selected(h, 0, 'while joint.0.select is held') - h.pulse('joint.2.select') - expect_selected(h, 2, 'after joint.2.select while joint.0.select is still held') - h.set('joint.0.select', 0) - h.settle() - expect_selected(h, 2, 'after releasing joint.0.select (falling edges do nothing)') - - -def homing(h): - manual_joint_mode(h) - h.nml_unhome_all() - for j in range(JOINTS): - h.expect_pin('joint.%d.is-homed is false after unhoming' % j, 'joint.%d.is-homed' % j, False) - - h.pulse('joint.1.home') - h.expect('joint.1.home homes joint 1', lambda: h.stat.homed[1]) - h.expect_pin('joint.1.is-homed sets', 'joint.1.is-homed', True) - h.pulse('joint.1.unhome') - h.expect('joint.1.unhome unhomes joint 1', lambda: not h.stat.homed[1]) - h.expect_pin('joint.1.is-homed clears', 'joint.1.is-homed', False) - - h.pulse('joint.2.select') - h.expect_pin('joint.selected.is-homed is false for unhomed joint 2', - 'joint.selected.is-homed', False) - h.pulse('joint.selected.home') - h.expect('joint.selected.home homes the selected joint (2)', lambda: h.stat.homed[2]) - h.expect_pin('joint.selected.is-homed follows joint 2', 'joint.selected.is-homed', True) - h.pulse('joint.selected.unhome') - h.expect('joint.selected.unhome unhomes the selected joint (2)', lambda: not h.stat.homed[2]) - h.expect_pin('joint.selected.is-homed clears', 'joint.selected.is-homed', False) - - h.pulse('home-all') - h.expect('home-all homes every joint', lambda: all(h.stat.homed[:JOINTS]), timeout=20) - for j in range(JOINTS): - h.expect_pin('joint.%d.is-homed is true after home-all' % j, 'joint.%d.is-homed' % j, True) - h.expect_pin('joint.selected.is-homed is true after home-all', 'joint.selected.is-homed', True) - # task puts an identity-kins machine into teleop once everything is homed - h.expect_pin('mode.is-teleop reports the switch to teleop after homing', 'mode.is-teleop', True) - - # homing is refused while in ESTOP - h.nml_unhome_all() - h.machine_estop() - h.pulse('joint.0.home') - h.expect_steady('joint.0.home in ESTOP does not home', lambda: not h.stat.homed[0]) - h.pulse('home-all') - h.expect_steady('home-all in ESTOP does not home', lambda: not any(h.stat.homed[:JOINTS])) - - -def hard_limits_and_fault(h): - manual_joint_mode(h, homed=True) - h.set('joint.jog-speed', 60) - h.set('joint.0.increment', 0.1) - for kind, motion_pin, key in (('min', 'neg-lim-sw-in', 'min_hard_limit'), - ('max', 'pos-lim-sw-in', 'max_hard_limit')): - manual_joint_mode(h) - h.pulse('joint.0.select') - pin = 'joint.0.on-hard-%s-limit' % kind - sel = 'joint.selected.on-hard-%s-limit' % kind - h.expect_pin('%s is false with the switch open' % pin, pin, False) - hal.set_p('joint.0.' + motion_pin, '1') - h.expect('task sees joint 0 on its hard %s limit' % kind, - lambda k=key: h.stat.joint[0][k]) - h.expect_pin('%s sets' % pin, pin, True) - h.expect_pin('%s follows selected joint 0' % sel, sel, True) - for other in (1, 2): - h.expect_pin('joint.%d.on-hard-%s-limit stays false' % (other, kind), - 'joint.%d.on-hard-%s-limit' % (other, kind), False) - h.pulse('joint.1.select') - h.expect_pin('%s is false while joint 1 is selected' % sel, sel, False) - h.expect_pin('%s is still set for joint 0' % pin, pin, True) - h.pulse('joint.0.select') - h.expect_pin('%s follows joint 0 again once it is reselected' % sel, sel, True) - - # override-limits is a status pin in halui; the override comes over - # NML. task reports one flag for all joints (taskintf.cc: - # overrideLimits = !!overrideLimitMask), so every joint shows it. - h.cmd.override_limits() - h.cmd.wait_complete() - h.expect('task reports the limits overridden', lambda: h.stat.joint[0]['override_limits']) - for j in range(JOINTS): - h.expect_pin('joint.%d.override-limits is set (one flag for all joints)' % j, - 'joint.%d.override-limits' % j, True) - h.expect_pin('joint.selected.override-limits is set', 'joint.selected.override-limits', True) - - hal.set_p('joint.0.' + motion_pin, '0') - h.expect('the hard %s limit clears in task' % kind, lambda k=key: not h.stat.joint[0][k]) - h.expect_pin('%s clears' % pin, pin, False) - h.expect_pin('%s clears' % sel, sel, False) - - # motion drops the override once a jog made while overridden finishes - manual_joint_mode(h) - h.expect_pin('override-limits is still set before any jog', 'joint.0.override-limits', True) - h.pulse('joint.0.increment-plus' if kind == 'min' else 'joint.0.increment-minus') - h.expect('the jog off the switch completes', lambda: h.stat.inpos and close(jv(h, 0), 0.0, 1e-9)) - for j in range(JOINTS): - h.expect_pin('joint.%d.override-limits clears after that jog' % j, - 'joint.%d.override-limits' % j, False) - - manual_joint_mode(h) - h.pulse('joint.2.select') - h.expect_pin('joint.2.has-fault is false', 'joint.2.has-fault', False) - hal.set_p('joint.2.amp-fault-in', '1') - h.expect('task sees the joint 2 amp fault', lambda: h.stat.joint[2]['fault']) - h.expect_pin('joint.2.has-fault sets', 'joint.2.has-fault', True) - h.expect_pin('joint.selected.has-fault follows joint 2', 'joint.selected.has-fault', True) - h.expect_pin('joint.0.has-fault stays false', 'joint.0.has-fault', False) - hal.set_p('joint.2.amp-fault-in', '0') - manual_joint_mode(h) - h.expect('the fault clears in task', lambda: not h.stat.joint[2]['fault']) - h.expect_pin('joint.2.has-fault clears', 'joint.2.has-fault', False) - h.expect_pin('joint.selected.has-fault clears', 'joint.selected.has-fault', False) - - -def soft_limit_pins_never_set(h): - # task never reports per-joint soft limits: taskintf.cc hard-codes - # minSoftLimit/maxSoftLimit to 0 ("soft limits are now applied to the - # command, and should never happen"). motion does still detect a joint - # beyond its soft limit and says so on motion.on-soft-limit. - # - # [JOINT_2] limits are -4 .. 4 and the joint sits at 0. Move the limit - # past the joint through task's ini.N.* pins -- the case motion's own - # comment names as the way this happens. motion then wants the joint - # unhomed before it will move again, so this runs last. - to_zero(h) - manual_joint_mode(h, homed=True) - h.pulse('joint.2.select') - for kind, ini_pin, value in (('min', 'ini.2.min_limit', 1.0), - ('max', 'ini.2.max_limit', -1.0)): - pin = 'joint.2.on-soft-%s-limit' % kind - sel = 'joint.selected.on-soft-%s-limit' % kind - h.expect_pin('%s is false inside the limits' % pin, pin, False) - old = hal.get_value(ini_pin) - hal.set_p(ini_pin, str(value)) - h.expect('motion reports joint 2 beyond its soft %s limit' % kind, - lambda: hal.get_value('motion.on-soft-limit')) - h.known_bug('%s stays false while joint 2 is past that limit' % pin, - h.stays(lambda p=pin, s=sel: not h.get(p) and not h.get(s), 0.5), - 'task hard-codes minSoftLimit/maxSoftLimit to 0 (taskintf.cc), so ' - 'halui.joint.N.on-soft-*-limit and the selected mirrors can never be set') - hal.set_p(ini_pin, str(old)) - h.expect('motion clears on-soft-limit once the limit is restored', - lambda: not hal.get_value('motion.on-soft-limit')) - h.check('the ini limit is back to %g' % old, close(hal.get_value(ini_pin), old)) - h.nml_unhome_all() - - -def continuous_jog(h): - to_zero(h) - h.set('joint.jog-speed', 60) - for j in range(JOINTS): - h.set('joint.%d.plus' % j, 1) - expect_velocity(h, j, 1.0, 'while joint.%d.plus is held at jog-speed 60' % j) - h.set('joint.%d.plus' % j, 0) - expect_stopped(h, j, 'when joint.%d.plus is released' % j) - h.set('joint.%d.minus' % j, 1) - expect_velocity(h, j, -1.0, 'while joint.%d.minus is held' % j) - h.set('joint.%d.minus' % j, 0) - expect_stopped(h, j, 'when joint.%d.minus is released' % j) - - to_zero(h) - h.set('joint.0.plus', 1) - expect_velocity(h, 0, 1.0, 'at jog-speed 60') - h.set('joint.jog-speed', 120) - expect_velocity(h, 0, 2.0, 'after jog-speed changes to 120 mid-jog') - h.set('joint.jog-speed', 30) - expect_velocity(h, 0, 0.5, 'after jog-speed changes to 30 mid-jog') - h.set('joint.0.plus', 0) - expect_stopped(h, 0, 'on release') - - h.set('joint.jog-speed', 60) - h.set('joint.1.plus', 1) - h.set('joint.2.minus', 1) - expect_velocity(h, 1, 1.0, 'together with joint 2') - expect_velocity(h, 2, -1.0, 'together with joint 1') - h.set('joint.1.plus', 0) - expect_stopped(h, 1, 'on release while joint 2 keeps going') - expect_velocity(h, 2, -1.0, 'after joint 1 is released') - h.set('joint.2.minus', 0) - expect_stopped(h, 2, 'on release') - - h.set('joint.jog-speed', 0) - h.set('joint.0.plus', 1) - expect_not_moving(h, 0, 'at jog-speed 0') - h.set('joint.0.plus', 0) - h.set('joint.jog-speed', 60) - - -def jog_is_gated(h): - to_zero(h) - h.set('joint.jog-speed', 60) - - h.nml_state(L.STATE_OFF) - h.set('joint.0.plus', 1) - expect_not_moving(h, 0, 'when the machine is off') - h.set('joint.0.plus', 0) - - manual_joint_mode(h, homed=True) - h.nml_teleop(1) - h.set('joint.0.plus', 1) - expect_not_moving(h, 0, 'in teleop mode') - h.set('joint.0.plus', 0) - h.nml_teleop(0) - - # abort stops a jog; the held input does not restart it - h.set('joint.0.plus', 1) - expect_velocity(h, 0, 1.0, 'before abort') - h.pulse('abort') - expect_stopped(h, 0, 'after abort') - expect_not_moving(h, 0, 'while joint.0.plus is still held after abort') - h.set('joint.0.plus', 0) - - -def analog_jog(h): - to_zero(h) - h.set('joint.jog-speed', 60) - h.set('joint.0.analog', 0.5) - expect_velocity(h, 0, 0.5, 'at analog 0.5') - h.set('joint.0.analog', -0.8) - expect_velocity(h, 0, -0.8, 'at analog -0.8') - h.set('joint.0.analog', 0.1) - expect_stopped(h, 0, 'at analog 0.1, inside the 0.2 deadband') - h.set('joint.0.analog', 0.3) - expect_velocity(h, 0, 0.3, 'at analog 0.3') - h.set('joint.jog-speed', 120) - expect_velocity(h, 0, 0.6, 'at analog 0.3 after jog-speed changes to 120') - h.set('joint.jog-speed', 60) - h.set('joint.0.analog', 0.0) - expect_stopped(h, 0, 'at analog 0') - - h.set('joint.jog-deadband', 0.6) - h.set('joint.0.analog', 0.5) - expect_not_moving(h, 0, 'at analog 0.5 with a 0.6 deadband') - h.set('joint.0.analog', 0.7) - expect_velocity(h, 0, 0.7, 'at analog 0.7 with a 0.6 deadband') - h.set('joint.0.analog', -0.65) - expect_velocity(h, 0, -0.65, 'at analog -0.65 with a 0.6 deadband') - h.set('joint.0.analog', 0.0) - expect_stopped(h, 0, 'at analog 0') - h.set('joint.jog-deadband', 0.2) - - for j in (1, 2): - h.set('joint.%d.analog' % j, -0.4) - expect_velocity(h, j, -0.4, 'at analog -0.4') - h.set('joint.%d.analog' % j, 0.0) - expect_stopped(h, j, 'at analog 0') - - -def expect_at(h, j, pos, why): - return h.expect('joint %d ends at %+.3f %s' % (j, pos, why), - lambda: close(h.joint_pos(j), pos, 1e-4) and h.stat.inpos, - timeout=10, detail=lambda: 'position %+.4f' % h.joint_pos(j)) - - -def incremental_jog(h): - to_zero(h) - h.set('joint.jog-speed', 60) - for j in range(JOINTS): - h.set('joint.%d.increment' % j, 0.25) - h.pulse('joint.%d.increment-plus' % j) - expect_at(h, j, 0.25, 'after increment-plus') - h.pulse('joint.%d.increment-minus' % j) - expect_at(h, j, 0.0, 'after increment-minus') - - h.set('joint.0.increment-plus', 1) - expect_at(h, 0, 0.25, 'while increment-plus is held') - h.expect_steady('a held increment-plus moves only once', - lambda: close(h.joint_pos(0), 0.25, 1e-4), duration=0.6) - h.set('joint.0.increment-plus', 0) - h.settle() - h.expect_steady('releasing increment-plus moves nothing', - lambda: close(h.joint_pos(0), 0.25, 1e-4)) - - h.pulse('joint.1.select') - h.set('joint.selected.increment', 0.5) - h.pulse('joint.selected.increment-plus') - expect_at(h, 1, 0.5, 'after joint.selected.increment-plus with joint 1 selected') - h.pulse('joint.selected.increment-minus') - expect_at(h, 1, 0.0, 'after joint.selected.increment-minus') - h.check('the selected increment did not move joint 0', - close(h.joint_pos(0), 0.25, 1e-4), 'joint 0 at %+.4f' % h.joint_pos(0)) - - h.nml_state(L.STATE_OFF) - h.pulse('joint.2.increment-plus') - h.expect_steady('increment-plus does nothing when the machine is off', - lambda: close(h.joint_pos(2), 0.0, 1e-4)) - - -def selected_jog(h): - to_zero(h) - h.set('joint.jog-speed', 60) - h.pulse('joint.0.select') - - h.set('joint.selected.plus', 1) - expect_velocity(h, 0, 1.0, 'while joint.selected.plus is held') - h.pulse('joint.1.select') - expect_stopped(h, 0, 'when the selection moves to joint 1 mid-jog') - expect_velocity(h, 1, 1.0, 'after being selected mid-jog') - h.set('joint.selected.plus', 0) - expect_stopped(h, 1, 'when joint.selected.plus is released') - - h.set('joint.selected.minus', 1) - expect_velocity(h, 1, -1.0, 'while joint.selected.minus is held') - h.pulse('joint.2.select') - expect_stopped(h, 1, 'when the selection moves to joint 2') - expect_velocity(h, 2, -1.0, 'after being selected during a minus jog') - h.set('joint.selected.minus', 0) - expect_stopped(h, 2, 'on release') - - # a joint jogged on its own pin keeps going when the selection changes - to_zero(h) - h.pulse('joint.0.select') - h.set('joint.2.plus', 1) - h.set('joint.selected.plus', 1) - expect_velocity(h, 0, 1.0, 'as the selected joint') - expect_velocity(h, 2, 1.0, 'on its own pin') - h.pulse('joint.1.select') - expect_stopped(h, 0, 'after the selection moves to joint 1') - expect_velocity(h, 1, 1.0, 'as the newly selected joint') - expect_velocity(h, 2, 1.0, 'still, because its own pin is held') - h.set('joint.selected.plus', 0) - h.set('joint.2.plus', 0) - expect_stopped(h, 1, 'on release') - expect_stopped(h, 2, 'on release') - - # changing the selection when nothing is jogging moves nothing - h.pulse('joint.0.select') - for j in range(JOINTS): - expect_not_moving(h, j, 'after a selection change with no jog active') - - -run(pins_and_defaults, - select, - homing, - hard_limits_and_fault, - continuous_jog, - jog_is_gated, - analog_jog, - incremental_jog, - selected_jog, - soft_limit_pins_never_set) diff --git a/tests/halui/joints/test.sh b/tests/halui/joints/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/joints/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/machine-state/checkresult b/tests/halui/machine-state/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/machine-state/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/machine-state/halui.ini b/tests/halui/machine-state/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/machine-state/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/machine-state/test-ui.py b/tests/halui/machine-state/test-ui.py deleted file mode 100755 index e2d00e1300f..00000000000 --- a/tests/halui/machine-state/test-ui.py +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python3 -"""halui: estop, machine power, task mode and motion mode. - -Pins: estop.activate, estop.reset, estop.is-activated, - machine.on, machine.off, machine.is-on, machine.units-per-mm, - mode.manual, mode.auto, mode.mdi, mode.teleop, mode.joint, - mode.is-manual, mode.is-auto, mode.is-mdi, mode.is-teleop, mode.is-joint -""" - -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, INCH_PER_MM # noqa: E402 - -import linuxcnc as L # noqa: E402 - -# task has no distinct OFF state: it reports ESTOP_RESET when the machine is -# neither estopped nor enabled (emctask.cc, emcTaskSetState) -POWERED_OFF = L.STATE_ESTOP_RESET - -MODE_PINS = {L.MODE_MANUAL: 'mode.is-manual', - L.MODE_AUTO: 'mode.is-auto', - L.MODE_MDI: 'mode.is-mdi'} - - -def startup_status(h): - h.expect('task starts in ESTOP', lambda: h.stat.task_state == L.STATE_ESTOP) - h.expect_pin('estop.is-activated reflects startup ESTOP', 'estop.is-activated', True) - h.expect_pin('machine.is-on is false at startup', 'machine.is-on', False) - # linear units are units per mm; this is an inch machine - h.expect_pin('machine.units-per-mm is published once task is up', - 'machine.units-per-mm', INCH_PER_MM, tol=1e-9) - - -def estop_and_power(h): - h.pulse('estop.reset') - h.expect('estop.reset -> task ESTOP_RESET', - lambda: h.stat.task_state == L.STATE_ESTOP_RESET) - h.expect_pin('estop.is-activated clears on reset', 'estop.is-activated', False) - h.expect_pin('machine.is-on stays false after reset', 'machine.is-on', False) - - h.pulse('machine.on') - h.expect('machine.on -> task ON', lambda: h.stat.task_state == L.STATE_ON) - h.expect_pin('machine.is-on sets', 'machine.is-on', True) - - h.pulse('machine.off') - h.expect('machine.off powers down (task reads back ESTOP_RESET)', - lambda: h.stat.task_state == POWERED_OFF) - h.expect_pin('machine.is-on clears on OFF', 'machine.is-on', False) - h.expect_pin('estop.is-activated stays clear on OFF', 'estop.is-activated', False) - - h.pulse('machine.on') - h.expect('machine.on from OFF -> task ON', lambda: h.stat.task_state == L.STATE_ON) - - h.pulse('estop.activate') - h.expect('estop.activate from ON -> task ESTOP', lambda: h.stat.task_state == L.STATE_ESTOP) - h.expect_pin('estop.is-activated sets', 'estop.is-activated', True) - h.expect_pin('machine.is-on clears on ESTOP', 'machine.is-on', False) - - -def power_on_refused_in_estop(h): - # task refuses ON straight from ESTOP; halui passes the request on and - # does not try to work around it - h.machine_estop() - h.pulse('machine.on') - h.expect_steady('machine.on while in ESTOP is refused by task', - lambda: h.stat.task_state == L.STATE_ESTOP) - h.expect_pin('machine.is-on stays false', 'machine.is-on', False) - - -def inputs_are_edge_triggered(h): - h.machine_estop() - h.nml_state(L.STATE_ESTOP_RESET) - h.set('machine.on', 1) - h.expect('rising edge on machine.on powers on', lambda: h.stat.task_state == L.STATE_ON) - h.nml_state(L.STATE_OFF) - h.expect_steady('a held machine.on does not power on again', - lambda: h.stat.task_state == POWERED_OFF, duration=0.6) - h.set('machine.on', 0) - h.expect_steady('the falling edge of machine.on does nothing', - lambda: h.stat.task_state == POWERED_OFF, duration=0.4) - - h.nml_state(L.STATE_ON) - h.set('estop.activate', 1) - h.expect('rising edge on estop.activate estops', lambda: h.stat.task_state == L.STATE_ESTOP) - h.nml_state(L.STATE_ESTOP_RESET) - h.expect_steady('a held estop.activate does not estop again', - lambda: h.stat.task_state == L.STATE_ESTOP_RESET, duration=0.6) - h.set('estop.activate', 0) - - -def status_follows_other_clients(h): - # output pins mirror task state no matter who changed it - h.machine_estop() - h.expect_pin('estop.is-activated follows an NML estop', 'estop.is-activated', True) - h.machine_on() - h.expect_pin('machine.is-on follows an NML power-on', 'machine.is-on', True) - h.expect_pin('estop.is-activated follows an NML reset', 'estop.is-activated', False) - - -def expect_task_mode_pins(h, want, why): - for mode, pin in MODE_PINS.items(): - h.expect_pin('%s is %s %s' % (pin, mode == want, why), pin, mode == want) - - -def task_modes(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - for request, mode, label in (('mode.mdi', L.MODE_MDI, 'MDI'), - ('mode.auto', L.MODE_AUTO, 'AUTO'), - ('mode.manual', L.MODE_MANUAL, 'MANUAL')): - h.pulse(request) - h.expect('%s -> task %s' % (request, label), lambda m=mode: h.stat.task_mode == m) - expect_task_mode_pins(h, mode, 'after ' + request) - - # asking for the mode task is already in sends nothing at all - for request, mode in (('mode.manual', L.MODE_MANUAL), - ('mode.auto', L.MODE_AUTO), - ('mode.mdi', L.MODE_MDI)): - h.nml_mode(mode) - h.settle(0.1) - serial = h.poll().echo_serial_number - h.pulse(request) - h.settle(0.3) - h.check('%s while already in that mode sends no command' % request, - h.poll().echo_serial_number == serial, - 'echo_serial_number %d -> %d' % (serial, h.stat.echo_serial_number)) - - # status pins follow a mode change made by another client - h.nml_mode(L.MODE_AUTO) - expect_task_mode_pins(h, L.MODE_AUTO, 'after an NML mode change') - h.nml_mode(L.MODE_MANUAL) - - -def task_mode_while_not_on(h): - for state, label in ((L.STATE_ESTOP, 'ESTOP'), (L.STATE_OFF, 'OFF')): - if state == L.STATE_ESTOP: - h.machine_estop() - else: - h.machine_on() - h.nml_state(L.STATE_OFF) - h.nml_mode(L.MODE_MANUAL) - h.pulse('mode.mdi') - h.expect('mode.mdi is accepted while in %s' % label, - lambda: h.stat.task_mode == L.MODE_MDI) - h.pulse('mode.manual') - h.expect('mode.manual is accepted while in %s' % label, - lambda: h.stat.task_mode == L.MODE_MANUAL) - - -def motion_modes(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - h.nml_home_all() - - h.pulse('mode.teleop') - h.expect('mode.teleop -> motion TELEOP', lambda: h.stat.motion_mode == L.TRAJ_MODE_TELEOP) - h.expect_pin('mode.is-teleop sets', 'mode.is-teleop', True) - h.expect_pin('mode.is-joint clears in teleop', 'mode.is-joint', False) - - h.pulse('mode.joint') - h.expect('mode.joint -> motion FREE', lambda: h.stat.motion_mode == L.TRAJ_MODE_FREE) - h.expect_pin('mode.is-joint sets', 'mode.is-joint', True) - h.expect_pin('mode.is-teleop clears in joint mode', 'mode.is-teleop', False) - - # in MDI, motion is in coordinated mode: neither teleop nor joint - h.nml_mode(L.MODE_MDI) - h.expect('MDI puts motion in COORD', lambda: h.stat.motion_mode == L.TRAJ_MODE_COORD) - h.expect_pin('mode.is-joint is false in COORD', 'mode.is-joint', False) - h.expect_pin('mode.is-teleop is false in COORD', 'mode.is-teleop', False) - - # status follows another client switching to teleop - h.nml_mode(L.MODE_MANUAL) - h.nml_teleop(1) - h.expect_pin('mode.is-teleop follows an NML teleop enable', 'mode.is-teleop', True) - h.nml_teleop(0) - h.expect_pin('mode.is-joint follows an NML teleop disable', 'mode.is-joint', True) - - -run(startup_status, - estop_and_power, - power_on_refused_in_estop, - inputs_are_edge_triggered, - status_follows_other_clients, - task_modes, - task_mode_while_not_on, - motion_modes) diff --git a/tests/halui/machine-state/test.sh b/tests/halui/machine-state/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/machine-state/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/mdi-commands/checkresult b/tests/halui/mdi-commands/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/mdi-commands/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/mdi-commands/halui.ini b/tests/halui/mdi-commands/halui.ini deleted file mode 100644 index b7ddfc5ab00..00000000000 --- a/tests/halui/mdi-commands/halui.ini +++ /dev/null @@ -1,102 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G20 G90 G0 X1 -MDI_COMMAND = G20 G90 G0 X0 -MDI_COMMAND = G20 G90 G1 X2 F60 -MDI_COMMAND = G20 G90 G1 X0 F60 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/mdi-commands/long.ngc b/tests/halui/mdi-commands/long.ngc deleted file mode 100644 index cac45d6b3e7..00000000000 --- a/tests/halui/mdi-commands/long.ngc +++ /dev/null @@ -1,5 +0,0 @@ -(six seconds out along X, six back: long enough to pause, resume and stop) -G20 G90 G17 -G1 X3 F30 -G1 X0 F30 -M2 diff --git a/tests/halui/mdi-commands/test-ui.py b/tests/halui/mdi-commands/test-ui.py deleted file mode 100755 index 89516f9c54b..00000000000 --- a/tests/halui/mdi-commands/test-ui.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python3 -"""halui: [HALUI]MDI_COMMAND buttons. - -Pins: mdi-command-NN, halui-mdi-is-running - -halui switches task to MDI, runs the command, and switches back to the mode -it found once task reports DONE. tests/halui/mdi covers the basic round trip; -this covers the running flag, queueing, and the paths where task refuses. - -MDI_COMMAND 00: G0 X1 01: G0 X0 - 02: G1 X2 F60 03: G1 X0 F60 (two seconds each) -""" - -import os -import sys -import time - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - -MODES = {L.MODE_MANUAL: 'MANUAL', L.MODE_AUTO: 'AUTO', L.MODE_MDI: 'MDI'} - - -def x(h): - return h.stat.actual_position[0] - - -def expect_x(h, want, why, timeout=10): - return h.expect('X reaches %g %s' % (want, why), - lambda: close(x(h), want, 1e-4) and h.stat.inpos, timeout, - detail=lambda: 'X=%.4f' % x(h)) - - -def expect_mode(h, mode, why, timeout=5): - return h.expect('task is back in %s %s' % (MODES[mode], why), - lambda: h.stat.task_mode == mode, timeout, - detail=lambda: 'mode=%s' % MODES.get(h.stat.task_mode, h.stat.task_mode)) - - -def at_x0(h, mode): - h.machine_on() - h.nml_mdi('G20 G90 G0 X0 Y0 Z0') - h.nml_mode(mode) - - -def pins(h): - for n in range(4): - h.check('mdi-command-%02d exists' % n, h.has('mdi-command-%02d' % n)) - h.check('there is no pin beyond the configured commands', not h.has('mdi-command-04')) - h.check('halui-mdi-is-running exists because MDI commands are configured', - h.has('halui-mdi-is-running')) - h.expect_pin('halui-mdi-is-running is false at startup', 'halui-mdi-is-running', False) - - -def round_trip_from_each_mode(h): - for mode in (L.MODE_MANUAL, L.MODE_AUTO, L.MODE_MDI): - at_x0(h, mode) - h.pulse('mdi-command-00') - expect_x(h, 1, 'after mdi-command-00 from %s' % MODES[mode]) - expect_mode(h, mode, 'after the command') - h.expect_pin('halui-mdi-is-running clears after the command from %s' % MODES[mode], - 'halui-mdi-is-running', False) - - -def running_flag(h): - at_x0(h, L.MODE_MANUAL) - h.pulse('mdi-command-02') - h.expect('task switches to MDI for the command', lambda: h.stat.task_mode == L.MODE_MDI) - h.expect_pin('halui-mdi-is-running sets while the command runs', 'halui-mdi-is-running', True) - h.expect('the command is moving X', lambda: 0.2 < x(h) < 1.8) - h.check('task is still in MDI mid-command', h.stat.task_mode == L.MODE_MDI) - expect_x(h, 2, 'at the end of mdi-command-02') - expect_mode(h, L.MODE_MANUAL, 'once the command is done') - h.expect_pin('halui-mdi-is-running clears when it is done', 'halui-mdi-is-running', False) - - -def queued_commands(h): - at_x0(h, L.MODE_MANUAL) - h.pulse('mdi-command-02') - h.expect('first command under way', lambda: x(h) > 0.2) - h.pulse('mdi-command-03') - furthest = 0.0 - end = time.time() + 10 - while time.time() < end: - h.poll() - furthest = max(furthest, x(h)) - if h.stat.task_mode != L.MODE_MDI: - break - time.sleep(0.01) - h.check('both queued commands ran in order (X went to 2 and back to 0)', - furthest > 1.99 and close(x(h), 0, 1e-4), - 'furthest X=%.4f, final X=%.4f' % (furthest, x(h))) - h.check('the mode is restored only after the whole queue is done', - close(x(h), 0, 1e-4), 'mode left MDI at X=%.4f' % x(h)) - expect_mode(h, L.MODE_MANUAL, 'after the queue') - h.expect_pin('halui-mdi-is-running clears after the queue', 'halui-mdi-is-running', False) - - -def edge_only(h): - at_x0(h, L.MODE_MANUAL) - h.set('mdi-command-00', 1) - expect_x(h, 1, 'while mdi-command-00 is held') - expect_mode(h, L.MODE_MANUAL, 'while it is still held') - h.nml_mdi('G0 X0') - h.nml_mode(L.MODE_MANUAL) - h.expect_steady('a held mdi-command-00 does not run again', - lambda: close(x(h), 0, 1e-4) and h.stat.task_mode == L.MODE_MANUAL, - duration=0.8) - h.set('mdi-command-00', 0) - - -def refused_by_task(h): - # In ESTOP task accepts the switch to MDI but refuses the command itself. - at_x0(h, L.MODE_MANUAL) - h.machine_estop() - h.nml_mode(L.MODE_MANUAL) - h.drain_errors() - h.pulse('mdi-command-00') - h.settle(1.0) - s = h.poll() - h.log('mdi-command-00 in ESTOP: mode=%s status=%d X=%.4f is-running=%s errors=%r' - % (MODES.get(s.task_mode), s.state, x(h), h.get('halui-mdi-is-running'), - h.drain_errors())) - h.check('the command does not move anything in ESTOP', close(x(h), 0, 1e-4)) - h.check('task reports the refused command as an error', s.state == L.RCS_ERROR, - 'status=%d' % s.state) - # halui restores the old mode only on RCS DONE (modify_hal_pins). The - # refused command leaves task in ERROR, so nothing is restored and the - # running flag never drops. - h.known_bug('task is left in MDI after an MDI button is refused', - h.stays(lambda: h.stat.task_mode == L.MODE_MDI, 1.0), - 'halui only restores the previous mode when task status is DONE; ' - 'on ERROR it waits forever. Should be back in MANUAL') - h.known_bug('halui-mdi-is-running stays true after the refused command', - h.stays(lambda: h.get('halui-mdi-is-running'), 1.0), - 'halui_sent_mdi is cleared only on DONE; should be false') - - # The stale state resolves on the next command that finishes with DONE, - # whatever it is. Here that is powering the machine on, which therefore - # also switches task out of MDI -- long after the button press. - h.machine_on() - h.known_bug('turning the machine on later switches task back to MANUAL', - h.wait_for(lambda: h.stat.task_mode == L.MODE_MANUAL), - 'the delayed restore from the refused MDI button fires on the next DONE, ' - 'from an unrelated command') - h.expect_pin('halui-mdi-is-running clears after that', 'halui-mdi-is-running', False) - - -def while_program_runs(h): - # task refuses the switch to MDI while a program runs - at_x0(h, L.MODE_AUTO) - here = os.path.dirname(os.path.abspath(__file__)) - h.cmd.program_open(os.path.join(here, 'long.ngc')) - h.cmd.wait_complete() - h.cmd.auto(L.AUTO_RUN, 0) - h.expect('the program is running', lambda: x(h) > 0.2) - h.pulse('mdi-command-00') - h.settle(0.5) - running_flag = h.get('halui-mdi-is-running') - h.log('mdi-command-00 while a program runs: mode=%s is-running=%s' - % (MODES.get(h.poll().task_mode), running_flag)) - h.check('task stays in AUTO', h.stat.task_mode == L.MODE_AUTO) - h.known_bug('halui-mdi-is-running is true although no MDI command was sent', - running_flag, - 'sendMdiCommand() sets halui_sent_mdi before task has refused the ' - 'switch to MDI; should stay false') - h.check('the program keeps running', h.stat.interp_state != L.INTERP_IDLE) - h.nml_abort() - h.expect_pin('halui-mdi-is-running is clear once the program is gone', - 'halui-mdi-is-running', False) - h.check('task is still in AUTO afterwards', h.poll().task_mode == L.MODE_AUTO) - - -run(pins, - round_trip_from_each_mode, - running_flag, - queued_commands, - edge_only, - refused_by_task, - while_program_runs) diff --git a/tests/halui/mdi-commands/test.sh b/tests/halui/mdi-commands/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/mdi-commands/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/overrides/checkresult b/tests/halui/overrides/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/overrides/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/overrides/halui.ini b/tests/halui/overrides/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/overrides/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/overrides/test-ui.py b/tests/halui/overrides/test-ui.py deleted file mode 100755 index 25840468ee0..00000000000 --- a/tests/halui/overrides/test-ui.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python3 -"""halui: feed, rapid, spindle and max-velocity overrides. - -For each override: counts (relative and direct-value), count-enable, scale, -increase, decrease, reset, value -- and the clamping halui applies. - -Limits in halui.ini: [DISPLAY]MAX_FEED_OVERRIDE = 1.5, -MIN_SPINDLE_OVERRIDE = 0.5, MAX_SPINDLE_OVERRIDE = 1.2, -[TRAJ]MAX_LINEAR_VELOCITY = 4. -""" - -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - - -class Model: - """What halui should ask for: last value +/- steps, clamped.""" - - def __init__(self, value, lo, hi): - self.value, self.lo, self.hi, self.counts = value, lo, hi, 0 - - def clamp(self, v): - return max(self.lo, min(self.hi, v)) - - def relative(self, counts, scale): - self.value = self.clamp(self.value + (counts - self.counts) * scale) - self.counts = counts - - def direct(self, counts, scale): - self.value = self.clamp(counts * scale) - self.counts = counts - - def ignored(self, counts): - self.counts = counts - - def set(self, v): - self.value = self.clamp(v) - - -def exercise(h, label, pfx, read, lo, hi, has_reset=True): - def P(s): - return pfx + '.' + s - - m = Model(read(h.poll()), lo, hi) - - def expect(why): - # When a step leaves the value unchanged (already at a limit) the - # check below passes at once, so give halui time to sample the input - # before the next one arrives -- otherwise two steps look like one. - h.settle() - want = m.value - h.expect('%s is %.3f %s' % (label, want, why), - lambda: close(read(h.stat), want, 1e-6), - detail=lambda: 'task has %.4f' % read(h.stat)) - h.expect_pin('%s.value is %.3f %s' % (pfx, want, why), P('value'), want, tol=1e-6) - - h.check('%s.scale defaults to 0.1' % pfx, close(h.default(P('scale')), 0.1), - 'default %r' % h.default(P('scale'))) - h.check('%s.count-enable defaults to on' % pfx, h.default(P('count-enable')) is True, - 'default %r' % h.default(P('count-enable'))) - expect('at startup') - - scale = 0.1 - for c in (1, 4, 20, 19, -40, -38): - h.set(P('counts'), c) - m.relative(c, scale) - expect('after counts -> %d (relative)' % c) - - h.set(P('count-enable'), 0) - h.set(P('counts'), -30) - m.ignored(-30) - h.expect_steady('%s ignores counts while count-enable is off' % pfx, - lambda: close(read(h.stat), m.value, 1e-6)) - h.set(P('count-enable'), 1) - h.set(P('counts'), -29) - m.relative(-29, scale) - expect('after re-enabling: one count, no jump from the ignored ones') - - h.pulse(P('increase')) - m.set(m.value + scale) - expect('after increase') - h.pulse(P('decrease')) - m.set(m.value - scale) - expect('after decrease') - - h.set(P('increase'), 1) - h.settle(0.3) - m.set(m.value + scale) - expect('while increase is held (one step per edge)') - h.set(P('increase'), 0) - h.settle() - - scale = 0.25 - h.set(P('scale'), scale) - h.pulse(P('increase')) - m.set(m.value + scale) - expect('after increase with scale 0.25') - for _ in range(8): - h.pulse(P('increase')) - m.set(m.value + scale) - expect('after increasing past the upper limit') - for _ in range(12): - h.pulse(P('decrease')) - m.set(m.value - scale) - expect('after decreasing past the lower limit') - - if has_reset: - h.pulse(P('reset')) - m.set(1.0) - expect('after reset') - else: - h.check('%s has no reset pin' % pfx, not h.has(P('reset'))) - - scale = 0.1 - h.set(P('scale'), scale) - h.set(P('direct-value'), 1) - for c in (7, 30, -1, 9): - h.set(P('counts'), c) - m.direct(c, scale) - expect('after counts -> %d (direct-value)' % c) - h.set(P('direct-value'), 0) - h.set(P('counts'), 10) - m.relative(10, scale) - expect('after counts -> 10 (relative again)') - return m - - -def feed_override(h): - h.machine_on() - exercise(h, 'task feed override', 'feed-override', lambda s: s.feedrate, 0.0, 1.5) - h.cmd.feedrate(0.7) - h.expect_pin('feed-override.value follows an NML change', 'feed-override.value', 0.7) - - -def rapid_override(h): - h.machine_on() - # halui hard-codes the rapid override ceiling at 1.0 - exercise(h, 'task rapid override', 'rapid-override', lambda s: s.rapidrate, 0.0, 1.0) - h.cmd.rapidrate(0.3) - h.expect_pin('rapid-override.value follows an NML change', 'rapid-override.value', 0.3) - - -def spindle_override(h): - h.machine_on() - exercise(h, 'task spindle 0 override', 'spindle.0.override', - lambda s: s.spindle[0]['override'], 0.5, 1.2) - h.cmd.spindleoverride(0.8, 0) - h.expect_pin('spindle.0.override.value follows an NML change', - 'spindle.0.override.value', 0.8) - - -def max_velocity(h): - h.machine_on() - start = h.poll().max_velocity - h.check('task starts at [TRAJ]MAX_LINEAR_VELOCITY', close(start, 4.0), 'max_velocity=%.3f' % start) - h.expect_pin('max-velocity.value shows it', 'max-velocity.value', 4.0) - h.check('max-velocity.scale defaults to 0 (halui never initialises it)', - close(h.default('max-velocity.scale'), 0.0), 'default %r' % h.default('max-velocity.scale')) - h.check('max-velocity.count-enable defaults to on', h.default('max-velocity.count-enable') is True) - - h.set('max-velocity.scale', 0.5) - h.pulse('max-velocity.decrease') - h.known_bug('max-velocity.decrease from 4.0 lands on 1.0 instead of 3.5', - h.wait_for(lambda: close(h.stat.max_velocity, 1.0)), - 'every request is clamped to 1.0: iniLoad() no longer reads ' - '[TRAJ]MAX_LINEAR_VELOCITY into maxMaxVelocity since 2f57090adb ' - '(new ini parser); intended ceiling here is 4.0') - h.expect_pin('max-velocity.value follows the clamped value', 'max-velocity.value', 1.0) - - # inside [0, 1.0] the override behaves as intended - m = Model(1.0, 0.0, 1.0) - - def expect(why): - h.settle() - want = m.value - h.expect('task max velocity is %.3f %s' % (want, why), - lambda: close(h.stat.max_velocity, want, 1e-6), - detail=lambda: 'task has %.4f' % h.stat.max_velocity) - h.expect_pin('max-velocity.value is %.3f %s' % (want, why), 'max-velocity.value', want) - - h.pulse('max-velocity.decrease') - m.set(0.5) - expect('after decrease') - h.pulse('max-velocity.increase') - m.set(1.0) - expect('after increase') - h.pulse('max-velocity.increase') - expect('after increasing past the (buggy) 1.0 ceiling') - for c in (-1, -5, -3): - h.set('max-velocity.counts', c) - m.relative(c, 0.5) - expect('after counts -> %d (relative)' % c) - - h.set('max-velocity.count-enable', 0) - h.set('max-velocity.counts', 5) - m.ignored(5) - h.expect_steady('max-velocity ignores counts while count-enable is off', - lambda: close(h.stat.max_velocity, m.value, 1e-6)) - h.set('max-velocity.count-enable', 1) - - h.set('max-velocity.direct-value', 1) - h.set('max-velocity.counts', 1) - m.direct(1, 0.5) - expect('after counts -> 1 (direct-value)') - h.set('max-velocity.counts', 6) - h.known_bug('max-velocity direct-value 3.0 lands on 1.0', - h.wait_for(lambda: close(h.stat.max_velocity, 1.0)), - 'same maxMaxVelocity clamp; intended result is 3.0') - h.set('max-velocity.direct-value', 0) - h.check('max-velocity has no reset pin', not h.has('max-velocity.reset')) - - h.cmd.maxvel(2.5) - h.expect_pin('max-velocity.value follows an NML change', 'max-velocity.value', 2.5) - - -def not_on(h): - # overrides are immediate commands: task accepts them even when not ON - h.machine_estop() - h.cmd.feedrate(1.0) - h.cmd.wait_complete() - h.pulse('feed-override.decrease') - h.expect('feed override changes while in ESTOP', lambda: close(h.stat.feedrate, 0.9)) - - -run(feed_override, rapid_override, spindle_override, max_velocity, not_on) diff --git a/tests/halui/overrides/test.sh b/tests/halui/overrides/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/overrides/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/program/block-delete.ngc b/tests/halui/program/block-delete.ngc deleted file mode 100644 index ccec84254ac..00000000000 --- a/tests/halui/program/block-delete.ngc +++ /dev/null @@ -1,4 +0,0 @@ -G20 G90 -G0 Z0 -/G0 Z-1 -M2 diff --git a/tests/halui/program/checkresult b/tests/halui/program/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/program/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/program/halui.ini b/tests/halui/program/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/program/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/program/long.ngc b/tests/halui/program/long.ngc deleted file mode 100644 index cac45d6b3e7..00000000000 --- a/tests/halui/program/long.ngc +++ /dev/null @@ -1,5 +0,0 @@ -(six seconds out along X, six back: long enough to pause, resume and stop) -G20 G90 G17 -G1 X3 F30 -G1 X0 F30 -M2 diff --git a/tests/halui/program/optional-stop.ngc b/tests/halui/program/optional-stop.ngc deleted file mode 100644 index 563612d0428..00000000000 --- a/tests/halui/program/optional-stop.ngc +++ /dev/null @@ -1,5 +0,0 @@ -G20 G90 -G0 X0 -M1 -G0 X0.5 -M2 diff --git a/tests/halui/program/step.ngc b/tests/halui/program/step.ngc deleted file mode 100644 index 111479bd529..00000000000 --- a/tests/halui/program/step.ngc +++ /dev/null @@ -1,5 +0,0 @@ -(every line moves, so each step is visible as a change in X) -G20 G90 G0 X0.1 -G0 X0.2 -G0 X0.3 -M2 diff --git a/tests/halui/program/test-ui.py b/tests/halui/program/test-ui.py deleted file mode 100755 index dc5fe39abb6..00000000000 --- a/tests/halui/program/test-ui.py +++ /dev/null @@ -1,295 +0,0 @@ -#!/usr/bin/env python3 -"""halui: program control and program status. - -Pins: program.run, program.pause, program.resume, program.step, program.stop, - program.optional-stop.on, program.optional-stop.off, - program.optional-stop.is-on, - program.block-delete.on, program.block-delete.off, - program.block-delete.is-on, - program.is-idle, program.is-running, program.is-paused, abort - -halui cannot open a program, so opening one is done over NML as setup. -""" - -import os -import sys -import time - -HERE = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.join(HERE, '..', '_lib')) -from halui_test import run, close # noqa: E402 - -import linuxcnc as L # noqa: E402 - - -def running(h): - return h.stat.interp_state in (L.INTERP_READING, L.INTERP_WAITING) - - -def paused(h): - return h.stat.interp_state == L.INTERP_PAUSED - - -def idle(h): - return h.stat.interp_state == L.INTERP_IDLE - - -def x(h): - return h.poll().actual_position[0] - - -def expect_program_pins(h, is_idle, is_running, is_paused, why): - h.expect_pin('program.is-idle is %s %s' % (is_idle, why), 'program.is-idle', is_idle) - h.expect_pin('program.is-running is %s %s' % (is_running, why), 'program.is-running', is_running) - h.expect_pin('program.is-paused is %s %s' % (is_paused, why), 'program.is-paused', is_paused) - - -def to_origin(h): - h.machine_on() - h.nml_mdi('G20 G90 G0 X0 Y0 Z0') - - -def open_program(h, name): - h.nml_mode(L.MODE_AUTO) - h.cmd.program_open(os.path.join(HERE, name)) - h.cmd.wait_complete() - if not h.wait_for(lambda: h.stat.file.endswith(name)): - raise RuntimeError('setup: could not open ' + name) - - -def nml_run(h): - # wait_complete() on a run only returns once the program has finished, - # so for a short program just wait for task to take the command - h.cmd.auto(L.AUTO_RUN, 0) - if not h.wait_for(lambda: h.stat.echo_serial_number >= h.cmd.serial): - raise RuntimeError('setup: task did not take the run command') - - -def expect_still(h, name): - h.settle(0.3) - a = x(h) - h.settle(0.4) - b = x(h) - return h.check(name, close(a, b, 1e-6), 'X %.5f -> %.5f' % (a, b)) - - -def run_without_a_program(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - h.check('no program is open at startup', h.poll().file == '', 'file=%r' % h.stat.file) - expect_program_pins(h, True, False, False, 'at startup') - serial = h.poll().echo_serial_number - h.pulse('program.run') - h.settle(0.3) - h.check('program.run with no program open sends nothing', - h.poll().echo_serial_number == serial, - 'echo_serial_number %d -> %d' % (serial, h.stat.echo_serial_number)) - h.check('program.run with no program open leaves task in MANUAL', - h.stat.task_mode == L.MODE_MANUAL, 'mode=%d' % h.stat.task_mode) - - -def run_pause_resume_stop(h): - to_origin(h) - open_program(h, 'long.ngc') - h.nml_mode(L.MODE_MANUAL) - - h.pulse('program.run') - h.expect('program.run switches task to AUTO by itself', - lambda: h.stat.task_mode == L.MODE_AUTO) - h.expect('program.run starts the program', lambda: running(h)) - h.expect('the program moves X', lambda: h.stat.actual_position[0] > 0.2) - expect_program_pins(h, False, True, False, 'while running') - - h.pulse('program.pause') - h.expect('program.pause pauses the program', lambda: paused(h)) - expect_program_pins(h, False, False, True, 'while paused') - expect_still(h, 'motion stops while paused') - - h.pulse('program.pause') - h.expect_steady('program.pause while paused keeps it paused', lambda: paused(h), duration=0.4) - - here = x(h) - h.pulse('program.resume') - h.expect('program.resume resumes the program', lambda: running(h)) - h.expect('motion continues after resume', lambda: h.stat.actual_position[0] > here + 0.05) - expect_program_pins(h, False, True, False, 'after resume') - - h.pulse('program.resume') - h.expect_steady('program.resume while running keeps it running', lambda: running(h), duration=0.4) - - h.pulse('program.stop') - h.expect('program.stop ends the program', lambda: idle(h)) - expect_program_pins(h, True, False, False, 'after program.stop') - expect_still(h, 'motion stops after program.stop') - - -def run_while_already_in_auto(h): - to_origin(h) - open_program(h, 'long.ngc') - h.pulse('program.run') - h.expect('program.run from AUTO starts the program', lambda: running(h)) - h.pulse('program.stop') - h.expect('program.stop ends it', lambda: idle(h)) - - -def pause_when_idle(h): - # task accepts a pause with a program open but not running, and reports - # the interpreter as PAUSED. That is task behaviour, not halui's; halui - # passes the request on and its status pins report what task says. - to_origin(h) - open_program(h, 'long.ngc') - h.pulse('program.pause') - h.expect('program.pause with nothing running puts task in PAUSED', lambda: paused(h)) - expect_program_pins(h, False, False, True, 'after a pause while idle') - h.pulse('program.stop') - h.expect('program.stop leaves that paused state', lambda: idle(h)) - expect_program_pins(h, True, False, False, 'after stopping it') - - -def abort_pin(h): - to_origin(h) - open_program(h, 'long.ngc') - nml_run(h) - h.expect('the program runs (started over NML)', lambda: h.stat.actual_position[0] > 0.2) - expect_program_pins(h, False, True, False, 'while a program started over NML runs') - h.pulse('abort') - h.expect('abort ends a running program', lambda: idle(h)) - expect_program_pins(h, True, False, False, 'after abort') - expect_still(h, 'motion stops after abort') - - # abort also stops a paused program - to_origin(h) - open_program(h, 'long.ngc') - nml_run(h) - h.cmd.auto(L.AUTO_PAUSE) - h.cmd.wait_complete() - h.wait_for(lambda: paused(h)) - h.pulse('abort') - h.expect('abort ends a paused program', lambda: idle(h)) - expect_program_pins(h, True, False, False, 'after aborting a paused program') - - # and an MDI move - to_origin(h) - h.nml_mode(L.MODE_MDI) - h.cmd.mdi('G1 X3 F30') - h.expect('an MDI move is under way', lambda: h.stat.actual_position[0] > 0.1) - h.pulse('abort') - h.expect('abort ends an MDI move', lambda: idle(h)) - expect_still(h, 'motion stops after aborting MDI') - - -def step_trace(h, do_step, steps=8): - """Step through step.ngc, recording (X, interpreter state) after each step.""" - to_origin(h) - open_program(h, 'step.ngc') - trace = [] - for _ in range(steps): - do_step() - h.settle(0.6) - s = h.poll() - trace.append((round(s.actual_position[0], 4), s.interp_state)) - return trace - - -def step(h): - # How far one step gets is task's business (it lags the presses while the - # program starts up). halui's job is to turn each rising edge into exactly - # one step, so compare it with stepping over NML. - def nml_step(): - h.cmd.auto(L.AUTO_STEP) - h.cmd.wait_complete() - - reference = step_trace(h, nml_step) - h.nml_abort() - via_pin = step_trace(h, lambda: h.pulse('program.step')) - h.check('program.step steps exactly like an NML step, press for press', - via_pin == reference, 'NML %s / pin %s' % (reference, via_pin)) - - xs = [x for x, _ in via_pin] - h.check('stepping walks through the whole program', 0.3 in xs, 'X after each step: %s' % xs) - h.check('no step moves more than one line', - all(b - a <= 0.1 + 1e-6 for a, b in zip([0.0] + xs, xs)), 'X after each step: %s' % xs) - - h.pulse('program.stop') - h.expect('program.stop ends a stepped program', lambda: idle(h)) - - -def optional_stop(h): - h.machine_on() - h.pulse('program.optional-stop.on') - h.expect('optional-stop.on turns optional stop on in task', lambda: h.stat.optional_stop) - h.expect_pin('optional-stop.is-on sets', 'program.optional-stop.is-on', True) - - to_origin(h) - h.nml_mdi('G0 X0') - open_program(h, 'optional-stop.ngc') - nml_run(h) - h.expect('with optional stop on, M1 pauses the program', lambda: paused(h)) - h.check('the move after M1 has not happened', close(x(h), 0.0, 1e-4), 'X=%.4f' % x(h)) - h.pulse('program.resume') - h.expect('program.resume continues past M1', - lambda: idle(h) and close(h.stat.actual_position[0], 0.5, 1e-4)) - - h.pulse('program.optional-stop.off') - h.expect('optional-stop.off turns optional stop off in task', lambda: not h.stat.optional_stop) - h.expect_pin('optional-stop.is-on clears', 'program.optional-stop.is-on', False) - - to_origin(h) - open_program(h, 'optional-stop.ngc') - saw_pause = False - nml_run(h) - end = time.time() + 10 - while time.time() < end: - h.poll() - saw_pause = saw_pause or paused(h) - if idle(h): - break - time.sleep(0.01) - h.check('with optional stop off, M1 is skipped', not saw_pause and idle(h) - and close(h.stat.actual_position[0], 0.5, 1e-4), - 'paused=%s X=%.4f' % (saw_pause, h.stat.actual_position[0])) - - h.cmd.set_optional_stop(1) - h.expect_pin('optional-stop.is-on follows an NML change', 'program.optional-stop.is-on', True) - h.cmd.set_optional_stop(0) - h.expect_pin('optional-stop.is-on follows it back', 'program.optional-stop.is-on', False) - - -def block_delete(h): - h.machine_on() - h.pulse('program.block-delete.on') - h.expect('block-delete.on turns block delete on in task', lambda: h.stat.block_delete) - h.expect_pin('block-delete.is-on sets', 'program.block-delete.is-on', True) - - to_origin(h) - open_program(h, 'block-delete.ngc') - nml_run(h) - h.wait_idle() - h.check('with block delete on, the "/" line is skipped', - close(h.poll().actual_position[2], 0.0, 1e-4), 'Z=%.4f' % h.stat.actual_position[2]) - - h.pulse('program.block-delete.off') - h.expect('block-delete.off turns block delete off in task', lambda: not h.stat.block_delete) - h.expect_pin('block-delete.is-on clears', 'program.block-delete.is-on', False) - - to_origin(h) - open_program(h, 'block-delete.ngc') - nml_run(h) - h.wait_idle() - h.check('with block delete off, the "/" line runs', - close(h.poll().actual_position[2], -1.0, 1e-4), 'Z=%.4f' % h.stat.actual_position[2]) - - h.cmd.set_block_delete(1) - h.expect_pin('block-delete.is-on follows an NML change', 'program.block-delete.is-on', True) - h.cmd.set_block_delete(0) - h.expect_pin('block-delete.is-on follows it back', 'program.block-delete.is-on', False) - - -run(run_without_a_program, - run_pause_resume_stop, - run_while_already_in_auto, - pause_when_idle, - abort_pin, - step, - optional_stop, - block_delete) diff --git a/tests/halui/program/test.sh b/tests/halui/program/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/program/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/spindle-coolant/checkresult b/tests/halui/spindle-coolant/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/spindle-coolant/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/spindle-coolant/halui.ini b/tests/halui/spindle-coolant/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/spindle-coolant/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/spindle-coolant/test-ui.py b/tests/halui/spindle-coolant/test-ui.py deleted file mode 100755 index f1daa19269b..00000000000 --- a/tests/halui/spindle-coolant/test-ui.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python3 -"""halui: spindle control, spindle brake, mist and flood. - -Pins: spindle.0.start, stop, forward, reverse, increase, decrease, - brake-on, brake-off, is-on, runs-forward, runs-backward, brake-is-on, - mist.on, mist.off, mist.is-on, flood.on, flood.off, flood.is-on -""" - -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run # noqa: E402 - -import linuxcnc as L # noqa: E402 - -SP = 'spindle.0.' - - -def sp(h): - return h.stat.spindle[0] - - -def expect_spindle(h, speed, why): - direction = (speed > 0) - (speed < 0) - h.expect('spindle 0 runs at %g %s' % (speed, why), - lambda: sp(h)['speed'] == speed and sp(h)['direction'] == direction - and bool(sp(h)['enabled']) == (speed != 0), - detail=lambda: 'speed=%g direction=%d enabled=%d' - % (sp(h)['speed'], sp(h)['direction'], sp(h)['enabled'])) - h.expect_pin(SP + 'is-on is %s %s' % (speed != 0, why), SP + 'is-on', speed != 0) - h.expect_pin(SP + 'runs-forward is %s %s' % (speed > 0, why), SP + 'runs-forward', speed > 0) - h.expect_pin(SP + 'runs-backward is %s %s' % (speed < 0, why), SP + 'runs-backward', speed < 0) - - -def expect_speed_steady(h, speed, why): - h.expect_steady('spindle 0 stays at %g %s' % (speed, why), - lambda: sp(h)['speed'] == speed, - detail=lambda: 'speed=%g' % sp(h)['speed']) - - -def without_s_word(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - expect_spindle(h, 0, 'at startup') - # with no S word active, halui asks for speed +/-1 - h.pulse(SP + 'start') - expect_spindle(h, 1, 'after start with no S word') - h.pulse(SP + 'stop') - expect_spindle(h, 0, 'after stop') - h.pulse(SP + 'reverse') - expect_spindle(h, -1, 'after reverse with no S word') - h.pulse(SP + 'forward') - expect_spindle(h, 1, 'after forward with no S word') - h.pulse(SP + 'stop') - expect_spindle(h, 0, 'after stop') - - -def with_s_word(h): - h.machine_on() - h.nml_mdi('S500') - h.nml_mode(L.MODE_MANUAL) - h.pulse(SP + 'forward') - expect_spindle(h, 500, 'after forward with S500') - h.pulse(SP + 'reverse') - expect_spindle(h, -500, 'after reverse with S500') - h.pulse(SP + 'start') - expect_spindle(h, 500, 'after start with S500 (start is forward)') - - # each rising edge steps by [SPINDLE_0]INCREMENT (default 100); - # the falling edge sends SPINDLE_CONSTANT, which keeps the speed - h.set(SP + 'increase', 1) - expect_spindle(h, 600, 'on the rising edge of increase') - expect_speed_steady(h, 600, 'while increase is held') - h.set(SP + 'increase', 0) - expect_speed_steady(h, 600, 'after increase is released') - - h.set(SP + 'decrease', 1) - expect_spindle(h, 500, 'on the rising edge of decrease') - h.set(SP + 'decrease', 0) - expect_speed_steady(h, 500, 'after decrease is released') - - h.pulse(SP + 'reverse') - expect_spindle(h, -500, 'after reverse') - h.pulse(SP + 'increase') - expect_spindle(h, -600, 'after increase while in reverse (magnitude grows)') - h.pulse(SP + 'decrease') - expect_spindle(h, -500, 'after decrease while in reverse') - - h.pulse(SP + 'stop') - expect_spindle(h, 0, 'after stop') - h.pulse(SP + 'increase') - expect_spindle(h, 0, 'after increase while stopped (does nothing)') - h.pulse(SP + 'decrease') - expect_spindle(h, 0, 'after decrease while stopped (does nothing)') - - -def brake(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - h.pulse(SP + 'brake-on') - h.expect('brake-on engages the brake', lambda: sp(h)['brake'] == 1) - h.expect_pin(SP + 'brake-is-on sets', SP + 'brake-is-on', True) - h.pulse(SP + 'brake-off') - h.expect('brake-off releases the brake', lambda: sp(h)['brake'] == 0) - h.expect_pin(SP + 'brake-is-on clears', SP + 'brake-is-on', False) - - h.cmd.brake(L.BRAKE_ENGAGE, 0) - h.expect_pin(SP + 'brake-is-on follows an NML brake engage', SP + 'brake-is-on', True) - h.cmd.brake(L.BRAKE_RELEASE, 0) - h.expect_pin(SP + 'brake-is-on follows an NML brake release', SP + 'brake-is-on', False) - - -def status_follows_other_clients(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - h.cmd.spindle(L.SPINDLE_FORWARD, 300, 0) - expect_spindle(h, 300, 'after an NML spindle forward') - h.cmd.spindle(L.SPINDLE_REVERSE, 300, 0) - expect_spindle(h, -300, 'after an NML spindle reverse') - h.cmd.spindle(L.SPINDLE_OFF, 0) - expect_spindle(h, 0, 'after an NML spindle off') - - -def spindle_when_not_on(h): - h.machine_estop() - h.pulse(SP + 'start') - expect_speed_steady(h, 0, 'when start is pressed in ESTOP') - h.expect_pin(SP + 'is-on stays false in ESTOP', SP + 'is-on', False) - - -def coolant(h): - h.machine_on() - h.nml_mode(L.MODE_MANUAL) - for kind in ('mist', 'flood'): - read = (lambda s: s.mist) if kind == 'mist' else (lambda s: s.flood) - h.pulse(kind + '.on') - h.expect('%s.on turns %s on' % (kind, kind), lambda r=read: r(h.stat)) - h.expect_pin('%s.is-on sets' % kind, kind + '.is-on', True) - h.pulse(kind + '.off') - h.expect('%s.off turns %s off' % (kind, kind), lambda r=read: not r(h.stat)) - h.expect_pin('%s.is-on clears' % kind, kind + '.is-on', False) - - h.cmd.mist(L.MIST_ON) - h.expect_pin('mist.is-on follows an NML mist on', 'mist.is-on', True) - h.cmd.flood(L.FLOOD_ON) - h.expect_pin('flood.is-on follows an NML flood on', 'flood.is-on', True) - h.cmd.mist(L.MIST_OFF) - h.cmd.flood(L.FLOOD_OFF) - h.expect_pin('mist.is-on follows an NML mist off', 'mist.is-on', False) - h.expect_pin('flood.is-on follows an NML flood off', 'flood.is-on', False) - - -def machine_off_stops_flood(h): - # task turns flood off whenever the machine is turned on or off - # (emcTaskSetState); flood.is-on has to follow that - h.machine_on() - h.pulse('flood.on') - h.expect_pin('flood is on', 'flood.is-on', True) - h.pulse('machine.off') - h.expect('machine.off turns flood off in task', lambda: not h.stat.flood) - h.expect_pin('flood.is-on follows task turning flood off', 'flood.is-on', False) - - -run(without_s_word, - with_s_word, - brake, - status_follows_other_clients, - spindle_when_not_on, - coolant, - machine_off_stops_flood) diff --git a/tests/halui/spindle-coolant/test.sh b/tests/halui/spindle-coolant/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/spindle-coolant/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/startup-halfile/checkresult b/tests/halui/startup-halfile/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/startup-halfile/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/startup-halfile/halui-nets.hal b/tests/halui/startup-halfile/halui-nets.hal deleted file mode 100644 index bf0bcf2c075..00000000000 --- a/tests/halui/startup-halfile/halui-nets.hal +++ /dev/null @@ -1,7 +0,0 @@ -# halui pins wired from a regular HALFILE. The startup script runs HAL files -# only after halui is ready, and configs rely on that: this must keep loading -# if halui ever moves into task. -net machine-is-on-led halui.machine.is-on -net remote-estop halui.estop.activate -net remote-estop-reset halui.estop.reset -net remote-mode-mdi halui.mode.mdi diff --git a/tests/halui/startup-halfile/halui.ini b/tests/halui/startup-halfile/halui.ini deleted file mode 100644 index 901508b390c..00000000000 --- a/tests/halui/startup-halfile/halui.ini +++ /dev/null @@ -1,102 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal -# halui pins wired in a regular HALFILE, not POSTGUI_HALFILE -HALFILE = halui-nets.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/startup-halfile/test-ui.py b/tests/halui/startup-halfile/test-ui.py deleted file mode 100755 index c07b51daac6..00000000000 --- a/tests/halui/startup-halfile/test-ui.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -"""halui pins wired from a regular HALFILE. - -The startup script runs HAL files only after halui is ready, and configs -rely on that ordering. This config nets halui pins in a HALFILE (see -halui-nets.hal); if halui's pins did not exist yet, linuxcnc would not get -as far as running this script. -""" - -import os -import sys -import time - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '_lib')) -from halui_test import run, HOLD # noqa: E402 - -import hal # noqa: E402 -import linuxcnc as L # noqa: E402 - -NETTED = {'machine.is-on', 'estop.activate', 'estop.reset', 'mode.mdi'} - - -def pulse_signal(h, sig, pin): - h.touched.add(pin) - hal.set_s(sig, True) - time.sleep(HOLD) - hal.set_s(sig, False) - time.sleep(HOLD) - - -def wiring(h): - h.check('linuxcnc started with halui pins netted from a HALFILE', True) - h.check('exactly the netted pins are wired outside the harness', - h.external == NETTED, 'external: %s' % sorted(h.external)) - - -def netted_pins_work(h): - h.expect('the machine-is-on-led signal is false in ESTOP', - lambda: not hal.get_value('machine-is-on-led')) - - pulse_signal(h, 'remote-estop-reset', 'estop.reset') - h.expect('a pulse on the netted estop.reset resets estop', - lambda: h.stat.task_state == L.STATE_ESTOP_RESET) - - h.machine_on() - h.expect('the machine-is-on-led signal follows the machine turning on', - lambda: hal.get_value('machine-is-on-led')) - - h.nml_mode(L.MODE_MANUAL) - pulse_signal(h, 'remote-mode-mdi', 'mode.mdi') - h.expect('a pulse on the netted mode.mdi switches task to MDI', - lambda: h.stat.task_mode == L.MODE_MDI) - - pulse_signal(h, 'remote-estop', 'estop.activate') - h.expect('a pulse on the netted estop.activate estops the machine', - lambda: h.stat.task_state == L.STATE_ESTOP) - h.expect('the machine-is-on-led signal drops with it', - lambda: not hal.get_value('machine-is-on-led')) - - try: - h.set('estop.activate', 1) - h.check('the harness refuses to drive a pin the config wired', False) - except KeyError: - h.check('the harness refuses to drive a pin the config wired', True) - - -run(wiring, netted_pins_work) diff --git a/tests/halui/startup-halfile/test.sh b/tests/halui/startup-halfile/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/startup-halfile/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh diff --git a/tests/halui/tool/checkresult b/tests/halui/tool/checkresult deleted file mode 100755 index 73e90a43dfc..00000000000 --- a/tests/halui/tool/checkresult +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/tool/halui.ini b/tests/halui/tool/halui.ini deleted file mode 100644 index 4d21b0429ec..00000000000 --- a/tests/halui/tool/halui.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Test machine shared by the halui pin tests: XYZ trivkins, one spindle, -# a tool table, a home sequence (so halui.home-all exists) and two MDI -# commands (so halui.halui-mdi-is-running and halui.mdi-command-NN exist). - -[EMC] -VERSION = 1.1 -DEBUG = 0 - -[DISPLAY] -DISPLAY = ./test-ui.py -MAX_FEED_OVERRIDE = 1.5 -MIN_SPINDLE_OVERRIDE = 0.5 -MAX_SPINDLE_OVERRIDE = 1.2 - -[TASK] -TASK = milltask -CYCLE_TIME = 0.001 - -[RS274NGC] -PARAMETER_FILE = sim.var - -[EMCMOT] -EMCMOT = motmod -COMM_TIMEOUT = 4.0 -BASE_PERIOD = 0 -SERVO_PERIOD = 1000000 - -[EMCIO] -TOOL_TABLE = tool.tbl - -[HAL] -HALFILE = LIB:core_sim.hal - -[HALUI] -MDI_COMMAND = G0 X1 Y0 Z0 -MDI_COMMAND = G0 X0 Y0 Z0 - -[TRAJ] -COORDINATES = X Y Z -LINEAR_UNITS = inch -ANGULAR_UNITS = degree -DEFAULT_LINEAR_VELOCITY = 1.2 -MAX_LINEAR_VELOCITY = 4 -SPINDLES = 1 -NO_FORCE_HOMING = 1 - -[KINS] -KINEMATICS = trivkins -JOINTS = 3 - -[AXIS_X] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Y] -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[AXIS_Z] -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 - -[JOINT_0] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_1] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -40.0 -MAX_LIMIT = 40.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 - -[JOINT_2] -TYPE = LINEAR -HOME = 0.0 -MAX_VELOCITY = 4 -MAX_ACCELERATION = 1000.0 -MIN_LIMIT = -4.0 -MAX_LIMIT = 4.0 -FERROR = 0.050 -MIN_FERROR = 0.010 -HOME_SEQUENCE = 0 diff --git a/tests/halui/tool/test-ui.py b/tests/halui/tool/test-ui.py deleted file mode 100755 index 5c0f4d9d6c0..00000000000 --- a/tests/halui/tool/test-ui.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python3 -"""halui: tool status. - -Pins: tool.number, tool.diameter, - tool.length_offset.x/y/z/a/b/c/u/v/w - -tool.tbl: T1 Z0.5 D0.25, T2 Z1.0 D0.5, T3 Z0 D0.125. test.sh copies it -fresh from ../_lib before every run, because G10 L1 rewrites it. -""" - -import os -import sys - -HERE = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.join(HERE, '..', '_lib')) -from halui_test import run # noqa: E402 - -import linuxcnc as L # noqa: E402 - -OFFSET_LETTERS = 'xyzabcuvw' - - -def mdi(h, *codes): - h.machine_on() - for c in codes: - h.nml_mdi(c) - - -def expect_tool(h, number, diameter, why): - h.expect('task has tool %d in the spindle %s' % (number, why), - lambda: h.stat.tool_in_spindle == number, - detail=lambda: 'tool_in_spindle=%d' % h.stat.tool_in_spindle) - h.expect_pin('tool.number is %d %s' % (number, why), 'tool.number', number) - h.expect_pin('tool.diameter is %g %s' % (diameter, why), 'tool.diameter', diameter, tol=1e-6) - - -def expect_offsets(h, offsets, why): - for i, a in enumerate(OFFSET_LETTERS): - want = offsets.get(a, 0.0) - h.expect('task tool offset %s is %g %s' % (a, want, why), - lambda i=i, w=want: abs(h.stat.tool_offset[i] - w) < 1e-6, - detail=lambda i=i: 'tool_offset[%d]=%g' % (i, h.stat.tool_offset[i])) - h.expect_pin('tool.length_offset.%s is %g %s' % (a, want, why), - 'tool.length_offset.' + a, want, tol=1e-6) - - -def startup(h): - expect_tool(h, 0, 0.0, 'at startup') - expect_offsets(h, {}, 'at startup') - - -def tool_changes(h): - mdi(h, 'G20 G90 G49', 'M61 Q2') - expect_tool(h, 2, 0.5, 'after M61 Q2') - expect_offsets(h, {}, 'before G43') - - mdi(h, 'G43') - expect_offsets(h, {'z': 1.0}, 'after G43 with tool 2') - - mdi(h, 'M61 Q1', 'G43') - expect_tool(h, 1, 0.25, 'after M61 Q1') - expect_offsets(h, {'z': 0.5}, 'after G43 with tool 1') - - mdi(h, 'T3 M6') - expect_tool(h, 3, 0.125, 'after T3 M6') - mdi(h, 'G43') - expect_offsets(h, {'z': 0.0}, 'after G43 with tool 3') - - mdi(h, 'G43.1 X0.1 Y0.2 Z0.3') - expect_offsets(h, {'x': 0.1, 'y': 0.2, 'z': 0.3}, 'after G43.1 X0.1 Y0.2 Z0.3') - - mdi(h, 'G49') - expect_offsets(h, {}, 'after G49') - - mdi(h, 'M61 Q0') - expect_tool(h, 0, 0.0, 'after M61 Q0 (empty spindle)') - - -def status_follows_table_edits(h): - mdi(h, 'G20 G90 M61 Q2') - expect_tool(h, 2, 0.5, 'before the table edit') - mdi(h, 'G10 L1 P2 R0.4') - expect_tool(h, 2, 0.8, 'after G10 L1 P2 R0.4 (radius 0.4)') - mdi(h, 'G10 L1 P2 Z1.25', 'G43') - expect_offsets(h, {'z': 1.25}, 'after G10 L1 P2 Z1.25 and G43') - mdi(h, 'G49', 'M61 Q0') - - -def unknown_tool(h): - # modify_hal_pins() has a latent bug: its "tool not found" test compares - # the loop index with CANON_POCKETS_MAX, but the loop stops after the last - # used index, so a tool missing from the table would leave the previous - # diameter on the pin. It cannot be reached this way: task refuses M61 for - # a tool that is not in the table, and on a non-random changer index 0 - # always mirrors the loaded tool. - mdi(h, 'G20 G90 M61 Q3') - expect_tool(h, 3, 0.125, 'before asking for an unknown tool') - h.drain_errors() - h.nml_mode(L.MODE_MDI) - h.cmd.mdi('M61 Q99') - h.cmd.wait_complete() - h.wait_idle() - h.settle(0.3) - errors = h.drain_errors() - h.check('task refuses M61 for a tool that is not in the table', - h.poll().tool_in_spindle == 3 and any('99' in e for e in errors), - 'tool_in_spindle=%d errors=%r' % (h.stat.tool_in_spindle, errors)) - expect_tool(h, 3, 0.125, 'after the refused M61 Q99') - mdi(h, 'M61 Q0') - - -run(startup, tool_changes, status_follows_table_edits, unknown_tool) diff --git a/tests/halui/tool/test.sh b/tests/halui/tool/test.sh deleted file mode 100755 index fd122f82169..00000000000 --- a/tests/halui/tool/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../_lib/launch.sh From fea0822fab96bf3fa2a383667868b44568dac83d Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sat, 17 Oct 2026 12:15:48 +0200 Subject: [PATCH 11/12] halui: read the max-velocity limit from the INI file again The conversion to the new INI parser kept the condition but dropped the read, so maxMaxVelocity stayed 1 and halui.max-velocity.* could never set more than 1 unit/s. Read [TRAJ]MAX_LINEAR_VELOCITY, falling back to [AXIS_X]MAX_VELOCITY and then 1.0, as before. --- src/emc/task/halui.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emc/task/halui.cc b/src/emc/task/halui.cc index cfbf16166ee..c3c0697784a 100644 --- a/src/emc/task/halui.cc +++ b/src/emc/task/halui.cc @@ -1089,8 +1089,8 @@ static int haluiIniLoad(const char *filename) } } - if(!inifile.isSet("MAX_LINEAR_VELOCITY", "TRAJ") && !inifile.isSet("MAX_VELOCITY", "AXIS_X")) - maxMaxVelocity = 1.0; + maxMaxVelocity = inifile.findRealV("MAX_LINEAR_VELOCITY", "TRAJ", + inifile.findRealV("MAX_VELOCITY", "AXIS_X", 1.0)); if (auto inival = inifile.findReal("MIN_SPINDLE_OVERRIDE", "DISPLAY")) { if (*inival > 0.0) { From 00590940ad44e1f93bc51a358ceab1410c63d1a4 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Sat, 17 Oct 2026 12:15:48 +0200 Subject: [PATCH 12/12] task: keep halui command errors out of the NML client status A halui command does not consume a serial number, so the echo still points at the last NML command while it runs. Clearing the error flags for it hid the error of a failed NML command, and a halui command that the planner refused set ERROR on a client command that had succeeded. Leave the flags to NML commands; the planner still reports a refused halui command on the error channel. tests/halui/client-status checks both, and the max-velocity limit. --- src/emc/task/emctaskmain.cc | 13 ++-- tests/halui/client-status/checkresult | 2 + tests/halui/client-status/halui.ini | 96 ++++++++++++++++++++++++++ tests/halui/client-status/test-ui.py | 99 +++++++++++++++++++++++++++ tests/halui/client-status/test.sh | 4 ++ 5 files changed, 209 insertions(+), 5 deletions(-) create mode 100755 tests/halui/client-status/checkresult create mode 100644 tests/halui/client-status/halui.ini create mode 100755 tests/halui/client-status/test-ui.py create mode 100755 tests/halui/client-status/test.sh diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index bbe9a8b2cc7..655b70a81de 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -3575,6 +3575,7 @@ int main(int argc, char *argv[]) check_ini_hal_items(emcStatus->motion.traj.joints); // read command + bool internalDispatch = false; if (0 != emcCommandBuffer->read()) { // got a new command, so clear out errors emcCommand = emcCommandBuffer->get_address(); @@ -3585,14 +3586,16 @@ int main(int argc, char *argv[]) taskcmd::next(emcStatus->echo_serial_number)) { // A command came from inside task (halui). Point emcCommand at // it and the rest of the loop treats it exactly like one read - // from NML. + // from NML, except for the error flags: they belong to the last + // NML command, the one whose serial a client waits on. emcCommand = queued; emcCommandInternal = true; - taskPlanError = 0; - taskExecuteError = 0; + internalDispatch = true; } - // run control cycle - if (0 != emcTaskPlan()) { + // run control cycle. A command from inside task that fails is + // reported on the error channel by the planner; it must not turn + // the status of an NML client's command into ERROR. + if (0 != emcTaskPlan() && !internalDispatch) { taskPlanError = 1; } if (0 != emcTaskExecute()) { diff --git a/tests/halui/client-status/checkresult b/tests/halui/client-status/checkresult new file mode 100755 index 00000000000..73e90a43dfc --- /dev/null +++ b/tests/halui/client-status/checkresult @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 # test failure is indicated by test.sh exit value diff --git a/tests/halui/client-status/halui.ini b/tests/halui/client-status/halui.ini new file mode 100644 index 00000000000..26f32e13f82 --- /dev/null +++ b/tests/halui/client-status/halui.ini @@ -0,0 +1,96 @@ +[EMC] +VERSION = 1.1 +DEBUG = 0x7fffffff +RCS_DEBUG = 0x05400f01 + +[DISPLAY] +DISPLAY = ./test-ui.py + +[RS274NGC] +PARAMETER_FILE = sim.var +USER_M_PATH = ./subs + +[EMCMOT] +EMCMOT = motmod +COMM_TIMEOUT = 4.0 +BASE_PERIOD = 0 +SERVO_PERIOD = 1000000 + +[TASK] +TASK = milltask +CYCLE_TIME = 0.001 +MDI_QUEUED_COMMANDS=10000 + +[HAL] +HALFILE = LIB:core_sim.hal + +[TRAJ] +NO_FORCE_HOMING=1 +AXES = 3 +COORDINATES = X Y Z +HOME = 0 0 0 +LINEAR_UNITS = inch +ANGULAR_UNITS = degree +DEFAULT_LINEAR_VELOCITY = 1.2 +MAX_LINEAR_VELOCITY = 4 + +[KINS] +KINEMATICS = trivkins +JOINTS = 3 + +[AXIS_X] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_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_Y] +MIN_LIMIT = -40.0 +MAX_LIMIT = 40.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_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_Z] +MIN_LIMIT = -4.0 +MAX_LIMIT = 4.0 +MAX_VELOCITY = 4 +MAX_ACCELERATION = 1000.0 + +[JOINT_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 = -4.0 +MAX_LIMIT = 4.0 +FERROR = 0.050 +MIN_FERROR = 0.010 diff --git a/tests/halui/client-status/test-ui.py b/tests/halui/client-status/test-ui.py new file mode 100755 index 00000000000..fdecbf8cae2 --- /dev/null +++ b/tests/halui/client-status/test-ui.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# halui inside task and an NML client side by side: +# - halui.max-velocity is limited by [TRAJ]MAX_LINEAR_VELOCITY, not 1; +# - a halui command that task refuses does not turn the status of the +# client's own command into ERROR, and a halui command does not clear +# the ERROR of a client command that failed. + +import os +import sys +import time + +import hal +import linuxcnc + +c = linuxcnc.command() +s = linuxcnc.stat() +e = linuxcnc.error_channel() +h = hal.component("test-ui") +h.newpin("home", hal.Type.BOOL, hal.Dir.OUT) +h.newpin("mv-counts", hal.Type.SINT, hal.Dir.OUT) +h.ready() +os.system("halcmd net home test-ui.home halui.joint.0.home") +os.system("halcmd net mv-counts test-ui.mv-counts halui.max-velocity.counts") +os.system("halcmd setp halui.max-velocity.count-enable 1") +os.system("halcmd setp halui.max-velocity.scale 0.01") +os.system("halcmd setp halui.max-velocity.direct-value 1") + +fails = 0 + + +def check(name, ok, detail=''): + global fails + print('%s: %s %s' % ('ok' if ok else 'FAIL', name, detail), flush=True) + if not ok: + fails += 1 + + +def wait(fn, timeout=5.0): + end = time.time() + timeout + while time.time() < end: + s.poll() + if fn(): + return True + time.sleep(0.01) + s.poll() + return fn() + + +def errors(): + msgs = [] + while True: + m = e.poll() + if not m: + return msgs + msgs.append(m[1]) + + +def settle(): + # give task a few cycles to dispatch a halui command + time.sleep(0.2) + + +wait(lambda: s.task_state != 0, 10) +c.state(linuxcnc.STATE_ESTOP_RESET) +c.state(linuxcnc.STATE_ON) +check('machine on', c.wait_complete() == linuxcnc.RCS_DONE) + +# --- max velocity above 1 unit/s through the counts pins +h['mv-counts'] = 250 +check('max-velocity counts 250 gives 2.5', wait(lambda: abs(s.max_velocity - 2.5) < 1e-9), s.max_velocity) +h['mv-counts'] = 1000 +check('max-velocity capped at MAX_LINEAR_VELOCITY', wait(lambda: abs(s.max_velocity - 4) < 1e-9), s.max_velocity) +errors() + +# --- a refused halui command leaves the client's DONE alone +c.state(linuxcnc.STATE_OFF) +check('machine off', c.wait_complete() == linuxcnc.RCS_DONE) +h['home'] = 1 +settle() +h['home'] = 0 +msgs = errors() +check('halui home refused while off', msgs != [], msgs) +check('client command still DONE after the refused halui command', + c.wait_complete() == linuxcnc.RCS_DONE) +s.poll() +check('status not ERROR', s.state != linuxcnc.RCS_ERROR, s.state) + +# --- a halui command leaves the client's ERROR alone +c.home(0) +check('client home refused while off', c.wait_complete() == linuxcnc.RCS_ERROR) +errors() +h['mv-counts'] = 150 +check('halui max-velocity applied', wait(lambda: abs(s.max_velocity - 1.5) < 1e-9), s.max_velocity) +check('client command still ERROR after a halui command', + c.wait_complete() == linuxcnc.RCS_ERROR) + +errors() +print('%d failures' % fails, flush=True) +os._exit(1 if fails else 0) diff --git a/tests/halui/client-status/test.sh b/tests/halui/client-status/test.sh new file mode 100755 index 00000000000..2d0bb0375f1 --- /dev/null +++ b/tests/halui/client-status/test.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +exec linuxcnc -r halui.ini +