From 95cb7d15dcd634fb8f4a37b8b6bf6080735dac08 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Tue, 11 Aug 2026 17:07:11 +1000 Subject: [PATCH 1/9] G12.1, G13.1: select kinematics from G-code G12.1 P- selects one of the kinematics offered by a switchable kinematics module and G13.1 cancels back to kinematics 0. Both are queue synchronisation points, so no motion is ever planned in one kinematics and executed in another. Until now the only way to switch from a program was to write motion.switchkins-type through an analog output and force a sync by hand, typically M68 E3 Q1 followed by M66 E0 L0, wrapped in a subroutine or a remapped M-code. That also costs the #5399 variable on every switch, because M66 writes it. G13.1 cancels to kinematics 0 rather than restoring whatever was selected before, which is how every other cancel in the language behaves and keeps a block's meaning independent of the path taken through the program. To put back a caller's selection, read #<_kins_type>: # = #<_kins_type> G12.1 P2 ( ... ) G12.1 P# Nothing cancels the selection implicitly. It survives program end and abort so that the kinematics keeps matching the position readout, since switching re-derives world position from the joints and would otherwise move the readout while the machine stands still. Motion takes the G-code request and the motion.switchkins-type pin on their edges, so whichever asked most recently wins and a config can use either or both. Writing the pin from motion instead does not work: the configs source it from an analog output that would put its own value back on the next servo cycle. motion.kins-type reports the selection now in force. Q was parsed and carried all the way to motion without anything ever reading it, so it is gone. EMC_ADJUST_KINS_OFFSET_DATA is registered in the NML format and name tables and has the update() its declaration promised, without which the message could not cross the channel. --- docs/src/gcode/g-code.adoc | 61 ++++++++++++++++++++ docs/src/gcode/overview.adoc | 4 ++ docs/src/man/man9/motion.9.adoc | 6 ++ docs/src/motion/switchkins.adoc | 77 ++++++++++++++++++++------ src/emc/motion/command.c | 10 ++++ src/emc/motion/control.c | 26 ++++++++- src/emc/motion/mot_priv.h | 1 + src/emc/motion/motion.c | 1 + src/emc/motion/motion.h | 10 ++++ src/emc/nml_intf/canon.hh | 3 + src/emc/nml_intf/emc.cc | 12 ++++ src/emc/nml_intf/emc.hh | 5 +- src/emc/nml_intf/emc_nml.hh | 20 ++++++- src/emc/nml_intf/emcops.cc | 5 +- src/emc/rs274ngc/gcodemodule.cc | 7 +++ src/emc/rs274ngc/interp_array.cc | 2 +- src/emc/rs274ngc/interp_check.cc | 9 ++- src/emc/rs274ngc/interp_convert.cc | 38 ++++++++++++- src/emc/rs274ngc/interp_execute.cc | 3 + src/emc/rs274ngc/interp_internal.hh | 4 ++ src/emc/rs274ngc/interp_namedparams.cc | 8 +++ src/emc/rs274ngc/interp_setup.cc | 2 + src/emc/rs274ngc/rs274ngc_interp.hh | 1 + src/emc/rs274ngc/rs274ngc_pre.cc | 9 +++ src/emc/rs274ngc/rs274ngc_return.hh | 3 + src/emc/sai/saicanon.cc | 8 +++ src/emc/task/emccanon.cc | 11 ++++ src/emc/task/emctaskmain.cc | 27 +++++++++ src/emc/task/taskintf.cc | 13 +++++ tests/remap/introspect/expected | 4 +- 30 files changed, 363 insertions(+), 27 deletions(-) diff --git a/docs/src/gcode/g-code.adoc b/docs/src/gcode/g-code.adoc index 4670688041d..bcaeb998dc0 100644 --- a/docs/src/gcode/g-code.adoc +++ b/docs/src/gcode/g-code.adoc @@ -70,6 +70,7 @@ as the 'L number', and so on for any other letter. |<> |Set Tool Table, Calculated, Fixture |<> |Coordinate System Origin Setting |<> |Coordinate System Origin Setting Calculated +|<> |Select Kinematics |<> |Plane Select |<> |Set Units of Measure |<> |Go to Predefined Position @@ -934,6 +935,66 @@ It is an error if: * The P number does not evaluate to an integer in the range 0 to 9. * An axis is programmed that is not defined in the configuration. +[[gcode:g12.1-g13.1]] +== G12.1, G13.1 Select Kinematics(((G12.1, G13.1 Select Kinematics))) + +---- +G12.1 P- +G13.1 +---- + +'G12.1' selects one of the kinematics provided by a switchable kinematics +module, and 'G13.1' cancels back to kinematics 0. The 'P' word is the +kinematics number, the same number that the `motion.switchkins-type` pin +takes, so 'G13.1' and `G12.1 P0` do the same thing. A config may select +the kinematics from G-code, from that pin, or from both: each is acted on +when it changes, so the most recent request is the one in force. + +Both codes are queue synchronisation points. The interpreter waits for +queued motion to finish before the kinematics changes, so no move is ever +planned in one kinematics and executed in another. Because of that, both +codes stop any blending that was in progress, in the same way 'G4' does. + +The kinematics module decides what each number means. See the +`switchkins` section of the kins(9) man page for the modules that support +switching and the order in which they list their kinematics. A machine +whose kinematics module is not switchable rejects the change. + +Selecting a kinematics does not move the machine. It changes how joint +positions and coordinate positions map onto each other, so the position +readout can change even though nothing has moved. + +The active kinematics is available to the program as the read-only +parameter '#<_kins_type>', which lets a subroutine put back whatever was +selected before it ran: + +[source,ngc] +---- +# = #<_kins_type> +G12.1 P2 (work in kinematics 2) +( ... ) +G12.1 P# (put back whatever the caller was using) +---- + +Nothing cancels the selection on its own. It survives the end of the +program and an abort, so that the kinematics keeps matching what the +position readout shows. End a program with 'G13.1' if it should leave the +machine in kinematics 0. + +.G12.1, G13.1 Example +[source,ngc] +---- +G12.1 P1 (switch to kinematics 1) +G0 X0 Y0 +G13.1 (back to kinematics 0) +---- + +It is an error if: + +* 'G12.1' is used without a 'P' word. +* The 'P' word is negative. +* A 'P' word is used with 'G13.1'. + [[gcode:g17-g19.1]] == G17 - G19.1 Plane Select(((G17 - G19.1 Plane Select))) diff --git a/docs/src/gcode/overview.adoc b/docs/src/gcode/overview.adoc index 683f72cc154..4ed0ec7c73d 100644 --- a/docs/src/gcode/overview.adoc +++ b/docs/src/gcode/overview.adoc @@ -503,6 +503,10 @@ can be added easily without changes to the source code. | G89 | 890 |=== +* '#<_kins_type>' - Kinematics selected by 'G12.1' or 'G13.1'. Returns the + 'P' number of the last 'G12.1', or 0 after 'G13.1' or when no kinematics + has been selected. See <>. + * '#<_plane>' - returns the value designating the current plane: [width="20%",options="header"] diff --git a/docs/src/man/man9/motion.9.adoc b/docs/src/man/man9/motion.9.adoc index 43859fcef14..8b1c78a936e 100644 --- a/docs/src/man/man9/motion.9.adoc +++ b/docs/src/man/man9/motion.9.adoc @@ -256,6 +256,12 @@ Note: feed-inhibit applies to G-code commands -- not jogs. select the machine kinematics functions. Extra G-code commands may be required to synchronize task and motion before and after changes to the pin value. + The G-code words *G12.1 P-* and *G13.1* write this pin and synchronize + task and motion themselves, so a program that uses them needs no such + extra commands. +*motion.kins-type* OUT float:: + The kinematics currently selected, echoing the value that was last + applied from *motion.switchkins-type*. *motion.teleop-mode* OUT BIT:: Motion mode is teleop (axis coordinate jogging available). *motion.tooloffset.L* OUT FLOAT:: diff --git a/docs/src/motion/switchkins.adoc b/docs/src/motion/switchkins.adoc index a250825cd3e..d02633d1515 100644 --- a/docs/src/motion/switchkins.adoc +++ b/docs/src/motion/switchkins.adoc @@ -20,17 +20,18 @@ specific kinematics calculations for most operations but can be switched to identity kinematics for control of individual joints after homing. -The kinematics type is selected by a motion module HAL pin that -can be updated from a G-code program or by interactive MDI -commands. The halui provisions for activating MDI commands can be -used to allow buttons to select the kinematics type using -hardware controls or a virtual panel (PyVCP, GladeVCP, etc.). - -When a kinematics type is changed, the G-code must also issue -commands to *force synchronization* of the interpreter and motion -parts of LinuxCNC. Typically, a HAL pin 'read' command (M66 E0 L0) is -used immediately after altering the controlling HAL pin to force -synchronization. +The kinematics type is selected with 'G12.1 P-' and 'G13.1', from a +G-code program or by interactive MDI commands. It can also be selected +by a motion module HAL pin, which allows the halui provisions for +activating MDI commands to be used so that buttons select the +kinematics type from hardware controls or a virtual panel (PyVCP, +GladeVCP, etc.). + +Changing the kinematics type requires the interpreter and motion parts +of LinuxCNC to be *synchronized*. 'G12.1' and 'G13.1' do this +themselves. When the HAL pin is written instead, the G-code must force +synchronization, typically with a HAL pin 'read' command (M66 E0 L0) +immediately after altering the pin. == Switchable Kinematic Modules @@ -124,6 +125,7 @@ program behavior in accordance with the active kinematics type. === HAL Pin Summary . *motion.switchkins-type* Input (float) +. *motion.kins-type* Output (float) . *kinstype.is-0* Output (bit) . *kinstype.is-1* Output (bit) . *kinstype.is-2* Output (bit) @@ -136,9 +138,10 @@ A module providing more than three kinematics types has one === HAL Connections Switchkins functionality is enabled by the pin -*motion.switchkins-type*. Typically, this pin is sourced by an -analog output pin like motion.analog-out-03 so that it can be -set by M68 commands. Example: +*motion.switchkins-type*, which 'G12.1' and 'G13.1' write directly. +To select a kinstype from HAL instead, source the pin from an analog +output pin like motion.analog-out-03 so that it can be set by M68 +commands. Example: [source,hal] ---- @@ -146,9 +149,51 @@ net :kinstype-select <= motion.analog-out-03 net :kinstype-select => motion.switchkins-type ---- -=== G-/M-code commands +=== G-code commands -Kinstype selection is managed using G-code sequences like: +'G12.1 P-' selects a kinstype and 'G13.1' cancels back to kinstype 0: + +[source,ngc] +---- +... +G12.1 P1 ;select kinstype 1 +... +... ;user G-code +... +G13.1 ;back to kinstype 0 +... +---- + +These codes ask motion for the kinstype directly and synchronize task and +motion themselves, so no HAL connection and no separate sync command are +needed. The G-code words and the *motion.switchkins-type* pin are both +acted on when they change, so whichever asked most recently is the one in +force, and a config can use either or both. *motion.kins-type* reports +what is currently selected. + +The kinstype in force is readable in G-code as '#<_kins_type>', which lets +a subroutine restore whatever its caller had selected: + +[source,ngc] +---- +# = #<_kins_type> +G12.1 P2 +( ... ) +G12.1 P# +---- + +Selection is not cancelled by the end of a program or by an abort, so +that the kinstype continues to match the position readout. A program +that should leave the machine in kinstype 0 ends with 'G13.1'. + +See the G-code documentation for 'G12.1' and 'G13.1' for the full +description. + +=== M-code commands + +A kinstype can also be selected by writing *motion.switchkins-type* +through an analog output pin, which needs the HAL connection shown +above. Kinstype selection is then managed using G-code sequences like: [source,ngc] ---- diff --git a/src/emc/motion/command.c b/src/emc/motion/command.c index 8905ad05d13..1a48585fb5e 100644 --- a/src/emc/motion/command.c +++ b/src/emc/motion/command.c @@ -2054,6 +2054,16 @@ void emcmotCommandHandler_locked(void *arg, long servo_period) axis_set_locking_joint(emcmotCommand->axis, joint_num); break; + case EMCMOT_ADJUST_KINS_OFFSET_DATA: + emcmotConfig->adjustKinsVar0 = emcmotCommand->adjustKinsVar0; + if(emcmotConfig->kinsType == 'r'){ + emcmotConfig->kinsType = 's'; + } + else{ + emcmotConfig->kinsType = 'r'; + } + break; + default: rtapi_print_msg(RTAPI_MSG_DBG, "UNKNOWN"); reportError(_("unrecognized command %d"), emcmotCommand->command); diff --git a/src/emc/motion/control.c b/src/emc/motion/control.c index 593c337e071..14842dd9dc7 100644 --- a/src/emc/motion/control.c +++ b/src/emc/motion/control.c @@ -301,12 +301,34 @@ static bool joint_jog_is_active(void) { static void handle_kinematicsSwitch(void) { int joint_num; int hal_switchkins_type = 0; + static int prev_hal_switchkins_type = 0; + int requested_type; if (!kinematicsSwitchable()) return; + + /* Two things can ask for a kinematics: G12.1/G13.1, and the + motion.switchkins-type pin. Both are taken on their edge, so that + whichever asked most recently wins. Writing the pin here instead + would not work: configs source it from an analog output, which + would put its own value back on the next servo cycle. */ hal_switchkins_type = (int)hal_get_real(emcmot_hal_data->switchkins_type); - if (switchkins_type == hal_switchkins_type) return; + requested_type = switchkins_type; + + if (emcmotStatus->kinsType != emcmotConfig->kinsType) { + requested_type = (int)emcmotConfig->adjustKinsVar0; + emcmotStatus->kinsType = emcmotConfig->kinsType; + } else if (hal_switchkins_type != prev_hal_switchkins_type) { + requested_type = hal_switchkins_type; + } + prev_hal_switchkins_type = hal_switchkins_type; + + hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); + emcmotStatus->adjustKinsVar0 = switchkins_type; + if (switchkins_type == requested_type) return; - switchkins_type = hal_switchkins_type; + switchkins_type = requested_type; + hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); + emcmotStatus->adjustKinsVar0 = switchkins_type; emcmot_joint_t *jointKinsSwitch; double joint_posKinsSwitch[EMCMOT_MAX_JOINTS] = {0,}; diff --git a/src/emc/motion/mot_priv.h b/src/emc/motion/mot_priv.h index 64cbb507132..a996e183fa6 100644 --- a/src/emc/motion/mot_priv.h +++ b/src/emc/motion/mot_priv.h @@ -198,6 +198,7 @@ typedef struct { hal_real_t feed_mm_per_second; /* feed mm per second*/ hal_real_t switchkins_type; + hal_real_t kins_type; /* Interp State Pins */ hal_sint_t interp_line_number; hal_sint_t interp_motion_type; diff --git a/src/emc/motion/motion.c b/src/emc/motion/motion.c index d2cb7615958..9a7985902fe 100644 --- a/src/emc/motion/motion.c +++ b/src/emc/motion/motion.c @@ -661,6 +661,7 @@ static int init_hal_io(void) if (kinematicsSwitchable()) { CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_IN, &(emcmot_hal_data->switchkins_type), 0.0, "motion.switchkins-type")); + CALL_CHECK(hal_pin_new_real(mot_comp_id, HAL_OUT, &(emcmot_hal_data->kins_type), 0.0, "motion.kins-type")); } /* export spindle pins and params */ diff --git a/src/emc/motion/motion.h b/src/emc/motion/motion.h index aad1d345730..fb36c96f278 100644 --- a/src/emc/motion/motion.h +++ b/src/emc/motion/motion.h @@ -176,6 +176,8 @@ extern "C" { EMCMOT_SET_AXIS_LOCKING_JOINT, /* set the axis locking joint */ EMCMOT_SET_AXIS_JERK_LIMIT, /* set the max axis jerk */ + EMCMOT_ADJUST_KINS_OFFSET_DATA, /* set the offset in kins (G12.1) */ + EMCMOT_SET_SPINDLE_PARAMS, /* One command to set all spindle params */ } cmd_code_t; @@ -270,6 +272,8 @@ extern "C" { double ext_offset_vel; /* velocity for an external axis offset */ double ext_offset_acc; /* acceleration for an external axis offset */ struct state_tag_t tag; + + double adjustKinsVar0; } emcmot_command_t; /*! \todo FIXME - these packed bits might be replaced with chars @@ -667,6 +671,9 @@ Suggestion: Split this in to an Error and a Status flag register.. int numExtraJoints; int stepping; bool jogging_active; + + char kinsType; + double adjustKinsVar0; } emcmot_status_t; /********************************* @@ -738,6 +745,9 @@ Suggestion: Split this in to an Error and a Status flag register.. double maxFeedScale; int inhibit_probe_jog_error; int inhibit_probe_home_error; + + double adjustKinsVar0; + char kinsType; } emcmot_config_t; /* error structure - lockfree MPSC ring buffer. See emcmotutil.c. */ diff --git a/src/emc/nml_intf/canon.hh b/src/emc/nml_intf/canon.hh index 31cbb3cb3c8..9b5276b3916 100644 --- a/src/emc/nml_intf/canon.hh +++ b/src/emc/nml_intf/canon.hh @@ -1070,4 +1070,7 @@ extern int GET_EXTERNAL_OFFSET_APPLIED(); extern EmcPose GET_EXTERNAL_OFFSETS(); extern void UPDATE_TAG(const StateTag& tag); +// adjust kins offset (G12.1 kinematics switch) +extern void ADJUST_KINS_OFFSET(double adjustKinsVar0); + #endif /* ifndef CANON_HH */ diff --git a/src/emc/nml_intf/emc.cc b/src/emc/nml_intf/emc.cc index 0374a196a1f..3ae7134c4d6 100644 --- a/src/emc/nml_intf/emc.cc +++ b/src/emc/nml_intf/emc.cc @@ -298,6 +298,9 @@ int emcFormat(NMLTYPE type, void *buffer, CMS * cms) case EMC_TRAJ_SET_OFFSET_TYPE: ((EMC_TRAJ_SET_OFFSET *) buffer)->update(cms); break; + case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + ((EMC_ADJUST_KINS_OFFSET_DATA *) buffer)->update(cms); + break; case EMC_TRAJ_SET_G5X_TYPE: ((EMC_TRAJ_SET_G5X *) buffer)->update(cms); break; @@ -522,6 +525,8 @@ const char *emc_symbol_lookup(uint32_t type) return "EMC_TRAJ_SET_MODE"; case EMC_TRAJ_SET_OFFSET_TYPE: return "EMC_TRAJ_SET_OFFSET"; + case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + return "EMC_ADJUST_KINS_OFFSET_DATA"; case EMC_TRAJ_SET_G5X_TYPE: return "EMC_TRAJ_SET_G5X"; case EMC_TRAJ_SET_G92_TYPE: @@ -1593,6 +1598,13 @@ void EMC_TRAJ_SET_OFFSET::update(CMS * cms) EmcPose_update(cms, &offset); } +// cppcheck-suppress duplInheritedMember +void EMC_ADJUST_KINS_OFFSET_DATA::update(CMS * cms) +{ + EMC_TRAJ_CMD_MSG::update(cms); + cms->update(adjustKinsVar0); +} + /* * NML/CMS Update function for EMC_TRAJ_CMD_MSG * Automatically generated by NML CodeGen Java Applet. diff --git a/src/emc/nml_intf/emc.hh b/src/emc/nml_intf/emc.hh index b70fc4504a7..be1d6e9739b 100644 --- a/src/emc/nml_intf/emc.hh +++ b/src/emc/nml_intf/emc.hh @@ -112,6 +112,7 @@ struct PM_CARTESIAN; #define EMC_TRAJ_SET_FH_ENABLE_TYPE ((NMLTYPE) 236) #define EMC_TRAJ_RIGID_TAP_TYPE ((NMLTYPE) 237) +#define EMC_ADJUST_KINS_OFFSET_DATA_TYPE ((NMLTYPE) 289) #define EMC_TRAJ_STAT_TYPE ((NMLTYPE) 299) // EMC_MOTION aggregate class type declaration @@ -214,7 +215,8 @@ enum class EMC_TASK_EXEC { WAITING_FOR_MOTION_AND_IO = 7, WAITING_FOR_DELAY = 8, WAITING_FOR_SYSTEM_CMD = 9, - WAITING_FOR_SPINDLE_ORIENTED = 10 + WAITING_FOR_SPINDLE_ORIENTED = 10, + WAITING_FOR_KINS_SWITCH = 11 }; // types for EMC_TASK interpState @@ -460,6 +462,7 @@ int emcSetupArcBlends(int arcBlendEnable, int emcSetProbeErrorInhibit(int j_inhibit, int h_inhibit); int emcGetExternalOffsetApplied(void); EmcPose emcGetExternalOffsets(void); +extern int emcAdjustKinsOffset(double adjustKinsVar0); extern int emcUpdate(EMC_STAT * stat); // full EMC status diff --git a/src/emc/nml_intf/emc_nml.hh b/src/emc/nml_intf/emc_nml.hh index 717de3ce619..9e17c10f1d4 100644 --- a/src/emc/nml_intf/emc_nml.hh +++ b/src/emc/nml_intf/emc_nml.hh @@ -960,13 +960,27 @@ class EMC_TRAJ_RIGID_TAP:public EMC_TRAJ_CMD_MSG { double vel, ini_maxvel, acc, scale, ini_maxjerk; }; +class EMC_ADJUST_KINS_OFFSET_DATA:public EMC_TRAJ_CMD_MSG { + public: + EMC_ADJUST_KINS_OFFSET_DATA():EMC_TRAJ_CMD_MSG(EMC_ADJUST_KINS_OFFSET_DATA_TYPE, + sizeof(EMC_ADJUST_KINS_OFFSET_DATA)), + adjustKinsVar0(0.0) + {}; + + double adjustKinsVar0; + + // For internal NML/CMS use only. + // Sub-class update() calls base-class update() + // cppcheck-suppress duplInheritedMember + void update(CMS * cms); +}; + // EMC_TRAJ status base class class EMC_TRAJ_STAT_MSG:public RCS_STAT_MSG { public: EMC_TRAJ_STAT_MSG(NMLTYPE t, size_t s) : RCS_STAT_MSG(t, s) {}; - // For internal NML/CMS use only. void update(CMS * cms); }; @@ -1167,6 +1181,10 @@ class EMC_MOTION_STAT:public EMC_MOTION_STAT_MSG { int numExtraJoints; bool jogging_active; uint64_t heartbeat; // motion controller's heartbeat counter + + char trajKinsType; + bool trajKinsTypeModified; + double adjustKinsVar0; }; // declarations for EMC_TASK classes diff --git a/src/emc/nml_intf/emcops.cc b/src/emc/nml_intf/emcops.cc index d58c87c637a..ee99dcce6fd 100644 --- a/src/emc/nml_intf/emcops.cc +++ b/src/emc/nml_intf/emcops.cc @@ -112,7 +112,10 @@ EMC_MOTION_STAT::EMC_MOTION_STAT() eoffset_pose{}, numExtraJoints(0), jogging_active(0), - heartbeat(0) + heartbeat(0), + trajKinsType(0), + trajKinsTypeModified(false), + adjustKinsVar0(0.0) { } diff --git a/src/emc/rs274ngc/gcodemodule.cc b/src/emc/rs274ngc/gcodemodule.cc index a6114cf1808..9034c036a86 100644 --- a/src/emc/rs274ngc/gcodemodule.cc +++ b/src/emc/rs274ngc/gcodemodule.cc @@ -892,6 +892,13 @@ void ON_RESET() {} void PALLET_SHUTTLE() {} void SELECT_TOOL(int tool) {selected_tool = tool;} void UPDATE_TAG(const StateTag& /*tag*/) {} +void ADJUST_KINS_OFFSET(double adjustKinsVar0) +{ + (void)adjustKinsVar0; + printf("gcodemodule: ADJUST_KINS_OFFSET\n"); + + return; +} void OPTIONAL_PROGRAM_STOP() {} int GET_EXTERNAL_TC_FAULT() {return 0;} int GET_EXTERNAL_TC_REASON() {return 0;} diff --git a/src/emc/rs274ngc/interp_array.cc b/src/emc/rs274ngc/interp_array.cc index e33cb4b565f..7a41740ca2b 100644 --- a/src/emc/rs274ngc/interp_array.cc +++ b/src/emc/rs274ngc/interp_array.cc @@ -77,7 +77,7 @@ const int Interp::gees[] = { /* 60 */ 1, 1, 1, 0,-1,-1,-1,-1,-1,-1,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, // jjf added G6 /* 80 */ 15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 100 */ 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 120 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +/* 120 */ -1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,-1, /* 140 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 160 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1, /* 180 */ 2, 2,-1,-1,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1, diff --git a/src/emc/rs274ngc/interp_check.cc b/src/emc/rs274ngc/interp_check.cc index 196f2772763..40a1fe152fd 100644 --- a/src/emc/rs274ngc/interp_check.cc +++ b/src/emc/rs274ngc/interp_check.cc @@ -109,6 +109,11 @@ int Interp::check_g_codes(block_pointer block, //!< pointer to a block to be c (settings->distance_mode == DISTANCE_MODE::INCREMENTAL))), NCE_CANNOT_USE_G53_INCREMENTAL); } else if (mode0 == G_92) { + } else if (mode0 == G_12_1){ + // kins-switch + CHKS((!block->p_flag), NCE_P_WORD_MISSING_WITH_G121); + } else if (mode0 == G_13_1){ + // kins-switch cancel: no words, the kinematics goes back to 0 } else ERS(NCE_BUG_BAD_G_CODE_MODAL_GROUP_0); return INTERP_OK; @@ -319,7 +324,7 @@ int Interp::check_other_codes(block_pointer block) //!< pointer to a block } if (block->p_flag) { - CHKS(((block->g_modes[GM_MODAL_0] != G_10) && (block->g_modes[GM_MODAL_0] != G_4) && (block->g_modes[GM_CONTROL_MODE] != G_64) && + CHKS(((block->g_modes[GM_MODAL_0] != G_10) && (block->g_modes[GM_MODAL_0] != G_4) && (block->g_modes[GM_CONTROL_MODE] != G_64 && (block->g_modes[GM_MODAL_0] != G_12_1)) && (motion != G_76) && (motion != G_82) && (motion != G_86) && (motion != G_88) && (motion != G_89) && (motion != G_5) && (motion != G_5_2) && (motion != G_70) && @@ -331,7 +336,7 @@ int Interp::check_other_codes(block_pointer block) //!< pointer to a block (block->m_modes[5] != 64) && (block->m_modes[5] != 65) && (block->m_modes[5] != 66) && (block->m_modes[7] != 19) && (block->user_m != 1) && (block->o_type != M_98)), - _("P word with no G2 G3 G4 G10 G64 G5 G5.2 G6, G6.2, G76 G82 G86 G88 G89" + _("P word with no G2 G3 G4 G10 G12.1 G64 G5 G5.2 G6, G6.2, G76 G82 G86 G88 G89" " or M50 M51 M52 M53 M62 M63 M64 M65 M66 M98 " "or user M code to use it")); int p_value = round_to_int(block->p_number); diff --git a/src/emc/rs274ngc/interp_convert.cc b/src/emc/rs274ngc/interp_convert.cc index 638e87eb0c3..7ca5ab6513c 100644 --- a/src/emc/rs274ngc/interp_convert.cc +++ b/src/emc/rs274ngc/interp_convert.cc @@ -4351,7 +4351,11 @@ int Interp::convert_modal_0(int code, //!< G-code, must be from group 0 CHP(convert_axis_offsets(code, block, settings)); } else if ((code == G_5_3)||(code == G_6_3)) { // jjf CHP(convert_nurbs(code, block, settings)); - } else if ((code == G_4) || (code == G_53)); // handled elsewhere + } else if ((code == G_4) || (code == G_53)); // handled elsewhere + else if ((code == G_12_1) || (code == G_13_1)) { + settings->kinsSwitch_flag = true; + CHP(convert_kins_switch(code, block, settings)); + } else ERS(NCE_BUG_CODE_NOT_G4_G10_G28_G30_G52_G53_OR_G92_SERIES); return INTERP_OK; @@ -6490,6 +6494,38 @@ int Interp::convert_tool_select(block_pointer block, //!< pointer to a block return INTERP_OK; } +/*! convert_kins_switch + +Returned Value: int (INTERP_OK) + +Side effects: + The selected kinematics is sent to the motion controller and recorded + in the interpreter so that #<_kins_type> reports it. + +Called by: convert_modal_0 + +G12.1 P- selects a kinematics; G13.1 cancels back to kinematics 0, which +is the same thing as G12.1 P0 and exists so that the pair reads the way +it does on other controls. Both are queue synchronisation points: the +caller sets kinsSwitch_flag, which makes the interpreter wait for motion +to drain before the switch takes effect, so no motion is ever planned +across a change of kinematics. + +*/ + +int Interp::convert_kins_switch(int code, //!< G_12_1 or G_13_1 + block_pointer block, //!< pointer to a block of RS274 instructions + setup_pointer settings) //!< pointer to machine settings +{ + int kins_type = (code == G_13_1) ? 0 : round_to_int(block->p_number); + + CHKS((kins_type < 0), _("G12.1 requires a non-negative P word")); + + ADJUST_KINS_OFFSET((double)kins_type); + settings->kins_type = kins_type; + return INTERP_OK; +} + int Interp::update_tag(StateTag &tag) { diff --git a/src/emc/rs274ngc/interp_execute.cc b/src/emc/rs274ngc/interp_execute.cc index e30635d8810..5863fc168e9 100644 --- a/src/emc/rs274ngc/interp_execute.cc +++ b/src/emc/rs274ngc/interp_execute.cc @@ -325,6 +325,9 @@ int Interp::execute_block(block_pointer block, //!< pointer to a block of RS27 if (settings->toolchange_flag) return (INTERP_EXECUTE_FINISH); + if (settings->kinsSwitch_flag) + return (INTERP_EXECUTE_FINISH); + // All changes to settings are complete write_canon_state_tag(block, settings); return INTERP_OK; diff --git a/src/emc/rs274ngc/interp_internal.hh b/src/emc/rs274ngc/interp_internal.hh index 22268854211..0069c1f178f 100644 --- a/src/emc/rs274ngc/interp_internal.hh +++ b/src/emc/rs274ngc/interp_internal.hh @@ -211,6 +211,8 @@ enum GCodes G_7 = 70, G_8 = 80, G_10 = 100, + G_12_1 = 121, + G_13_1 = 131, G_17 = 170, G_17_1 = 171, G_18 = 180, @@ -747,6 +749,8 @@ struct setup CANON_PLANE plane; // active plane, XY-, YZ-, or XZ-plane bool probe_flag; // flag indicating probing done bool input_flag; // flag indicating waiting for input done + bool kinsSwitch_flag; // flag indicating waiting for kinematics switch done + int kins_type; // kinematics selected by G12.1/G13.1 bool toolchange_flag; // flag indicating we just had a tool change int input_index; // channel queried bool input_digital; // input queried was digital (false=analog) diff --git a/src/emc/rs274ngc/interp_namedparams.cc b/src/emc/rs274ngc/interp_namedparams.cc index d0f2d4b8b63..fb12f1e8d26 100644 --- a/src/emc/rs274ngc/interp_namedparams.cc +++ b/src/emc/rs274ngc/interp_namedparams.cc @@ -58,6 +58,7 @@ using namespace linuxcnc; enum predefined_named_parameters { NP_LINE, NP_MOTION_MODE, + NP_KINS_TYPE, NP_PLANE, NP_CCOMP, NP_METRIC, @@ -541,6 +542,10 @@ int Interp::lookup_named_param(const char *nameBuf, *value = _setup.motion_mode; break; + case NP_KINS_TYPE: // _kins_type + *value = _setup.kins_type; + break; + case NP_PLANE: // _plane switch(_setup.plane) { case CANON_PLANE::XY: @@ -890,6 +895,9 @@ int Interp::init_named_parameters() init_readonly_param("_motion_mode", NP_MOTION_MODE, PA_USE_LOOKUP); + // kinematics selected by G12.1 P- / G13.1, 0 when none has been selected + init_readonly_param("_kins_type", NP_KINS_TYPE, PA_USE_LOOKUP); + // G17/18/19/17.1/18.1/19.1 -> return 170/180/190/171/181/191 init_readonly_param("_plane", NP_PLANE, PA_USE_LOOKUP); diff --git a/src/emc/rs274ngc/interp_setup.cc b/src/emc/rs274ngc/interp_setup.cc index 365e4682d6c..29161513258 100644 --- a/src/emc/rs274ngc/interp_setup.cc +++ b/src/emc/rs274ngc/interp_setup.cc @@ -116,6 +116,8 @@ setup::setup() : plane(CANON_PLANE::XY), probe_flag(0), input_flag(0), + kinsSwitch_flag(0), + kins_type(0), toolchange_flag(0), input_index(0), input_digital(0), diff --git a/src/emc/rs274ngc/rs274ngc_interp.hh b/src/emc/rs274ngc/rs274ngc_interp.hh index ebf77786fd9..e4e70cf2264 100644 --- a/src/emc/rs274ngc/rs274ngc_interp.hh +++ b/src/emc/rs274ngc/rs274ngc_interp.hh @@ -356,6 +356,7 @@ public: int convert_tool_length_offset(int g_code, block_pointer block, setup_pointer settings); int convert_tool_select(block_pointer block, setup_pointer settings); + int convert_kins_switch(int code, block_pointer block, setup_pointer settings); int update_tag(StateTag &tag); int cycle_feed(block_pointer block, CANON_PLANE plane, double end1, double end2, double end3); diff --git a/src/emc/rs274ngc/rs274ngc_pre.cc b/src/emc/rs274ngc/rs274ngc_pre.cc index 54212aa1850..16208923637 100644 --- a/src/emc/rs274ngc/rs274ngc_pre.cc +++ b/src/emc/rs274ngc/rs274ngc_pre.cc @@ -1196,6 +1196,7 @@ int Interp::init() _setup.probe_flag = false; _setup.toolchange_flag = false; _setup.input_flag = false; + _setup.kinsSwitch_flag = false; _setup.input_index = -1; _setup.input_digital = false; _setup.program_x = 0.; /* for cutter comp */ @@ -1477,6 +1478,13 @@ int Interp::read_inputs(setup_pointer settings) } settings->input_flag = false; } + + if( settings->kinsSwitch_flag ){ + CHKS((GET_EXTERNAL_QUEUE_EMPTY() == 0), NCE_QUEUE_IS_NOT_EMPTY_AFTER_KINS_SWITCH); + + settings->kinsSwitch_flag = false; + } + return INTERP_OK; } @@ -2677,6 +2685,7 @@ int Interp::on_abort(int reason, const char *message) _setup.toolchange_flag = false; _setup.probe_flag = false; _setup.input_flag = false; + _setup.kinsSwitch_flag = false; if (_setup.on_abort_command == NULL) { return -1; diff --git a/src/emc/rs274ngc/rs274ngc_return.hh b/src/emc/rs274ngc/rs274ngc_return.hh index 9f6d8674b84..3cd733da7f3 100644 --- a/src/emc/rs274ngc/rs274ngc_return.hh +++ b/src/emc/rs274ngc/rs274ngc_return.hh @@ -196,6 +196,8 @@ #define NCE_CANNOT_CHANGE_PLANES_WITH_CUTTER_RADIUS_COMP_ON _("Cannot change planes with cutter radius compensation on") #define NCE_RADIUS_COMP_ONLY_IN_XY_OR_XZ _("Cutter radius compensation allowed only in XY, XZ planes") #define NCE_P_WORD_MISSING_WITH_G76 _("P word missing with G76") +#define NCE_P_WORD_MISSING_WITH_G121 _("P word missing with G12.1") +#define NCE_Q_WORD_MISSING_WITH_G121 _("Q word missing with G12.1") #define NCE_I_J_OR_K_WORDS_MISSING_WITH_G76 _("I J or K words missing with G76") #define NCE_CANNOT_MOVE_ROTARY_AXES_WITH_G76 _("Cannot move rotary axes with G76") #define NCE_MULTIPLE_E_WORDS_ON_ONE_LINE _("Multiple e words on one line") @@ -203,6 +205,7 @@ #define NCE_OUT_OF_MEMORY _("Out of memory") #define NCE_S_WORD_MISSING_WITH_G96 _("S word missing with G96") #define NCE_QUEUE_IS_NOT_EMPTY_AFTER_INPUT _("Queue is not empty after external input") +#define NCE_QUEUE_IS_NOT_EMPTY_AFTER_KINS_SWITCH _("Queue is not empty after Kinematics Switch") #define NCE_ANALOG_INPUT_WITH_WAIT_NOT_IMMEDIATE _("Can't select analog input with wait type != immediate return") #define NCE_ZERO_TIMEOUT_WITH_WAIT_NOT_IMMEDIATE _("Zero timeout with wait type != immediate return") #define NCE_BOTH_DIGITAL_AND_ANALOG_INPUT_SELECTED _("Invalid to select both a digital and an analog input with M66") diff --git a/src/emc/sai/saicanon.cc b/src/emc/sai/saicanon.cc index 8bbc3a6387c..8477ff730c9 100644 --- a/src/emc/sai/saicanon.cc +++ b/src/emc/sai/saicanon.cc @@ -1192,3 +1192,11 @@ StandaloneInterpInternals::StandaloneInterpInternals() : void UPDATE_TAG(const StateTag& /*tag*/){ //Do nothing } + +void ADJUST_KINS_OFFSET(double adjustKinsVar0) +{ + (void)adjustKinsVar0; + printf("saicanon: ADJUST_KINS_OFFSET\n"); + + return; +} diff --git a/src/emc/task/emccanon.cc b/src/emc/task/emccanon.cc index 21815adad51..aa1cf1c7693 100644 --- a/src/emc/task/emccanon.cc +++ b/src/emc/task/emccanon.cc @@ -1206,6 +1206,17 @@ void ON_RESET() { drop_segments(); } +void ADJUST_KINS_OFFSET(double adjustKinsVar0) +{ + flush_segments(); + + auto adjustKinsOffsetMsg = std::make_unique(); + + adjustKinsOffsetMsg->adjustKinsVar0 = adjustKinsVar0; + + interp_list.append(std::move(adjustKinsOffsetMsg)); +} + CanonConfig_t& get_canon(){ return canon; diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index ff0978fe922..e8b2488018b 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -418,6 +418,8 @@ static EMC_AUX_INPUT_WAIT *emcAuxInputWaitMsg; static int emcAuxInputWaitType = 0; static int emcAuxInputWaitIndex = -1; +static EMC_ADJUST_KINS_OFFSET_DATA *kSwitch_msg; + // commands we compose here static EMC_TASK_PLAN_RUN taskPlanRunCmd; // 16-Aug-1999 FMP //static EMC_TASK_PLAN_INIT taskPlanInitCmd; @@ -1605,6 +1607,10 @@ static EMC_TASK_EXEC emcTaskCheckPreconditions(NMLmsg * cmd) return EMC_TASK_EXEC::WAITING_FOR_MOTION; break; + case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + return EMC_TASK_EXEC::WAITING_FOR_MOTION_AND_IO; + break; + default: // unrecognized command if (emc_debug & EMC_DEBUG_TASK_ISSUE) { @@ -2427,6 +2433,12 @@ static int emcTaskIssueCommand(NMLmsg * cmd) retval = 0; break; + case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + kSwitch_msg = (EMC_ADJUST_KINS_OFFSET_DATA *) cmd; + emcStatus->motion.adjustKinsVar0 = kSwitch_msg->adjustKinsVar0; + retval = emcAdjustKinsOffset(kSwitch_msg->adjustKinsVar0); + break; + default: // unrecognized command if (emc_debug & EMC_DEBUG_TASK_ISSUE) { @@ -2538,6 +2550,10 @@ static EMC_TASK_EXEC emcTaskCheckPostconditions(NMLmsg * cmd) return EMC_TASK_EXEC::DONE; break; + case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + return EMC_TASK_EXEC::WAITING_FOR_KINS_SWITCH; + break; + default: // unrecognized command if (emc_debug & EMC_DEBUG_TASK_ISSUE) { @@ -2758,6 +2774,17 @@ static int emcTaskExecute(void) } break; + case EMC_TASK_EXEC::WAITING_FOR_KINS_SWITCH: + { + if(emcStatus->motion.trajKinsTypeModified) + { + emcStatus->motion.trajKinsTypeModified = false; + emcTaskPlanSynch(); + emcStatus->task.execState = EMC_TASK_EXEC::DONE; + } + break; + } + case EMC_TASK_EXEC::WAITING_FOR_DELAY: STEPPING_CHECK(); // check if delay has passed diff --git a/src/emc/task/taskintf.cc b/src/emc/task/taskintf.cc index 3d0b7bc05fd..2215345069f 100644 --- a/src/emc/task/taskintf.cc +++ b/src/emc/task/taskintf.cc @@ -2125,6 +2125,11 @@ int emcMotionUpdate(EMC_MOTION_STAT * stat) r1 = emcJointUpdate(&stat->joint[0], stat->traj.joints); r2 = emcAxisUpdate(&stat->axis[0], stat->traj.axis_mask); r3 = emcTrajUpdate(&stat->traj); + if(stat->trajKinsType != emcmotStatus.kinsType) + { + stat->trajKinsType = emcmotStatus.kinsType; + stat->trajKinsTypeModified = true; + } r4 = emcSpindleUpdate(&stat->spindle[0], stat->traj.spindles); stat->command_type = localMotionCommandType; stat->echo_serial_number = localMotionEchoSerialNumber; @@ -2217,3 +2222,11 @@ int emcGetExternalOffsetApplied(void) { EmcPose emcGetExternalOffsets(void) { return emcmotStatus.eoffset_pose; } + +int emcAdjustKinsOffset(double adjustKinsVar0) +{ + emcmotCommand.command = EMCMOT_ADJUST_KINS_OFFSET_DATA; + emcmotCommand.adjustKinsVar0 = adjustKinsVar0; + + return usrmotWriteEmcmotCommand(&emcmotCommand); +} diff --git a/tests/remap/introspect/expected b/tests/remap/introspect/expected index b191db142ea..2f33b4bbe08 100644 --- a/tests/remap/introspect/expected +++ b/tests/remap/introspect/expected @@ -29,8 +29,8 @@ speed= 3000.0 global parameter set in test.ngc: 47.11 parameter set via test.ini: 3.14159 locals: ['a_new_local'] -globals: ['_a', '_a_global_set_in_test_dot_ngc', '_a_new_global', '_abs_a', '_abs_b', '_abs_c', '_abs_u', '_abs_v', '_abs_w', '_abs_x', '_abs_y', '_abs_z', '_absolute', '_adaptive_feed', '_b', '_c', '_call_level', '_ccomp', '_coord_system', '_current_pocket', '_current_tool', '_feed', '_feed_hold', '_feed_override', '_flood', '_ijk_absolute_mode', '_imperial', '_incremental', '_ini[example]variable', '_inverse_time', '_lathe_diameter_mode', '_lathe_radius_mode', '_line', '_metric', '_metric_machine', '_mist', '_motion_mode', '_plane', '_remap_level', '_retract_old_z', '_retract_r_plane', '_rpm', '_selected_pocket', '_selected_tool', '_speed_override', '_spindle_css_mode', '_spindle_cw', '_spindle_on', '_spindle_rpm_mode', '_task', '_tool_offset', '_u', '_units_per_minute', '_units_per_rev', '_v', '_value', '_value_returned', '_vmajor', '_vminor', '_w', '_x', '_y', '_z', 'foo'] -params(): ['a_new_local', '_a', '_a_global_set_in_test_dot_ngc', '_a_new_global', '_abs_a', '_abs_b', '_abs_c', '_abs_u', '_abs_v', '_abs_w', '_abs_x', '_abs_y', '_abs_z', '_absolute', '_adaptive_feed', '_b', '_c', '_call_level', '_ccomp', '_coord_system', '_current_pocket', '_current_tool', '_feed', '_feed_hold', '_feed_override', '_flood', '_ijk_absolute_mode', '_imperial', '_incremental', '_ini[example]variable', '_inverse_time', '_lathe_diameter_mode', '_lathe_radius_mode', '_line', '_metric', '_metric_machine', '_mist', '_motion_mode', '_plane', '_remap_level', '_retract_old_z', '_retract_r_plane', '_rpm', '_selected_pocket', '_selected_tool', '_speed_override', '_spindle_css_mode', '_spindle_cw', '_spindle_on', '_spindle_rpm_mode', '_task', '_tool_offset', '_u', '_units_per_minute', '_units_per_rev', '_v', '_value', '_value_returned', '_vmajor', '_vminor', '_w', '_x', '_y', '_z', 'foo'] +globals: ['_a', '_a_global_set_in_test_dot_ngc', '_a_new_global', '_abs_a', '_abs_b', '_abs_c', '_abs_u', '_abs_v', '_abs_w', '_abs_x', '_abs_y', '_abs_z', '_absolute', '_adaptive_feed', '_b', '_c', '_call_level', '_ccomp', '_coord_system', '_current_pocket', '_current_tool', '_feed', '_feed_hold', '_feed_override', '_flood', '_ijk_absolute_mode', '_imperial', '_incremental', '_ini[example]variable', '_inverse_time', '_kins_type', '_lathe_diameter_mode', '_lathe_radius_mode', '_line', '_metric', '_metric_machine', '_mist', '_motion_mode', '_plane', '_remap_level', '_retract_old_z', '_retract_r_plane', '_rpm', '_selected_pocket', '_selected_tool', '_speed_override', '_spindle_css_mode', '_spindle_cw', '_spindle_on', '_spindle_rpm_mode', '_task', '_tool_offset', '_u', '_units_per_minute', '_units_per_rev', '_v', '_value', '_value_returned', '_vmajor', '_vminor', '_w', '_x', '_y', '_z', 'foo'] +params(): ['a_new_local', '_a', '_a_global_set_in_test_dot_ngc', '_a_new_global', '_abs_a', '_abs_b', '_abs_c', '_abs_u', '_abs_v', '_abs_w', '_abs_x', '_abs_y', '_abs_z', '_absolute', '_adaptive_feed', '_b', '_c', '_call_level', '_ccomp', '_coord_system', '_current_pocket', '_current_tool', '_feed', '_feed_hold', '_feed_override', '_flood', '_ijk_absolute_mode', '_imperial', '_incremental', '_ini[example]variable', '_inverse_time', '_kins_type', '_lathe_diameter_mode', '_lathe_radius_mode', '_line', '_metric', '_metric_machine', '_mist', '_motion_mode', '_plane', '_remap_level', '_retract_old_z', '_retract_r_plane', '_rpm', '_selected_pocket', '_selected_tool', '_speed_override', '_spindle_css_mode', '_spindle_cw', '_spindle_on', '_spindle_rpm_mode', '_task', '_tool_offset', '_u', '_units_per_minute', '_units_per_rev', '_v', '_value', '_value_returned', '_vmajor', '_vminor', '_w', '_x', '_y', '_z', 'foo'] 14 N..... MESSAGE(" after introspect: return value=2.718280 call_level= 0.000000") 15 N..... SET_G5X_OFFSET(1, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000) 16 N..... SET_XY_ROTATION(0.0000) From 5dfb1b8a8eef03a5a9fb3165b372577656029c1e Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Tue, 11 Aug 2026 19:04:42 +1000 Subject: [PATCH 2/9] G12.1, G13.1: take the kinematics from motion on every synch The interpreter tracked the kinematics it had selected itself, which is not always the one motion is running. An abort clears the interpreter list, so a G12.1 that was queued but not yet sent is dropped while the interpreter keeps the type it converted. A config that drives motion.switchkins-type from HAL changes the kinematics without the interpreter hearing about it at all. Either way #<_kins_type> reports something that is not running, and the save and restore idiom # = #<_kins_type> G12.1 P3 ( ... ) G12.1 P# puts back the wrong kinematics. Carry the kinematics motion is running up into status and read it back in Interp::synch(), which already runs after an abort and after every completed switch. Task no longer writes the requested value into status, so the field has a single writer and always reports what motion is actually running. --- src/emc/nml_intf/canon.hh | 3 +++ src/emc/rs274ngc/gcodemodule.cc | 1 + src/emc/rs274ngc/rs274ngc_pre.cc | 1 + src/emc/sai/saicanon.cc | 5 +++++ src/emc/task/emccanon.cc | 9 +++++++++ src/emc/task/emctaskmain.cc | 1 - src/emc/task/taskintf.cc | 2 ++ 7 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/emc/nml_intf/canon.hh b/src/emc/nml_intf/canon.hh index 9b5276b3916..7abb63a749a 100644 --- a/src/emc/nml_intf/canon.hh +++ b/src/emc/nml_intf/canon.hh @@ -897,6 +897,9 @@ extern int GET_EXTERNAL_MIST(); // Returns the current motion control mode extern CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE(); +// Returns the kinematics type motion is running (G12.1, G13.1) +extern int GET_EXTERNAL_KINS_TYPE(); + // Returns the current motion path-following tolerance extern double GET_EXTERNAL_MOTION_CONTROL_TOLERANCE(); diff --git a/src/emc/rs274ngc/gcodemodule.cc b/src/emc/rs274ngc/gcodemodule.cc index 9034c036a86..da61abe6f45 100644 --- a/src/emc/rs274ngc/gcodemodule.cc +++ b/src/emc/rs274ngc/gcodemodule.cc @@ -1205,6 +1205,7 @@ void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE mode, double /*tolerance*/, int / void SET_MOTION_CONTROL_MODE(double /*tolerance*/) { } void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE mode) { motion_mode = mode; } CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE() { return motion_mode; } +int GET_EXTERNAL_KINS_TYPE() { return 0; } void SET_NAIVECAM_TOLERANCE(double /*tolerance*/) { } #define RESULT_OK (result == INTERP_OK || result == INTERP_EXECUTE_FINISH) diff --git a/src/emc/rs274ngc/rs274ngc_pre.cc b/src/emc/rs274ngc/rs274ngc_pre.cc index 16208923637..7b3a4c154e3 100644 --- a/src/emc/rs274ngc/rs274ngc_pre.cc +++ b/src/emc/rs274ngc/rs274ngc_pre.cc @@ -2073,6 +2073,7 @@ int Interp::synch() _setup.length_units = GET_EXTERNAL_LENGTH_UNIT_TYPE(); _setup.mist = GET_EXTERNAL_MIST(); _setup.plane = GET_EXTERNAL_PLANE(); + _setup.kins_type = GET_EXTERNAL_KINS_TYPE(); _setup.traverse_rate = GET_EXTERNAL_TRAVERSE_RATE(); _setup.feed_override = GET_EXTERNAL_FEED_OVERRIDE_ENABLE(); _setup.adaptive_feed = GET_EXTERNAL_ADAPTIVE_FEED_ENABLE(); diff --git a/src/emc/sai/saicanon.cc b/src/emc/sai/saicanon.cc index 8477ff730c9..f9165efb8cf 100644 --- a/src/emc/sai/saicanon.cc +++ b/src/emc/sai/saicanon.cc @@ -778,6 +778,11 @@ extern CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE() return _sai._motion_mode; } +extern int GET_EXTERNAL_KINS_TYPE() +{ + return 0; +} + extern void SET_PARAMETER_FILE_NAME(const char *name) { strncpy(_parameter_file_name, name, PARAMETER_FILE_NAME_LENGTH - 1); diff --git a/src/emc/task/emccanon.cc b/src/emc/task/emccanon.cc index aa1cf1c7693..e6a26625bc1 100644 --- a/src/emc/task/emccanon.cc +++ b/src/emc/task/emccanon.cc @@ -4052,6 +4052,15 @@ CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE() return canon.motionMode; } +int GET_EXTERNAL_KINS_TYPE() +{ + // motion publishes the kinematics it is actually running, which is + // not necessarily the one G-code last asked for: an abort can drop a + // queued switch, and the motion.switchkins-type pin can select one + // without the interpreter seeing it + return (int)emcStatus->motion.adjustKinsVar0; +} + double GET_EXTERNAL_MOTION_CONTROL_TOLERANCE() { return TO_PROG_LEN(canon.motionTolerance); diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index e8b2488018b..a8213ff1c3e 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -2435,7 +2435,6 @@ static int emcTaskIssueCommand(NMLmsg * cmd) case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: kSwitch_msg = (EMC_ADJUST_KINS_OFFSET_DATA *) cmd; - emcStatus->motion.adjustKinsVar0 = kSwitch_msg->adjustKinsVar0; retval = emcAdjustKinsOffset(kSwitch_msg->adjustKinsVar0); break; diff --git a/src/emc/task/taskintf.cc b/src/emc/task/taskintf.cc index 2215345069f..8ac9c9c73a5 100644 --- a/src/emc/task/taskintf.cc +++ b/src/emc/task/taskintf.cc @@ -2130,6 +2130,8 @@ int emcMotionUpdate(EMC_MOTION_STAT * stat) stat->trajKinsType = emcmotStatus.kinsType; stat->trajKinsTypeModified = true; } + // the kinematics motion is running, whoever selected it + stat->adjustKinsVar0 = emcmotStatus.adjustKinsVar0; r4 = emcSpindleUpdate(&stat->spindle[0], stat->traj.spindles); stat->command_type = localMotionCommandType; stat->echo_serial_number = localMotionEchoSerialNumber; From 5ae4567e8b19756d2774ed1976b0345f21d5a61a Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:11:24 +1000 Subject: [PATCH 3/9] motion: record the kinematics type only once the switch succeeds handle_kinematicsSwitch() assigned the requested type, published it on motion.kins-type, stored it in the status, and only then asked the module to switch. A module that refuses a type it does not provide goes on running the one it has, so the readout named a kinematics that was not in force, and G12.1 P#<_kins_type> put that wrong number back. Ask first, record after. A refused switch leaves the type, the pin and #<_kins_type> on the kinematics still running, and still raises the motion error. The refusal reached the operator as nothing at all, only a line in the realtime log, which was survivable while switching came from HAL and is not once a G-code block can ask: say which type was refused and which one is still running. The failure message names the type that was asked for rather than the HAL pin, which is not where the request came from when it came from G-code. G12.1 P7 on xyzab_tdr_kins, which provides two types, left motion.kins-type reading 7 while kinstype.is-0 stayed true. It reads 0. --- src/emc/motion/control.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/emc/motion/control.c b/src/emc/motion/control.c index 14842dd9dc7..31aa306b766 100644 --- a/src/emc/motion/control.c +++ b/src/emc/motion/control.c @@ -326,10 +326,6 @@ static void handle_kinematicsSwitch(void) { emcmotStatus->adjustKinsVar0 = switchkins_type; if (switchkins_type == requested_type) return; - switchkins_type = requested_type; - hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); - emcmotStatus->adjustKinsVar0 = switchkins_type; - emcmot_joint_t *jointKinsSwitch; double joint_posKinsSwitch[EMCMOT_MAX_JOINTS] = {0,}; /* copy joint position feedback to local array */ @@ -340,13 +336,22 @@ static void handle_kinematicsSwitch(void) { joint_posKinsSwitch[joint_num] = jointKinsSwitch->pos_cmd; } - if (kinematicsSwitch(switchkins_type)) { - rtapi_print_msg(RTAPI_MSG_ERR,"kinematicsSwitch() FAIL<%f>\n", - hal_get_real(emcmot_hal_data->switchkins_type)); + /* a module refuses a type it does not provide and goes on running the + one it has, so nothing is recorded until the switch has happened */ + if (kinematicsSwitch(requested_type)) { + rtapi_print_msg(RTAPI_MSG_ERR,"kinematicsSwitch() FAIL<%d>\n", + requested_type); + reportError(_("kinematics type %d is not provided by this module," + " type %d is still in force"), + requested_type, switchkins_type); SET_MOTION_ERROR_FLAG(1); // abort - return; // no updates for abort + return; // the kinematics in force is unchanged } + switchkins_type = requested_type; + hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); + emcmotStatus->adjustKinsVar0 = switchkins_type; + KINEMATICS_FORWARD_FLAGS tmpFFlags = fflags; KINEMATICS_INVERSE_FLAGS tmpIFlags = iflags; #ifdef SWITCHKINS_DEBUG From b387e3e0f7ae4020465602b07bf26ead5f95d0c3 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:28:10 +1000 Subject: [PATCH 4/9] motion: deprecate selecting the kinematics type from HAL motion.switchkins-type cannot be the general way to choose kinematics. The interpreter never sees it, so a program is read, its limits checked and its path looked ahead in whatever kinematics the interpreter last knew about, which need not be the one that ends up running it. Nothing in the pin can fix that; the interpreter has to be told, which is what G12.1 and G13.1 are for. Motion says so once per session, the first time the pin is used to change the type. A configuration that never switches never sees it, and the G-code route never triggers it. The pin is in a grace period: it keeps working for now, and is meant to go. Both the man page and the switchkins chapter claimed G12.1 and G13.1 write this pin. They do not, and cannot: the configs source it from an analog output that would put its own value back on the next servo cycle. They ask motion directly. --- docs/src/man/man9/motion.9.adoc | 17 +++++++++++------ docs/src/motion/switchkins.adoc | 31 +++++++++++++++++++++++-------- src/emc/motion/control.c | 12 ++++++++++++ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/docs/src/man/man9/motion.9.adoc b/docs/src/man/man9/motion.9.adoc index 8b1c78a936e..b68359287d1 100644 --- a/docs/src/man/man9/motion.9.adoc +++ b/docs/src/man/man9/motion.9.adoc @@ -253,15 +253,20 @@ Note: feed-inhibit applies to G-code commands -- not jogs. *motion.switchkins-type* IN float:: Kinematics modules that define the functions kinematicsSwitchable() and kinematicsSwitch() receive the *integer* value of this pin to - select the machine kinematics functions. Extra G-code commands may be + select the machine kinematics functions. Extra G-code commands are required to synchronize task and motion before and after changes to the pin value. - The G-code words *G12.1 P-* and *G13.1* write this pin and synchronize - task and motion themselves, so a program that uses them needs no such - extra commands. + *Deprecated*: the interpreter does not see this pin, so limits and + look ahead go on using the kinematics it last knew about. Use the + G-code words *G12.1 P-* and *G13.1*, which ask motion directly and + synchronize task and motion themselves. Motion reports the + deprecation once, the first time the pin is used to change the + kinematics. The pin is in a grace period: it keeps working for now, + but is meant to be removed in the future. *motion.kins-type* OUT float:: - The kinematics currently selected, echoing the value that was last - applied from *motion.switchkins-type*. + The kinematics currently in force, whether it was selected by + *G12.1*, by *G13.1* or from *motion.switchkins-type*. A kinematics + type the module refuses is not reported here. *motion.teleop-mode* OUT BIT:: Motion mode is teleop (axis coordinate jogging available). *motion.tooloffset.L* OUT FLOAT:: diff --git a/docs/src/motion/switchkins.adoc b/docs/src/motion/switchkins.adoc index d02633d1515..67eab672180 100644 --- a/docs/src/motion/switchkins.adoc +++ b/docs/src/motion/switchkins.adoc @@ -137,11 +137,12 @@ A module providing more than three kinematics types has one === HAL Connections -Switchkins functionality is enabled by the pin -*motion.switchkins-type*, which 'G12.1' and 'G13.1' write directly. -To select a kinstype from HAL instead, source the pin from an analog -output pin like motion.analog-out-03 so that it can be set by M68 -commands. Example: +'G12.1' and 'G13.1' ask motion for a kinstype directly and need no HAL +connection at all. + +A kinstype can also be selected by writing the pin +*motion.switchkins-type*, which is sourced from an analog output pin +like motion.analog-out-03 so that it can be set by M68 commands: [source,hal] ---- @@ -149,6 +150,15 @@ net :kinstype-select <= motion.analog-out-03 net :kinstype-select => motion.switchkins-type ---- +[WARNING] +Selecting the kinstype from HAL is deprecated and motion says so, once, +the first time the pin is used to change it. The interpreter does not +see the pin, so a program is read, its limits checked and its path +looked ahead in whatever kinematics the interpreter last knew about, +which is not necessarily the one that will run it. Use 'G12.1' and +'G13.1'. The pin is in a grace period: it keeps working for now, but is +meant to be removed in the future. + === G-code commands 'G12.1 P-' selects a kinstype and 'G13.1' cancels back to kinstype 0: @@ -191,9 +201,14 @@ description. === M-code commands -A kinstype can also be selected by writing *motion.switchkins-type* -through an analog output pin, which needs the HAL connection shown -above. Kinstype selection is then managed using G-code sequences like: +[WARNING] +This is the deprecated route described under HAL Connections above. It +is documented because existing configurations use it. New ones should +use 'G12.1' and 'G13.1'. + +Writing *motion.switchkins-type* through an analog output pin needs the +HAL connection shown above. Kinstype selection is then managed using +G-code sequences like: [source,ngc] ---- diff --git a/src/emc/motion/control.c b/src/emc/motion/control.c index 31aa306b766..c82875ce489 100644 --- a/src/emc/motion/control.c +++ b/src/emc/motion/control.c @@ -302,6 +302,7 @@ static void handle_kinematicsSwitch(void) { int joint_num; int hal_switchkins_type = 0; static int prev_hal_switchkins_type = 0; + static int said_hal_is_deprecated = 0; int requested_type; if (!kinematicsSwitchable()) return; @@ -319,6 +320,17 @@ static void handle_kinematicsSwitch(void) { emcmotStatus->kinsType = emcmotConfig->kinsType; } else if (hal_switchkins_type != prev_hal_switchkins_type) { requested_type = hal_switchkins_type; + /* Once per session. The pin cannot become the general way to + switch: the interpreter does not see it, so a program is read, + its limits checked and its path looked ahead in whatever + kinematics the interpreter last knew about. */ + if (!said_hal_is_deprecated) { + said_hal_is_deprecated = 1; + reportError(_("motion.switchkins-type is deprecated, use G12.1 and" + " G13.1. Switching kinematics from HAL is invisible" + " to the interpreter, so limits and look ahead go on" + " using the kinematics it last knew about.")); + } } prev_hal_switchkins_type = hal_switchkins_type; From 31bd17739417b76151019cfd42a211a09c3606c5 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:05:45 +1000 Subject: [PATCH 5/9] motion: name the kinematics selection for what it is The G12.1 plumbing arrived from the out-of-tree patch with names that describe nothing. `adjustKinsVar0` is the kinematics type, there is no Var1, and nothing adjusts an offset. `kinsType` is not a type at all: it was a char toggling between 'r' and 's' so the servo cycle could notice that a new request had arrived. The field named like a type was a flag and the field with the opaque name was the type. So: adjustKinsVar0 -> switchkins_type, an int kinsType ('r'/'s' toggle) -> switchkins_seq, a counter trajKinsType -> switchkins_seq in EMC_TRAJ_STAT trajKinsTypeModified -> switchkins_changed in EMC_TRAJ_STAT ADJUST_KINS_OFFSET(double) -> SELECT_KINS_TYPE(int) EMC_ADJUST_KINS_OFFSET_DATA -> EMC_TRAJ_SELECT_KINS EMCMOT_ADJUST_KINS_OFFSET_DATA -> EMCMOT_SELECT_KINS_TYPE emcAdjustKinsOffset() -> emcSelectKinsType() switchkins_type rather than kinsType because EMC_TRAJ_STAT already has kinematics_type, which is the identity/serial/parallel/custom kind and a different thing entirely. switchkins_type is what the HAL pin and switchkins.c already call it. The three status fields were prefixed traj but lived in EMC_MOTION_STAT. They are trajectory status, so they move into EMC_TRAJ_STAT and lose the prefix, which also means EMC_TRAJ_STAT::update() carries them. A counter instead of a two-state toggle keeps the property the toggle had, that asking for the type already in force is still seen as a request, without pretending to be an enum. No G-code, HAL pin or INI name changes. --- src/emc/motion/command.c | 11 +++-------- src/emc/motion/control.c | 10 +++++----- src/emc/motion/motion.h | 16 ++++++++-------- src/emc/nml_intf/canon.hh | 2 +- src/emc/nml_intf/emc.cc | 15 +++++++++------ src/emc/nml_intf/emc.hh | 4 ++-- src/emc/nml_intf/emc_nml.hh | 18 ++++++++++-------- src/emc/nml_intf/emcops.cc | 8 ++++---- src/emc/rs274ngc/gcodemodule.cc | 6 +++--- src/emc/rs274ngc/interp_convert.cc | 2 +- src/emc/sai/saicanon.cc | 6 +++--- src/emc/task/emccanon.cc | 10 +++++----- src/emc/task/emctaskmain.cc | 16 ++++++++-------- src/emc/task/taskintf.cc | 14 +++++++------- 14 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/emc/motion/command.c b/src/emc/motion/command.c index 1a48585fb5e..22b51ac533f 100644 --- a/src/emc/motion/command.c +++ b/src/emc/motion/command.c @@ -2054,14 +2054,9 @@ void emcmotCommandHandler_locked(void *arg, long servo_period) axis_set_locking_joint(emcmotCommand->axis, joint_num); break; - case EMCMOT_ADJUST_KINS_OFFSET_DATA: - emcmotConfig->adjustKinsVar0 = emcmotCommand->adjustKinsVar0; - if(emcmotConfig->kinsType == 'r'){ - emcmotConfig->kinsType = 's'; - } - else{ - emcmotConfig->kinsType = 'r'; - } + case EMCMOT_SELECT_KINS_TYPE: + emcmotConfig->switchkins_type = emcmotCommand->switchkins_type; + emcmotConfig->switchkins_seq++; break; default: diff --git a/src/emc/motion/control.c b/src/emc/motion/control.c index c82875ce489..5b341381c30 100644 --- a/src/emc/motion/control.c +++ b/src/emc/motion/control.c @@ -315,9 +315,9 @@ static void handle_kinematicsSwitch(void) { hal_switchkins_type = (int)hal_get_real(emcmot_hal_data->switchkins_type); requested_type = switchkins_type; - if (emcmotStatus->kinsType != emcmotConfig->kinsType) { - requested_type = (int)emcmotConfig->adjustKinsVar0; - emcmotStatus->kinsType = emcmotConfig->kinsType; + if (emcmotStatus->switchkins_seq != emcmotConfig->switchkins_seq) { + requested_type = emcmotConfig->switchkins_type; + emcmotStatus->switchkins_seq = emcmotConfig->switchkins_seq; } else if (hal_switchkins_type != prev_hal_switchkins_type) { requested_type = hal_switchkins_type; /* Once per session. The pin cannot become the general way to @@ -335,7 +335,7 @@ static void handle_kinematicsSwitch(void) { prev_hal_switchkins_type = hal_switchkins_type; hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); - emcmotStatus->adjustKinsVar0 = switchkins_type; + emcmotStatus->switchkins_type = switchkins_type; if (switchkins_type == requested_type) return; emcmot_joint_t *jointKinsSwitch; @@ -362,7 +362,7 @@ static void handle_kinematicsSwitch(void) { switchkins_type = requested_type; hal_set_real(emcmot_hal_data->kins_type, (double)switchkins_type); - emcmotStatus->adjustKinsVar0 = switchkins_type; + emcmotStatus->switchkins_type = switchkins_type; KINEMATICS_FORWARD_FLAGS tmpFFlags = fflags; KINEMATICS_INVERSE_FLAGS tmpIFlags = iflags; diff --git a/src/emc/motion/motion.h b/src/emc/motion/motion.h index fb36c96f278..8fcdf318904 100644 --- a/src/emc/motion/motion.h +++ b/src/emc/motion/motion.h @@ -174,10 +174,9 @@ extern "C" { EMCMOT_SET_AXIS_VEL_LIMIT, /* set the max axis vel */ EMCMOT_SET_AXIS_ACC_LIMIT, /* set the max axis acc */ EMCMOT_SET_AXIS_LOCKING_JOINT, /* set the axis locking joint */ - EMCMOT_SET_AXIS_JERK_LIMIT, /* set the max axis jerk */ - - EMCMOT_ADJUST_KINS_OFFSET_DATA, /* set the offset in kins (G12.1) */ + EMCMOT_SET_AXIS_JERK_LIMIT, /* set the max axis jerk */ + EMCMOT_SELECT_KINS_TYPE, /* select the switchkins type (G12.1) */ EMCMOT_SET_SPINDLE_PARAMS, /* One command to set all spindle params */ } cmd_code_t; @@ -273,7 +272,7 @@ extern "C" { double ext_offset_acc; /* acceleration for an external axis offset */ struct state_tag_t tag; - double adjustKinsVar0; + int switchkins_type; /* switchkins type requested by G12.1 */ } emcmot_command_t; /*! \todo FIXME - these packed bits might be replaced with chars @@ -672,8 +671,8 @@ Suggestion: Split this in to an Error and a Status flag register.. int stepping; bool jogging_active; - char kinsType; - double adjustKinsVar0; + int switchkins_seq; /* echoes the config counter once acted on */ + int switchkins_type; /* switchkins type now in force */ } emcmot_status_t; /********************************* @@ -746,8 +745,9 @@ Suggestion: Split this in to an Error and a Status flag register.. int inhibit_probe_jog_error; int inhibit_probe_home_error; - double adjustKinsVar0; - char kinsType; + int switchkins_type; /* switchkins type requested by G12.1 */ + int switchkins_seq; /* bumped per request, so a repeat of + the same type is still seen */ } emcmot_config_t; /* error structure - lockfree MPSC ring buffer. See emcmotutil.c. */ diff --git a/src/emc/nml_intf/canon.hh b/src/emc/nml_intf/canon.hh index 7abb63a749a..c460ee81e02 100644 --- a/src/emc/nml_intf/canon.hh +++ b/src/emc/nml_intf/canon.hh @@ -1074,6 +1074,6 @@ extern EmcPose GET_EXTERNAL_OFFSETS(); extern void UPDATE_TAG(const StateTag& tag); // adjust kins offset (G12.1 kinematics switch) -extern void ADJUST_KINS_OFFSET(double adjustKinsVar0); +extern void SELECT_KINS_TYPE(int switchkins_type); #endif /* ifndef CANON_HH */ diff --git a/src/emc/nml_intf/emc.cc b/src/emc/nml_intf/emc.cc index 3ae7134c4d6..a8c4f9593af 100644 --- a/src/emc/nml_intf/emc.cc +++ b/src/emc/nml_intf/emc.cc @@ -298,8 +298,8 @@ int emcFormat(NMLTYPE type, void *buffer, CMS * cms) case EMC_TRAJ_SET_OFFSET_TYPE: ((EMC_TRAJ_SET_OFFSET *) buffer)->update(cms); break; - case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: - ((EMC_ADJUST_KINS_OFFSET_DATA *) buffer)->update(cms); + case EMC_TRAJ_SELECT_KINS_TYPE: + ((EMC_TRAJ_SELECT_KINS *) buffer)->update(cms); break; case EMC_TRAJ_SET_G5X_TYPE: ((EMC_TRAJ_SET_G5X *) buffer)->update(cms); @@ -525,8 +525,8 @@ const char *emc_symbol_lookup(uint32_t type) return "EMC_TRAJ_SET_MODE"; case EMC_TRAJ_SET_OFFSET_TYPE: return "EMC_TRAJ_SET_OFFSET"; - case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: - return "EMC_ADJUST_KINS_OFFSET_DATA"; + case EMC_TRAJ_SELECT_KINS_TYPE: + return "EMC_TRAJ_SELECT_KINS"; case EMC_TRAJ_SET_G5X_TYPE: return "EMC_TRAJ_SET_G5X"; case EMC_TRAJ_SET_G92_TYPE: @@ -1599,10 +1599,10 @@ void EMC_TRAJ_SET_OFFSET::update(CMS * cms) } // cppcheck-suppress duplInheritedMember -void EMC_ADJUST_KINS_OFFSET_DATA::update(CMS * cms) +void EMC_TRAJ_SELECT_KINS::update(CMS * cms) { EMC_TRAJ_CMD_MSG::update(cms); - cms->update(adjustKinsVar0); + cms->update(switchkins_type); } /* @@ -1740,6 +1740,9 @@ void EMC_TRAJ_STAT::update(CMS * cms) cms->update(feed_override_enabled); cms->update(adaptive_feed_enabled); cms->update(feed_hold_enabled); + cms->update(switchkins_type); + cms->update(switchkins_seq); + cms->update(switchkins_changed); } /* diff --git a/src/emc/nml_intf/emc.hh b/src/emc/nml_intf/emc.hh index be1d6e9739b..52e742d6127 100644 --- a/src/emc/nml_intf/emc.hh +++ b/src/emc/nml_intf/emc.hh @@ -112,7 +112,7 @@ struct PM_CARTESIAN; #define EMC_TRAJ_SET_FH_ENABLE_TYPE ((NMLTYPE) 236) #define EMC_TRAJ_RIGID_TAP_TYPE ((NMLTYPE) 237) -#define EMC_ADJUST_KINS_OFFSET_DATA_TYPE ((NMLTYPE) 289) +#define EMC_TRAJ_SELECT_KINS_TYPE ((NMLTYPE) 289) #define EMC_TRAJ_STAT_TYPE ((NMLTYPE) 299) // EMC_MOTION aggregate class type declaration @@ -462,7 +462,7 @@ int emcSetupArcBlends(int arcBlendEnable, int emcSetProbeErrorInhibit(int j_inhibit, int h_inhibit); int emcGetExternalOffsetApplied(void); EmcPose emcGetExternalOffsets(void); -extern int emcAdjustKinsOffset(double adjustKinsVar0); +extern int emcSelectKinsType(int switchkins_type); extern int emcUpdate(EMC_STAT * stat); // full EMC status diff --git a/src/emc/nml_intf/emc_nml.hh b/src/emc/nml_intf/emc_nml.hh index 9e17c10f1d4..2927c0fff0e 100644 --- a/src/emc/nml_intf/emc_nml.hh +++ b/src/emc/nml_intf/emc_nml.hh @@ -960,14 +960,14 @@ class EMC_TRAJ_RIGID_TAP:public EMC_TRAJ_CMD_MSG { double vel, ini_maxvel, acc, scale, ini_maxjerk; }; -class EMC_ADJUST_KINS_OFFSET_DATA:public EMC_TRAJ_CMD_MSG { +class EMC_TRAJ_SELECT_KINS:public EMC_TRAJ_CMD_MSG { public: - EMC_ADJUST_KINS_OFFSET_DATA():EMC_TRAJ_CMD_MSG(EMC_ADJUST_KINS_OFFSET_DATA_TYPE, - sizeof(EMC_ADJUST_KINS_OFFSET_DATA)), - adjustKinsVar0(0.0) + EMC_TRAJ_SELECT_KINS():EMC_TRAJ_CMD_MSG(EMC_TRAJ_SELECT_KINS_TYPE, + sizeof(EMC_TRAJ_SELECT_KINS)), + switchkins_type(0) {}; - double adjustKinsVar0; + int switchkins_type; // For internal NML/CMS use only. // Sub-class update() calls base-class update() @@ -1039,6 +1039,11 @@ 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; + + int switchkins_type; // switchkins type now in force + int switchkins_seq; // motion's request counter, echoed once seen + bool switchkins_changed; // a switch landed, task has yet to synch + StateTag tag; }; @@ -1182,9 +1187,6 @@ class EMC_MOTION_STAT:public EMC_MOTION_STAT_MSG { bool jogging_active; uint64_t heartbeat; // motion controller's heartbeat counter - char trajKinsType; - bool trajKinsTypeModified; - double adjustKinsVar0; }; // declarations for EMC_TASK classes diff --git a/src/emc/nml_intf/emcops.cc b/src/emc/nml_intf/emcops.cc index ee99dcce6fd..8c1d9f86b8b 100644 --- a/src/emc/nml_intf/emcops.cc +++ b/src/emc/nml_intf/emcops.cc @@ -95,6 +95,9 @@ EMC_TRAJ_STAT::EMC_TRAJ_STAT() feed_override_enabled(OFF), adaptive_feed_enabled(OFF), feed_hold_enabled(OFF), + switchkins_type(0), + switchkins_seq(0), + switchkins_changed(false), tag() { } @@ -112,10 +115,7 @@ EMC_MOTION_STAT::EMC_MOTION_STAT() eoffset_pose{}, numExtraJoints(0), jogging_active(0), - heartbeat(0), - trajKinsType(0), - trajKinsTypeModified(false), - adjustKinsVar0(0.0) + heartbeat(0) { } diff --git a/src/emc/rs274ngc/gcodemodule.cc b/src/emc/rs274ngc/gcodemodule.cc index da61abe6f45..eb2cc840090 100644 --- a/src/emc/rs274ngc/gcodemodule.cc +++ b/src/emc/rs274ngc/gcodemodule.cc @@ -892,10 +892,10 @@ void ON_RESET() {} void PALLET_SHUTTLE() {} void SELECT_TOOL(int tool) {selected_tool = tool;} void UPDATE_TAG(const StateTag& /*tag*/) {} -void ADJUST_KINS_OFFSET(double adjustKinsVar0) +void SELECT_KINS_TYPE(int switchkins_type) { - (void)adjustKinsVar0; - printf("gcodemodule: ADJUST_KINS_OFFSET\n"); + (void)switchkins_type; + printf("gcodemodule: SELECT_KINS_TYPE\n"); return; } diff --git a/src/emc/rs274ngc/interp_convert.cc b/src/emc/rs274ngc/interp_convert.cc index 7ca5ab6513c..166281d1d88 100644 --- a/src/emc/rs274ngc/interp_convert.cc +++ b/src/emc/rs274ngc/interp_convert.cc @@ -6521,7 +6521,7 @@ int Interp::convert_kins_switch(int code, //!< G_12_1 or G_13_1 CHKS((kins_type < 0), _("G12.1 requires a non-negative P word")); - ADJUST_KINS_OFFSET((double)kins_type); + SELECT_KINS_TYPE(kins_type); settings->kins_type = kins_type; return INTERP_OK; } diff --git a/src/emc/sai/saicanon.cc b/src/emc/sai/saicanon.cc index f9165efb8cf..6363319d7e9 100644 --- a/src/emc/sai/saicanon.cc +++ b/src/emc/sai/saicanon.cc @@ -1198,10 +1198,10 @@ void UPDATE_TAG(const StateTag& /*tag*/){ //Do nothing } -void ADJUST_KINS_OFFSET(double adjustKinsVar0) +void SELECT_KINS_TYPE(int switchkins_type) { - (void)adjustKinsVar0; - printf("saicanon: ADJUST_KINS_OFFSET\n"); + (void)switchkins_type; + printf("saicanon: SELECT_KINS_TYPE\n"); return; } diff --git a/src/emc/task/emccanon.cc b/src/emc/task/emccanon.cc index e6a26625bc1..818eefc1895 100644 --- a/src/emc/task/emccanon.cc +++ b/src/emc/task/emccanon.cc @@ -1206,15 +1206,15 @@ void ON_RESET() { drop_segments(); } -void ADJUST_KINS_OFFSET(double adjustKinsVar0) +void SELECT_KINS_TYPE(int switchkins_type) { flush_segments(); - auto adjustKinsOffsetMsg = std::make_unique(); + auto selectKinsMsg = std::make_unique(); - adjustKinsOffsetMsg->adjustKinsVar0 = adjustKinsVar0; + selectKinsMsg->switchkins_type = switchkins_type; - interp_list.append(std::move(adjustKinsOffsetMsg)); + interp_list.append(std::move(selectKinsMsg)); } @@ -4058,7 +4058,7 @@ int GET_EXTERNAL_KINS_TYPE() // not necessarily the one G-code last asked for: an abort can drop a // queued switch, and the motion.switchkins-type pin can select one // without the interpreter seeing it - return (int)emcStatus->motion.adjustKinsVar0; + return emcStatus->motion.traj.switchkins_type; } double GET_EXTERNAL_MOTION_CONTROL_TOLERANCE() diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index a8213ff1c3e..5e41127a5a2 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -418,7 +418,7 @@ static EMC_AUX_INPUT_WAIT *emcAuxInputWaitMsg; static int emcAuxInputWaitType = 0; static int emcAuxInputWaitIndex = -1; -static EMC_ADJUST_KINS_OFFSET_DATA *kSwitch_msg; +static EMC_TRAJ_SELECT_KINS *kSwitch_msg; // commands we compose here static EMC_TASK_PLAN_RUN taskPlanRunCmd; // 16-Aug-1999 FMP @@ -1607,7 +1607,7 @@ static EMC_TASK_EXEC emcTaskCheckPreconditions(NMLmsg * cmd) return EMC_TASK_EXEC::WAITING_FOR_MOTION; break; - case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + case EMC_TRAJ_SELECT_KINS_TYPE: return EMC_TASK_EXEC::WAITING_FOR_MOTION_AND_IO; break; @@ -2433,9 +2433,9 @@ static int emcTaskIssueCommand(NMLmsg * cmd) retval = 0; break; - case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: - kSwitch_msg = (EMC_ADJUST_KINS_OFFSET_DATA *) cmd; - retval = emcAdjustKinsOffset(kSwitch_msg->adjustKinsVar0); + case EMC_TRAJ_SELECT_KINS_TYPE: + kSwitch_msg = (EMC_TRAJ_SELECT_KINS *) cmd; + retval = emcSelectKinsType(kSwitch_msg->switchkins_type); break; default: @@ -2549,7 +2549,7 @@ static EMC_TASK_EXEC emcTaskCheckPostconditions(NMLmsg * cmd) return EMC_TASK_EXEC::DONE; break; - case EMC_ADJUST_KINS_OFFSET_DATA_TYPE: + case EMC_TRAJ_SELECT_KINS_TYPE: return EMC_TASK_EXEC::WAITING_FOR_KINS_SWITCH; break; @@ -2775,9 +2775,9 @@ static int emcTaskExecute(void) case EMC_TASK_EXEC::WAITING_FOR_KINS_SWITCH: { - if(emcStatus->motion.trajKinsTypeModified) + if(emcStatus->motion.traj.switchkins_changed) { - emcStatus->motion.trajKinsTypeModified = false; + emcStatus->motion.traj.switchkins_changed = false; emcTaskPlanSynch(); emcStatus->task.execState = EMC_TASK_EXEC::DONE; } diff --git a/src/emc/task/taskintf.cc b/src/emc/task/taskintf.cc index 8ac9c9c73a5..44aa60b15e3 100644 --- a/src/emc/task/taskintf.cc +++ b/src/emc/task/taskintf.cc @@ -2125,13 +2125,13 @@ int emcMotionUpdate(EMC_MOTION_STAT * stat) r1 = emcJointUpdate(&stat->joint[0], stat->traj.joints); r2 = emcAxisUpdate(&stat->axis[0], stat->traj.axis_mask); r3 = emcTrajUpdate(&stat->traj); - if(stat->trajKinsType != emcmotStatus.kinsType) + if(stat->traj.switchkins_seq != emcmotStatus.switchkins_seq) { - stat->trajKinsType = emcmotStatus.kinsType; - stat->trajKinsTypeModified = true; + stat->traj.switchkins_seq = emcmotStatus.switchkins_seq; + stat->traj.switchkins_changed = true; } // the kinematics motion is running, whoever selected it - stat->adjustKinsVar0 = emcmotStatus.adjustKinsVar0; + stat->traj.switchkins_type = emcmotStatus.switchkins_type; r4 = emcSpindleUpdate(&stat->spindle[0], stat->traj.spindles); stat->command_type = localMotionCommandType; stat->echo_serial_number = localMotionEchoSerialNumber; @@ -2225,10 +2225,10 @@ EmcPose emcGetExternalOffsets(void) { return emcmotStatus.eoffset_pose; } -int emcAdjustKinsOffset(double adjustKinsVar0) +int emcSelectKinsType(int switchkins_type) { - emcmotCommand.command = EMCMOT_ADJUST_KINS_OFFSET_DATA; - emcmotCommand.adjustKinsVar0 = adjustKinsVar0; + emcmotCommand.command = EMCMOT_SELECT_KINS_TYPE; + emcmotCommand.switchkins_type = switchkins_type; return usrmotWriteEmcmotCommand(&emcmotCommand); } From 9dd4b5e64a2dd4ec5428025a96ca19ab213fcff3 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:57:15 +1000 Subject: [PATCH 6/9] configs: select kinematics with G12.1 in the switchkins comp sims The four sim configs whose kinematics components now use the switchkins core chose their kinematics by writing motion.switchkins-type through an analog output, the route motion has just deprecated. Each of them would have met the user with the deprecation warning the first time they pressed a kinematics button. The M428, M429 and M430 remaps, the TWP wrappers behind G53.1, G53.3, G53.6 and G69, the abort handler and remap.py now use G12.1 and G13.1. That drops the M66 sync either side of every switch, the test that the HAL pin exists at all, and the #5399 clobber each M66 costs, since G12.1 and G13.1 synchronise interpreter and motion themselves. The check that the switch took reads #<_kins_type> instead of the pin. millturn keeps the M66 at the end of M428 and M429. That one is not there for the switch: M128 and M129 change the axis limits from a Tcl script, which reaches motion through inihal, so read-ahead has to stop until the new limits have landed. The vismach guis for the two trsrn configs were reading the value requested through the analog output. They now take motion.kins-type, which is the kinematics actually in force. Eight other sim config directories still select kinematics from HAL: bridgemill, table-rotary-tilting, hexapod-sim, melfa-sim, puma, and the three copies of scara. They are untouched here, and still work. --- .../vismach/5axis/table-dual-rotary/README | 3 --- .../table-dual-rotary/remap_subs/428remap.ngc | 21 +++++-------------- .../table-dual-rotary/remap_subs/429remap.ngc | 17 +++------------ .../5axis/table-dual-rotary/xyzab-tdr.ini | 10 ++++----- .../python/remap.py | 2 +- .../remap_subs/428remap.ngc | 17 +++------------ .../remap_subs/429remap.ngc | 17 +++------------ .../remap_subs/430remap.ngc | 17 +++------------ .../remap_subs/g531remap.ngc | 2 +- .../remap_subs/g533remap.ngc | 2 +- .../remap_subs/g536remap.ngc | 2 +- .../remap_subs/g69remap.ngc | 2 +- .../remap_subs/on_abort_with_twp_reset.ngc | 2 +- .../xyzacb-trsrn_twp/xyzacb-trsrn.ini | 10 ++++----- .../xyzbca-trsrn_twp/xyzbca-trsrn.ini | 10 ++++----- .../sim/axis/vismach/millturn/millturn.ini | 1 - .../sim/axis/vismach/millturn/millturn.txt | 5 ++--- .../vismach/millturn/remap_subs/428remap.ngc | 19 ++++------------- .../vismach/millturn/remap_subs/429remap.ngc | 19 ++++------------- 19 files changed, 45 insertions(+), 133 deletions(-) diff --git a/configs/sim/axis/vismach/5axis/table-dual-rotary/README b/configs/sim/axis/vismach/5axis/table-dual-rotary/README index 0a9f1130e42..29e0a4c88a4 100644 --- a/configs/sim/axis/vismach/5axis/table-dual-rotary/README +++ b/configs/sim/axis/vismach/5axis/table-dual-rotary/README @@ -28,9 +28,6 @@ For proper tool-path preview RELOAD THE CGODE after startup and after changing o *********************************************** Note: IMPORTANT ini file requirements: -[HAL] -HALCMD = net :kinstype-select <= motion.analog-out-0N => motion.switchkins-type - [RS274NGC] SUBROUTINE_PATH = ./remap_subs REMAP = M428 modalgroup=10 ngc=428remap diff --git a/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc b/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc index 46e2d01ba5b..062edba961e 100644 --- a/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ -;M428 by remap: kinstype==1 (xyzac,xyzbc) (note: sparm=identityfirst) +;M428 by remap: kinstype==1 (xyzab-tdr kinematics) o<428remap>sub - # = 1 ; xyzac,xyzbc - # = 3 ; set N as required: motion.analog-out-0N + # = 1 ; xyzab-tdr -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc b/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc index 3fa610c8ee0..ff81c491a6f 100644 --- a/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: kinstype==0 Identity kinematics o<429remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini b/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini index 75eb952757e..1871559c75d 100644 --- a/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini +++ b/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini @@ -25,8 +25,8 @@ SUBROUTINE_PATH = ./remap_subs [KINS] #NOTE: -# switchkins-type == 0 is identity kins -# switchkins-type == 1 is xyzab-tdr-kins +# kinstype 0 is identity kins +# kinstype 1 is xyzab-tdr-kins KINEMATICS = xyzab_tdr_kins JOINTS = 5 @@ -36,8 +36,6 @@ KINEMATICS = xyzab_tdr_kins HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = xyzab-tdr-postgui.hal -# net for control of motion.switchkins-type -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type # Values '(x,z)-offsets' for geometric offset of the rotary-assembly and the # values '(x,y,z)-rot-point' that describe the position of the @@ -76,8 +74,8 @@ HALCMD = sets :x-offset -20 HALCMD = sets :z-offset -10 [HALUI] -# M429:identity kins (motion.switchkins-type==0 startupDEFAULT) -# M428:xyzab-tdr kins (motion.switchkins-type==1) +# M429:identity kins (kinstype 0, startupDEFAULT) +# M428:xyzab-tdr kins (kinstype 1) MDI_COMMAND = M429 MDI_COMMAND = M428 diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/python/remap.py b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/python/remap.py index c8b15c9c4e9..f4f9506a846 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/python/remap.py +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/python/remap.py @@ -871,7 +871,7 @@ def g53x_core(self): # switch to the dedicated TWP work offsets self.execute("G59", lineno()) # activate TOOL kinematics - self.execute("M68 E3 Q2") + self.execute("G12.1 P2") if (x,y,z) != (None,None,None): log.debug('G53.3 called') self.execute("G0 X%s Y%s Z%s %s%f %s%f" % (x, y, z, joint_letter_secondary, degrees(theta_2), joint_letter_primary, degrees(theta_1)), lineno()) diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/428remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/428remap.ngc index bcd3c730a1f..381a6116adf 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: kinstype==0 (IDENTITY kinematics) o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc index 0d14ad1bf82..d1b54b5250d 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: kinstype==1 TCP kinematics o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/430remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/430remap.ngc index 55fbf966e11..5f726a6df12 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: kinstype==2 Tool kinematics o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M430:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g531remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g531remap.ngc index b7c27d221d3..4b2fd293c61 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g531remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g531remap.ngc @@ -6,7 +6,7 @@ o100 if [EXISTS [#

]] o100 else #

