Skip to content

Commit cc6c465

Browse files
committed
tests: Add a test for spindle INI speed limits function
1 parent 0eab8f8 commit cc6c465

6 files changed

Lines changed: 439 additions & 0 deletions

File tree

tests/spindle_limits/checkresult

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
# Test passes if test-ui.py returns successfully
3+
exit 0

tests/spindle_limits/spindle.hal

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# HAL file for spindle limits test
2+
3+
# first load all the RT modules that will be needed
4+
# kinematics
5+
loadrt [KINS]KINEMATICS
6+
# motion controller, get name and thread periods from INI file
7+
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS num_spindles=[TRAJ]SPINDLES
8+
9+
# add motion controller functions to servo thread
10+
addf motion-command-handler servo-thread
11+
addf motion-controller servo-thread
12+
13+
# estop loopback
14+
net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
15+
16+
17+

tests/spindle_limits/spindle.ini

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
[EMC]
2+
VERSION = 1.1
3+
DEBUG = 0x0
4+
5+
[DISPLAY]
6+
DISPLAY = ./test-ui.py
7+
8+
[RS274NGC]
9+
PARAMETER_FILE = sim.var
10+
USER_M_PATH = ./subs
11+
12+
[EMCMOT]
13+
EMCMOT = motmod
14+
COMM_TIMEOUT = 4.0
15+
BASE_PERIOD = 0
16+
SERVO_PERIOD = 1000000
17+
18+
[TASK]
19+
TASK = milltask
20+
CYCLE_TIME = 0.001
21+
MDI_QUEUED_COMMANDS=10000
22+
23+
[HAL]
24+
HALFILE = spindle.hal
25+
26+
[TRAJ]
27+
NO_FORCE_HOMING=1
28+
AXES = 3
29+
COORDINATES = X Y Z
30+
HOME = 0 0 0
31+
LINEAR_UNITS = inch
32+
ANGULAR_UNITS = degree
33+
DEFAULT_LINEAR_VELOCITY = 1.2
34+
MAX_LINEAR_VELOCITY = 4
35+
SPINDLES = 3
36+
37+
[EMCIO]
38+
EMCIO = io
39+
CYCLE_TIME = 0.100
40+
41+
[KINS]
42+
KINEMATICS = trivkins
43+
JOINTS = 3
44+
45+
[AXIS_X]
46+
MIN_LIMIT = -40.0
47+
MAX_LIMIT = 40.0
48+
MAX_VELOCITY = 4
49+
MAX_ACCELERATION = 1000.0
50+
51+
[JOINT_0]
52+
TYPE = LINEAR
53+
HOME = 0.000
54+
MAX_VELOCITY = 4
55+
MAX_ACCELERATION = 1000.0
56+
BACKLASH = 0.000
57+
INPUT_SCALE = 4000
58+
OUTPUT_SCALE = 1.000
59+
MIN_LIMIT = -40.0
60+
MAX_LIMIT = 40.0
61+
FERROR = 0.050
62+
MIN_FERROR = 0.010
63+
64+
[AXIS_Y]
65+
MIN_LIMIT = -40.0
66+
MAX_LIMIT = 40.0
67+
MAX_VELOCITY = 4
68+
MAX_ACCELERATION = 1000.0
69+
70+
[JOINT_1]
71+
TYPE = LINEAR
72+
HOME = 0.000
73+
MAX_VELOCITY = 4
74+
MAX_ACCELERATION = 1000.0
75+
BACKLASH = 0.000
76+
INPUT_SCALE = 4000
77+
OUTPUT_SCALE = 1.000
78+
MIN_LIMIT = -40.0
79+
MAX_LIMIT = 40.0
80+
FERROR = 0.050
81+
MIN_FERROR = 0.010
82+
83+
[AXIS_Z]
84+
MIN_LIMIT = -4.0
85+
MAX_LIMIT = 4.0
86+
MAX_VELOCITY = 4
87+
MAX_ACCELERATION = 1000.0
88+
89+
[JOINT_2]
90+
TYPE = LINEAR
91+
HOME = 0.0
92+
MAX_VELOCITY = 4
93+
MAX_ACCELERATION = 1000.0
94+
BACKLASH = 0.000
95+
INPUT_SCALE = 4000
96+
OUTPUT_SCALE = 1.000
97+
MIN_LIMIT = -4.0
98+
MAX_LIMIT = 4.0
99+
FERROR = 0.050
100+
MIN_FERROR = 0.010
101+
102+
[SPINDLE_0]
103+
MAX_FORWARD_VELOCITY = 1000
104+
MIN_FORWARD_VELOCITY = 100
105+
MAX_REVERSE_VELOCITY = 1500
106+
MIN_REVERSE_VELOCITY = 500
107+
108+
[SPINDLE_1]
109+
MAX_FORWARD_VELOCITY = 2000
110+
MIN_FORWARD_VELOCITY = 200
111+
MAX_REVERSE_VELOCITY = 2500
112+
113+
[SPINDLE_2]
114+
MAX_FORWARD_VELOCITY = 3000
115+
MIN_FORWARD_VELOCITY = 300

tests/spindle_limits/test-ui.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#!/usr/bin/env python3
2+
3+
import linuxcnc
4+
import hal
5+
import time
6+
import sys
7+
8+
def wait_for_linuxcnc_startup(status, timeout=10.0):
9+
10+
"""Poll the Status buffer waiting for it to look initialized,
11+
rather than just allocated (all-zero). Returns on success, throws
12+
RuntimeError on failure."""
13+
14+
start_time = time.time()
15+
while time.time() - start_time < timeout:
16+
status.poll()
17+
if (status.angular_units == 0.0) \
18+
or (status.axis_mask == 0) \
19+
or (status.cycle_time == 0.0) \
20+
or (status.exec_state != linuxcnc.EXEC_DONE) \
21+
or (status.interp_state != linuxcnc.INTERP_IDLE) \
22+
or (status.inpos == False) \
23+
or (status.linear_units == 0.0) \
24+
or (status.max_acceleration == 0.0) \
25+
or (status.max_velocity == 0.0) \
26+
or (status.program_units == 0.0) \
27+
or (status.rapidrate == 0.0) \
28+
or (status.state != linuxcnc.RCS_DONE) \
29+
or (status.task_state != linuxcnc.STATE_ESTOP):
30+
time.sleep(0.1)
31+
else:
32+
# looks good
33+
return
34+
35+
# timeout, throw an exception
36+
raise RuntimeError
37+
38+
39+
def wait_for_mdi_queue(queue_len, timeout=10):
40+
start_time = time.time()
41+
while (time.time() - start_time) < timeout:
42+
s.poll()
43+
if s.queued_mdi_commands == queue_len:
44+
return
45+
time.sleep(0.1)
46+
print("queued_mdi_commands at %d after %.3f seconds" % (s.queued_mdi_commands, timeout))
47+
sys.exit(1)
48+
49+
50+
c = linuxcnc.command()
51+
s = linuxcnc.stat()
52+
e = linuxcnc.error_channel()
53+
comp = hal.component('hal-watcher')
54+
55+
# Wait for LinuxCNC to initialize itself so the Status buffer stabilizes.
56+
wait_for_linuxcnc_startup(s)
57+
58+
c.state(linuxcnc.STATE_ESTOP_RESET)
59+
c.state(linuxcnc.STATE_ON)
60+
c.wait_complete()
61+
62+
63+
# Check G-code / MDI spindle commands
64+
65+
c.mode(linuxcnc.MODE_MDI)
66+
67+
c.mdi("M3 S10 $0")
68+
c.mdi("M3 S10 $1")
69+
c.mdi("M3 S10 $2")
70+
c.wait_complete()
71+
72+
s.poll()
73+
74+
assert hal.get_value('spindle.0.speed-out') == 100
75+
assert s.spindle[0]['speed'] == 100
76+
assert hal.get_value('spindle.1.speed-out') == 200
77+
assert s.spindle[1]['speed'] == 200
78+
assert hal.get_value('spindle.2.speed-out') == 300
79+
assert s.spindle[2]['speed'] == 300
80+
81+
c.mdi("M3 S10000 $0")
82+
c.mdi("M3 S10000 $1")
83+
c.mdi("M3 S10000 $2")
84+
c.wait_complete()
85+
86+
s.poll()
87+
88+
assert hal.get_value('spindle.0.speed-out') == 1000
89+
assert s.spindle[0]['speed'] == 1000
90+
assert hal.get_value('spindle.1.speed-out') == 2000
91+
assert s.spindle[1]['speed'] == 2000
92+
assert hal.get_value('spindle.2.speed-out') == 3000
93+
assert s.spindle[2]['speed'] == 3000
94+
95+
c.mdi("M4 S10 $0")
96+
c.mdi("M4 S10 $1")
97+
c.mdi("M4 S10 $2")
98+
c.wait_complete()
99+
100+
s.poll()
101+
102+
assert hal.get_value('spindle.0.speed-out') == -500
103+
assert s.spindle[0]['speed'] == -500
104+
assert hal.get_value('spindle.1.speed-out') == -200
105+
assert s.spindle[1]['speed'] == -200
106+
assert hal.get_value('spindle.2.speed-out') == -300
107+
assert s.spindle[2]['speed'] == -300
108+
109+
c.mdi("M4 S10000 $0")
110+
c.mdi("M4 S10000 $1")
111+
c.mdi("M4 S10000 $2")
112+
c.wait_complete()
113+
114+
s.poll()
115+
116+
assert hal.get_value('spindle.0.speed-out') == -1500
117+
assert s.spindle[0]['speed'] == -1500
118+
assert hal.get_value('spindle.1.speed-out') == -2500
119+
assert s.spindle[1]['speed'] == -2500
120+
assert hal.get_value('spindle.2.speed-out') == -3000
121+
assert s.spindle[2]['speed'] == -3000
122+
123+
# Check Python interface commands
124+
125+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10, 0, 0)
126+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10, 1, 0)
127+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10, 2, 0)
128+
c.wait_complete()
129+
130+
s.poll()
131+
132+
assert hal.get_value('spindle.0.speed-out') == 100
133+
assert s.spindle[0]['speed'] == 100
134+
assert hal.get_value('spindle.1.speed-out') == 200
135+
assert s.spindle[1]['speed'] == 200
136+
assert hal.get_value('spindle.2.speed-out') == 300
137+
assert s.spindle[2]['speed'] == 300
138+
139+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10000, 0, 0)
140+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10000, 1, 0)
141+
c.spindle(linuxcnc.SPINDLE_FORWARD, 10000, 2, 0)
142+
c.wait_complete()
143+
144+
s.poll()
145+
146+
assert hal.get_value('spindle.0.speed-out') == 1000
147+
assert s.spindle[0]['speed'] == 1000
148+
assert hal.get_value('spindle.1.speed-out') == 2000
149+
assert s.spindle[1]['speed'] == 2000
150+
assert hal.get_value('spindle.2.speed-out') == 3000
151+
assert s.spindle[2]['speed'] == 3000
152+
153+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10, 0, 0)
154+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10, 1, 0)
155+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10, 2, 0)
156+
c.wait_complete()
157+
158+
s.poll()
159+
160+
assert hal.get_value('spindle.0.speed-out') == -500
161+
assert s.spindle[0]['speed'] == -500
162+
assert hal.get_value('spindle.1.speed-out') == -200
163+
assert s.spindle[1]['speed'] == -200
164+
assert hal.get_value('spindle.2.speed-out') == -300
165+
assert s.spindle[2]['speed'] == -300
166+
167+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10000, 0, 0)
168+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10000, 1, 0)
169+
c.spindle(linuxcnc.SPINDLE_REVERSE, 10000, 2, 0)
170+
c.wait_complete()
171+
172+
s.poll()
173+
174+
assert hal.get_value('spindle.0.speed-out') == -1500
175+
assert s.spindle[0]['speed'] == -1500
176+
assert hal.get_value('spindle.1.speed-out') == -2500
177+
assert s.spindle[1]['speed'] == -2500
178+
assert hal.get_value('spindle.2.speed-out') == -3000
179+
assert s.spindle[2]['speed'] == -3000
180+
181+
sys.exit(0)
182+

0 commit comments

Comments
 (0)