Automatic workholding
Ctrl models each automatic workholding device as an independently indexed peripheral. A device may be a power chuck, collet, expanding mandrel, or another mechanism that supports external and internal grip configurations. A part program can select the grip configuration before it asks the machine controller to clamp or unclamp the part.
Grip selection is lasting machine intent. Ctrl publishes and persists it, while the machine action controller owns the physical mechanism, pressure, feedback, and interlocks.
Configure the available devices
Section titled “Configure the available devices”Set the number of automatic workholding devices in the machine INI:
[CTRL]AUTOMATIC_WORKHOLDING_DEVICES = 1The device count must be a non-negative integer. Omitting it or setting it to 0 disables automatic-workholding integration. A configured device is available on any machine type; explicit peripheral configuration, rather than the machine’s axis layout, controls whether Ctrl registers the integration.
Devices use stable, zero-based machine-local indices. Device 0 is the first configured workholding mechanism, device 1 is the second, and so on. A workholding index does not identify or imply a LinuxCNC spindle or axis.
Use semantic clamp commands
Section titled “Use semantic clamp commands”Ctrl reserves these commands for automatic workholding:
| Code | Intent |
|---|---|
M10 |
Unclamp the selected workholding device |
M11 |
Clamp the selected workholding device |
M14 P<device> Q0 |
Select external/OD gripping for the indexed device |
M14 P<device> Q1 |
Select internal/ID gripping for the indexed device |
M14 requires both words: P is a configured, zero-based workholding device index, and Q is exactly 0 or 1. Missing arguments, fractional or unconfigured indices, and other mode values must fail before an executor request. For example, M14 P1 Q1 selects internal grip on device 1. Every device uses this same command; no per-device M-code configuration is needed.
M10 and M11 remain argument-free; their remap endpoint and machine wiring choose the target device.
M14 changes the grip configuration; they do not move the mechanism. The next M10 or M11 asks the workholding controller for a semantic result, and that controller translates the request into physical motion:
| Grip configuration | M10 unclamp |
M11 clamp |
|---|---|---|
| External/OD | Open outward | Close inward |
| Internal/ID | Retract inward | Expand outward |
This keeps the part program independent of valve polarity and cylinder layout. The machine controller must preserve the requested clamped or unclamped condition after the executor transaction finishes.
Understand the indexed Ctrl contract
Section titled “Understand the indexed Ctrl contract”For each configured index N, Ctrl provides:
| Interface | Meaning |
|---|---|
INI [CTRL] AUTOMATIC_WORKHOLDING_DEVICES |
Declares the number of indexed devices |
ctrl.workholding.N.grip-internal |
False for external gripping; true for internal gripping |
Executor ctrl.executor.workholding.N.grip.* |
Applies an M14 P<N> Q<mode> grip-selection request |
Selecting a grip mode in the operator panel submits M14 P<N> Q0 or M14 P<N> Q1 and waits for interpreter completion. The same machine remap handles operator-panel requests and part-program commands. Put grip-selection interlocks before the remap requests the grip executor; the executor only applies an accepted selection.
Ctrl persists the selected grip mode for each indexed device. At startup, restoration waits for the same powered-on, homed, idle readiness used for tool, feed, and RPM settings, then runs each configured device’s grip-selection M-code and requires successful interpreter completion. Restoration therefore uses the same remap interlocks. It never issues clamp or unclamp commands, and a rejected restoration is reported rather than applied directly.
Connect ctrl.workholding.N.grip-internal directly to the machine-owned workholding controller. That controller combines the pin with its semantic clamp or unclamp request. Do not use this pin as a direct valve command.
Add workholding remaps
Section titled “Add workholding remaps”Complete the shared peripheral remap setup first. Add these commands to the machine’s existing [RS274NGC] section:
REMAP = M10 modalgroup=10 python=m10_workholding_unclampREMAP = M11 modalgroup=10 python=m11_workholding_clampREMAP = M14 modalgroup=10 argspec=PQ python=m14_workholding_select_gripAdd the indexed action and grip-selection executors to the shared __init__ function in toplevel.py, before component.ready():
self.workholding = HalExecutor(self, "workholding.0.action", component)self.workholding_grips = [HalExecutor(self, "workholding.0.grip", component)]Add the operations to the shared remap.py module:
from math import isfinitefrom interpreter import INTERP_ERROR
def m10_workholding_unclamp(self, **words): yield from executor_execute(self, self.workholding, request=0)
def m11_workholding_clamp(self, **words): yield from executor_execute(self, self.workholding, request=1)
def m14_workholding_select_grip(self, **words): device = words["p"] mode = words["q"] if ( not isfinite(device) or device != int(device) or not 0 <= device < len(self.workholding_grips) ): self.set_errormsg("M14 requires a configured workholding device index in P") yield INTERP_ERROR return if mode not in (0, 1): self.set_errormsg("M14 requires Q0 for external or Q1 for internal grip") yield INTERP_ERROR return
yield from executor_execute( self, self.workholding_grips[int(device)], request=int(mode) )Wire remap.executor.workholding.0.action.* to the machine-owned clamp controller. Wire each remap.executor.workholding.0.grip.* request output to the matching ctrl.executor.workholding.0.grip. input, and each ctrl.executor.workholding.0.grip. response output to its matching remap input. Ctrl acknowledges M14 after it has changed the grip mode and updated the indexed output pin.
For another device, append its executor to self.workholding_grips before component.ready(), such as HalExecutor(self, "workholding.1.grip", component), and wire its indexed pins. Keep the list in device-index order and consistent with AUTOMATIC_WORKHOLDING_DEVICES. The same M14 remap selects the endpoint using P.