Skip to content

Lathe txxxx - #4579

Closed
jorgeviloria wants to merge 17 commits into
LinuxCNC:masterfrom
jorgeviloria:lathe-txxxx
Closed

jorgeviloria wants to merge 17 commits into
LinuxCNC:masterfrom
jorgeviloria:lathe-txxxx

Conversation

@jorgeviloria

Copy link
Copy Markdown

No description provided.

Add [RS274NGC]LATHE_TXXXX so Fanuc-style Taa ww (T0101) selects the
turret station, changes the tool without M6, and applies geometry plus
wear. T1 is T0101; T0100 cancels the offset. M6 is a no-op.

Wear is stored on the tool table (WX/WZ/WD), set with G10 L12, and
legacy T10001..T10099 rows are copied into WX/WZ on load. Mill T/M6/G43
is unchanged when the INI switch is off.
With LATHE_TXXXX the Wear tab shows the same tools as the geometry
tab and edits WX/WZ on that row. All Offsets gains WX/WZ/WD columns.
Without the INI switch, T10001 remap wear is unchanged.
Gate the remap-era T10000+ wear migration on [RS274NGC]LATHE_TXXXX
(it ran unconditionally in tooldata_load) and run it from the task
constructor, emcIoInit, emcToolLoadToolTable and the standalone rs274
driver.  Warn at startup when a T remap is configured, since it takes
precedence over LATHE_TXXXX and silently disables the native T word.

Serialize pocketno/orientation/comment and the new wear fields in
CANON_TOOL_TABLE_update so remote NML clients see them, expose wear and
wear_diameter on the Python CANON_TOOL_TABLE type (and zero them in
tool_zero), keep a 7-argument SET_TOOL_TABLE_ENTRY binding for existing
Python remaps, initialize the returned entry in
GET_EXTERNAL_TOOL_TABLE(), and print WX/WZ/WD in tool_mmap_read.

G10 L12 now rejects cutter compensation being on and reports a clear
error when no wear word is given.
GladeVCP tooledit and QtPyVCP tool tables now parse and write the
native WX/WY/WZ/WA/WB/WC/WU/WV/WW/WD words instead of dropping them,
and with LATHE_TXXXX they edit WX/WZ/WD on the tool row rather than
using fake T10000+ rows (which are still preserved verbatim).

The Tcl tooledit (AXIS default TOOL_EDITOR) no longer skips rows that
contain wear tags and writes the wear words back on save; the wear
columns can be requested by name.  hide_columns in GladeVCP understands
the uppercase wear tokens.

Update tests/tooledit with a wear row.
Describe the exact Taa ww decoding rules, that T performs the M6 work,
the offset/geometry semantics, that WD is stored but not applied, the
gating of the T10000+ migration and that programs must use T0101.  Note
that a T remap takes precedence over LATHE_TXXXX, that the Tcl tooledit
preserves wear words, that tool_offset() in the Python API does not
change wear, and that tooldb programs should keep the wear words.
- g10-l12-wear: absolute + incremental wear (X/Z, U/W), R stored as WD,
  and the W axis geometry offset kept intact.
- g10-l12-cutter-comp: G10 L12 is rejected while cutter compensation is
  on.
- lathe-txxxx-off: with LATHE_TXXXX off there is no T10000+ migration
  and no native wear is applied to offsets.
