Import LinuxCNC source tree

This commit is contained in:
Wang Dequan
2026-08-20 06:17:39 +08:00
commit 2c814634c3
9429 changed files with 10556013 additions and 0 deletions

5
tests/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
result
stderr
*.var
*.var.bak
*.ini.expanded

109
tests/README Normal file
View File

@@ -0,0 +1,109 @@
The HAL test suite
~~~~~~~~~~~~~~~~~~~
The tests in these directories serve to test the behavior of HAL components.
Each subdirectory of this directory may contain a test item. The runtests
script recurses through the directory structure, so multiple tests could
be structured as
tests/
xyz.0
xyz.1
xyz.2
or
tests/
xyz/
0
1
2
Two types of tests are supported: Regression tests, in which the output is
tested against a "known good" output, and functional tests, in which the
output is fed to a program that can determine whether it is correct or not
Running the tests
~~~~~~~~~~~~~~~~~
Currently, tests only work with the "run in place" configuration. They
can be run by executing (from the top emc2 directory)
scripts/runtests tests
A subset of the tests can also be run:
scripts/runtests tests/xyz tests/a*
To only run the tests that do not require root or sudo access, use the
-u option:
scripts/runtests -u tests
The directories named on the commandline are searched recursively for
'test.hal' or 'test.sh' files, and a directory with such a file is
assumed to contain a regression test or a functional test.
Tests may contain files other than the ones specified below. For instance,
when using 'streamer' data as test input, a shell script with
"halstreamer<<EOF" and a "here document" will generally be present.
(see and-or-not-mux.0/runstreamer for an example)
Regression Tests
~~~~~~~~~~~~~~~~
A regression test should consist of these three files:
README
A human-readable file describing the test
test.hal *or* test.sh *or* test
The test script to execute. test.hal is executed with
'halrun -f', test.sh is executed with 'bash -x', and
test is executed as ./test
expected
A file whose contents are compared with the stdout of
halrun -f test.hal
A typical regression test will load several components, usually including
'threads' and 'sampler', and often including 'streamer', then collect samples
from some number of calls to the realtime thread, then exit.
Regression test "test.hal" files will almost always include the line
setexact_for_test_suite_only
which causes HAL to act as though the requested base_period was available.
Otherwise, results will differ slightly depending on the actual base_period
and regression tests will fail.
The test passes if the expected and actual output are identical.
Otherwise, the test fails.
Functional Tests
~~~~~~~~~~~~~~~~
A functional test should consist of three files:
README
A human-readable file describing the test
test.hal *or* test.sh *or* test
The test script to execute. test.hal is executed with
'halrun -f', test.sh is executed with 'bash -x', and
test is executed as ./test
checkresult
An executable file (such as a shell or python script)
which determines if the stdout of
halrun -f test.hal
indicates success or failure
Regression test "test.hal" files will often include the line
setexact_for_test_suite_only
which causes HAL to act as though the requested base_period was available.
Otherwise, results will differ slightly depending on the actual base_period,
which could affect whether 'checkresult' gives an accurate result.
A typical regression test will load several components, usually including
'threads' and 'sample', then collect samples from some number of calls
to the realtime thread, then exit. 'checkresult' will look at the output
and see if it indicates success.
The test passes if the command "checkresult actual" returns a shell
success value (exit code 0). Otherwise, the test fails.
Tests requiring root or sudo access are flagged by creating a file
named control in the test directory, with the 'sudo' flag in the
Restrictions field:
Restrictions: sudo
Other restrictions might be added in the future

37
tests/Submakefile Normal file
View File

@@ -0,0 +1,37 @@
# Prepare tests to run even when separated from the rest of
# the sources
userspace: test-inputs
PERSONALITIES_MOD_COMPS = \
$(patsubst %,../tests/halcompile/personalities_mod/%_test.comp,\
lincurve logic bitslice)
$(PERSONALITIES_MOD_COMPS): ../tests/halcompile/personalities_mod/%_test.comp: \
hal/components/%.comp
$(ECHO) Copying test input $<
$(Q)sed $< -e "1 s/$(*)/$(*)_test/" > $@
../tests/halcompile/serial-out-of-tree/mesa_uart_test.comp: \
hal/drivers/mesa_uart.comp
sed $< -e "1 s/mesa_uart/mesa_uart_test/" > $@
../tests/halcompile/userspace/rand_test.comp: \
../tests/halcompile/userspace/rand.comp
sed $< -e "1 s/rand/rand_test/" > $@
../tests/uspace/spawnv-root/rtapi.conf: ../scripts/rtapi.conf
cp $< $@
test-inputs: $(PERSONALITIES_MOD_COMPS) \
../tests/halcompile/serial-out-of-tree/mesa_uart_test.comp \
../tests/halcompile/userspace/rand_test.comp \
../tests/uspace/spawnv-root/rtapi.conf
clean: test-inputs-clean
test-inputs-clean:
rm -f $(PERSONALITIES_MOD_COMPS) \
../tests/halcompile/serial-out-of-tree/mesa_uart_test.comp \
../tests/halcompile/userspace/rand_test.comp \
../tests/uspace/spawnv-root/rtapi.conf

1
tests/abort/feed-rate/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
sim.var*

View File

@@ -0,0 +1,4 @@
This test starts LinuxCNC, sets the feed rate (in G94 and G95), then
Aborts and verifies that the expected feed rate is active.
In 2.6.12 and 2.7.7 this test replicates Github Issue #180.

View File

@@ -0,0 +1,2 @@
#!/bin/sh
exit 0 # test failure is indicated by test.sh exit value

View File

@@ -0,0 +1,61 @@
# core HAL config file for simulation
# first load all the RT modules that will be needed
# kinematics
loadrt [KINS]KINEMATICS
#autoconverted trivkins
# motion controller, get name and thread periods from INI file
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
# load 6 differentiators (for velocity and accel signals
loadrt ddt count=6
# load additional blocks
loadrt hypot count=2
loadrt comp count=3
loadrt or2 count=1
# add motion controller functions to servo thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
# link the differentiator functions into the code
addf ddt.0 servo-thread
addf ddt.1 servo-thread
addf ddt.2 servo-thread
addf ddt.3 servo-thread
addf ddt.4 servo-thread
addf ddt.5 servo-thread
addf hypot.0 servo-thread
addf hypot.1 servo-thread
# create HAL signals for position commands from motion module
# loop position commands back to motion module feedback
net Xpos joint.0.motor-pos-cmd => joint.0.motor-pos-fb ddt.0.in
net Ypos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt.2.in
net Zpos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt.4.in
# send the position commands thru differentiators to
# generate velocity and accel signals
net Xvel ddt.0.out => ddt.1.in hypot.0.in0
net Xacc <= ddt.1.out
net Yvel ddt.2.out => ddt.3.in hypot.0.in1
net Yacc <= ddt.3.out
net Zvel ddt.4.out => ddt.5.in hypot.1.in0
net Zacc <= ddt.5.out
# Cartesian 2- and 3-axis velocities
net XYvel hypot.0.out => hypot.1.in1
net XYZvel <= hypot.1.out
# estop loopback
net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
# create signals for tool loading loopback
net tool-prepare <= iocontrol.0.tool-prepare
net tool-prepared => iocontrol.0.tool-prepared
net tool-change <= iocontrol.0.tool-change
net tool-changed => iocontrol.0.tool-changed
net tool-number <= iocontrol.0.tool-number
net tool-prep-number <= iocontrol.0.tool-prep-number
net tool-prep-pocket <= iocontrol.0.tool-prep-pocket

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
import linuxcnc
import hal
import math
import time
import sys
import subprocess
import os
import signal
import glob
import re
def wait_for_linuxcnc_startup(status, timeout=10.0):
"""Poll the Status buffer waiting for it to look initialized,
rather than just allocated (all-zero). Returns on success, throws
RuntimeError on failure."""
start_time = time.time()
while time.time() - start_time < timeout:
status.poll()
if (status.angular_units == 0.0) \
or (status.axis_mask == 0) \
or (status.cycle_time == 0.0) \
or (status.exec_state != linuxcnc.EXEC_DONE) \
or (status.interp_state != linuxcnc.INTERP_IDLE) \
or (status.inpos == False) \
or (status.linear_units == 0.0) \
or (status.max_acceleration == 0.0) \
or (status.max_velocity == 0.0) \
or (status.program_units == 0.0) \
or (status.rapidrate == 0.0) \
or (status.state != linuxcnc.RCS_DONE) \
or (status.task_state != linuxcnc.STATE_ESTOP):
time.sleep(0.1)
else:
# looks good
return
# timeout, throw an exception
raise RuntimeError("Timeout")
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
# Wait for LinuxCNC to initialize itself so the Status buffer stabilizes.
wait_for_linuxcnc_startup(s)
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.home(-1)
c.wait_complete()
c.mode(linuxcnc.MODE_MDI)
feed_rate = 234.5
c.mdi('g94 ; normal "units per minute" feed mode')
c.mdi('f%.1f' % feed_rate)
c.wait_complete()
c.abort()
c.wait_complete()
s.poll()
print("feed rate:{}".format(s.settings[1]))
assert(math.fabs(s.settings[1] - feed_rate) < 0.0000001)
feed_rate = 345.6
c.mdi('g95 ; "units per revolution" feed mode')
c.mdi('f%.1f' % feed_rate)
c.wait_complete()
c.abort()
c.wait_complete()
s.poll()
print("feed rate:{}".format(s.settings[1]))
assert(math.fabs(s.settings[1] - feed_rate) < 0.0000001)
sys.exit(0)

View File

