Files
linuxcncWebWASM/patches/linuxcnc-working-tree.patch

945 lines
33 KiB
Diff

diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini
index cc4ad63..fcee728 100644
--- a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini
@@ -11,7 +11,7 @@
# Version of this INI file
-VERSION = 1.0
+VERSION = 1.1
# Name of machine, for use with display, etc.
MACHINE = 3axis-tutorial
@@ -43,6 +43,7 @@ MAX_FEED_OVERRIDE = 1.2
MAX_SPINDLE_OVERRIDE = 1.0
# Prefix to be used
PROGRAM_PREFIX =/home/rolf/linuxcnc/nc_files #need to change
+OPEN_FILE = configs/nc_files/3dtest.ngc
# Introductory graphic
INTRO_GRAPHIC = linuxcnc.gif
diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
index 957336f..41ebee0 100644
--- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
+++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
@@ -18,7 +18,7 @@ MAX_ANGULAR_VELOCITY = 360
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 2
PROGRAM_PREFIX = ../../nc_files
- INTRO_GRAPHIC = emc2.gif
+ INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 1
#EDITOR = geany
TOOL_EDITOR = tooledit z diam
diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
index f49430b..29ac1a6 100644
--- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
+++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
@@ -18,7 +18,7 @@ MAX_ANGULAR_VELOCITY = 360
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 2
PROGRAM_PREFIX = ../../nc_files
- INTRO_GRAPHIC = emc2.gif
+ INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 1
#EDITOR = geany
TOOL_EDITOR = tooledit z diam
diff --git a/lib/hallib/sim_lib.tcl b/lib/hallib/sim_lib.tcl
index 7d98add..27f1270 100644
--- a/lib/hallib/sim_lib.tcl
+++ b/lib/hallib/sim_lib.tcl
@@ -108,6 +108,8 @@ proc setup_kins {axes} {
# set up axis indices for known kins
switch $kins_module {
trivkins {indices_for_trivkins $axes}
+ xyzac-trt-kins {indices_for_trivkins $axes}
+ xyzbc-trt-kins {indices_for_trivkins $axes}
default {
puts stderr "setup_kins: unknown \[KINS\]KINEMATICS=<$::KINS(KINEMATICS)>"
}
diff --git a/src/emc/motion/control.c b/src/emc/motion/control.c
index 8c9ce66..0ab0f5f 100644
--- a/src/emc/motion/control.c
+++ b/src/emc/motion/control.c
@@ -19,6 +19,9 @@
#ifdef SWITCHKINS_DEBUG
#include <stdio.h> // rtpreempt only, consolidate to stderr
#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
#include "posemath.h"
#include "rtapi.h"
@@ -67,6 +70,46 @@ extern struct emcmot_status_t *emcmotStatus;
// etc.
static double *pcmd_p[EMCMOT_MAX_AXIS];
+/* Optional simulation-only servo oracle. It is disabled unless the caller
+ * provides a file path, so normal LinuxCNC motion timing is unchanged. */
+static FILE *xyzac_trace_stream;
+static void xyzac_trace_tick(void) {
+ const char *path;
+ int joint;
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (xyzac_trace_stream == NULL) {
+ path = getenv("LINUXCNC_XYZAC_TRACE_FILE");
+ if (path == NULL || path[0] == '\0') return;
+ xyzac_trace_stream = fopen(path, "w");
+ if (xyzac_trace_stream == NULL) return;
+ setvbuf(xyzac_trace_stream, NULL, _IOLBF, 0);
+ }
+ fprintf(xyzac_trace_stream,
+ "{\"wall_ns\":%llu,\"motion_heartbeat\":%u,\"position\":[%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g],\"actual_position\":[%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g,%.17g],\"velocity\":%.17g,\"acceleration\":%.17g,\"queue_depth\":%d,\"active_depth\":%d,\"motion_id\":%d,\"motion_type\":%d,\"paused\":%d,\"queue_full\":%d,\"joints\":[",
+ (unsigned long long)now.tv_sec * 1000000000ull + (unsigned long long)now.tv_nsec,
+ emcmotStatus->heartbeat,
+ emcmotStatus->carte_pos_cmd.tran.x, emcmotStatus->carte_pos_cmd.tran.y, emcmotStatus->carte_pos_cmd.tran.z,
+ emcmotStatus->carte_pos_cmd.a, emcmotStatus->carte_pos_cmd.b, emcmotStatus->carte_pos_cmd.c,
+ emcmotStatus->carte_pos_cmd.u, emcmotStatus->carte_pos_cmd.v, emcmotStatus->carte_pos_cmd.w,
+ emcmotStatus->carte_pos_fb.tran.x, emcmotStatus->carte_pos_fb.tran.y, emcmotStatus->carte_pos_fb.tran.z,
+ emcmotStatus->carte_pos_fb.a, emcmotStatus->carte_pos_fb.b, emcmotStatus->carte_pos_fb.c,
+ emcmotStatus->carte_pos_fb.u, emcmotStatus->carte_pos_fb.v, emcmotStatus->carte_pos_fb.w,
+ emcmotStatus->current_vel, emcmotStatus->acc, emcmotStatus->depth,
+ emcmotStatus->activeDepth, emcmotStatus->id, emcmotStatus->motionType,
+ emcmotStatus->paused, emcmotStatus->queueFull);
+ for (joint = 0; joint < EMCMOT_MAX_JOINTS; ++joint) {
+ if (joint != 0) fputc(',', xyzac_trace_stream);
+ fprintf(xyzac_trace_stream, "{\"cmd\":%.17g,\"fb\":%.17g,\"vel\":%.17g,\"acc\":%.17g,\"homed\":%d}",
+ emcmotStatus->joint_status[joint].pos_cmd,
+ emcmotStatus->joint_status[joint].pos_fb,
+ emcmotStatus->joint_status[joint].vel_cmd,
+ emcmotStatus->joint_status[joint].acc_cmd,
+ emcmotStatus->joint_status[joint].homed);
+ }
+ fputs("]}\n", xyzac_trace_stream);
+}
+
/***********************************************************************
* LOCAL FUNCTION PROTOTYPES *
************************************************************************/
@@ -271,6 +314,7 @@ void emcmotController(void *arg, long period)
update_status();
/* here ends the core of the controller */
emcmotStatus->heartbeat++;
+ xyzac_trace_tick();
/* set tail to head, to indicate work complete */
emcmotStatus->tail = emcmotStatus->head;
/* end of controller function */
diff --git a/src/emc/nml_intf/emc.cc b/src/emc/nml_intf/emc.cc
index 59fdabe..cdba7ed 100644
--- a/src/emc/nml_intf/emc.cc
+++ b/src/emc/nml_intf/emc.cc
@@ -1838,6 +1838,7 @@ void EMC_TRAJ_STAT::update(CMS * cms)
cms->update(probeval);
cms->update(kinematics_type);
cms->update(motion_type);
+ cms->update(motion_heartbeat);
}
@@ -2261,4 +2262,4 @@ void EMC_MOTION_ADAPTIVE::update(CMS * cms)
void EMC_MOTION_CMD_MSG::update(CMS * cms)
{
-}
\ No newline at end of file
+}
diff --git a/src/emc/nml_intf/emc_nml.hh b/src/emc/nml_intf/emc_nml.hh
index 2d5e61e..8c713b7 100644
--- a/src/emc/nml_intf/emc_nml.hh
+++ b/src/emc/nml_intf/emc_nml.hh
@@ -834,6 +834,7 @@ class EMC_TRAJ_STAT:public EMC_TRAJ_STAT_MSG {
//bool spindle_override_enabled; moved to SPINDLE_STAT
bool adaptive_feed_enabled;
bool feed_hold_enabled;
+ uint32_t motion_heartbeat; // native motion-controller servo-cycle counter
StateTag tag;
};
diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc
index 6d5ebd5..d215e2e 100644
--- a/src/emc/task/emctaskmain.cc
+++ b/src/emc/task/emctaskmain.cc
@@ -3490,6 +3490,11 @@ int main(int argc, char *argv[])
// since emcStatus was passed to the WM init functions, it
// will be updated in the _update() functions above. There's
// no need to call the individual functions on all WM items.
+ // EMC_TASK_STAT_MSG::heartbeat is the native task-cycle oracle used by
+ // external clients. Keep it monotonic and publish it with this cycle's
+ // status image so a reader can identify every task tick without relying on
+ // wall-clock sampling.
+ emcStatus->task.heartbeat++;
emcStatusBuffer->write(emcStatus);
// wait on timer cycle, if specified, or calculate actual
diff --git a/src/emc/task/taskintf.cc b/src/emc/task/taskintf.cc
index 36fbd97..b3ae2aa 100644
--- a/src/emc/task/taskintf.cc
+++ b/src/emc/task/taskintf.cc
@@ -1612,6 +1612,7 @@ int emcTrajUpdate(EMC_TRAJ_STAT * stat)
stat->feed_override_enabled = enables & FS_ENABLED;
stat->adaptive_feed_enabled = enables & AF_ENABLED;
stat->feed_hold_enabled = enables & FH_ENABLED;
+ stat->motion_heartbeat = emcmotStatus.heartbeat;
if (new_config) {
stat->cycleTime = emcmotConfig.trajCycleTime;
diff --git a/src/emc/usr_intf/axis/extensions/emcmodule.cc b/src/emc/usr_intf/axis/extensions/emcmodule.cc
index b43f041..96f12a2 100644
--- a/src/emc/usr_intf/axis/extensions/emcmodule.cc
+++ b/src/emc/usr_intf/axis/extensions/emcmodule.cc
@@ -409,6 +409,9 @@ static PyMemberDef Stat_members[] = {
{(char*)"echo_serial_number", T_INT, O(echo_serial_number), READONLY},
{(char*)"echo_serial_number", T_INT, O(echo_serial_number), READONLY},
{(char*)"state", T_INT, O(status), READONLY},
+ {(char*)"task_heartbeat", T_UINT, O(task.heartbeat), READONLY,
+ "Native EMC task-loop heartbeat. This counter is incremented by the "
+ "LinuxCNC task thread and is suitable for identifying native status ticks."},
// task
{(char*)"task_mode", T_INT, O(task.mode), READONLY},
@@ -473,6 +476,8 @@ static PyMemberDef Stat_members[] = {
{(char*)"feed_override_enabled", T_BOOL, O(motion.traj.feed_override_enabled), READONLY},
{(char*)"adaptive_feed_enabled", T_BOOL, O(motion.traj.adaptive_feed_enabled), READONLY},
{(char*)"feed_hold_enabled", T_BOOL, O(motion.traj.feed_hold_enabled), READONLY},
+ {(char*)"motion_heartbeat", T_UINT, O(motion.traj.motion_heartbeat), READONLY,
+ "Native motion-controller servo-cycle counter."},
{(char*)"num_extrajoints", T_INT, O(motion.numExtraJoints), READONLY},
diff --git a/configs/sim/axis/corexy/tool.tbl b/configs/sim/axis/corexy/tool.tbl
new file mode 100644
index 0000000..6239879
--- /dev/null
+++ b/configs/sim/axis/corexy/tool.tbl
@@ -0,0 +1,5 @@
+T1 P1 Z0.511 D0.125 ;1/8 end mill
+T2 P2 Z0.1 D0.0625 ;1/16 end mill
+T3 P3 Z1.273 D0.201 ;#7 tap drill
+T99999 P99999 Z0.1 ;big tool number
+T4 P4 Z0 D.005 ;Added 20131029
diff --git a/configs/sim/axis/rotate/rotatekins.hal b/configs/sim/axis/rotate/rotatekins.hal
new file mode 100644
index 0000000..f42bec6
--- /dev/null
+++ b/configs/sim/axis/rotate/rotatekins.hal
@@ -0,0 +1,6 @@
+# Workspace-derived rotatekins candidate. The runtime integration remains a
+# later K2-HAL task; this file is intentionally limited to module registration.
+loadrt [KINS]KINEMATICS
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
diff --git a/configs/sim/axis/rotate/rotatekins.ini b/configs/sim/axis/rotate/rotatekins.ini
new file mode 100644
index 0000000..40e40a8
--- /dev/null
+++ b/configs/sim/axis/rotate/rotatekins.ini
@@ -0,0 +1,27 @@
+# Workspace-derived simulation candidate for the rotatekins source module.
+# LinuxCNC ships the module and man-page example but no dedicated configs/sim
+# entry; this fixture keeps that absence explicit in the coupled report.
+
+[EMC]
+MACHINE = rotatekins_candidate
+VERSION = 1.1
+
+[KINS]
+JOINTS = 6
+KINEMATICS = rotatekins
+
+[TRAJ]
+COORDINATES = XYZABC
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+
+[HAL]
+HALFILE = rotatekins.hal
+
+[EMCMOT]
+EMCMOT = motmod
+SERVO_PERIOD = 1000000
+
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.010
diff --git a/configs/sim/axis/tool.tbl b/configs/sim/axis/tool.tbl
new file mode 100644
index 0000000..6239879
--- /dev/null
+++ b/configs/sim/axis/tool.tbl
@@ -0,0 +1,5 @@
+T1 P1 Z0.511 D0.125 ;1/8 end mill
+T2 P2 Z0.1 D0.0625 ;1/16 end mill
+T3 P3 Z1.273 D0.201 ;#7 tap drill
+T99999 P99999 Z0.1 ;big tool number
+T4 P4 Z0 D.005 ;Added 20131029
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial
new file mode 100755
index 0000000..2b374b9
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial
@@ -0,0 +1,284 @@
+#!/usr/bin/env python3
+
+# Rolf Redford, Nov 2018
+
+#import libraries
+from vismach import *
+import hal
+import math
+import sys
+
+#----------------------------------------------------------------------------------------------------------------------------------
+# Starting and defining
+
+# used for diameter for versions less than 2.8.
+# it gives us way to access variable values from vismach script.
+import linuxcnc
+s = linuxcnc.stat()
+s.poll()
+
+# Here is where we define pins that linuxcnc will send
+# data to, in order to make movements.
+# We will need 5 pins, 3 for motion and 2 for tool stats.
+# tooldiameter isn't really used but if you are using 2.8 you can make couple changes
+# in this file, and uncomment last line in HAL file.
+# add joints. Mill has 3.
+c = hal.component("3axis-tutorial")
+c.newpin("jointX", hal.HAL_FLOAT, hal.HAL_IN)
+c.newpin("jointY", hal.HAL_FLOAT, hal.HAL_IN)
+c.newpin("jointZ", hal.HAL_FLOAT, hal.HAL_IN)
+
+# tool length and diameter pins?
+c.newpin("toollength", hal.HAL_FLOAT, hal.HAL_IN)
+c.newpin("tooldiameter", hal.HAL_FLOAT, hal.HAL_IN)
+
+# tells loadusr pins is ready
+c.ready()
+
+# Used for tool cylinder
+# it will be updated in shape and length by function below.
+toolshape = CylinderZ(0)
+toolshape = Color([1, .5, .5, .5],[toolshape])
+
+# updates tool cylinder shape.
+class HalToolCylinder(CylinderZ):
+ def __init__(self, comp, *args):
+ # get machine access so it can
+ # change itself as it runs
+ # specifically tool cylinder in this case.
+ CylinderZ.__init__(self, *args)
+ self.comp = c
+ def coords(self):
+ # update data - not needed if using 2.8 and self.comp["tooldiameter"]
+ # 2.7 does not have direct pin for diameter so this is workaround. commented out code is direct way to do it.
+ # s.poll() # 2.8 don't need this, comment out if using 2.8.
+ # get diameter and divide by 2 to get radius.
+ # rad = ( s.tool_table[s.tool_in_spindle].diameter ) # 2.7 workaround
+ rad = ( self.comp["tooldiameter"] ) # 2.8 only
+ rad = rad / 2 # change to rad
+ # this instantly updates tool model but tooltip doesn't move till -
+ # tooltip, the drawing point will NOT move till g43h(tool number) is called, however.
+ # Tool will "crash" if h and tool length does not match.
+ leng = s.tool_table[s.tool_in_spindle].zoffset
+ # Update tool length when g43h(toolnumber) is called, otherwise stays at 0 or previous size.
+ # commented out as I prefer machine to show actual tool size right away.
+ #leng = self.comp["toollength"]
+ return (-leng, rad, 0, rad)
+
+
+#----------------------------------------------------------------------------------------------------------------------------------
+# Concept of machine design
+
+# The model follows logical tree design - picture the tree, with branch and smaller branches off it
+# if you move the larger branch, smaller branches will move with it, but if you move smaller branch larger will not.
+#
+# Machine design follows that conceptal design, so for example if you move X, it can move on its own, but if you move Y,
+# it will also move X assembly, as it is attached to Y assembly.
+# so for this machine, tree looks like this:
+
+# model
+# |
+# |---frame
+# | |
+# | |---base
+# | |
+# | |---column
+# | |
+# | |---top
+# |
+# |
+# |---yassembly
+# | |
+# | |
+# | |---xassembly
+# | | |
+# | | |
+# | | |---xbase
+# | | |
+# | | |---work
+# | |
+# | |
+# | |---ybase
+# |
+# |
+# |---zassembly
+# |
+# |
+# |---zframe
+# | |
+# | |---zbody
+# | |
+# | |---spindle
+# |
+# |
+# |---toolassembly
+# |
+# |---cat30
+# |
+# |---tool
+# |
+# |---tooltip
+# |
+# |---(tool cylinder function)
+
+# As you can see, lowest parts must exist first before it can be grouped with others into assembly.
+# So you build upwards from lowest point in tree and assembly them together.
+# Same is applicable for any design of machine. Look at machine arm example and you will see that it starts
+# with tip and adds to larger part of arm then it finally groups with base.
+
+
+#----------------------------------------------------------------------------------------------------------------------------------
+# Starting with fixed frame
+
+# start creating base itself, floor and column for z. box is centered on 0,0,0
+base = BoxCentered(200, 560, 20)
+# translate it so top of base is at zero
+base = Translate([base], 0,0,-10)
+
+# column, attached to base on side.
+# Box() accepts extents
+# ie -100 to 100 is 200 wide, and rightmost is at -100 on coord.
+# Box(x rightmost, y futherest, z lowest, x leftmost, y nearest, z highest)
+column = Box( -60, -260, 0, 60, -200, 400)
+
+# add block on top
+# not really needed, but I like how it looks with it.
+# bare column looks little bit strange for some reason.
+top = Box(-80,-280,400, 80,-160,440)
+
+# now fuse it into "frame"
+frame = Collection([base, column, top])
+# color it grayish
+frame = Color([.8,.8,.8,1],[frame])
+
+
+#----------------------------------------------------------------------------------------------------------------------------------
+# Moving parts section
+
+# Start with X, Y then finally Z with tool and spindle.
+
+# X table addition
+xbase = BoxCentered(1000,200,30)
+# let's color it blue
+xbase = Color([0,0,1,1], [xbase])
+# Move table so top is at zero for now,
+# so work (default 0,0,0) is on top of table.
+xbase = Translate([xbase], 0,0, -15)
+
+# now create work which would be defined by Linuxcnc.
+# I suspect we would need to define shape but not enough is known.
+# for now just create an point that would be bottom center of stock.
+work = Capture()
+
+# group work and xbase together so they move together.
+xassembly = Collection([xbase, work])
+# work is now defined and grouped, and default at 0,0,0, or
+# currently on top of x part table.
+# so we move table group upwards, taking work with it.
+xassembly = Translate([xassembly], 0,0, 35)
+
+# Must define part motion before it becomes part of collection.
+# Must have arguments, object itself, c (defined above), then finally scale from the pin to x y z.
+# since this moves solely on X axis, only x is 1, rest is zero.
+# you could use fractions for say axis that moves in compound like arm for example
+# but this machine is very simple, so all axis will be purely full on axis and zero on other axis.
+xassembly = HalTranslate([xassembly], c, "jointX", 1, 0, 0)
+
+# Y assembly creation
+ybase = BoxCentered(200, 200, 10)
+# colorize it green so we can see it separate from frame.
+ybase = Color([0,1,0,1], [ybase])
+# don't define translation for this one, as y also moves X table.
+# translating this would move itself alone. You want it to move X parts also.
+
+# X table is moved by Y base, so we have to make X child of Y.
+# now define collection of ybase and xassembly.
+yassembly = Collection([ybase, xassembly])
+# define its motion first before translate.
+yassembly = HalTranslate([yassembly], c, "jointY", 0, 1, 0)
+# Now that translate is locked with part,
+# move it upwards so its on frame base.
+yassembly = Translate([yassembly], 0,0,5)
+
+# spindle head
+# define small cylinder where tool will be attached to.
+# It is shallow, basically exposed end of "cat30" toolholder.
+# let's pretend machine uses cat30.
+cat30 = CylinderZ(0, 30, 20, 40) # cone wider top smaller bottom
+# color it red, as in danger, tool!
+cat30 = Color([1,0,0,1], [cat30])
+
+# Define tool and grab such model information from linuxcnc
+# tooltip is initially in vismach "world" 0,0,0.
+# what it does is place where line drawing is in world, so
+# you can see where machine think tip of tool is.
+# first capture it, so we can use it and move it to where
+# defined end of tool is.
+tooltip = Capture()
+
+# Now that we have tooltip, let's attach it to cylinder function (see above)
+# it creates cylinder then translates tooltip to end of it.
+tool = Collection([
+ Translate([HalTranslate([tooltip], c, "toollength", 0, 0, -1)], 0, 0, 0),
+ HalToolCylinder(toolshape)
+ ])
+
+# Since tool is defined, lets attach it to cat30
+# Group cat30 and tooltip
+toolassembly = Collection([cat30, tool])
+# now that tool is properly attached, we can move it
+# and tool will "move" with it now.
+# BUT we need to build rest of head in such way that TOP of head is defined as Z zero.
+# Move it so it attaches to bottom of spindle body.
+toolassembly = Translate([toolassembly],0,0,-120)
+
+# Start building Z assembly head, including spindle and support
+# top is at zero as I want top to be defined as Z home top.
+spindle = CylinderZ(-100, 60, 0, 60) # top is at zero
+# define rest of head using Box
+zbody = Box(-30, -200, 0, 30, 0, -100)
+
+# fuse into z assembly
+zframe = Collection([zbody, spindle])
+# color it yellow
+zframe = Color([1,1,0,1], [zframe])
+
+# Now that all parts are created, let's group it and finally make Z motion
+zassembly = Collection([zframe, toolassembly])
+# define Z motion
+zassembly = HalTranslate([zassembly], c, "jointZ", 0, 0, 1)
+# Now that motion is defined,
+# we can now move it to Z home position.
+zassembly = Translate([zassembly], 0,0, 400)
+
+#----------------------------------------------------------------------------------------------------------------------------------
+# Getting it all together and finishing model
+
+# Assembly everything into single model.
+# xassembly is already included into yassembly so don't need to include it.
+model = Collection([frame, yassembly, zassembly])
+
+# Finally, call main() with parameter to let linuxcnc know.
+# parameter list:
+# final model name must include all parts you want to use
+# tooltip (special for tool tip inclusuion)
+# work (special for work part inclusion)
+# size of screen (bigger means more zoomed out to show more of machine)
+# last 2 is where view point source is.
+main(model, tooltip, work, 600, lat=-75, lon=215)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.hal b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.hal
new file mode 100644
index 0000000..aa04e3b
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.hal
@@ -0,0 +1,71 @@
+# 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 names=ddt_x,ddt_xv,ddt_y,ddt_yv,ddt_z,ddt_zv
+# load additional blocks
+loadrt hypot names=vel_xy,vel_xyz
+
+# 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_x servo-thread
+addf ddt_xv servo-thread
+addf ddt_y servo-thread
+addf ddt_yv servo-thread
+addf ddt_z servo-thread
+addf ddt_zv servo-thread
+addf vel_xy servo-thread
+addf vel_xyz 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_x.in
+net Ypos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt_y.in
+net Zpos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt_z.in
+
+# send the position commands thru differentiators to
+# generate velocity and accel signals
+net Xvel ddt_x.out => ddt_xv.in vel_xy.in0
+net Xacc <= ddt_xv.out
+net Yvel ddt_y.out => ddt_yv.in vel_xy.in1
+net Yacc <= ddt_yv.out
+net Zvel ddt_z.out => ddt_zv.in vel_xyz.in0
+net Zacc <= ddt_zv.out
+
+# Cartesian 2- and 3-axis velocities
+net XYvel vel_xy.out => vel_xyz.in1
+net XYZvel <= vel_xyz.out
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+loadusr -W hal_manualtoolchange
+net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change
+net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed
+net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number
+net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
+
+# start 3axis-tutorial vismach addition
+loadusr -W ./3axis-tutorial
+
+# "wire" linuxcnc pins to joints defined in vismach file
+net j0 joint.0.pos-fb => 3axis-tutorial.jointX
+net j1 joint.1.pos-fb => 3axis-tutorial.jointY
+net j2 joint.2.pos-fb => 3axis-tutorial.jointZ
+
+#tool sinput
+net tool_len 3axis-tutorial.toollength <= motion.tooloffset.z
+net tool_rad halui.tool.diameter 3axis-tutorial.tooldiameter # Only in 2.8 or later
+
+
+
+
+
+
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.ini b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.ini
new file mode 100644
index 0000000..4133b0d
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/3axis-tutorial.ini
@@ -0,0 +1,224 @@
+# This config file was created 2018-11-21 06:26:44.941844 by the update_ini script
+# The original config files may be found in the /home/john/linuxcnc/configs/rolfmill/rolfmill.old directory
+
+# EMC controller parameters for a simulated machine.
+
+# General note: Comments can either be preceded with a # or ; - either is
+# acceptable, although # is in keeping with most linux config files.
+
+# General section -------------------------------------------------------------
+[EMC]
+
+
+# Version of this INI file
+VERSION = 1.0
+
+# Name of machine, for use with display, etc.
+MACHINE = 3axis-tutorial
+
+# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
+# DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# Sections for display options ------------------------------------------------
+[DISPLAY]
+
+# Name of display program, e.g., xemc
+DISPLAY = axis
+
+# Cycle time, in seconds, that display will sleep between polls
+CYCLE_TIME = 0.100
+
+# Path to help file
+HELP_FILE = doc/help.txt
+
+# Initial display setting for position, RELATIVE or MACHINE
+POSITION_OFFSET = RELATIVE
+
+# Initial display setting for position, COMMANDED or ACTUAL
+POSITION_FEEDBACK = ACTUAL
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.2
+MAX_SPINDLE_OVERRIDE = 1.0
+# Prefix to be used
+PROGRAM_PREFIX =/home/rolf/linuxcnc/nc_files #need to change
+OPEN_FILE = configs/nc_files/3dtest.ngc
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+#EDITOR = geany
+
+INCREMENTS = 1 mm, .01 in, .1mm, 1 mil, .1 mil, 1/8000 in
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python3
+
+# Task controller section -----------------------------------------------------
+
+[RS274NGC]
+
+# File containing interpreter variables
+PARAMETER_FILE = 3axis-tutorial_mm.var
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+
+
+EMCMOT = motmod
+
+# Timeout for comm to emcmot, in seconds
+COMM_TIMEOUT = 1.0
+
+
+# BASE_PERIOD is unused in this configuration but specified in core_sim.hal
+BASE_PERIOD = 0
+# Servo task period, in nano-seconds
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+
+# Name of task controller program, e.g., milltask
+TASK = milltask
+
+# Cycle time, in seconds, that task controller will sleep between polls
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+
+[HAL]
+
+# The run script first uses halcmd to execute any HALFILE
+# files, and then to execute any individual HALCMD commands.
+#
+
+# list of hal config files to run through halcmd
+# files are executed in the order in which they appear
+HALFILE = 3axis-tutorial.hal
+
+# list of halcmd commands to execute
+# commands are executed in the order in which they appear
+#HALCMD = save neta
+
+# Single file that is executed after the GUI has started. Only supported by
+# AXIS at this time (only AXIS creates a HAL component of its own)
+#POSTGUI_HALFILE = test_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+
+[HALUI]
+#No Content
+
+[TRAJ]
+
+
+AXES = 3
+COORDINATES = X Y Z
+HOME = 0 0 0
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 30.48
+MAX_LINEAR_VELOCITY = 53.34
+DEFAULT_ACCELERATION = 508
+MAX_LINEAR_ACCELERATION = 508
+POSITION_FILE = position_mm.txt
+ARC_BLEND_ENABLE = 1
+ARC_BLEND_FALLBACK_ENABLE = 1
+ARC_BLEND_OPTIMIZATION_DEPTH = 50
+#Use this setting for no smoothing (for debugging and stress-testing)
+ARC_BLEND_SMOOTHING_THRESHOLD = .75
+#Use this setting for "normal" smoothing, i.e. if we blend over more than 40% of a segment
+#ARC_BLEND_SMOOTHING_THRESHOLD = 0.40
+
+# Axes sections ---------------------------------------------------------------
+
+[EMCIO]
+
+# Name of IO controller program, e.g., io
+EMCIO = io
+
+# cycle time, in seconds
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = tool.tbl
+TOOL_CHANGE_POSITION = 0 0 0
+
+
+[KINS]
+KINEMATICS = trivkins
+#This is a best-guess at the number of joints, it should be checked
+JOINTS = 3
+
+[AXIS_X]
+MIN_LIMIT = -500.0
+MAX_LIMIT = 500.0
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+
+[JOINT_0]
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+STEPGEN_MAXACCEL = 937.5
+SCALE = 80.0
+FERROR = 1
+MIN_FERROR = .25
+MIN_LIMIT = -500.0
+MAX_LIMIT = 500.0
+HOME_OFFSET = 0.0
+
+[AXIS_Y]
+MIN_LIMIT = -100.0
+MAX_LIMIT = 100.0
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+
+[JOINT_1]
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+STEPGEN_MAXACCEL = 937.5
+SCALE = 80.0
+FERROR = 1
+MIN_FERROR = .25
+MIN_LIMIT = -100.0
+MAX_LIMIT = 100.0
+HOME_OFFSET = 0.0
+
+[AXIS_Z]
+MIN_LIMIT = -240.0
+MAX_LIMIT = 0.001
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+
+[JOINT_2]
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 25.0
+MAX_ACCELERATION = 750.0
+STEPGEN_MAXACCEL = 937.5
+SCALE = 80.0
+FERROR = 1
+MIN_FERROR = .25
+MIN_LIMIT = -240.0
+MAX_LIMIT = 0.001
+HOME_OFFSET = 0.0
+
+# section for main IO controller parameters -----------------------------------
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README
new file mode 100644
index 0000000..6522282
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README
@@ -0,0 +1,2 @@
+A simple vismach 3 axis mill example built using primitives.
+Comments is in 3axis-tutorial vismach file, and some in 3axis-tutorial.hal explains step by step the process to build.
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README_es b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README_es
new file mode 100644
index 0000000..5193b11
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/README_es
@@ -0,0 +1,2 @@
+Un ejemplo simple de fresadora vismach de 3 ejes construido usando primitivas.
+Los comentarios se encuentran en el archivo vismach 3axis-tutorial, y algunos en 3axis-tutorial.hal explican paso a paso el proceso de creación.
diff --git a/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/tool.tbl b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/tool.tbl
new file mode 100644
index 0000000..2e64501
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.old/tool.tbl
@@ -0,0 +1,4 @@
+T1 P1 Z12 D30 ;big
+T2 P2 Z50 D10 ;1/16 end mill
+T3 P3 Z50 D5 ;#7 tap drill
+T99999 P99999 Z0.1 ;big tool number
diff --git a/configs/sim/axis/vismach/scorbot/scorbot.hal b/configs/sim/axis/vismach/scorbot/scorbot.hal
new file mode 100644
index 0000000..d5da59d
--- /dev/null
+++ b/configs/sim/axis/vismach/scorbot/scorbot.hal
@@ -0,0 +1,5 @@
+# Workspace-derived scorbot-kins module registration candidate.
+loadrt [KINS]KINEMATICS
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
diff --git a/configs/sim/axis/vismach/scorbot/scorbot.ini b/configs/sim/axis/vismach/scorbot/scorbot.ini
new file mode 100644
index 0000000..f18fde2
--- /dev/null
+++ b/configs/sim/axis/vismach/scorbot/scorbot.ini
@@ -0,0 +1,26 @@
+# Workspace-derived simulation candidate for scorbot-kins.
+# The locked LinuxCNC source contains scorbot-kins.c but no shipped sim INI.
+
+[EMC]
+MACHINE = scorbot_candidate
+VERSION = 1.1
+
+[KINS]
+JOINTS = 5
+KINEMATICS = scorbot-kins
+
+[TRAJ]
+COORDINATES = XYZAB
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+
+[HAL]
+HALFILE = scorbot.hal
+
+[EMCMOT]
+EMCMOT = motmod
+SERVO_PERIOD = 1000000
+
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.010