Add iocontrol.0.toolchanger-fault (bit in) and
iocontrol.0.toolchanger-reason (s32 in) so the tool change logic can
report faults: they are copied to emcStatus->io.fault/reason (tracked by
the interpreter as #5600/#5601) and are only forced into the IO error
state while a tool change is active, so an idle fault does not error the
machine.
F1 of the lathe turret project: a userspace Python HAL component
(turret.manager) with a robust FSM for hydraulic single-solenoid
turrets (timeout on every transition, latched faults with codes,
adaptive stop lead, spurious strobe detection, service commands,
maintenance counters/intervals and the iocontrol handshake).  It reads
and writes the machine pins and the iocontrol pins by name, so changing
the pin mapping or the station count is a configuration reload - no
nets and no LinuxCNC restart.

Includes the Spanish QtPyVCP panel (estado, estaciones, alarmas,
mantenimiento y configuracion con asistente de pines), the mechanism
simulator with its sim configuration, the user documentation page and
the unit tests.
Port the turret controller to a userspace .comp (loadusr) with the same
pins, parameters and configuration as the Python manager.  It cannot
read JSON, so the configuration is exported to turret.conf with
turret.genconf (also written automatically by the panel).  Machine and
iocontrol pins are still resolved by name, so no nets are required and
turret.reload re-reads the configuration.  State is persisted in
<config>_state.conf (component) and <config>_state.json (panel, same
format as F1).

The simulation configuration includes a F2 HAL file (run_sim.sh f2).
Only station 1 has a position sensor, so the controller now starts
unhomed (the station restored from the last session is only a display
hint) and the first T/M6 performs the reference search automatically.

The panel gets a Referenciar button that works without service mode
(unclamp, rotate to position 1 + strobe, clamp) and an Avanzar
(mantener) hold-to-run jog: it rotates while held, settles/locates/
clamps safely on release or after jog_timeout, and if it crosses
position 1 during the jog the controller becomes referenced.  Both
features are implemented in the Python manager (F1) and in the compiled
component (F2), with new tests.
Review of the reference/jog feature:

* Reference detection now triggers on a strobe pulse while the position
  1 sensor is active (sensor-first and pulse-first both work) instead of
  requiring the sensor edge and the pulse in the same cycle.
* Entering a jog with the position 1 sensor already active references
  immediately (no need for a full revolution).
* Jogging is allowed from the released (service) state too.
* The panel disables the advance/step/clamp buttons unless service mode
  is on, and enables them when it is; the manual reference does not
  need service mode.
* Removed the now unused position 1 edge tracking in both the Python
  FSM and the C component.
* New FSM tests: jog from release and immediate reference at station 1.
The task lowers iocontrol.0.tool-prepare as soon as it reads
tool-prepared; deriving tool-changed from the current levels could drop
it before the task reads it, hanging the T/M6 change.  The Python
manager and the compiled component now latch prepared/changed until the
corresponding input goes low, so the task can consume them in order.

Also report a clear configuration alarm (E10) when the iocontrol inputs
cannot be written because they are still connected to a loopback net
(tool-prep-loop / tool-change-loop), and document the whole T0101
integration.

New manager tests: handshake latch race and loopback diagnostic.
Review of the Fanuc T integration found several conflicts:

* A manual selection from the panel left pocket-request set, which then
  hijacked every later T (the station came from the panel instead of the
  tool table P).  Manual requests are now used only while the panel's
  own prepare pin is active; T/M6 always uses iocontrol tool-prep-pocket.
* The panel's prepare/change/pocket-request pins were ignored whenever
  the iocontrol pins were configured, so "Ir a estacion" did nothing on
  a real machine.  The own pins are now ORed with the iocontrol ones.
* T0 (prepare of no tool) is acknowledged without moving; a tool whose
  table entry has no P raises E10 instead of claiming a prepared tool.
* The compiled component now also faults on missing configured machine
  pins, validates a reloaded configuration before applying it and only
  forgets the reference when the station count changes.

New manager tests: manual prepare with iocontrol present, stale manual
request not hijacking a T, T0 immediate and missing-P diagnostic.
configs/turret-template/ contains a Spanish checklist (hardware,
forbidden nets, INI, tool table P=station, first start, tuning and
troubleshooting) plus a turret.json, a turret.hal (F1/F2 loadusr line
and hardware watchdog) and an example tool.tbl.  Referenced from the
turret documentation.
* Install lib/python/turret/ so 'python3 -m turret.manager' also works on
  an installed (non-RIP) system.
* Sample the controller at 5 ms (Python and compiled component) and widen
  the simulator strobe pulse, so a station pulse cannot be missed or
  double counted; documented the strobe_filter_ms relation.
* Delay the missing/writer pin diagnostic by 2 s so a HAL file that
  loads the controller before the hardware pins is not faulted by
  mistake.
* Warn once when the watchdog pet pin cannot be written, and use a
  separate flag for the tool-without-P diagnostic in the component.
Step by step review of the whole logic found one safety issue and
several smaller ones:

* A fault during a tool change could let the program continue with the
  tool unchanged: setting io.status=ERROR made the task treat the fault
  as soft (reason>0), print it and set io.status=DONE, completing the
  change without the handshake.  The fault pins now only carry
  fault/reason for diagnostics; the pending change simply never
  completes, so the program pauses until the fault is reset and the
  change is re-run (abort_on_fault still aborts in F1).
* prepared/changed are dropped while faulted, so the task can never
  complete a change with the turret in a fault state.
* located is cleared on faults, on unhome and when a release starts, so
  a reset can never claim prepared for a station that was not
  re-referenced.
* The compiled component only latches prepared when it is idle, and both
  implementations re-arm the pin-existence check after a configuration
  reload.

New tests: reset requires a new reference before claiming prepared,
release clears located, reload re-arms the pin check.
Add [RS274NGC]FANUC_LATHE.  read_g puts G92 in the motion group,
G98/G99 in the feed mode group and G50 in group 0; G90/G94 keep their
groups and enhance_block promotes them to one-shot cycles when axis
words are present, so without axis words they still mean absolute mode
and feed-per-minute.

interp_fanuc_cycles.cc implements the cycles: G90 turning, straight or
with the R taper amount (the cut starts at X - 2R), G94 facing and the
single pass G92 threading cycle with the spindle synchronized pass.
Every cycle ends at the cycle start point, so an axis-only block repeats
it, and the programmed X/Z words stay modal for the cycle, apart from
the start point.

U/W are the incremental X/Z words in this mode: the readers are enabled
even on machines without U/W axes, and convert_motion folds them into
X/Z at execution time so the read-ahead stays correct.

G50 S sets the clamp used by G96 and is kept when G96 has no D word;
G50 X/Z sets the coordinate system through the G92 offset path.  The S
word of G50 no longer changes the commanded spindle speed.  G92 is
straight threading only on the 0i-TF: R/I and Q are rejected, as are
G94 taper words.

Warn at startup when G92/G98/G99/G50 are remapped, since the remap
takes precedence.  Add tests/interp fanuc-g90-g94, fanuc-g92-thread,
fanuc-g50 and fanuc-off (flag off regression), and document the mode in
g-code.adoc, ini-config.adoc, lathe-user.adoc and remap.adoc.
@alex-pres

Copy link
Copy Markdown
Contributor

Why is it better than existing code?

Should it be done in the post-processor instead?

@grandixximo

grandixximo commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Having the CNC managing the tool compensation has advantages, managing tool wear should be done in the CNC IMO, you can run the same code hundreds of times that the CAM generated only once, how do you propose the post-processor can manage that? It would still be the CNC updating the tool diameter in your model? So why not having native code to manage the path as well? Then you could hand write the code with wear instead of relying on the CAM, and we would all get the same calculations not CAM depedent...

@andypugh

Copy link
Copy Markdown
Collaborator

Tormach already has a lathe-style 4-digit T word (not requiring M6 or G43).

The function is available as a remap, demonstrated in:
https://github.com/LinuxCNC/linuxcnc/tree/master/configs/sim/axis/lathe-fanucy

I think at this point I could be persuaded that lathe-style toolchange should be natively supported, but I don't think that such a solution would need to touch 126 source files like this one does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants