Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions configs/sim/gmoccapy/simulated_home.hal
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
loadrt or2 names=or2_0
loadrt comp names=comp_x,comp_y,comp_z

net Xhomeswpos => comp_x.in0
Expand All @@ -17,16 +16,10 @@ setp comp_x.hyst .02
setp comp_y.hyst .02
setp comp_z.hyst .02

net Xhomesw <= comp_x.out
net Xhomesw <= comp_x.out => joint.0.home-sw-in
net Yhomesw <= comp_y.out => joint.1.home-sw-in
net Zhomesw <= comp_z.out

net Xhomesw => or2_0.in0
net Zhomesw => or2_0.in1
net XZhomesw or2_0.out => joint.0.home-sw-in joint.2.home-sw-in
net Zhomesw <= comp_z.out => joint.2.home-sw-in

addf comp_x servo-thread
addf comp_y servo-thread
addf comp_z servo-thread

addf or2_0 servo-thread
2 changes: 1 addition & 1 deletion configs/sim/touchy/touchy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ SERVO_PERIOD = 1000000

HALFILE = core_sim.hal
# add a test panel so people can actually test the screen
HALCMD = loadusr gladevcp --always_above -c touchy_test touchy_test_panel.glade
HALCMD = loadusr -Wn touchy_test gladevcp --always_above -c touchy_test touchy_test_panel.glade
POSTGUI_HALFILE = touchy_postgui.hal

[TRAJ]
Expand Down
4 changes: 3 additions & 1 deletion src/emc/task/taskintf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,9 @@ int emcTrajUpdate(EMC_TRAJ_STAT * stat)

if (emcmotStatus.motionFlag & EMCMOT_MOTION_ERROR_BIT) {
stat->status = RCS_STATUS::ERROR;
} else if (stat->inpos && (stat->queue == 0)) {
} else if (stat->inpos && (stat->queue == 0) && !emcmotStatus.probing) {
// a probe move that ends without contact is reported a servo
// cycle after the planner goes idle, so wait for the verdict
stat->status = RCS_STATUS::DONE;
} else {
stat->status = RCS_STATUS::EXEC;
Expand Down
2 changes: 1 addition & 1 deletion tests/abort/stop-button-crazy-move/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# Time increment and timeout, seconds
TIME_INCR = 0.1
TIMEOUT = 10.0
TIMEOUT = 60.0

#
# connect to LinuxCNC
Expand Down
12 changes: 12 additions & 0 deletions tests/hal-show/checkresult
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e

TESTDIR=$(dirname "$1")
cd "${TESTDIR}"

# The owner column is the component ID, which depends on the order in which
# halcmd and rtapi_app take IDs during each loadrt. That order changes with
# CPU load, so mask it.
sed --in-place --regexp-extended --expression='s/^ *[0-9]+( +[a-z0-9]+ +(IN|OUT|I\/O) .*)$/(ignored comp id)\1/' result

diff -u expected result
24 changes: 12 additions & 12 deletions tests/hal-show/expected
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Component Pins:
Owner Type Dir Value Name
10 bool IN FALSE conv-bool-uint.0.in <== net-conv-bool-uint.0.in
16 real IN 0 conv-real-sint.0.in <== net-conv-real-sint.0.in
19 sint IN 0 conv-sint-real.0.in <== net-conv-sint-real.0.in
22 sint IN 0 conv-sint-uint.0.in <== net-conv-sint-uint.0.in
13 uint IN 0x0000000000000000 conv-uint-bool.0.in <== net-conv-uint-bool.0.in
25 uint IN 0x0000000000000000 conv-uint-sint.0.in <== net-conv-uint-sint.0.in
(ignored comp id) bool IN FALSE conv-bool-uint.0.in <== net-conv-bool-uint.0.in
(ignored comp id) real IN 0 conv-real-sint.0.in <== net-conv-real-sint.0.in
(ignored comp id) sint IN 0 conv-sint-real.0.in <== net-conv-sint-real.0.in
(ignored comp id) sint IN 0 conv-sint-uint.0.in <== net-conv-sint-uint.0.in
(ignored comp id) uint IN 0x0000000000000000 conv-uint-bool.0.in <== net-conv-uint-bool.0.in
(ignored comp id) uint IN 0x0000000000000000 conv-uint-sint.0.in <== net-conv-uint-sint.0.in

Signals:
Type Value Name (linked to)
Expand Down Expand Up @@ -36,12 +36,12 @@ sint 0 net-conv-uint-sint.0.out

Component Pins:
Owner Type Dir Value Name
10 bool IN TRUE conv-bool-uint.0.in <== net-conv-bool-uint.0.in
16 real IN 2.147484e+09 conv-real-sint.0.in <== net-conv-real-sint.0.in
19 sint IN -2147483648 conv-sint-real.0.in <== net-conv-sint-real.0.in
22 sint IN -9223372036854775808 conv-sint-uint.0.in <== net-conv-sint-uint.0.in
13 uint IN 0x00000000FFFFFFFF conv-uint-bool.0.in <== net-conv-uint-bool.0.in
25 uint IN 0xFFFFFFFFFFFFFFFF conv-uint-sint.0.in <== net-conv-uint-sint.0.in
(ignored comp id) bool IN TRUE conv-bool-uint.0.in <== net-conv-bool-uint.0.in
(ignored comp id) real IN 2.147484e+09 conv-real-sint.0.in <== net-conv-real-sint.0.in
(ignored comp id) sint IN -2147483648 conv-sint-real.0.in <== net-conv-sint-real.0.in
(ignored comp id) sint IN -9223372036854775808 conv-sint-uint.0.in <== net-conv-sint-uint.0.in
(ignored comp id) uint IN 0x00000000FFFFFFFF conv-uint-bool.0.in <== net-conv-uint-bool.0.in
(ignored comp id) uint IN 0xFFFFFFFFFFFFFFFF conv-uint-sint.0.in <== net-conv-uint-sint.0.in

Signals:
Type Value Name (linked to)
Expand Down
3 changes: 2 additions & 1 deletion tests/halmodule/stream/stream_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
assert reader.sampleno == i+1
assert reader.read() is None
assert reader.num_underruns == 1
# report before ready(): halrun ends the run once it sees ready
print("pass", flush=True)
c.ready()
print("pass")

try:
while 1: time.sleep(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ SPINDLE_OFF
DISABLE
JOINT_UNHOME joint=-2
FREE
SET_TERM_COND termCond=2, tolerance=0.001
JOG_ABORT joint=0
JOG_ABORT joint=1
JOG_ABORT joint=2
Expand Down
16 changes: 16 additions & 0 deletions tests/interp/m98m99/12-M99-endless-main-program/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
e = linuxcnc.error_channel()


#
# Task queues the canon commands of interpreter init before it reads its
# first command. Let it issue them, or an early ESTOP_RESET wipes them
# and the log depends on how fast this script starts.
#

deadline = time.monotonic() + 60
while True:
s.poll()
if s.state == linuxcnc.RCS_DONE: break
if time.monotonic() > deadline:
print("task did not finish startup")
sys.exit(1)
time.sleep(0.01)


#
# Come out of E-stop, turn the machine on, home, and switch to Auto mode.
#
Expand Down
1 change: 1 addition & 0 deletions tests/motion-logger/basic/expected.builtin-startup.in
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ SPINDLE_OFF
DISABLE
JOINT_UNHOME joint=-2
FREE
SET_TERM_COND termCond=2, tolerance=0.001
JOG_ABORT joint=0
JOG_ABORT joint=1
JOG_ABORT joint=2
Expand Down
16 changes: 16 additions & 0 deletions tests/motion-logger/basic/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ def end_log(logfile_name):
e = linuxcnc.error_channel()


#
# Task queues the canon commands of interpreter init before it reads its
# first command. Let it issue them, or an early ESTOP_RESET wipes them
# and the log depends on how fast this script starts.
#

deadline = time.monotonic() + 60
while True:
s.poll()
if s.state == linuxcnc.RCS_DONE: break
if time.monotonic() > deadline:
print("task did not finish startup")
sys.exit(1)
time.sleep(0.01)


#
# Come out of E-stop, turn the machine on, and switch to Auto mode.
#
Expand Down
1 change: 1 addition & 0 deletions tests/motion-logger/mountaindew/expected.motion-logger
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ SPINDLE_OFF
DISABLE
JOINT_UNHOME joint=-2
FREE
SET_TERM_COND termCond=2, tolerance=0.001
JOG_ABORT joint=0
JOG_ABORT joint=1
JOG_ABORT joint=2
Expand Down
16 changes: 16 additions & 0 deletions tests/motion-logger/mountaindew/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
e = linuxcnc.error_channel()


#
# Task queues the canon commands of interpreter init before it reads its
# first command. Let it issue them, or an early ESTOP_RESET wipes them
# and the log depends on how fast this script starts.
#

deadline = time.monotonic() + 60
while True:
s.poll()
if s.state == linuxcnc.RCS_DONE: break
if time.monotonic() > deadline:
print("task did not finish startup")
sys.exit(1)
time.sleep(0.01)


#
# Come out of E-stop, turn the machine on, home, and switch to Auto mode.
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,15 @@ JOINT_UNHOME joint=-2
FREE

#
# Task is now got the 'motion.in-position' pin visible, and is
# accepting abort calls from the UI.
# Task now issues what interp_list holds: the interpreter's init and the
# first move of the startup code, then waits in its dwell.
#

SET_TERM_COND termCond=2, tolerance=0.001
SET_LINE x=-1, y=-2, z=-3, a=0, b=0, c=0, u=0, v=0, w=0, id=2, motion_type=1, vel=4.98888, ini_maxvel=4.98888, acc=1247.22, turn=-1

#
# The test UI immediately sent an Abort.
# The test UI sent an Abort during the dwell.
#

JOG_ABORT joint=0
Expand Down
9 changes: 9 additions & 0 deletions tests/motion-logger/startup-gcode-abort/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
time.sleep(0.1)
waitlimit -= 1

# Abort in the dwell of the startup code, after its first move went out.
waitlimit = 600
while 0 < waitlimit:
s.poll()
if s.exec_state == linuxcnc.EXEC_WAITING_FOR_DELAY:
break
time.sleep(0.1)
waitlimit -= 1

print("UI abort")
sys.stdout.flush()

Expand Down
10 changes: 5 additions & 5 deletions tests/multiclick/test.hal
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
loadrt threads name1=millisecond period1=1000000

loadrt multiclick count=2
loadrt sampler depth=100 cfg=bbbbbbbbbsbbbbbbbbbs
loadrt streamer depth=100 cfg=bb
loadrt sampler depth=128 cfg=bbbbbbbbbsbbbbbbbbbs
loadrt streamer depth=128 cfg=bb


net in0 streamer.0.pin.0 => multiclick.0.in sampler.0.pin.0
Expand Down Expand Up @@ -50,9 +50,9 @@ setp multiclick.1.output-hold-ns 1500000
setp multiclick.1.invert-input True


# run halstreamer and let it pre-load the fifo
loadusr halstreamer input-signals
loadusr -w sleep 0.5
# pre-load the whole input before the thread starts; halstreamer exits
# once the last line is in the fifo
loadusr -w halstreamer input-signals

start
loadusr -w halsampler -n 105
Expand Down
9 changes: 5 additions & 4 deletions tests/mux/test.hal
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
setexact_for_test_suite_only
loadrt threads name1=slow period1=1000000
loadrt mux_generic config="b2b,b2f,b2s,b2u,f2b,f2f,f2s,f2u,s2b,s2f,s2s,s2u,u2b,u2f,u2s,u2u,b2b,f5f"
loadrt streamer depth=100 cfg=bu
loadrt sampler depth=100 cfg=bfsubfsubfsubfsubfbu
loadrt streamer depth=128 cfg=bu
loadrt sampler depth=128 cfg=bfsubfsubfsubfsubfbu

addf streamer.0 slow
addf mux-gen.00 slow
Expand Down Expand Up @@ -80,8 +80,9 @@ net o15 mux-gen.15.out-uint sampler.0.pin.15
net o16 mux-gen.16.out-bool sampler.0.pin.16
net o17 mux-gen.17.out-real sampler.0.pin.17

loadusr halstreamer input-signals
loadusr -w sleep 0.5
# pre-load the whole input before the thread starts; halstreamer exits
# once the last line is in the fifo
loadusr -w halstreamer input-signals

start
loadusr -w halsampler -n 105
Expand Down
5 changes: 4 additions & 1 deletion tests/remap/remap-io/test-ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,17 @@ def do_in(inp, d_in=True, wait_mode=None, timeout=None):
timeout = (' Q%d' % timeout if timeout is not None else ''),
)

# Read the pre-test values before setting the input pin; motion copies
# the pin into the status within a servo cycle
s.poll() # Update status channel

# Set input pin
if d_in:
h['d_in'] = inp
else:
h['a_in'] = inp

# Print pre-test values
s.poll() # Update status channel
c.mdi('(print,cmd: "%s"; input: %.4f)' % (cmd, inp))
c.mdi('(print, M66 remapping pre: 5399=#5399; 100=#100; '
'ain0=%.2f; din0=%d)' % (s.ain[0], s.din[0]))
Expand Down
25 changes: 20 additions & 5 deletions tests/ui-smoke/_lib/drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,15 @@ def home_all(cmd, stat, timeout):
Ensures ESTOP_RESET + ON + MANUAL and retries the whole sequence
(see HOME_RETRY_BUDGET)."""
attempt_timeout = min(timeout, HOME_ATTEMPT_TIMEOUT_S)
deadline = time.monotonic() + timeout
for attempt in range(1, HOME_RETRY_BUDGET + 1):
if not ensure_state(cmd, stat, linuxcnc.STATE_ESTOP_RESET,
"STATE_ESTOP_RESET"):
# Task reports ESTOP_RESET only while the machine is off, and an
# ESTOP_RESET command does not turn it off, so requesting it on a
# retry after the machine came on would never be met.
stat.poll()
if (stat.task_state != linuxcnc.STATE_ON and
not ensure_state(cmd, stat, linuxcnc.STATE_ESTOP_RESET,
"STATE_ESTOP_RESET")):
return False
if not ensure_state(cmd, stat, linuxcnc.STATE_ON, "STATE_ON"):
return False
Expand All @@ -171,10 +177,19 @@ def home_all(cmd, stat, timeout):
stat.poll()
njoints = stat.joints
cmd.home(-1)
if wait_until_quiet(
all_homed = lambda s: all(s.homed[i] for i in range(njoints))
done = wait_until_quiet(stat, all_homed, attempt_timeout)
# On a slow machine homing can still be running here. Homing
# again would restart joints whose home switch another, already
# homed joint now holds active (the gmoccapy sim shares one switch
# between X and Z), so let a running sequence finish instead.
if not done and any(stat.joint[i]["homing"] for i in range(njoints)):
done = wait_until_quiet(
stat,
lambda s: all(s.homed[i] for i in range(njoints)),
attempt_timeout):
lambda s: all_homed(s) or not any(
s.joint[i]["homing"] for i in range(njoints)),
max(0.0, deadline - time.monotonic())) and all_homed(stat)
if done:
cmd.teleop_enable(1)
cmd.wait_complete()
return True
Expand Down
34 changes: 27 additions & 7 deletions tests/ui-smoke/_lib/window-fit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
#
# window_fit_check <wm-class-pattern>
# <wm-class-pattern> is matched literally against the xwininfo tree
# line, e.g. '("touchy" "Touchy")'. The first matching window is checked
# against the root window (the screen). Needs xwininfo (x11-utils).
# line, e.g. '("touchy" "Touchy")'. The first viewable matching window
# is checked against the root window (the screen). Needs xwininfo
# (x11-utils).

window_fit_check() {
pattern="$1"
Expand All @@ -22,11 +23,30 @@ window_fit_check() {
root=$(xwininfo -root 2>/dev/null)
screen_w=$(echo "$root" | awk '/Width:/{print $2; exit}')
screen_h=$(echo "$root" | awk '/Height:/{print $2; exit}')
geom=$(xwininfo -root -tree 2>/dev/null | grep -F "$pattern" \
| grep -oE '[0-9]+x[0-9]+\+[0-9]+\+[0-9]+' | head -1)
win_w=${geom%%x*}
rest=${geom#*x}
win_h=${rest%%+*}
# drive.py returns once task is up, which under load can be before
# the GUI maps its window. The tree also lists unmapped windows, at
# the size they were created with, so measure only a viewable one,
# and poll until its size reads the same twice in a row.
win_w=
win_h=
prev=
for _ in $(seq "${UI_SMOKE_FIT_TIMEOUT:-60}"); do
size=
for w in $(xwininfo -root -tree 2>/dev/null | grep -F "$pattern" \
| grep -oE '^ +0x[0-9a-f]+'); do
info=$(xwininfo -id "$w" 2>/dev/null)
echo "$info" | grep -q "Map State: IsViewable" || continue
size=$(echo "$info" | awk '/^ *Width:/{w=$2} /^ *Height:/{h=$2} END{print w "x" h}')
break
done
if [ -n "$size" ] && [ "$size" = "$prev" ]; then
win_w=${size%x*}
win_h=${size#*x}
break
fi
prev=$size
sleep 1
done
if [ -z "$win_w" ] || [ -z "$win_h" ]; then
echo "UI_SMOKE_FAIL: window-fit: no window matching $pattern found"
return 1
Expand Down
Loading