@@ -0,0 +1,119 @@
# This config file was created 2016-10-21 21:15:55.646298 by the update_ini script
# The original config files may be found in the /home/seb/linuxcnc-dev/tests/abort/feed-rate/test.old directory
[EMC]
# The version string for this INI file.
VERSION = 1.1
#DEBUG = 0x0
DEBUG = 0xffffffff
[DISPLAY]
DISPLAY = ./test-ui.py
[FILTER]
#No Content
[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
[HAL]
HALUI = halui
HALFILE = core_sim.hal
[HALUI]
#No Content
[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_ACCELERATION = 123.45
MAX_LINEAR_VELOCITY = 45.67
[EMCIO]
TOOL_TABLE = simpockets.tbl
TOOL_CHANGE_QUILL_UP = 1
RANDOM_TOOLCHANGER = 0
[KINS]
KINEMATICS = trivkins
#This is a best-guess at the number of joints, it should be checked
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 = -40.0
MAX_LIMIT = 40.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 = -40.0
MAX_LIMIT = 40.0
FERROR = 0.050
MIN_FERROR = 0.010

5
tests/abort/feed-rate/test.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -f sim.var
linuxcnc -r test.ini

1
tests/abort/g64/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
sim.var*

24
tests/abort/g64/README Normal file
View File

@@ -0,0 +1,24 @@
After program abort, show whether G61/G61.1/G64 settings are
consistent with machine state at last executing motion prior to abort.
This test runs and aborts a test .ngc program several times with
various motion mode and blend/naive CAM tolerance settings. Checks
are performed at various times relative to program execution:
1) Motion mode: Does stat buffer agree with programmed mode?
2) G64 tolerance settings: Does stat buffer agree with programmed P/Q
args? (Only for G64, and only when these params are available in
stat buffer)
3) G64 tolerance settings: Do programmed tolerance settings produce
expected motion, as evidenced by samples taken during program
execution?
The .ngc program is aborted before ever reaching a G64 programmed at
the end. This demonstrates a bug caused by motion and interp running
out of synch, affecting LinuxCNC v. 2.7 and reported in Github issue
#177.
The fix will be introduced with Rob Ellenberg's state tags work,
discussed in Github issue #134.

2
tests/abort/g64/checkresult Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
exit 0 # test failure is indicated by test.sh exit value

View File

@@ -0,0 +1,18 @@
# sample where motion tells us to go
loadrt sampler depth=1000 cfg=fffffffff
addf sampler.0 servo-thread
net Xpos => sampler.0.pin.0
net Ypos => sampler.0.pin.1
net Zpos => sampler.0.pin.2
net Xvel => sampler.0.pin.3
net Yvel => sampler.0.pin.4
net Zvel => sampler.0.pin.5
net Xacc => sampler.0.pin.6
net Yacc => sampler.0.pin.7
net Zacc => sampler.0.pin.8
loadusr halsampler -t motion-samples.log

161
tests/abort/g64/test-ui.py Executable file
View File

@@ -0,0 +1,161 @@
#!/usr/bin/env python3
import linuxcnc
import time, sys, os
def process_samples(z_lev, expected_max_x):
# Read motion-samples.log for samples at the specified Z level and
# find the maximum X
res = 0
f = open('motion-samples.log','r')
max_x = 0.0
max_y = 0.0
samples = 0
for line in f:
try:
i, x, y, z, xvel, yvel, zvel, xacc, yacc, zacc = [
float(n) for n in line.split(' ')[:10]]
except ValueError:
# halsampler is still writing, so an incomplete line may be read
break
if z < z_lev:
# Ignore travel between Z levels
continue
if z > z_lev:
break
if x > max_x:
# Record new maximum
max_x = x
max_y = y
samples += 1
f.close()
print("z=%.1f; max_x = %.6f; max_y = %.6f; samples = %d" % (
z_lev, max_x, max_y, samples))
if abs(max_x - expected_max_x) > 0.1:
print("*** ERROR max X%.3f != expected X%.3f" % (
max_x, expected_max_x))
res += 1
return res
def check_status(msg, expected_mode, expected_p, expected_q):
res = 0
# Read status and print control mode and tolerances
s.poll()
control_mode = None
for i in s.gcodes:
if i in (610, 611, 640):
control_mode = i
if len(s.settings) == 3:
# Pre-state-tags fix
print("%s: Control mode = %d" % (msg, control_mode))
p, q = (expected_p, expected_q) # Fake valid results
else:
# After state-tags fix
print("%s: Control mode = %d; tolerances = P%.3f Q%.3f" % (
msg, control_mode, s.settings[3], s.settings[4]))
p, q = (s.settings[3], s.settings[4])
if control_mode != expected_mode:
print("*** ERROR control mode %d != expected %d" % (
control_mode, expected_mode))
res += 1
if expected_p is not None and abs(p - expected_p) > 0.001:
print("*** ERROR blend tolerance P%.3f != expected P%.3f" % (
p, expected_p))
res += 1
if expected_q is not None and abs(q - expected_q) > 0.001:
print("*** ERROR naive CAM tolerance Q%.3f != expected Q%.3f" % (
q, expected_q))
res += 1
return res
def run_and_abort(msg, z_lev, expected_max_x,
expected_mode, expected_p, expected_q, *init_cmds):
res = 0
# Move to specified Z level and run init commands; run test.ngc
# and abort; print status and max X values during run
# Run init commands
c.mode(linuxcnc.MODE_MDI)
c.mdi('F1200 G0X0Y0Z%.1f' % z_lev)
c.wait_complete()
for cmd in init_cmds:
print("Running command '%s'" % cmd)
c.mdi(cmd)
c.wait_complete()
res += check_status(
'%s post-command' % msg, expected_mode, expected_p, expected_q)
# Run program
print("Running program 'test.ngc'")
c.mode(linuxcnc.MODE_AUTO)
c.program_open("test.ngc")
c.auto(linuxcnc.AUTO_RUN, 1)
# Wait for things to get underway, then abort
c.wait_complete()
# Let zig-zags run to a certain point
while s.position[1] < 1.0:
time.sleep(0.1)
s.poll()
res += check_status(
'%s pre-abort' % msg, expected_mode, expected_p, expected_q)
c.abort()
c.wait_complete()
# Check settings
res += check_status(
'%s post-abort' % msg, expected_mode, expected_p, expected_q)
# Print max
res += process_samples(z_lev, expected_max_x)
print()
return res
#
# INIT
#
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.home(-1)
c.wait_complete()
#
# TESTS
#
# Set up with various G61/G61.1/G64 commands, run test.ngc, and check
# 1) whether stat buffer shows correct motion mode;
# 2) whether tolerance settings produce expected motion;
# 3) for G64, whether tolerance settings are correct in stat buffer
res = 0
# Z=0: exact path mode: X up to 5"
res += run_and_abort('G61', 0.0, 5.0, 610, None, None, 'G61')
res += run_and_abort('G61 redo', 0.5, 5.0, 610, None, None)
# Z=1: exact stop mode: X up to 5"
res += run_and_abort('G61.1', 1.0, 5.0, 611, None, None, 'G61.1')
res += run_and_abort('G61.1 redo', 1.5, 5.0, 611, None, None)
# Z=2: path blending, 0.5" blend tolerance: X up to 4.5"
res += run_and_abort('G64P0.5', 2.0, 4.5, 640, 0.5, 0.0, 'G64P0.5Q0')
res += run_and_abort('G64P0.5 redo', 2.5, 4.5, 640, 0.5, 0.0)
# Z=3: path blending, best possible speed: X up to 3.725"
res += run_and_abort('G64', 3.0, 3.7, 640, 0.0, 0.0, 'G64')
res += run_and_abort('G64 redo', 3.5, 3.7, 640, 0.0, 0.0)
# Z=4: path blending, 6" naive cam tolerance: X always 0" (zig-zags collapse)
res += run_and_abort('G64P0Q6', 4.0, 0.0, 640, 0.0, 6.0, 'G64Q6')
res += run_and_abort('G64P0Q6 redo', 4.5, 0.0, 640, 0.0, 6.0)
#
# CLEANUP
#
if res == 0: # Leave samples in case of error
os.unlink('motion-samples.log')
os.unlink('sim.var')
os.unlink('sim.var.bak')
print("Exiting with %d errors" % res)
sys.exit(res)

120
tests/abort/g64/test.ini Normal file
View File

@@ -0,0 +1,120 @@
[EMC]
# The version string for this INI file.
VERSION = 1.1
DEBUG = 0x0
#DEBUG = 2147483647
[DISPLAY]
DISPLAY = ./test-ui.py
[FILTER]
#No Content
[RS274NGC]
PARAMETER_FILE = sim.var
USER_M_PATH = ./subs
LOG_LEVEL=5
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 4.0
COMM_WAIT = 0.010
BASE_PERIOD = 0
SERVO_PERIOD = 1000000
[TASK]
TASK = milltask
CYCLE_TIME = 0.001
[HAL]
HALUI = halui
HALFILE = LIB:core_sim.hal
HALFILE = motion-test.hal
[HALUI]
#No Content
[TRAJ]
NO_FORCE_HOMING=1
AXES = 3
COORDINATES = X Y Z
HOME = 0 0 0
LINEAR_UNITS = inch
ANGULAR_UNITS = degree
CYCLE_TIME = 0.010
DEFAULT_LINEAR_VELOCITY = 1.2
MAX_LINEAR_ACCELERATION = 10
MAX_LINEAR_VELOCITY = 140
[EMCIO]
TOOL_TABLE = simpockets.tbl
TOOL_CHANGE_QUILL_UP = 1
RANDOM_TOOLCHANGER = 0
[KINS]
KINEMATICS = trivkins
#This is a best-guess at the number of joints, it should be checked
JOINTS = 3
[AXIS_X]
MIN_LIMIT = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 4
MAX_ACCELERATION = 5
[JOINT_0]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 4
MAX_ACCELERATION = 5
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 = 5
[JOINT_1]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 4
MAX_ACCELERATION = 5
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 = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 4
MAX_ACCELERATION = 5
[JOINT_2]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 4
MAX_ACCELERATION = 5
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

25
tests/abort/g64/test.ngc Normal file
View File

@@ -0,0 +1,25 @@
%
; Stepover for zig-zag
#100 = 1
; Start at a fast clip from X0Y0
G0 X0Y0 F120
; Run a bunch of zig-zags
#1 = 0
O100 WHILE [#1 LT 5*#100]
; zig
G1 X5 Y[#1 + #100]
; zag
G1 X0 Y[#1 + 2*#100]
#1 = [#1 + 2*#100]
O100 ENDWHILE
; Do a nice, slow move to ensure time for abort
F1 G1 Y10 (bogus location)
; Set G64; execution will never reach here
G64 P1 Q2
%

4
tests/abort/g64/test.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash -e
rm -f motion-samples.log
linuxcnc -r test.ini

View File

@@ -0,0 +1,4 @@
out.motion-logger
rs274ngc.var
rs274ngc.var.bak
test.ngc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
# Test for movement after abort
Test for issue [#579][1], [#393][2] & [#241][3], where an abort while
interp is loading a long `.ngc` file, and an `ON_ABORT_COMMAND` block
triggers a readahead bug where unflushed segments are appended to the
interp list.
[1]: https://github.com/LinuxCNC/linuxcnc/issues/579
[2]: https://github.com/LinuxCNC/linuxcnc/issues/393
[3]: https://github.com/LinuxCNC/linuxcnc/issues/241

View File

@@ -0,0 +1,3 @@
#!/bin/sh
# Python script exit indicates test success/fail
exit 0

View File

@@ -0,0 +1,3 @@
loadusr -W motion-logger out.motion-logger
setp iocontrol.0.emc-enable-in 1

View File

@@ -0,0 +1,2 @@
net Xpos => test-ui.Xpos
net Ypos => test-ui.Ypos

View File

@@ -0,0 +1,3 @@
T1 P0 D0.125000 Z+1.000000 ;
T10 P3 D0.500000 Z+3.000000 ;
T99999 P50 Z+2.000000 ;

View File

@@ -0,0 +1,4 @@
o<on_abort> sub
G64 P0.1
o<on_abort> endsub
m2

View File

@@ -0,0 +1,135 @@
#!/usr/bin/env python3
import linuxcnc
import linuxcnc_util
import hal
import time
import sys
import os
# Time increment and timeout, seconds
TIME_INCR = 0.1
TIMEOUT = 10.0
MAX_QWAIT_TRIES = 4
#
# connect to LinuxCNC
#
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
l = linuxcnc_util.LinuxCNC(command=c, status=s, error=e)
#
# Create and connect test feedback comp
#
h = hal.component("test-ui")
h.newpin("Xpos", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("Ypos", hal.HAL_FLOAT, hal.HAL_IN)
h.ready()
os.system("halcmd source ./postgui.hal")
#
# Come out of E-stop, turn the machine on, home
#
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.home(0)
c.home(1)
c.home(2)
l.wait_for_home([1, 1, 1, 0, 0, 0, 0, 0, 0])
#
# Print status function
#
def print_stats(x = None, y = None):
s.poll()
if x is None:
sys.stderr.write(
"queue=%d; active_queue=%d; queue_full=%s;"
" x=%.3f; y=%.3f\n" %
(s.queue, s.active_queue, s.queue_full, h['Xpos'], h['Ypos']))
else:
sys.stderr.write(
"queue=%d; active_queue=%d; queue_full=%s;"
" x=%.3f(%.3f); y=%.3f(%.3f)\n" %
(s.queue, s.active_queue, s.queue_full,
h['Xpos'], x-h['Xpos'], h['Ypos'], y-h['Ypos']))
#
# Set up tool and start position
#
c.mode(linuxcnc.MODE_MDI)
c.mdi('T1M6') # Load tool 1
c.mdi('G0 X2 Y2') # Move near to start
c.wait_complete()
start_time = time.time()
while (abs(h['Xpos'] - 2) > .001) or (abs(h['Ypos'] - 2) > .001):
if (time.time() - start_time) > TIMEOUT:
sys.stderr.write("Failed to reach start position in time\n")
os.system("halcmd show")
sys.exit(1)
time.sleep(TIME_INCR)
sys.stderr.write("Starting at X=%.3f Y=%.3f\n" % (h["Xpos"], h["Ypos"]))
#
# Run the generated program, wait for motion to start and the queue to
# fill up
#
c.mode(linuxcnc.MODE_AUTO)
# c.program_open('test.ngc')
c.program_open('3D_Chips.ngc')
c.auto(linuxcnc.AUTO_RUN, 0)
start_time = time.time()
s.poll()
MAX_QWAIT_TRIES=4
ct=0
while not (s.queue > 1000):
delta_t = time.time() - start_time
if delta_t > TIMEOUT:
sys.stderr.write("ct=%d s.queue=%d delta_t=%f TIMEOUT=%f\n"%(
ct,s.queue,delta_t,TIMEOUT))
start_time = time.time()
ct += 1
if ct > MAX_QWAIT_TRIES:
sys.stderr.write("Failed to load segments from program\n")
sys.exit(1)
print_stats()
time.sleep(TIME_INCR)
sys.stderr.write("Program partially loaded\n")
#
# Now stop the program and wait for any additional motion
#
# Program X stepover is 2.5mm, or 0.1in; error out if the X stepover
# exceeds 0.15 (fudge added to eliminate a legitimate stepover during
# lag between cycles)
pre_stop_x, pre_stop_y = h['Xpos'], h['Ypos']
c.abort()
start_time = time.time()
last_x = pre_stop_x
fail = False
while (time.time() - start_time) < TIMEOUT and h['Xpos'] != last_x:
print_stats(pre_stop_x, pre_stop_y)
err = abs(pre_stop_x - h['Xpos'])
if err > 0.15:
sys.stderr.write(
'ERROR: X axis motion stopped %.3f" past stop position\n' % err)
fail = True
last_x = h['Xpos']
time.sleep(TIME_INCR)
if fail:
sys.exit(1)
sys.stderr.write('Success\n')
sys.exit(0)

View File

@@ -0,0 +1,106 @@
[EMC]
# DEBUG = 0
DEBUG = 2147483647
VERSION = 1.1
[DISPLAY]
DISPLAY = ./test-ui.py
[TASK]
TASK = milltask
CYCLE_TIME = 0.001
[RS274NGC]
PARAMETER_FILE = sim.var
LOG_LEVEL = 5
ON_ABORT_COMMAND=O <on_abort> call
SUBROUTINE_PATH = subroutines
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 4.0
BASE_PERIOD = 0
SERVO_PERIOD = 1000000
[HAL]
HALFILE = LIB:core_sim.hal
[TRAJ]
AXES = 3
COORDINATES = X Y Z
HOME = 0 0 0
LINEAR_UNITS = inch
ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 120
MAX_LINEAR_VELOCITY = 400
NO_FORCE_HOMING = 1
[EMCIO]
TOOL_TABLE = simpockets.tbl
TOOL_CHANGE_QUILL_UP = 1
RANDOM_TOOLCHANGER = 1
[AXIS_X]
HOME = 0.000
MIN_LIMIT = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[AXIS_Y]
HOME = 0.000
MIN_LIMIT = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[AXIS_Z]
HOME = 0.0
MIN_LIMIT = -4.0
MAX_LIMIT = 4.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[KINS]
KINEMATICS = trivkins
JOINTS = 3
[JOINT_0]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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
[JOINT_1]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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
[JOINT_2]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
# Run test file in task
linuxcnc -r test.ini
RES=$?
exit $RES

View File

@@ -0,0 +1,4 @@
out.motion-logger
rs274ngc.var
rs274ngc.var.bak
test.ngc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
# Test for movement after abort
Test for [issue #865][1], where an abort while interp is loading a
long `.ngc` file, and a block restoring a state tag triggers a
readahead bug where unflushed segments are appended to the interp
list.
[1]: https://github.com/LinuxCNC/linuxcnc/issues/865

View File

@@ -0,0 +1,3 @@
#!/bin/sh
# Python script exit indicates test success/fail
exit 0

View File

@@ -0,0 +1,3 @@
loadusr -W motion-logger out.motion-logger
setp iocontrol.0.emc-enable-in 1

View File

@@ -0,0 +1,2 @@
net Xpos => test-ui.Xpos
net Ypos => test-ui.Ypos

View File

@@ -0,0 +1,3 @@
T1 P0 D0.125000 Z+1.000000 ;
T10 P3 D0.500000 Z+3.000000 ;
T99999 P50 Z+2.000000 ;

View File

@@ -0,0 +1,126 @@
#!/usr/bin/env python3
import linuxcnc
import linuxcnc_util
import hal
import time
import sys
import os
# Time increment and timeout, seconds
TIME_INCR = 0.1
TIMEOUT = 10.0
#
# connect to LinuxCNC
#
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
l = linuxcnc_util.LinuxCNC(command=c, status=s, error=e)
#
# Create and connect test feedback comp
#
h = hal.component("test-ui")
h.newpin("Xpos", hal.HAL_FLOAT, hal.HAL_IN)
h.newpin("Ypos", hal.HAL_FLOAT, hal.HAL_IN)
h.ready()
os.system("halcmd source ./postgui.hal")
#
# Come out of E-stop, turn the machine on, home
#
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.home(0)
c.home(1)
c.home(2)
l.wait_for_home([1, 1, 1, 0, 0, 0, 0, 0, 0])
#
# Print status function
#
def print_stats(x = None, y = None):
s.poll()
if x is None:
sys.stderr.write(
"queue=%d; active_queue=%d; queue_full=%s;"
" x=%.3f; y=%.3f\n" %
(s.queue, s.active_queue, s.queue_full, h['Xpos'], h['Ypos']))
else:
sys.stderr.write(
"queue=%d; active_queue=%d; queue_full=%s;"
" x=%.3f(%.3f); y=%.3f(%.3f)\n" %
(s.queue, s.active_queue, s.queue_full,
h['Xpos'], x-h['Xpos'], h['Ypos'], y-h['Ypos']))
#
# Set up tool and start position
#
c.mode(linuxcnc.MODE_MDI)
c.mdi('T1M6') # Load tool 1
c.mdi('G0 X2 Y2') # Move near to start
c.wait_complete()
start_time = time.time()
while (abs(h['Xpos'] - 2) > .001) or (abs(h['Ypos'] - 2) > .001):
if (time.time() - start_time) > TIMEOUT:
sys.stderr.write("Failed to reach start position in time\n")
os.system("halcmd show")
sys.exit(1)
time.sleep(TIME_INCR)
sys.stderr.write("Starting at X=%.3f Y=%.3f\n" % (h["Xpos"], h["Ypos"]))
#
# Run the generated program, wait for motion to start and the queue to
# fill up
#
c.mode(linuxcnc.MODE_AUTO)
# c.program_open('test.ngc')
c.program_open('3D_Chips.ngc')
c.auto(linuxcnc.AUTO_RUN, 0)
start_time = time.time()
s.poll()
while not (s.queue > 1000):
if (time.time() - start_time) > TIMEOUT:
sys.stderr.write("Failed to load segments from program\n")
sys.exit(1)
print_stats()
time.sleep(TIME_INCR)
sys.stderr.write("Program partially loaded\n")
#
# Now stop the program and wait for any additional motion
#
# Program X stepover is 2.5mm, or 0.1in; error out if the X stepover
# exceeds 0.15 (fudge added to eliminate a legitimate stepover during
# lag between cycles)
pre_stop_x, pre_stop_y = h['Xpos'], h['Ypos']
c.abort()
start_time = time.time()
last_x = pre_stop_x
fail = False
while (time.time() - start_time) < TIMEOUT and h['Xpos'] != last_x:
print_stats(pre_stop_x, pre_stop_y)
err = abs(pre_stop_x - h['Xpos'])
if err > 0.15:
sys.stderr.write(
'ERROR: X axis motion stopped %.3f" past stop position\n' % err)
fail = True
last_x = h['Xpos']
time.sleep(TIME_INCR)
if fail:
sys.exit(1)
sys.stderr.write('Success\n')
sys.exit(0)

View File

@@ -0,0 +1,104 @@
[EMC]
DEBUG = 0
# DEBUG = 2147483647
VERSION = 1.1
[DISPLAY]
DISPLAY = ./test-ui.py
[TASK]
TASK = milltask
CYCLE_TIME = 0.001
[RS274NGC]
PARAMETER_FILE = sim.var
# LOG_LEVEL = 5
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 4.0
BASE_PERIOD = 0
SERVO_PERIOD = 1000000
[HAL]
HALFILE = LIB:core_sim.hal
[TRAJ]
AXES = 3
COORDINATES = X Y Z
HOME = 0 0 0
LINEAR_UNITS = inch
ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 120
MAX_LINEAR_VELOCITY = 400
NO_FORCE_HOMING = 1
[EMCIO]
TOOL_TABLE = simpockets.tbl
TOOL_CHANGE_QUILL_UP = 1
RANDOM_TOOLCHANGER = 1
[AXIS_X]
HOME = 0.000
MIN_LIMIT = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[AXIS_Y]
HOME = 0.000
MIN_LIMIT = -40.0
MAX_LIMIT = 40.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[AXIS_Z]
HOME = 0.0
MIN_LIMIT = -4.0
MAX_LIMIT = 4.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.0
[KINS]
KINEMATICS = trivkins
JOINTS = 3
[JOINT_0]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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
[JOINT_1]
TYPE = LINEAR
HOME = 0.000
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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
[JOINT_2]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 400
MAX_ACCELERATION = 100.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

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
# Run test file in task
linuxcnc -r test.ini
RES=$?
exit $RES

7
tests/abs.0/expected Normal file
View File

@@ -0,0 +1,7 @@
0.000000 0.000000
0.250000 0.250000
-0.250000 0.250000
1.000000 1.000000
-1.000000 1.000000
64.000000 64.000000
-64.000000 64.000000

10
tests/abs.0/runstreamer Normal file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
halstreamer << EOF
0
0.25
-0.25
1
-1
64
-64
EOF

17
tests/abs.0/test.hal Normal file
View File

@@ -0,0 +1,17 @@
setexact_for_test_suite_only
loadrt sampler cfg=ff depth=350
loadrt streamer cfg=f depth=350
loadrt abs
loadrt threads name1=fast period1=100000
net in streamer.0.pin.0 => sampler.0.pin.0 abs.0.in
net out abs.0.out => sampler.0.pin.1
addf streamer.0 fast
addf abs.0 fast
addf sampler.0 fast
loadusr -w sh runstreamer
start
loadusr -w halsampler -n 7

1
tests/alias.0/expected Normal file
View File

@@ -0,0 +1 @@
and2.0.in1 and2.0.out and2.0.time something

7
tests/alias.0/test.hal Normal file
View File

@@ -0,0 +1,7 @@
loadrt and2 count=1
alias pin and2.0.in0 something
alias pin and2.0.in1 somethingelse
alias pin and2.0.out anotherthing
unalias pin somethingelse
unalias pin and2.0.out
list pin

View File

@@ -0,0 +1 @@
regression test for components: and2, or2, not, mux2, mux4

View File

@@ -0,0 +1,16 @@
0 0 1 1.000000 3.000000
0 1 1 1.000000 5.000000
1 1 0 2.000000 6.000000
0 1 0 2.000000 4.000000
0 0 1 1.000000 3.000000
0 1 1 1.000000 5.000000
1 1 0 2.000000 6.000000
0 1 0 2.000000 4.000000
0 0 1 1.000000 3.000000
0 1 1 1.000000 5.000000
1 1 0 2.000000 6.000000
0 1 0 2.000000 4.000000
0 0 1 1.000000 3.000000
0 1 1 1.000000 5.000000
1 1 0 2.000000 6.000000
0 1 0 2.000000 4.000000

View File

@@ -0,0 +1,19 @@
#!/bin/sh
halstreamer << EOF
0 0 0 0
0 1 0 0
1 1 0 0
1 0 0 0
0 0 1 0
0 1 1 0
1 1 1 0
1 0 1 0
0 0 0 1
0 1 0 1
1 1 0 1
1 0 0 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 1 1
EOF

View File

@@ -0,0 +1,51 @@
loadrt threads name1=fast period1=100000
loadrt and2
loadrt or2
loadrt not
loadrt mux2
loadrt mux4
loadrt sampler depth=1000 cfg=bbbff
loadrt streamer depth=32 cfg=bbbb
net a streamer.0.pin.0
net b streamer.0.pin.1
net c streamer.0.pin.2
net d streamer.0.pin.3
net a and2.0.in0
net b and2.0.in1
net n0 and2.0.out sampler.0.pin.0
net a or2.0.in0
net b or2.0.in1
net n1 or2.0.out sampler.0.pin.1
net a not.0.in
net n2 not.0.out sampler.0.pin.2
net a mux2.0.sel
net n3 mux2.0.out sampler.0.pin.3
setp mux2.0.in0 1
setp mux2.0.in1 2
net a mux4.0.sel0
net b mux4.0.sel1
net n4 mux4.0.out sampler.0.pin.4
setp mux4.0.in0 3
setp mux4.0.in1 4
setp mux4.0.in2 5
setp mux4.0.in3 6
addf streamer.0 fast
addf and2.0 fast
addf or2.0 fast
addf not.0 fast
addf mux2.0 fast
addf mux4.0 fast
addf sampler.0 fast
loadusr -w sh runstreamer
start
loadusr -w halsampler -n 16

1
tests/basic/README Normal file
View File

@@ -0,0 +1 @@
Tests that 'halrun' on an empty file produces no output

0
tests/basic/expected Normal file
View File

0
tests/basic/test.hal Normal file
View File

10
tests/biquad/expected Normal file
View File

@@ -0,0 +1,10 @@
0 0.123000 0.123000
0 0.550000 0.550000
0 1.120000 1.120000
0 0.123134 0.123134
1 0.000100 0.000100
1 1.123450 1.123450
1 444.555000 444.555000
1 0.000000 0.000000
0 1213.000000 1213.000000
0 0.000000 0.000000

15
tests/biquad/runstreamer Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
# first column is "enable", second is "in"
halstreamer << EOF
0 0.123
0 0.55
0 1.12
0 0.1231344
1 0.0001
1 1.12345
1 444.555
1 0
0 1213
0 0
EOF

19
tests/biquad/test.hal Normal file
View File

@@ -0,0 +1,19 @@
setexact_for_test_suite_only
loadrt threads name1=fast period1=100000
loadrt biquad
loadrt sampler cfg=bff depth=500
loadrt streamer cfg=bf depth=500
net enable streamer.0.pin.0 => sampler.0.pin.0 biquad.0.enable
net in streamer.0.pin.1 => sampler.0.pin.1 biquad.0.in
net out biquad.0.out => sampler.0.pin.2
addf streamer.0 fast
addf biquad.0 fast
addf sampler.0 fast
loadusr -w sh runstreamer
start
loadusr -w halsampler -n 10

2
tests/blendmath/checkresult Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
grep -q "all blendmath checks passed" "$1" && ! grep -q "FAIL" "$1"

5
tests/blendmath/skip Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
# This test compiles blendmath.c and internal TP headers from the source
# tree, which is only available in run-in-place builds. Skip when testing
# installed packages.
[ -z "$SYSTEM_BUILD" ]

17
tests/blendmath/test.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
set -e
# RIP layout: $HEADERS is $TOPDIR/include
TOPDIR=$(dirname "$HEADERS")
# blendmath.c references the rest of the TP (tc.c, spherical_arc.c,
# sp_scurve.c, motion globals). Only the tested functions are used here, so
# build with function sections and let the linker garbage-collect the rest
# instead of linking the whole trajectory planner.
gcc -O2 -Wall -ffunction-sections -fdata-sections -DULAPI -DUNIT_TEST \
-I"$HEADERS" -I"$TOPDIR/src" -I"$TOPDIR/src/emc" \
-o test_blendmath test_blendmath.c "$TOPDIR/src/emc/tp/blendmath.c" \
-L"$LIBDIR" -Wl,-rpath,"$LIBDIR" -Wl,--gc-sections -lposemath -lm
./test_blendmath
rm -f test_blendmath

View File

@@ -0,0 +1,93 @@
/*
* Unit tests for blendmath utility functions.
*
* Salvaged from the retired meson-only unit_tests/tp/test_blendmath.c
* (originally by Robert W. Ellenberg) and converted from the greatest
* framework to plain C so it can build and run as a runtest.
*/
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <rtapi.h>
#include <posemath.h>
#include "tp/blendmath.h"
#include "tp/tp_types.h"
/* kludge: satisfy rtapi_print_msg references without an rtapi app */
void rtapi_print_msg(msg_level_t level, const char *fmt, ...)
{
va_list args;
(void)level;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
static int failures = 0;
#define CHECK(cond) do { \
if (!(cond)) { \
printf("FAIL %s:%d: %s\n", __FILE__, __LINE__, #cond); \
failures++; \
} \
} while (0)
#define CHECK_FALSE(cond) CHECK(!(cond))
static void test_pmCartCartParallel_numerical(void)
{
PmCartesian u0 = {1, 0, 0};
PmCartesian u_close = {cos(TP_ANGLE_EPSILON), sin(TP_ANGLE_EPSILON), 0};
int k;
CHECK(pmCartCartParallel(&u0, &u0, TP_ANGLE_EPSILON_SQ));
CHECK_FALSE(pmCartCartParallel(&u0, &u_close, 0.0));
/* Test that the tolerance makes sense */
CHECK_FALSE(pmCartCartParallel(&u0, &u_close, 0.5 * TP_ANGLE_EPSILON_SQ));
CHECK(pmCartCartParallel(&u0, &u_close, 1.5 * TP_ANGLE_EPSILON_SQ));
/* Try a bunch of other angles including anti-parallel */
for (k = 1; k <= 7; ++k) {
PmCartesian u_far = {cos(PM_PI_4 * k), sin(PM_PI_4 * k), 0};
CHECK_FALSE(pmCartCartParallel(&u0, &u_far, TP_ANGLE_EPSILON_SQ));
}
}
static void test_pmCartCartAntiParallel_numerical(void)
{
PmCartesian u0 = {1, 0, 0};
PmCartesian u_close = {-cos(TP_ANGLE_EPSILON), sin(TP_ANGLE_EPSILON), 0};
PmCartesian u_opposite;
int k;
pmCartScalMult(&u0, -1.0, &u_opposite);
CHECK(pmCartCartAntiParallel(&u0, &u_opposite, TP_ANGLE_EPSILON_SQ));
CHECK_FALSE(pmCartCartAntiParallel(&u0, &u_close, 0.0));
/* Test that the tolerance makes sense */
CHECK_FALSE(pmCartCartAntiParallel(&u0, &u_close, 0.5 * TP_ANGLE_EPSILON_SQ));
CHECK(pmCartCartAntiParallel(&u0, &u_close, 1.5 * TP_ANGLE_EPSILON_SQ));
/* Try a bunch of other angles including anti-parallel */
for (k = 1; k <= 7; ++k) {
PmCartesian u_far = {-cos(PM_PI_4 * k), sin(PM_PI_4 * k), 0};
CHECK_FALSE(pmCartCartAntiParallel(&u0, &u_far, TP_ANGLE_EPSILON_SQ));
}
}
int main(void)
{
test_pmCartCartParallel_numerical();
test_pmCartCartAntiParallel_numerical();
if (failures) {
printf("%d check(s) FAILED\n", failures);
return 1;
}
printf("all blendmath checks passed\n");
return 0;
}

View File

View File

@@ -0,0 +1,26 @@
#!/bin/bash
set -xe
CPPFLAGS=$(pkg-config --silence-errors --cflags libtirpc)
for i in "$HEADERS"/*.h; do
case $i in
*/rtapi_app.h) continue ;;
esac
# CPPFLAGS is supposed to be word split
# shellcheck disable=SC2086
gcc ${CPPFLAGS} -DULAPI -I"$HEADERS" -E -x c "$i" > /dev/null
done
for i in "$HEADERS"/*.h "$HEADERS"/*.hh; do
case $i in
*/\*.hh) continue ;;
*/rtapi_app.h) continue ;;
*/interp_internal.hh) continue ;;
esac
# shellcheck disable=SC2086
if g++ ${CPPFLAGS} -std=c++11 -S -o /dev/null -xcxx /dev/null > /dev/null 2>&1; then
ELEVEN=-std=c++11
else
ELEVEN=-std=c++0x
fi
# shellcheck disable=SC2086
g++ ${CPPFLAGS} "$ELEVEN" -DULAPI -I"$HEADERS" -E -x c++ "$i" > /dev/null
done

2
tests/build/ui/README Normal file
View File

@@ -0,0 +1,2 @@
Test skipped because out-of-tree building with access to NML is not a real
option. It requires internal LinucCNC includes to be exposed.

0
tests/build/ui/expected Normal file
View File

View File

@@ -0,0 +1,22 @@
// g++ nml-position-logger.cc -I include -L lib -l nml -l linuxcnc
#include "emc.hh"
#include "emc_nml.hh"
#include <unistd.h>
#include <iostream>
#include <cstdlib>
int main(int argc, char **argv) {
if(argc < 2) { std::cerr << "Usage: " << argv[0] << " NMLFILE\n"; abort(); }
const char *nmlfile = argv[1];
RCS_STAT_CHANNEL *stat = new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "xemc", nmlfile);
while(1) {
usleep(100*1000);
if(!stat->valid()) continue;
if(stat->peek() != EMC_STAT_TYPE) continue;
EMC_STAT *emcStatus = static_cast<EMC_STAT*>(stat->get_address());
std::cout << emcStatus->motion.traj.position.tran.x << " "
<< emcStatus->motion.traj.position.tran.y << " "
<< emcStatus->motion.traj.position.tran.z << "\n";
}
return 0;
}

0
tests/build/ui/skip Normal file
View File

6
tests/build/ui/test.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
set -x
g++ -I"${HEADERS}" \
nml-position-logger.cc \
-L "${LIBDIR}" -lnml -llinuxcnc \
-o /dev/null

1
tests/ccomp/early-exit/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
sim.var*

View File

@@ -0,0 +1,5 @@
This test starts LinuxCNC, enables cutter comp (with G41.1), then
immediately cancels cutter comp (with G40) and verifies that the next
motion goes to the expected location.
In 2.6.12 and 2.7.7 this test replicates Github Issue #160.

View File

@@ -0,0 +1,2 @@
#!/bin/sh
exit 0 # test failure is indicated by test.sh exit value

View File

@@ -0,0 +1,61 @@
# core HAL config file for simulation
# first load all the RT modules that will be needed
# kinematics
loadrt [KINS]KINEMATICS
#autoconverted trivkins
# motion controller, get name and thread periods from INI file
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
# load 6 differentiators (for velocity and accel signals
loadrt ddt count=6
# load additional blocks
loadrt hypot count=2
loadrt comp count=3
loadrt or2 count=1
# add motion controller functions to servo thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
# link the differentiator functions into the code
addf ddt.0 servo-thread
addf ddt.1 servo-thread
addf ddt.2 servo-thread
addf ddt.3 servo-thread
addf ddt.4 servo-thread
addf ddt.5 servo-thread
addf hypot.0 servo-thread
addf hypot.1 servo-thread
# create HAL signals for position commands from motion module
# loop position commands back to motion module feedback
net Xpos joint.0.motor-pos-cmd => joint.0.motor-pos-fb ddt.0.in
net Ypos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt.2.in
net Zpos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt.4.in
# send the position commands thru differentiators to
# generate velocity and accel signals
net Xvel ddt.0.out => ddt.1.in hypot.0.in0
net Xacc <= ddt.1.out
net Yvel ddt.2.out => ddt.3.in hypot.0.in1
net Yacc <= ddt.3.out
net Zvel ddt.4.out => ddt.5.in hypot.1.in0
net Zacc <= ddt.5.out
# Cartesian 2- and 3-axis velocities
net XYvel hypot.0.out => hypot.1.in1
net XYZvel <= hypot.1.out
# estop loopback
net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
# create signals for tool loading loopback
net tool-prepare <= iocontrol.0.tool-prepare
net tool-prepared => iocontrol.0.tool-prepared
net tool-change <= iocontrol.0.tool-change
net tool-changed => iocontrol.0.tool-changed
net tool-number <= iocontrol.0.tool-number
net tool-prep-number <= iocontrol.0.tool-prep-number
net tool-prep-pocket <= iocontrol.0.tool-prep-pocket

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
import linuxcnc
import hal
import math
import time
import sys
import subprocess
import os
import signal
import glob
import re
def wait_for_linuxcnc_startup(status, timeout=10.0):
"""Poll the Status buffer waiting for it to look initialized,
rather than just allocated (all-zero). Returns on success, throws
RuntimeError on failure."""
start_time = time.time()
while time.time() - start_time < timeout:
status.poll()
if (status.angular_units == 0.0) \
or (status.axis_mask == 0) \
or (status.cycle_time == 0.0) \
or (status.exec_state != linuxcnc.EXEC_DONE) \
or (status.interp_state != linuxcnc.INTERP_IDLE) \
or (status.inpos == False) \
or (status.linear_units == 0.0) \
or (status.max_acceleration == 0.0) \
or (status.max_velocity == 0.0) \
or (status.program_units == 0.0) \
or (status.rapidrate == 0.0) \
or (status.state != linuxcnc.RCS_DONE) \
or (status.task_state != linuxcnc.STATE_ESTOP):
time.sleep(0.1)
else:
# looks good
return
# timeout, throw an exception
raise RuntimeError
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
# Wait for LinuxCNC to initialize itself so the Status buffer stabilizes.
wait_for_linuxcnc_startup(s)
#time.sleep(9999)
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.home(-1)
c.wait_complete()
c.mode(linuxcnc.MODE_MDI)
c.mdi('g0 x0.1 y0.2 z0.3')
c.mdi('g41.1 d0.1')
c.mdi('g40')
c.mdi('g0 x0.9 ; surprise motion on Y and Z, to 0!!')
c.wait_complete()
s.poll()
print("position: {}".format(s.position))
assert(math.fabs(s.position[0] - 0.9) < 0.0000001)
assert(math.fabs(s.position[1] - 0.2) < 0.0000001)
assert(math.fabs(s.position[2] - 0.3) < 0.0000001)
sys.exit(0)

View File

@@ -0,0 +1,118 @@
# This config file was created 2016-10-21 22:10:26.765121 by the update_ini script
# The original config files may be found in the /home/seb/linuxcnc-dev/tests/ccomp/early-exit/test.old directory
[EMC]
# The version string for this INI file.
VERSION = 1.1
DEBUG = 0x0
[DISPLAY]
DISPLAY = ./test-ui.py
[FILTER]
#No Content
[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
[HAL]
HALUI = halui
HALFILE = core_sim.hal
[HALUI]
#No Content
[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_ACCELERATION = 123.45
MAX_LINEAR_VELOCITY = 45.67
[EMCIO]
TOOL_TABLE = simpockets.tbl
TOOL_CHANGE_QUILL_UP = 1
RANDOM_TOOLCHANGER = 0
[KINS]
KINEMATICS = trivkins
#This is a best-guess at the number of joints, it should be checked
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 = -40.0
MAX_LIMIT = 40.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 = -40.0
MAX_LIMIT = 40.0
FERROR = 0.050
MIN_FERROR = 0.010

5
tests/ccomp/early-exit/test.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -f sim.var
linuxcnc -r test.ini

View File

@@ -0,0 +1,68 @@
N..... USE_LENGTH_UNITS(CANON_UNITS_MM)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_REFERENCE(CANON_XYZ)
N..... ON_RESET()
N..... SET_FEED_RATE(30.0000)
N..... SELECT_PLANE(CANON_PLANE_XZ)
N..... USE_LENGTH_UNITS(CANON_UNITS_INCHES)
N..... SET_MOTION_CONTROL_MODE(CANON_CONTINUOUS, 0.000000)
N..... SET_NAIVECAM_TOLERANCE(0.0000)
N..... USE_TOOL_LENGTH_OFFSET(0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000)
N..... SELECT_TOOL(0)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(0.1000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.1000, 0.0000, 0.1000, 0.1000, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.2500, -0.2500, 1.0000, -0.2500, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.5000, -0.5000, 1.5000, -0.2500, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(-0.5000, 0.0000, 1.7500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 1.7500, 0.0000, 0.0000, 0.0000)
N..... SELECT_TOOL(2)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... USE_TOOL_LENGTH_OFFSET(0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000)
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.0500, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.0500, 0.0000, 0.0500, 0.0500, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.0000, 0.0000, 0.9500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.2500, -0.3000, 0.9500, -0.3000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.4500, -0.5000, 1.4500, -0.3000, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(-0.5000, 0.0000, 1.7000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 1.7500, 0.0000, 0.0000, 0.0000)
N..... SELECT_TOOL(7)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... USE_TOOL_LENGTH_OFFSET(0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000)
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 1.8500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(-0.3000, 0.0000, 1.8500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on right")
N..... STRAIGHT_FEED(-0.4000, 0.0000, 1.7500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.7000, -0.4500, 1.7000, -0.4000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(-0.4500, 0.0000, 1.4500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.2500, -0.2500, 1.4500, -0.2500, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.9500, 0.0500, 0.9500, -0.2500, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.0500, 0.0000, 0.0500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.0000, 0.1000, 0.0500, 0.1000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_TRAVERSE(0.3000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... USE_TOOL_LENGTH_OFFSET(0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000, 0.0000 0.0000 0.0000)
N..... SELECT_TOOL(0)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SELECT_PLANE(CANON_PLANE_XY)
N..... SET_FEED_MODE(0, 0)
N..... SET_FEED_RATE(0.0000)
N..... STOP_SPINDLE_TURNING(0)
N..... SET_SPINDLE_MODE(0 0.0000)
N..... PROGRAM_END()
N..... ON_RESET()
N..... ON_RESET()

View File

@@ -0,0 +1,49 @@
g20 g64 g18 f30
g49
t0 m6
g0x.3z0
g40
g1x.1
g3x0z.1r.1
g1z1
g2r.25x-.25z1.25
g3r.25x-.5z1.5
g1z1.75
g0x.3
t2 m6
g43 h2
g0z0
g41
g1x.1
g3x0z.1r.1
g1z1
g2r.25x-.25z1.25
g3r.25x-.5z1.5
g1z1.75
g40
g0x.3
t7 m6
g43 h9
g0z1.85
g0x-.3
g42
g1x-.4
g2x-.5z1.75r.1
g1z1.5
g2r.25x-.25z1.25
g3r.25x0z1
g1z.1
g2r.1x.1z0
g40
g0x.3
g49
t0 m6
m2

View File

@@ -0,0 +1,3 @@
#!/bin/bash
rs274 -t test.tbl -g test.ngc | awk '{$1=""; print}'
exit "${PIPESTATUS[0]}"

View File

@@ -0,0 +1,19 @@
T1 P1 Z0.0 X0.0 D0.1 I95.0 J155.0 Q1;
T2 P2 Z0.0 X0.0 D0.1 I85.0 J25.0 Q2;
T3 P3 Z0.0 X0.0 D0.1 I275.0 J335.0 Q3;
T4 P4 Z0.0 X0.0 D0.1 I265.0 J205.0 Q4;
T5 P5 Z0.0 X0.0 D0.1 I210.0 J150.0 Q5;
T6 P6 Z0.5 X0.5 D0.1 I120.0 J60.0 Q6;
T7 P7 Z0.0 X0.0 D0.1 I-30.0 J30.0 Q7;
T8 P8 Z0.0 X0.0 D0.1 I240.0 J300.0 Q8;
T9 P9 Z0.0 X0.0 D0.1 I0.0 J0.0 Q9;
T10 P10 Z0.0 X0.0 D0.0 I0.0 J0.0 Q0;
T11 P11 Z0.0 X0.0 D0.0 I95.0 J155.0 Q1;
T12 P12 Z0.0 X0.0 D0.0 I85.0 J25.0 Q2;
T13 P13 Z0.0 X0.0 D0.0 I275.0 J335.0 Q3;
T14 P14 Z0.0 X0.0 D0.0 I265.0 J205.0 Q4;
T15 P15 Z0.0 X0.0 D0.0 I210.0 J150.0 Q5;
T16 P16 Z0.0 X0.0 D0.0 I120.0 J60.0 Q6;
T17 P17 Z0.0 X0.0 D0.0 I-30.0 J30.0 Q7;
T18 P18 Z0.0 X0.0 D0.0 I240.0 J300.0 Q8;
T19 P19 Z0.0 X0.0 D0.0 I0.0 J0.0 Q9;

View File

@@ -0,0 +1,50 @@
N..... USE_LENGTH_UNITS(CANON_UNITS_MM)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_REFERENCE(CANON_XYZ)
N..... ON_RESET()
N..... USE_LENGTH_UNITS(CANON_UNITS_INCHES)
N..... SELECT_TOOL(3)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... STRAIGHT_TRAVERSE(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_FEED_RATE(100.0000)
N..... STRAIGHT_TRAVERSE(0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(2.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.0000, 0.0000, 1.5000, -0.5000, 1, 0.5000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.0000, 1.0000, 1.0000, 1.0000, -1, 0.5000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(1.0000, 2.0000, -0.8229, 2.8229, 1, 0.9000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(2.0000, 1.0000, 0.7000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.0000, 0.0000, 0.5000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(1.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("This is perverse on purpose.")
N..... STRAIGHT_TRAVERSE(1.0000, 0.0000, 1.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.5000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(2.0000, 0.0000, 0.5000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(1.0884, -0.0884, 1.5979, -0.5979, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: distance mode changed to incremental")
N..... ARC_FEED(1.0000, -0.1250, 1.0000, 0.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(-0.1250, 1.0000, 1.0000, 1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: distance mode changed to absolute")
N..... ARC_FEED(-0.0514, 1.1139, 0.0000, 1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.8861, 2.0514, -0.8229, 2.8229, 1, 0.4000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: distance mode changed to incremental")
N..... ARC_FEED(1.0884, 2.0884, 1.0000, 2.0000, -1, 0.4000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(2.0884, 1.0884, 0.2000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: distance mode changed to absolute")
N..... ARC_FEED(2.0884, 0.9116, 2.0000, 1.0000, -1, 0.2000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.0884, -0.0884, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(1.0884, -0.0884, 1.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_MODE(0, 0)
N..... SET_FEED_RATE(0.0000)
N..... STOP_SPINDLE_TURNING(0)
N..... SET_SPINDLE_MODE(0 0.0000)
N..... PROGRAM_END()
N..... ON_RESET()
N..... ON_RESET()

View File

@@ -0,0 +1,28 @@
G20
T3 M6
G0 X0 Y0
F100
G0 Z1
X2Y0
G3 X1Y0 R[.5*SQRT[2]] Z.5
G2 X0Y1 R1
G3 X1Y2Z.9 R2
G1 X2Y1Z.7
X1Y0Z.5
G0Z1
(This is perverse on purpose.)
G0 Z1
G92 Z.5
X2Y0
G41
G3 X1Y0 R[.5*SQRT[2]] Z0
G91 G2 X-1Y1 R1
G90 G3 X1Y2Z.4 R2
G91 G1 X1Y-1Z-.2
G90 X1Y0Z0
G0Z1
G40
G92.1
M2

View File

@@ -0,0 +1,3 @@
#!/bin/bash
rs274 -t test.tbl -g test.ngc | awk '{$1=""; print}'
exit "${PIPESTATUS[0]}"

View File

@@ -0,0 +1,5 @@
T1 P1 Z0.5 D0.0625;first tool
T2 P2 Z0.7 D0.125;
T3 P3 Z0.5 D0.25;
T4 P4 Z0.7 D1.0;
T32 P32 Z0.5 D0.0;last tool

View File

@@ -0,0 +1,47 @@
N..... USE_LENGTH_UNITS(CANON_UNITS_MM)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_REFERENCE(CANON_XYZ)
N..... ON_RESET()
N..... COMMENT("this is the program describing entry moves for")
N..... COMMENT("radius compensation in Figure 3 of the Handbook")
N..... COMMENT("http://www.linuxcnc.org/handbook/RS274NGC_3/RS274NGC_38a.html#999268")
N..... SET_FEED_RATE(60.0000)
N..... USE_LENGTH_UNITS(CANON_UNITS_INCHES)
N..... COMMENT("first, no compensation so we can see the part outline")
N..... STRAIGHT_TRAVERSE(1.0000, 5.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.0000, 4.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, 3.0000, 2.0000, 4.0000, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(3.0000, 2.0000, 2.0000, 2.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(3.0000, -1.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, -2.0000, 2.0000, -1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(-2.0000, -2.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(-2.6000, -0.2000, -2.0000, -1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.4000, 2.8000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, 3.0000, 2.0000, 2.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("with compensation")
N..... SELECT_TOOL(4)
N..... STOP_SPINDLE_TURNING(0)
N..... CHANGE_TOOL()
N..... STRAIGHT_TRAVERSE(1.0000, 5.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(1.5000, 4.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, 3.5000, 2.0000, 4.0000, 1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(3.5000, 2.0000, 2.0000, 2.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(3.5000, -1.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, -2.5000, 2.0000, -1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(-2.0000, -2.5000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(-2.9000, 0.2000, -2.0000, -1.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.1000, 3.2000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(2.0000, 3.5000, 2.0000, 2.0000, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_MODE(0, 0)
N..... SET_FEED_RATE(0.0000)
N..... STOP_SPINDLE_TURNING(0)
N..... SET_SPINDLE_MODE(0 0.0000)
N..... PROGRAM_END()
N..... ON_RESET()
N..... ON_RESET()

View File

@@ -0,0 +1,33 @@
(this is the program describing entry moves for)
(radius compensation in Figure 3 of the Handbook)
(http://www.linuxcnc.org/handbook/RS274NGC_3/RS274NGC_38a.html#999268)
g20 f60
(first, no compensation so we can see the part outline)
g0 x1 y5
g1 y4
g3 x2 y3 i1
g2 x3 y2 j-1
g1 y-1
g2 x2 y-2 i-1
g1 x-2
g2 x-2.6 y-0.2 j1
g1 x1.4 y2.8
g2 x2 y3 i.6 j-.8
(with compensation)
t4 m6
g0 x1 y5
g41 g1 y4
g3 x2 y3 i1
g2 x3 y2 j-1
g1 y-1
g2 x2 y-2 i-1
g1 x-2
g2 x-2.6 y-0.2 j1
g1 x1.4 y2.8
g2 x2 y3 i.6 j-.8
g40
m2

View File

@@ -0,0 +1,3 @@
#!/bin/bash
rs274 -t test.tbl -g test.ngc | awk '{$1=""; print}'
exit "${PIPESTATUS[0]}"

View File

@@ -0,0 +1,5 @@
T1 P1 Z0.5 D0.0625;first tool
T2 P2 Z0.7 D0.125;
T3 P3 Z0.5 D0.25;
T4 P4 Z0.7 D1.0;
T32 P32 Z0.5 D0.0;last tool

View File

@@ -0,0 +1,107 @@
N..... USE_LENGTH_UNITS(CANON_UNITS_MM)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_G92_OFFSET(0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_REFERENCE(CANON_XYZ)
N..... ON_RESET()
N..... SET_FEED_RATE(60.0000)
N..... USE_LENGTH_UNITS(CANON_UNITS_INCHES)
N..... COMMENT("arc entry")
N..... COMMENT("uncomp")
N..... STRAIGHT_TRAVERSE(0.0000, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(0.5000, 0.7500, 0.5000, 0.5000, -1, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("comp")
N..... STRAIGHT_TRAVERSE(0.0000, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, 0.5000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(0.5000, 0.8125, 0.5000, 0.5562, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, 0.8125, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, 0.7500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(0.5000, 0.8125, 0.5000, 0.5562, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, 0.8125, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, 0.7500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(0.5000, 0.8125, 0.5000, 0.5562, -1, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, 0.8125, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, 0.7500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, 0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... ARC_FEED(0.5000, 0.8125, 0.5000, 0.5562, -1, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, 0.8125, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, 0.7500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, 0.7500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("line entry")
N..... COMMENT("uncomp")
N..... STRAIGHT_TRAVERSE(0.0000, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.5000, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("comp")
N..... STRAIGHT_TRAVERSE(0.0000, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, -0.5000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.4558, -0.2058, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.5000, -0.1875, 0.5000, -0.2500, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, -0.1875, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, -0.2500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.4558, -0.2058, 0.0000, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.5000, -0.1875, 0.5000, -0.2500, -1, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, -0.1875, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, -0.2500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.4558, -0.2058, 0.2500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.5000, -0.1875, 0.5000, -0.2500, -1, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, -0.1875, 0.0000, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, -0.2500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_TRAVERSE(0.0000, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.2500, -0.5000, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation on left")
N..... STRAIGHT_FEED(0.4558, -0.2058, 0.2500, 0.0000, 0.0000, 0.0000)
N..... ARC_FEED(0.5000, -0.1875, 0.5000, -0.2500, -1, 0.2500, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(0.7500, -0.1875, 0.2500, 0.0000, 0.0000, 0.0000)
N..... COMMENT("interpreter: cutter radius compensation off")
N..... STRAIGHT_FEED(1.0000, -0.2500, 0.0000, 0.0000, 0.0000, 0.0000)
N..... STRAIGHT_FEED(1.2500, -0.2500, 0.2500, 0.0000, 0.0000, 0.0000)
N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000)
N..... SET_XY_ROTATION(0.0000)
N..... SET_FEED_MODE(0, 0)
N..... SET_FEED_RATE(0.0000)
N..... STOP_SPINDLE_TURNING(0)
N..... SET_SPINDLE_MODE(0 0.0000)
N..... PROGRAM_END()
N..... ON_RESET()
N..... ON_RESET()

View File

@@ -0,0 +1,81 @@
g20 f60
(arc entry)
(uncomp)
g0x0y.5z.25
g1x.25
g41 g2 d0 x.5 y.75 i.25
g1 x.75
g40 x1
x1.25 z.25
(comp)
g0x0y.5z.25
g1x.25 z0
g41 g2 d2 x.5 y.75 i.25
g1 x.75
g40 x1
x1.25 z.25
g0x0y.5z.25
g1x.25
g41 g2 d2 x.5 y.75 i.25 z0
g1 x.75
g40 x1
x1.25 z.25
g0x0y.5z.25
g1x.25
g41 g2 d2 x.5 y.75 i.25
g1 x.75 z0
g40 x1
x1.25 z.25
g0x0y.5z.25
g1x.25
g41 g2 d2 x.5 y.75 i.25
g1 x.75
g40 x1 z0
x1.25 z.25
(line entry)
(uncomp)
g0x0y-.5z.25
g1x.25
g41 g1 d0 x.5 y-.25
g1 x.75
g40 x1
x1.25 z.25
(comp)
g0x0y-.5z.25
g1x.25 z0
g41 g1 d2 x.5 y-.25
g1 x.75
g40 x1
x1.25 z.25
g0x0y-.5z.25
g1x.25
g41 g1 d2 x.5 y-.25 z0
g1 x.75
g40 x1
x1.25 z.25
g0x0y-.5z.25
g1x.25
g41 g1 d2 x.5 y-.25
g1 x.75 z0
g40 x1
x1.25 z.25
g0x0y-.5z.25
g1x.25
g41 g1 d2 x.5 y-.25
g1 x.75
g40 x1 z0
x1.25 z.25
m2

View File

@@ -0,0 +1,3 @@
#!/bin/bash
rs274 -t test.tbl -g test.ngc | awk '{$1=""; print}'
exit "${PIPESTATUS[0]}"

View File

@@ -0,0 +1,5 @@
T1 P1 Z0.5 D0.0625;first tool
T2 P2 Z0.7 D0.125;
T3 P3 Z0.5 D0.25;
T4 P4 Z0.7 D1.0;
T32 P32 Z0.5 D0.0;last tool

View File

@@ -0,0 +1,10 @@
#!/bin/sh
result=$1
if grep -qi error: "$result" ; then
echo "found string 'error' in $result"
exit 1
fi
exit 0

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env python3
import os
import sys
import time
import linuxcnc
import linuxcnc_util
import hal
def wait_for_hal_pin(name, value, timeout=10):
start_time = time.time()
while (time.time() - start_time) < timeout:
if hal.get_value(name) == value:
return
time.sleep(0.1)
raise RuntimeError("error: hal pin %s didn't get to %s after %.3f seconds" % (name, value, timeout))
# unbuffer stdout
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w')
retval = 0
h = hal.component("python-ui")
h.newpin("ext-estop-button", hal.HAL_BIT, hal.HAL_OUT)
h.ready() # mark the component as 'ready'
hal.connect('python-ui.ext-estop-button', 'ext-estop')
c = linuxcnc.command()
s = linuxcnc.stat()
e = linuxcnc.error_channel()
l = linuxcnc_util.LinuxCNC(command=c, status=s, error=e)
c.state(linuxcnc.STATE_ESTOP_RESET)
c.state(linuxcnc.STATE_ON)
c.wait_complete()
if False == hal.get_value('estop-all-ok'):
print("error: estop not OK before ext-estop-button is touched")
retval = 1
h['ext-estop-button'] = 1
# Give HAL and classicladder time to react
try:
wait_for_hal_pin('estop-all-ok', False)
except RuntimeError as e:
print("error: estop still OK after ext-estop-button is set")
retval = 1
h['ext-estop-button'] = 0
c.state(linuxcnc.STATE_ESTOP_RESET)
# Give HAL and classicladder time to react
try:
wait_for_hal_pin('estop-all-ok', True)
except RuntimeError as e:
print("error: estop not OK aftet ext-estop-button is unset")
retval = 1
print("exiting linuxcnc")
sys.exit(retval)

View File

@@ -0,0 +1,238 @@
_FILES_CLASSICLADDER
_FILE-symbols.csv
#VER=1.0
%I0,GUI-E,
%I1,EXT-E,
%I2,E-RESET,
%I3,I3,
%I4,I4,
%I5,I5,
%I6,I6,
%I7,I7,
%I8,I8,
%I9, ,
%Q0,EMC-E,
%Q1,Q1,
%Q2,Q2,
%Q3,Q3,
%Q4,Q4,
%Q5,Q5,
%Q6,Q6,
%Q7,Q7,
%Q8,Q8,
%Q9,Q9,
%T0,T0,
%T1,T1,
%T2,T2,
%B0,reset,reset off timer
%B1,%B1,
%B2,%B2,
%B3,%B3,
%B4,%B4,
%B5,%B5,
%B6,%B6,
%B7,%B7,
%B8,%B8,
%B9,%B9,
%B10,%B10,
%B11,%B11,
%B12,%B12,
%B13,%B13,
%B14,%B14,
%B15,%B15,
%B16,%B16,
%B17,%B17,
%B18,%B18,
%B19,%B19,
%W0,%W0,
%W1,%W1,
%W2,%W2,
%W3,%W3,
%IW0,%IW0,
%IW1,%IW1,
%IW2,%IW2,
%IW3,%IW3,
%IW4,%IW4,
%IW5,%IW5,
%IW6,%IW6,
%IW7,%IW7,
%IW8,%IW8,
%IW9,%IW9,
%QW0,%QW0,
%QW1,%QW1,
%QW2,%QW2,
%QW3,%QW3,
%QW4,%QW4,
%QW5,%QW5,
%QW6,%QW6,
%QW7,%QW7,
%QW8,%QW8,
%QW9,%QW9,
%IF0,%IF0,
%IF1,%IF1,
%IF2,%IF2,
%IF3,%IF3,
%IF4,%IF4,
%IF5,%IF5,
%IF6,%IF6,
%IF7,%IF7,
%IF8,%IF8,
%IF9,%IF9,
%QF0,%QF0,
%QF1,%QF1,
%QF2,%QF2,
%QF3,%QF3,
%QF4,%QF4,
%QF5,%QF5,
%QF6,%QF6,
%QF7,%QF7,
%QF8,%QF8,
%QF9,%QF9,
%T3,%T3,Old Timer
%T4,%T4,Old Timer
%TM0,%TM0,New Timer
%TM1,%TM1,New Timer
%TM2,%TM2,New Timer
%TM3,%TM3,New Timer
%TM4,%TM4,New Timer
%TM5,%TM5,New Timer
%TM6,%TM6,New Timer
%TM7,%TM7,New Timer
%TM8,%TM8,New Timer
%TM9,%TM9,New Timer
%M0,%M0,One-shot
%M1,%M1,One-shot
%C0,%C0,Counter
%C1,%C1,Counter
%C2,%C2,Counter
%C3,%C3,Counter
%C4,%C4,Counter
%C5,%C5,Counter
%C6,%C6,Counter
%C7,%C7,Counter
%C8,%C8,Counter
%C9,%C9,Counter
%E0,%E0,Error Flag Bit
%E1,%E1,Error Flag Bit
%E2,%E2,Error Flag Bit
%E3,%E3,Error Flag Bit
%E4,%E4,Error Flag Bit
%E5,%E5,Error Flag Bit
%E6,%E6,Error Flag Bit
%E7,%E7,Error Flag Bit
%E8,%E8,Error Flag Bit
%E9,%E9,Error Flag Bit
_/FILE-symbols.csv
_FILE-modbusioconf.csv
#VER=1.0
_/FILE-modbusioconf.csv
_FILE-ioconf.csv
#VER=1.0
_/FILE-ioconf.csv
_FILE-sequential.csv
#VER=1.0
_/FILE-sequential.csv
_FILE-sections.csv
#VER=1.0
#NAME000=Prog1
000,0,-1,1,1,0
_/FILE-sections.csv
_FILE-rung_1.csv
#VER=2.0
#LABEL=Rung 1
#COMMENT=Stepper Estop Chain
#PREVRUNG=0
#NEXTRUNG=-1
0-0-50/0 , 1-0-50/0 , 9-0-50/0 , 9-0-50/1 , 9-0-0/0 , 9-0-0/0 , 9-0-60/0 , 9-0-0/0 , 9-0-0/0 , 50-0-60/0
0-0-0/0 , 2-0-50/1 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-50/2 , 9-0-0/0 , 9-0-0/0 , 0-1-60/1
0-0-50/0 , 1-0-50/0 , 2-0-50/1 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/1 , 9-0-0/0 , 0-1-60/1
9-0-0/0 , 1-0-50/0 , 2-0-50/1 , 1-0-60/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 0-1-0/0
0-0-60/1 , 0-0-0/0 , 0-0-0/0 , 1-1-50/2 , 0-1-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-60/6
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
_/FILE-rung_1.csv
_FILE-rung_0.csv
#VER=2.0
#LABEL=
#COMMENT=
#PREVRUNG=0
#NEXTRUNG=1
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
_/FILE-rung_0.csv
_FILE-arithmetic_expressions.csv
#VER=2.0
_/FILE-arithmetic_expressions.csv
_FILE-timers_iec.csv
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
1,0,0
_/FILE-timers_iec.csv
_FILE-counters.csv
0
0
0
0
0
0
0
0
0
0
_/FILE-counters.csv
_FILE-monostables.csv
1,10
1,20
_/FILE-monostables.csv
_FILE-timers.csv
1,10
1,20
0,20
2,1
2,5
_/FILE-timers.csv
_FILE-com_params.txt
MODBUS_MASTER_SERIAL_PORT=
MODBUS_MASTER_SERIAL_SPEED=9600
MODBUS_MASTER_SERIAL_DATABITS=8
MODBUS_MASTER_SERIAL_STOPBITS=1
MODBUS_MASTER_SERIAL_PARITY=0
MODBUS_ELEMENT_OFFSET=0
MODBUS_MASTER_SERIAL_USE_RTS_TO_SEND=0
MODBUS_MASTER_TIME_INTER_FRAME=100
MODBUS_MASTER_TIME_OUT_RECEIPT=500
MODBUS_MASTER_TIME_AFTER_TRANSMIT=0
MODBUS_DEBUG_LEVEL=0
MODBUS_MAP_COIL_READ=0
MODBUS_MAP_COIL_WRITE=0
MODBUS_MAP_INPUT=0
MODBUS_MAP_HOLDING=0
MODBUS_MAP_REGISTER_READ=0
MODBUS_MAP_REGISTER_WRITE=0
_/FILE-com_params.txt
_FILE-general.txt
PERIODIC_REFRESH=1
SIZE_NBR_RUNGS=12
SIZE_NBR_BITS=20
SIZE_NBR_WORDS=4
SIZE_NBR_TIMERS=5
SIZE_NBR_MONOSTABLES=2
SIZE_NBR_COUNTERS=10
SIZE_NBR_TIMERS_IEC=10
SIZE_NBR_PHYS_INPUTS=10
SIZE_NBR_PHYS_OUTPUTS=10
SIZE_NBR_ARITHM_EXPR=4
SIZE_NBR_SECTIONS=4
SIZE_NBR_SYMBOLS=121
_/FILE-general.txt
_/FILES_CLASSICLADDER

View File

@@ -0,0 +1,35 @@
# HAL config file for using classic ladder
# The core_sim.hal file sets up motion, stepgen and other common items
# Remove core_sim.hal connections for the following pins and implement
# using classic latter functionality instead:
unlinkp iocontrol.0.user-enable-out
unlinkp iocontrol.0.emc-enable-in
# This file adds:
# the possibility of an external momentary or sustained NC estop button
# (load the realtime portion)
# these classicladder parameters need to be optimized after ladder completion
loadrt classicladder_rt numRungs=12 numBits=20 numWords=4 numTimers=5 numMonostables=2 numPhysInputs=10 numPhysOutputs=10 numArithmExpr=4 numSections=4
# We kick ladder into a thread at the slower servo rate rather than base rate
addf classicladder.0.refresh servo-thread 1
# invoke the user part of CL to silently load the program
# later we will need to add the clp file mentioned below
# to the ini file so that we do not need to hardcode it here.
loadusr -w classicladder --nogui classicladder-estop.clp
# three axis motion allows 6 other outputs on pins 8,9,1,14,16,17
# five additional input pins are available 10,11,12,13,15
# these are setup by the work they perform below
# estop signals
# signal is the internal or gui estop command from EMC
net gui-estop iocontrol.0.user-enable-out classicladder.0.in-00
# one-shot on timer when signal above goes high.
net estop-strobe iocontrol.0.user-request-enable classicladder.0.in-02
# this bit is an external estop button connected to parport pin 11 and ground
net ext-estop classicladder.0.in-01
# This bit signal is command to estop from CL to EMC
net estop-all-ok iocontrol.0.emc-enable-in classicladder.0.out-00

View File

@@ -0,0 +1,35 @@
[EMC]
VERSION = 1.1
MACHINE = LinuxCNC-test-classicladder-estop
# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
DEBUG = 0
[DISPLAY]
DISPLAY = ./classicladder-estop-ui.py
CYCLE_TIME = 0.200
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
BASE_PERIOD = 50000
SERVO_PERIOD = 1000000
[TASK]
TASK = milltask
CYCLE_TIME = 0.010
[HAL]
HALFILE = core_sim.hal
HALFILE = classicladder-estop.hal
HALFILE = simulated_home.hal
[TRAJ]
COORDINATES = X Y Z
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
[KINS]
KINEMATICS = trivkins
JOINTS = 3

View File

View File

@@ -0,0 +1,10 @@
#!/bin/sh
#
# Test setup based on configs/sim/axis/classicladder/
#
# Disable eatmydata, as it do not seem to work with classicladder
if [ "libeatmydata.so" = "$LD_PRELOAD" ] ; then
unset LD_PRELOAD
fi
exec linuxcnc "$(dirname "$0")/classicladder-estop.ini"

View File

@@ -0,0 +1,2 @@
Tests that the encoder and counter modules give the expected results
on a simple increasing quadrature input

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
setexact_for_test_suite_only
loadrt sampler cfg=sss depth=3500
loadrt stepgen step_type=2
loadrt encoder num_chan=3
loadrt threads name1=fast period1=100000
net A stepgen.0.phase-A => encoder.0.phase-A encoder.1.phase-A encoder.2.phase-A
net B stepgen.0.phase-B => encoder.0.phase-B encoder.1.phase-B
net C0 encoder.0.counts => sampler.0.pin.0
net C1 encoder.1.counts => sampler.0.pin.1
net C2 encoder.2.counts => sampler.0.pin.2
addf stepgen.update-freq fast
addf stepgen.make-pulses fast
addf encoder.update-counters fast
addf encoder.capture-position fast
addf sampler.0 fast
setp stepgen.0.maxvel .15
setp stepgen.0.maxaccel 2
setp stepgen.0.position-cmd .04
setp stepgen.0.enable 1
setp stepgen.0.position-scale 32000
setp encoder.1.x4-mode 0
setp encoder.2.counter-mode 1
start
loadusr -w halsampler -n 3500

3
tests/edge/README Normal file
View File

@@ -0,0 +1,3 @@
This tests that the edge component does what it should.

View File

@@ -0,0 +1,10 @@
1 0 1
1 0 1
1 0 1
1 0 1
0 1 0
0 0 1
1 1 0
0 1 0
0 0 1
0 0 1

Some files were not shown because too many files have changed in this diff Show More