= 0 ;if no P word has been passed we use the default (0) o100 endif -M68 E3 Q0 ;switch to identity kinematic +G13.1 ;back to identity kinematic M66 L0 E0 M530 P#

;orient the spindle with P word M66 L0 E0 diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g533remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g533remap.ngc index c25356b27a8..16d9687cbe8 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g533remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g533remap.ngc @@ -3,7 +3,7 @@ osub M66 L0 E0 ;force sync, stop read ahead o100 if [[EXISTS [#]] AND [EXISTS [#]] AND [EXISTS [#]]] - M68 E3 Q0 ;switch to identity kinematic + G13.1 ;back to identity kinematic o100 else (abort, G53.3: X,Y and Z words are required) ;it is an error if X,Y or Z word is missing o100 endif diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g536remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g536remap.ngc index 718a572afae..a8b628a930c 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g536remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g536remap.ngc @@ -6,7 +6,7 @@ o100 if [EXISTS [#

]] o100 else #

= 0 ;if no P word has been passed we use the default (0) o100 endif -M68 E3 Q1 ;switch to tcp kinematic +G12.1 P1 ;switch to tcp kinematic M66 L0 E0 M530 P#

;orient the spindle with P word M66 L0 E0 diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g69remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g69remap.ngc index fd37ea30837..9efd1b7db29 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g69remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g69remap.ngc @@ -3,7 +3,7 @@ osub M66 L0 E0 ; force sync, stop read ahead M469 ; call the python G69_core code -M68 E3 Q0 ; switch to identity kins +G13.1 ; back to identity kins M68 E2 Q0 ; reset twp-state to 'undefined' (0) G54 ; switch to G54 M66 L0 E0 ; force sync, stop read ahead diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_with_twp_reset.ngc b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_with_twp_reset.ngc index 492552977e2..1cbf3d41db7 100755 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_with_twp_reset.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_with_twp_reset.ngc @@ -7,7 +7,7 @@ o sub ;(msg, on_abort START) M68 E2 Q0 ; reset twp-state to 'undefined' (0) -M68 E3 Q0 ; set IDENTITY kins +G13.1 ; back to identity kins G64 P0.01 ; reset the toolpath tolerance as this sometimes gets set to zero on estop events G54 ; switch to G54 (msg, on_abort END) diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini index 0e430c12691..06b9cd5d23f 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini @@ -80,8 +80,6 @@ POSTGUI_HALFILE = xyzacb-trsrn_postgui.hal # signal reflecting twp states (0=undefined, 1=defined, 2=active) HALCMD = net twp-status <= motion.analog-out-02 -# connection required for control of motion.switchkins-type -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type # connections required for the kinematics component HALCMD = net :tool-offset motion.tooloffset.z xyzacb_trsrn_kins.tool-offset-z @@ -124,7 +122,7 @@ HALCMD = net :rotary-b joint.4.pos-fb xyzacb-trsrn-gui.rot HALCMD = net :rotary-c joint.5.pos-fb xyzacb-trsrn-gui.rotary_c HALCMD = net :tool-diam halui.tool.diameter xyzacb-trsrn-gui.tool_diameter HALCMD = net :tool-offset xyzacb-trsrn-gui.tool_length -HALCMD = net :kinstype-select xyzacb-trsrn-gui.kinstype_select +HALCMD = net :kinstype-current motion.kins-type xyzacb-trsrn-gui.kinstype_select HALCMD = net :nutation-angle xyzacb-trsrn-gui.nutation_angle HALCMD = net :pivot-y xyzacb-trsrn-gui.pivot_y HALCMD = net :pivot-z xyzacb-trsrn-gui.pivot_z @@ -155,9 +153,9 @@ HALCMD = net twp-is-active xyzacb-trsrn-gui.twp [HALUI] # NOTE: kinstype==0 is identity kins because sparm=identityfirst -# M428:identity kins (motion.switchkins-type==0 startupDEFAULT) -# M429: tcp kins (motion.switchkins-type==1) -# M430: tool kins (motion.switchkins-type==2) +# M428:identity kins (kinstype 0, startupDEFAULT) +# M429: tcp kins (kinstype 1) +# M430: tool kins (kinstype 2) MDI_COMMAND = M428 MDI_COMMAND = M429 MDI_COMMAND = M430 diff --git a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini index 44e6144e653..d9ae382fefc 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini +++ b/configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini @@ -77,8 +77,6 @@ POSTGUI_HALFILE = xyzbca-trsrn_postgui.hal # signal reflecting twp states (0=undefined, 1=defined, 2=active) HALCMD = net twp-status <= motion.analog-out-02 -# connection required for control of motion.switchkins-type -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type # connections required for the kinematics component HALCMD = net :tool-offset motion.tooloffset.z xyzbca_trsrn_kins.tool-offset-z @@ -121,7 +119,7 @@ HALCMD = net :rotary-b joint.4.pos-fb xyzbca-trsrn-gui.rot HALCMD = net :rotary-c joint.5.pos-fb xyzbca-trsrn-gui.rotary_c HALCMD = net :tool-diam halui.tool.diameter xyzbca-trsrn-gui.tool_diameter HALCMD = net :tool-offset xyzbca-trsrn-gui.tool_length -HALCMD = net :kinstype-select xyzbca-trsrn-gui.kinstype_select +HALCMD = net :kinstype-current motion.kins-type xyzbca-trsrn-gui.kinstype_select HALCMD = net :nutation-angle xyzbca-trsrn-gui.nutation_angle HALCMD = net :pivot-x xyzbca-trsrn-gui.pivot_x HALCMD = net :pivot-z xyzbca-trsrn-gui.pivot_z @@ -152,9 +150,9 @@ HALCMD = net twp-is-active xyzbca-trsrn-gui.twp [HALUI] # NOTE: kinstype==0 is identity kins because sparm=identityfirst -# M428:identity kins (motion.switchkins-type==0 startupDEFAULT) -# M429: tcp kins (motion.switchkins-type==1) -# M430: tool kins (motion.switchkins-type==2) +# M428:identity kins (kinstype 0, startupDEFAULT) +# M429: tcp kins (kinstype 1) +# M430: tool kins (kinstype 2) MDI_COMMAND = M428 MDI_COMMAND = M429 MDI_COMMAND = M430 diff --git a/configs/sim/axis/vismach/millturn/millturn.ini b/configs/sim/axis/vismach/millturn/millturn.ini index 57776eeb38c..575947d9dce 100644 --- a/configs/sim/axis/vismach/millturn/millturn.ini +++ b/configs/sim/axis/vismach/millturn/millturn.ini @@ -14,7 +14,6 @@ JOINTS= 4 HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = millturn.hal -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = millturn-postgui.hal [RS274NGC] diff --git a/configs/sim/axis/vismach/millturn/millturn.txt b/configs/sim/axis/vismach/millturn/millturn.txt index b6cbe143a03..29b9960d6e4 100644 --- a/configs/sim/axis/vismach/millturn/millturn.txt +++ b/configs/sim/axis/vismach/millturn/millturn.txt @@ -7,9 +7,8 @@ For additional information see the README in the millturn folder. 2) pyvcp buttons are provided to switch between mill and turn kinematics. The buttons issue remapped commands M428,M429. These commands -a) set the motion.switchkins-type pin and -b) force a synchronization using a motion input read command. -c) set softlimits according to values set in millturn.ini [AXIS_X] and [AXIS_Z] section. +a) select the kinematics with G12.1, which synchronizes interpreter and motion itself. +b) set softlimits according to values set in millturn.ini [AXIS_X] and [AXIS_Z] section. 3) when set for mill, default assignments are: diff --git a/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc b/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc index ca6225fb421..63a2d118a6d 100644 --- a/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc @@ -1,29 +1,18 @@ ;M428 by remap: select mill kins o<428remap>sub - # = 3 ; set N as required: motion.analog-out-0N # = 0 ; mill -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing) - (debug,STOP) - M2 -o1 endif - - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value + G12.1 P# ; select kinstype, syncs interp and motion M128 ; switch limits G10 L2 P7 X-290 Y0 Z-160 A0 ; reset home offset G59.1 ; activate home offset - M66 E0 L0 ; force synch + M66 E0 L0 ; force synch, M128 changed the limits ;(debug, M428: mill) -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE 0]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc b/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc index 26207430a88..7be809a0d3e 100644 --- a/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc @@ -1,29 +1,18 @@ ;M429 by remap: select turn kins o<429remap>sub - # = 3 ; set N as required: motion.analog-out-0N # = 1 ; turn kins -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]FEATURE==8) - (debug,STOP) - M2 -o1 endif - - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value + G12.1 P# ; select kinstype, syncs interp and motion M129 ; switch limits G10 L2 P8 X-160 Y0 Z-290 A0 ; reset home offset G59.2 ; activate home offset - M66 E0 L0 ; force synch + M66 E0 L0 ; force synch, M129 changed the limits ;(debug, M429: turn) -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE 1]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub From 4ebcd25e1d664c7000f0891a58db4b85c421cb31 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 17:16:13 +1000 Subject: [PATCH 7/9] configs: select kinematics with G12.1 in the remaining switchkins sims The rest of the sim configs that shipped with switchkins chose their kinematics by writing motion.switchkins-type through an analog output, which motion now reports as deprecated: bridgemill, table-rotary-tilting, hexapod-sim, melfa-sim, puma and the three copies of scara. Same change as the comp sims got. The M428, M429 and M430 remaps use G12.1 and G13.1, which drops the M66 sync either side of every switch, the test for the hal pin, and the #5399 clobber each M66 costs. The check that the switch took reads #<_kins_type>. The [HAL] net from motion.analog-out-03 goes with them, and the two halshow watch lists follow motion.kins-type instead of the pin that used to drive it. No sim config selects kinematics from HAL now. --- .../axis/vismach/5axis/bridgemill/5axis.ini | 1 - .../5axis/bridgemill/remap_subs/428remap.ngc | 17 +++-------------- .../5axis/bridgemill/remap_subs/429remap.ngc | 17 +++-------------- .../5axis/bridgemill/remap_subs/430remap.ngc | 17 +++-------------- .../vismach/5axis/table-rotary-tilting/README | 3 --- .../remap_subs/428remap.ngc | 17 +++-------------- .../remap_subs/429remap.ngc | 17 +++-------------- .../remap_subs/430remap.ngc | 17 +++-------------- .../table-rotary-tilting/switchkins.halshow | 3 +-- .../5axis/table-rotary-tilting/xyzac-trt.ini | 12 +++++------- .../5axis/table-rotary-tilting/xyzac-trt.txt | 8 +++----- .../5axis/table-rotary-tilting/xyzbc-trt.ini | 12 +++++------- .../5axis/table-rotary-tilting/xyzbc-trt.txt | 8 +++----- .../sim/axis/vismach/hexapod-sim/hexapod.ini | 1 - .../hexapod-sim/remap_subs/428remap.ngc | 17 +++-------------- .../hexapod-sim/remap_subs/429remap.ngc | 17 +++-------------- .../hexapod-sim/remap_subs/430remap.ngc | 17 +++-------------- configs/sim/axis/vismach/melfa-sim/melfa.ini | 1 - configs/sim/axis/vismach/melfa-sim/melfa.txt | 8 ++++---- .../vismach/melfa-sim/remap_subs/428remap.ngc | 18 +++--------------- .../vismach/melfa-sim/remap_subs/429remap.ngc | 18 +++--------------- .../vismach/melfa-sim/remap_subs/430remap.ngc | 18 +++--------------- configs/sim/axis/vismach/puma/puma.ini | 1 - configs/sim/axis/vismach/puma/puma560.halshow | 2 +- configs/sim/axis/vismach/puma/puma560.ini | 1 - configs/sim/axis/vismach/puma/puma560.txt | 8 ++++---- configs/sim/axis/vismach/puma/puma560_uvw.ini | 1 - configs/sim/axis/vismach/puma/puma_cube.ini | 1 - .../axis/vismach/puma/remap_subs/428remap.ngc | 17 +++-------------- .../axis/vismach/puma/remap_subs/429remap.ngc | 17 +++-------------- .../axis/vismach/puma/remap_subs/430remap.ngc | 17 +++-------------- .../axis/vismach/scara/remap_subs/428remap.ngc | 17 +++-------------- .../axis/vismach/scara/remap_subs/429remap.ngc | 17 +++-------------- .../axis/vismach/scara/remap_subs/430remap.ngc | 17 +++-------------- configs/sim/axis/vismach/scara/scara.ini | 1 - .../non-trivial/scara/remap_subs/428remap.ngc | 17 +++-------------- .../non-trivial/scara/remap_subs/429remap.ngc | 17 +++-------------- .../non-trivial/scara/remap_subs/430remap.ngc | 17 +++-------------- .../non-trivial/scara/remap_subs/428remap.ngc | 17 +++-------------- .../non-trivial/scara/remap_subs/429remap.ngc | 17 +++-------------- .../non-trivial/scara/remap_subs/430remap.ngc | 17 +++-------------- 41 files changed, 98 insertions(+), 385 deletions(-) diff --git a/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini b/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini index 8ca0552431a..38e706fac22 100644 --- a/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini +++ b/configs/sim/axis/vismach/5axis/bridgemill/5axis.ini @@ -41,7 +41,6 @@ CYCLE_TIME = 0.010 HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = 5axisgui.hal -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = 5axis_postgui.hal [HALUI] diff --git a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc index 4ab3aaf922d..e9529f6d0f8 100644 --- a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype=0 genhexkins o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc index 54726d37a6c..0291e69889d 100644 --- a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 Identity kinematics o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc index 7586236a003..886fe727740 100644 --- a/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 userk kins o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/README b/configs/sim/axis/vismach/5axis/table-rotary-tilting/README index 4166a10fc2a..b85e076dd16 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/README +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/README @@ -17,9 +17,6 @@ Demonstrations: *********************************************** Note: IMPORTANT ini file requirements: -[HAL] -HALCMD = net :kinstype-select <= motion.analog-out-0N => motion.switchkins-type - [RS274NGC] SUBROUTINE_PATH = ./remap_subs REMAP = M428 modalgroup=10 ngc=428remap diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc index 46e2d01ba5b..5255b230004 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: kinstype==1 (xyzac,xyzbc) (note: sparm=identityfirst) o<428remap>sub # = 1 ; xyzac,xyzbc - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc index 3fa610c8ee0..be20d5b06b7 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: kinstype==0 Identity kinematics o<429remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc index 65a82221335..6679a3080da 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: kinstype==2 userk kins o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M430:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow b/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow index ede94bdc5bd..014d9531eb7 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins.halshow @@ -1,5 +1,4 @@ -pin+motion.analog-out-03 -pin+motion.switchkins-type +pin+motion.kins-type pin+joint.0.pos-cmd pin+joint.1.pos-cmd 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 6f78ca8cb20..cd600d3bd82 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 @@ -38,8 +38,8 @@ SUBROUTINE_PATH = ./remap_subs [KINS] #NOTE: for backwrds compatibility !!!!!!!!!!!!!!!!!!! -# default switchkins-type == 0 is xyzac-trt-kins -# here switchkins-type == 0 is identity kins +# default kinstype 0 is xyzac-trt-kins +# here kinstype 0 is identity kins KINEMATICS = xyzac-trt-kins sparm=identityfirst JOINTS = 5 @@ -48,8 +48,6 @@ KINEMATICS = xyzac-trt-kins sparm=identityfirst HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = switchkins_postgui.hal -# net for control of motion.switchkins-type -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type # vismach xyzac-trt-gui items HALCMD = loadusr -W xyzac-trt-gui @@ -73,9 +71,9 @@ HALCMD = setp xyzac-trt-kins.conventional-directions 0 [HALUI] # NOTE: kinstype==0 is identity kins because sparm=identityfirst -# M429:identity kins (motion.switchkins-type==0 startupDEFAULT) -# M428:xyzac kins (motion.switchkins-type==1) -# M430:userk kins (motion.switchkins-type==2) +# M429:identity kins (kinstype 0, startupDEFAULT) +# M428:xyzac kins (kinstype 1) +# M430:userk kins (kinstype 2) MDI_COMMAND = M429 MDI_COMMAND = M428 MDI_COMMAND = M430 diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt index acdbdebe6a5..7bc132e3159 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.txt @@ -6,11 +6,9 @@ Uses remapped user m codes for kins switch: M428: XYZAC (TCP) M430: userk Kinematics -A hal net is required to connect the -analog out pin N, Example (for N=3): - - net :kinstype-select <= motion.analog-out-03 - net :kinstype-select => motion.switchkins-type +The kinematics type is selected with +G12.1 and G13.1, no hal connection is +required. Hal Input pins: xyzac-trt-kins.y-offset 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 690b56ef8e7..518fae78a6f 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 @@ -38,8 +38,8 @@ SUBROUTINE_PATH = ./remap_subs [KINS] #NOTE: for backwrds compatibility !!!!!!!!!!!!!!!!!!! -# default switchkins-type == 0 is xyzbc-trt-kins -# here switchkins-type == 0 is identity kins +# default kinstype 0 is xyzbc-trt-kins +# here kinstype 0 is identity kins KINEMATICS = xyzbc-trt-kins sparm=identityfirst JOINTS = 5 @@ -48,8 +48,6 @@ KINEMATICS = xyzbc-trt-kins sparm=identityfirst HALFILE = LIB:basic_sim.tcl POSTGUI_HALFILE = switchkins_postgui.hal -# net for control of motion.switchkins-type -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type # vismach xyzbc-trt-gui items HALCMD = loadusr -W xyzbc-trt-gui @@ -73,9 +71,9 @@ HALCMD = setp xyzbc-trt-kins.conventional-directions 0 [HALUI] # NOTE: kinstype==0 is identity kins because sparm=identityfirst -# M429:identity kins (motion.switchkins-type==0 startupDEFAULT) -# M428:xyzbc kins (motion.switchkins-type==1) -# M430:userk kins (motion.switchkins-type==2) +# M429:identity kins (kinstype 0, startupDEFAULT) +# M428:xyzbc kins (kinstype 1) +# M430:userk kins (kinstype 2) MDI_COMMAND = M429 MDI_COMMAND = M428 MDI_COMMAND = M430 diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt index 4641cf6da28..20595fb39c7 100644 --- a/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt +++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt @@ -6,11 +6,9 @@ Uses remapped user m codes for kins switch: M428: XYZBC (TCP) M430: userk Kinematics -A hal net is required to connect the -analog out pin N, Example (for N=3): - - net :kinstype-select <= motion.analog-out-03 - net :kinstype-select => motion.switchkins-type +The kinematics type is selected with +G12.1 and G13.1, no hal connection is +required. Hal Input pins: xyzbc-trt-kins.x-offset diff --git a/configs/sim/axis/vismach/hexapod-sim/hexapod.ini b/configs/sim/axis/vismach/hexapod-sim/hexapod.ini index 6c691b1310c..e1d7f49dcad 100644 --- a/configs/sim/axis/vismach/hexapod-sim/hexapod.ini +++ b/configs/sim/axis/vismach/hexapod-sim/hexapod.ini @@ -40,7 +40,6 @@ HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = kinematics.hal HALCMD = loadusr -W hexagui -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = hexapod_postgui.hal [HALUI] diff --git a/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc b/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc index 4ab3aaf922d..e9529f6d0f8 100644 --- a/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/hexapod-sim/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype=0 genhexkins o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc b/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc index 54726d37a6c..0291e69889d 100644 --- a/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/hexapod-sim/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 Identity kinematics o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc b/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc index 7586236a003..886fe727740 100644 --- a/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 userk kins o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/melfa-sim/melfa.ini b/configs/sim/axis/vismach/melfa-sim/melfa.ini index 5bb62b6eaf1..247b00f7596 100644 --- a/configs/sim/axis/vismach/melfa-sim/melfa.ini +++ b/configs/sim/axis/vismach/melfa-sim/melfa.ini @@ -12,7 +12,6 @@ HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = melfa_dh.hal HALCMD = loadusr -W melfagui -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = melfa-postgui.hal [RS274NGC] diff --git a/configs/sim/axis/vismach/melfa-sim/melfa.txt b/configs/sim/axis/vismach/melfa-sim/melfa.txt index 588d90742bb..9ccf54bb374 100644 --- a/configs/sim/axis/vismach/melfa-sim/melfa.txt +++ b/configs/sim/axis/vismach/melfa-sim/melfa.txt @@ -8,10 +8,10 @@ with 6 revolute joints. 2) pyvcp buttons are provided to switch between genserkins and identity kinematics. The buttons issue remapped -commands M428,M429. These commands a) -set the motion.switchkins-type pin and -b) force a synchronization using a -motion input read command. +commands M428,M429. These commands +select the kinematics with G12.1, which +synchronizes interpreter and motion +itself. 3) when set for identity kins, default assignments are: diff --git a/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc b/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc index 8669ac0e781..c7dda9ab73d 100644 --- a/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/melfa-sim/remap_subs/428remap.ngc @@ -1,28 +1,16 @@ ;M428 by remap: select genserkins o<428remap>sub - # = 3 ; set N as required: motion.analog-out-0N # = 0 ; genserkins -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]FEATURE==8) - (debug,STOP) - M2 -o1 endif - - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value + G13.1 ; back to kinstype 0, syncs interp and motion G10 L2 P7 X0 Y0 Z0 A-180 B0 C0 G59.1 - M66 E0 L0 ; force synch ; (debug, M428:genserkins) -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE 0]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE 0]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc b/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc index 32dff4d4742..2d28bda961a 100644 --- a/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc @@ -1,28 +1,16 @@ ;M429 by remap: select identity kins o<429remap>sub - # = 3 ; set N as required: motion.analog-out-0N # = 1 ; identity kins -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]FEATURE==8) - (debug,STOP) - M2 -o1 endif - - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value + G12.1 P# ; select kinstype, syncs interp and motion G10 L2 P8 X0 Y-90 Z0 A0 B90 C0 G59.2 - M66 E0 L0 ; force synch ; (debug, M429:identity kins) -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE 1]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE 1]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc b/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc index c7d087435f6..e81d4ed4ac2 100644 --- a/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/melfa-sim/remap_subs/430remap.ngc @@ -1,26 +1,14 @@ ;M430 by remap: select gensertool kins o<430remap>sub - # = 3 ; set N as required: motion.analog-out-0N # = 2 ; gensertool kins -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M430:Missing [RS274NGC]FEATURE==8) - (debug,STOP) - M2 -o1 endif - - M66 E0 L0 ; force synch - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion ; (debug, M429:identity kins) -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE 2]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE 2]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/puma/puma.ini b/configs/sim/axis/vismach/puma/puma.ini index caa72922068..5cbcef99ab0 100644 --- a/configs/sim/axis/vismach/puma/puma.ini +++ b/configs/sim/axis/vismach/puma/puma.ini @@ -12,7 +12,6 @@ HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = puma_dh.hal HALCMD = loadusr -W pumagui -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = puma_postgui.hal [RS274NGC] diff --git a/configs/sim/axis/vismach/puma/puma560.halshow b/configs/sim/axis/vismach/puma/puma560.halshow index 11b090d98c6..eb532d6e928 100644 --- a/configs/sim/axis/vismach/puma/puma560.halshow +++ b/configs/sim/axis/vismach/puma/puma560.halshow @@ -1,4 +1,4 @@ -pin+motion.switchkins-type +pin+motion.kins-type pin+kinstype.is-0 pin+kinstype.is-1 pin+kinstype.is-2 diff --git a/configs/sim/axis/vismach/puma/puma560.ini b/configs/sim/axis/vismach/puma/puma560.ini index c461b1a929d..84d9017e6ed 100644 --- a/configs/sim/axis/vismach/puma/puma560.ini +++ b/configs/sim/axis/vismach/puma/puma560.ini @@ -16,7 +16,6 @@ HALUI = halui HALCMD = loadusr -W puma560gui HALFILE = LIB:basic_sim.tcl HALFILE = puma560_dh.hal -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = puma560_postgui.hal [RS274NGC] diff --git a/configs/sim/axis/vismach/puma/puma560.txt b/configs/sim/axis/vismach/puma/puma560.txt index 4fb318abbba..7353b02753c 100644 --- a/configs/sim/axis/vismach/puma/puma560.txt +++ b/configs/sim/axis/vismach/puma/puma560.txt @@ -8,10 +8,10 @@ with 6 revolute joints. 2) pyvcp buttons are provided to switch between genserkins and identity kinematics. The buttons issue remapped -commands M428,M429. These commands a) -set the motion.switchkins-type pin and -b) force a synchronization using a -motion input read command. +commands M428,M429. These commands +select the kinematics with G12.1, which +synchronizes interpreter and motion +itself. 3) when set for identity kins, default assignments are: diff --git a/configs/sim/axis/vismach/puma/puma560_uvw.ini b/configs/sim/axis/vismach/puma/puma560_uvw.ini index 774972ef2f1..49b34415c7b 100644 --- a/configs/sim/axis/vismach/puma/puma560_uvw.ini +++ b/configs/sim/axis/vismach/puma/puma560_uvw.ini @@ -16,7 +16,6 @@ HALUI = halui HALCMD = loadusr -W puma560gui HALFILE = LIB:basic_sim.tcl HALFILE = puma560_dh.hal -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = puma560_postgui.hal [RS274NGC] diff --git a/configs/sim/axis/vismach/puma/puma_cube.ini b/configs/sim/axis/vismach/puma/puma_cube.ini index 9c2d4a17315..5db24db99bd 100644 --- a/configs/sim/axis/vismach/puma/puma_cube.ini +++ b/configs/sim/axis/vismach/puma/puma_cube.ini @@ -103,7 +103,6 @@ HALUI = halui HALFILE = LIB:basic_sim.tcl HALFILE = puma_dh.hal HALCMD = loadusr -W pumagui -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = puma_postgui.hal [HALUI] diff --git a/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc b/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc index 36f8ee3e499..2b2016bfe50 100644 --- a/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/puma/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype=0 (default) o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc b/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc index 627d547052b..25a2ef41339 100644 --- a/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/puma/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 (Identity kinematics) o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc b/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc index 5af12f4fbf2..f5d2db707aa 100644 --- a/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/puma/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 (userk kins) o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc b/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc index 8698782fff7..f983c3870ea 100644 --- a/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc +++ b/configs/sim/axis/vismach/scara/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype==0 (default) o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc b/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc index 627d547052b..25a2ef41339 100644 --- a/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc +++ b/configs/sim/axis/vismach/scara/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 (Identity kinematics) o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc b/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc index 5af12f4fbf2..f5d2db707aa 100644 --- a/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc +++ b/configs/sim/axis/vismach/scara/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 (userk kins) o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/axis/vismach/scara/scara.ini b/configs/sim/axis/vismach/scara/scara.ini index baf72c9fb7a..32499dac8c7 100644 --- a/configs/sim/axis/vismach/scara/scara.ini +++ b/configs/sim/axis/vismach/scara/scara.ini @@ -58,7 +58,6 @@ KINEMATICS = scarakins coordinates=xyzcab HALUI = halui HALFILE = LIB:basic_sim.tcl HALCMD = loadusr -W scaragui -HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type POSTGUI_HALFILE = scara_postgui.hal [HALUI] diff --git a/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc b/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc index 8698782fff7..f983c3870ea 100644 --- a/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc +++ b/configs/sim/qtaxis/non-trivial/scara/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype==0 (default) o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc b/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc index 627d547052b..25a2ef41339 100644 --- a/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc +++ b/configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 (Identity kinematics) o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc b/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc index 5af12f4fbf2..f5d2db707aa 100644 --- a/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc +++ b/configs/sim/qtaxis/non-trivial/scara/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 (userk kins) o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub diff --git a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc index 8698782fff7..f983c3870ea 100644 --- a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc +++ b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc @@ -1,24 +1,13 @@ ;M428 by remap: select kinstype==0 (default) o<428remap>sub # = 0 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M428:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G13.1 ; back to kinstype 0, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M428: Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M428: Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<428remap>endsub diff --git a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc index 627d547052b..25a2ef41339 100644 --- a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc +++ b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc @@ -1,24 +1,13 @@ ;M429 by remap: select kinstype==1 (Identity kinematics) o<429remap>sub # = 1 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M429:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M429:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M429:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<429remap>endsub diff --git a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc index 5af12f4fbf2..f5d2db707aa 100644 --- a/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc +++ b/configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc @@ -1,24 +1,13 @@ ;M430 by remap: select kinstype==2 (userk kins) o<430remap>sub # = 2 - # = 3 ; set N as required: motion.analog-out-0N -o1 if [exists [#<_hal[motion.switchkins-type]>]] -o1 else - (debug,M30:Missing [RS274NGC]HAL_PIN_VARS=1) - (debug,STOP) - M2 -o1 endif - - M68 E# Q# ; set kinstype value - M66 E0 L0 ; force synch + G12.1 P# ; select kinstype, syncs interp and motion -o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #]] - (debug,M430:Wrong motion.switchkins-type) - (debug,or missing hal net to analog-out-0x) +o2 if [[#<_task> EQ 1] AND [#<_kins_type> NE #]] + (debug,M430:Wrong kinematics type) (debug,STOP) M2 -o2 else o2 endif o<430remap>endsub From 83c439aa77af0334cae9c7e825741d913fbbabfa Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 19:13:27 +1000 Subject: [PATCH 8/9] docs: stop offering the deprecated pin as an equal way to switch The G-code chapter told the reader a config may select the kinematics "from G-code, from that pin, or from both", and the switchkins chapter said the same twice, in its introduction and again under G-code commands. All three predate motion reporting the pin as deprecated, and they contradict it. They now say the pin is deprecated and why, in the same words as the man page. The G-code chapter keeps the fact that the pin takes the same numbering, which is what somebody migrating away from it needs to know. --- docs/src/gcode/g-code.adoc | 11 +++++++---- docs/src/motion/switchkins.adoc | 24 +++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/src/gcode/g-code.adoc b/docs/src/gcode/g-code.adoc index bcaeb998dc0..7f7e019f1c3 100644 --- a/docs/src/gcode/g-code.adoc +++ b/docs/src/gcode/g-code.adoc @@ -945,10 +945,13 @@ G13.1 'G12.1' selects one of the kinematics provided by a switchable kinematics module, and 'G13.1' cancels back to kinematics 0. The 'P' word is the -kinematics number, the same number that the `motion.switchkins-type` pin -takes, so 'G13.1' and `G12.1 P0` do the same thing. A config may select -the kinematics from G-code, from that pin, or from both: each is acted on -when it changes, so the most recent request is the one in force. +kinematics number, so 'G13.1' and `G12.1 P0` do the same thing. + +These are the way to select a kinematics. The `motion.switchkins-type` +HAL pin does the same thing and takes the same numbering, but it is +deprecated: the interpreter never sees it, so a program is read, its +limits checked and its path looked ahead in whatever kinematics the +interpreter last knew about, which need not be the one that runs it. Both codes are queue synchronisation points. The interpreter waits for queued motion to finish before the kinematics changes, so no move is ever diff --git a/docs/src/motion/switchkins.adoc b/docs/src/motion/switchkins.adoc index 67eab672180..dbda6e4cc52 100644 --- a/docs/src/motion/switchkins.adoc +++ b/docs/src/motion/switchkins.adoc @@ -21,17 +21,18 @@ switched to identity kinematics for control of individual joints after homing. The kinematics type is selected with 'G12.1 P-' and 'G13.1', from a -G-code program or by interactive MDI commands. It can also be selected -by a motion module HAL pin, which allows the halui provisions for -activating MDI commands to be used so that buttons select the -kinematics type from hardware controls or a virtual panel (PyVCP, -GladeVCP, etc.). +G-code program or by interactive MDI commands. Buttons on a virtual +panel (PyVCP, GladeVCP, etc.) or on hardware controls select a +kinematics type through the halui provisions for activating MDI +commands. Changing the kinematics type requires the interpreter and motion parts -of LinuxCNC to be *synchronized*. 'G12.1' and 'G13.1' do this -themselves. When the HAL pin is written instead, the G-code must force -synchronization, typically with a HAL pin 'read' command (M66 E0 L0) -immediately after altering the pin. +of LinuxCNC to be *synchronized*, which 'G12.1' and 'G13.1' do +themselves. + +A deprecated HAL pin, 'motion.switchkins-type', selects a kinematics +type as well. It is described under Usage below, because existing +configurations use it. == Switchable Kinematic Modules @@ -178,8 +179,9 @@ These codes ask motion for the kinstype directly and synchronize task and motion themselves, so no HAL connection and no separate sync command are needed. The G-code words and the *motion.switchkins-type* pin are both acted on when they change, so whichever asked most recently is the one in -force, and a config can use either or both. *motion.kins-type* reports -what is currently selected. +force. *motion.kins-type* reports what is currently selected. + +The pin is deprecated, see the warning under HAL Connections. The kinstype in force is readable in G-code as '#<_kins_type>', which lets a subroutine restore whatever its caller had selected: From 9d18951e195d1ec54dbfd97361ab27a712eaadd9 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 12 Aug 2026 21:02:46 +1000 Subject: [PATCH 9/9] docs: lead with the deprecation notice for the switchkins pin The paragraph read as though the pin were an equal alternative that happened to carry a caveat. State the deprecation first, as a warning. --- docs/src/gcode/g-code.adoc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/src/gcode/g-code.adoc b/docs/src/gcode/g-code.adoc index 7f7e019f1c3..ef318bc0e43 100644 --- a/docs/src/gcode/g-code.adoc +++ b/docs/src/gcode/g-code.adoc @@ -947,11 +947,13 @@ G13.1 module, and 'G13.1' cancels back to kinematics 0. The 'P' word is the kinematics number, so 'G13.1' and `G12.1 P0` do the same thing. -These are the way to select a kinematics. The `motion.switchkins-type` -HAL pin does the same thing and takes the same numbering, but it is -deprecated: the interpreter never sees it, so a program is read, its -limits checked and its path looked ahead in whatever kinematics the -interpreter last knew about, which need not be the one that runs it. +[WARNING] +Deprecation notice: selecting the kinematics by writing the +`motion.switchkins-type` HAL pin is deprecated. It takes the same +numbering and still works, but it does not tell the interpreter that +anything changed, so a program is read, its limits checked and its path +looked ahead in whatever kinematics the interpreter last knew about, +which need not be the one that runs it. Use 'G12.1' and 'G13.1'. Both codes are queue synchronisation points. The interpreter waits for queued motion to finish before the kinematics changes, so no move is ever