Skip to content

Commit 3fd555b

Browse files
committed
ioControl.cc new pin iocontrol.0.tool-from-pocket
tldr: pocket number for nonrandom toolchangers does not have to be fixed (unchangeable). For configs using [EMCIO]RANDOM_TOOLCHANGER=0 (default), an external application (or a [EMCIO]DB_PROGRAM) can alter the pocket number for a tool while LinuxnCNC is running. LinuxCNC can read such updated tooldata using python:linuxcnc.command().load_tool_table() from a gui or with G10L0 gcode. The pin iocontrol.0.tool-from-pocket can be used to return a tool to the appropriate pocket when such updates are employed. update linuxcnc.stat, docs, runtests
1 parent 13da660 commit 3fd555b

14 files changed

Lines changed: 256 additions & 11 deletions

File tree

docs/src/config/python-interface.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ machine angular units per deg, reflects [TRAJ]ANGULAR_UNITS INI value.
371371
*tool_in_spindle*:: '(returns integer)' -
372372
current tool number.
373373

374+
*tool_from_pocket*:: '(returns integer)' -
375+
pocket number for the currently loaded tool (0 if no tool loaded).
376+
374377
*tool_offset*:: '(returns tuple of floats)' -
375378
offset values of the current tool.
376379

docs/src/gcode/tool-compensation.adoc

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,29 +204,40 @@ The io program provides HAL output pins to facilitate toolchanger management:
204204
. *iocontrol.0.tool-prep-number*
205205
. *iocontrol.0.tool-prep-index*
206206
. *iocontrol.0.tool-prep-pocket*
207+
. *iocontrol.0.tool-from-pocket*
207208

208209
==== IO for non-random toolchanger
209210

210211
. Tool number n==0 indicates no tool
211-
. The pocket number for a tool is fixed when tooldata is loaded
212+
. The pocket number for a tool is set when tooldata is loaded/reloaded
213+
from its data source ([EMCIO]TOOL_TABLE or [EMCIO]DB_PROGRAM).
212214
. At G-code *Tn* (n != 0) command:
213215
.. *iocontrol.0.tool-prep-index* = idx (index based on tooldata load sequence)
214216
.. *iocontrol.0.tool-prep-number* = n
215-
.. *iocontrol.0.tool-prep-pocket* = the fixed pocketno for n
217+
.. *iocontrol.0.tool-prep-pocket* = the pocketno for n
216218
. At G-code *T0* (n == 0 remove) command:
217219
.. *iocontrol.0.tool-prep-index* = 0
218220
.. *iocontrol.0.tool-prep-number* = 0
219221
.. *iocontrol.0.tool-prep-pocket* = 0
222+
. At M-code *M6* (following iocontrol.0.tool-changed pin 0-->1):
223+
.. *iocontrol.0.tool-from-pocket* = pocket number used to retrieve tool
220224

221225
==== IO for random toolchanger
222226

223227
. Tool number n==0 is *not special*.
224228
. Pocket number 0 is *special* as it indicates the *spindle*.
225229
. The *current* pocket number for tool N is the tooldata index (idx) for tool n.
226230
. At G-code command *Tn*:
227-
.. *iocontrol.0.tool-prep-index* = pocket number for tool n
231+
.. *iocontrol.0.tool-prep-index* = tooldata index (idx) for tool n
228232
.. *iocontrol.0.tool-prep-number* = n
229233
.. *iocontrol.0.tool-prep-pocket* = pocket number for tool n
234+
. At M-code *M6* (following iocontrol.0.tool-changed pin 0-->1):
235+
.. *iocontrol.0.tool-from-pocket* = pocket number used to retrieve tool
236+
237+
[NOTE]
238+
At startup, *iocontrol.0.tool-from-pocket* = 0.
239+
An M61Qn (n!=0) command does not change the *iocontrol.0.tool-from-pocket*.
240+
An M61Qn (n==0) command sets *iocontrol.0.tool-from-pocket* to 0.
230241

231242
[[sub:tool-changers]]
232243
=== Tool Changers(((Tool Changers)))
@@ -248,21 +259,33 @@ with INI statements:
248259
HALFILE = axis_manualtoolchange.hal
249260
----
250261

251-
.Fixed Location Tool Changers
262+
.Fixed Location Tool Changers
252263
Fixed location tool changers always return the tools to a
253264
fixed position in the tool changer. This would also include
254265
designs like lathe turrets. When LinuxCNC is configured for a fixed
255266
location tool changer the 'P' number is not used internally (but read, preserved
256267
and rewritten) by LinuxCNC, so you can use P for any bookkeeping number you
257268
want.
258269

270+
[NOTE]
271+
When using [EMCIO]RANDOM_TOOLCHANGER = 0 (the default), the 'P'
272+
pocket number is a parameter of the tooldata that is retrieved from
273+
the tooldata source ([EMCIO]TOOL_TABLE or [EMCIO]DB_PROGRAM). In many
274+
applications it is fixed but it may be changed by edits to the
275+
[EMCIO]TOOL_TABLE or programatically when the [EMCIO]DB_PROGRAM is
276+
used. LinuxCNC pushes updates to the data source ([EMCIO]TOOL_TABLE
277+
or [EMCIO]DB_PROGRAM) for gcodes G10L1,G10L10,G10L11,M61. LinuxCNC
278+
can pull tooldata updates from the data source by UI (user-interface)
279+
commands (python example: linuxcnc.command().load_tool_table()) or by
280+
the gcode: G10L0.
281+
259282
.Random Location Tool Changers
260-
Random location tool changers swap the tool in the spindle with the
261-
one in the changer. With this type of tool changer the tool will
262-
always be in a different pocket after a tool change. When a tool is
263-
changed LinuxCNC rewrites the pocket number to keep track of where the tools
264-
are. T can be any number but P must be a number that makes sense for
265-
the machine.
283+
Random location tool changers ([EMCIO]RANDOM_TOOLCHANGER = 1) swap the
284+
tool in the spindle with the one in the changer. With this type of
285+
tool changer the tool will always be in a different pocket after a
286+
tool change. When a tool is changed LinuxCNC rewrites the pocket
287+
number to keep track of where the tools are. T can be any number but P
288+
must be a number that makes sense for the machine.
266289

267290

268291
== Tool Length Compensation(((Tool Length Compensation)))

src/emc/iotask/ioControl.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct iocontrol_str {
102102
hal_bit_t *tool_prepare; /* output, pin that notifies HAL it needs to prepare a tool */
103103
hal_s32_t *tool_prep_pocket;/* output, pin that holds the pocketno for the tool table entry matching the tool to be prepared,
104104
only valid when tool-prepare=TRUE */
105+
hal_s32_t *tool_from_pocket;/* output, pin indicating pocket current load tool retrieved from*/
105106
hal_s32_t *tool_prep_index; /* output, pin for internal index (idx) of prepped tool above */
106107
hal_s32_t *tool_prep_number;/* output, pin that holds the tool number to be prepared, only valid when tool-prepare=TRUE */
107108
hal_s32_t *tool_number; /* output, pin that holds the tool number currently in the spindle */
@@ -407,6 +408,16 @@ static int iocontrol_hal_init(void)
407408
hal_exit(comp_id);
408409
return -1;
409410
}
411+
// tool-from-pocket
412+
retval = hal_pin_s32_newf(HAL_OUT, &(iocontrol_data->tool_from_pocket), comp_id,
413+
"iocontrol.%d.tool-from-pocket", n);
414+
if (retval < 0) {
415+
rtapi_print_msg(RTAPI_MSG_ERR,
416+
"IOCONTROL: ERROR: iocontrol %d pin tool-from-pocket export failed with err=%i\n",
417+
n, retval);
418+
hal_exit(comp_id);
419+
return -1;
420+
}
410421
// tool-prepared
411422
retval = hal_pin_bit_newf(HAL_IN, &(iocontrol_data->tool_prepared), comp_id,
412423
"iocontrol.%d.tool-prepared", n);
@@ -483,6 +494,7 @@ static void hal_init_pins(void)
483494
*(iocontrol_data->tool_prepare)=0; /* output, pin that notifies HAL it needs to prepare a tool */
484495
*(iocontrol_data->tool_prep_number)=0; /* output, pin that holds the tool number to be prepared, only valid when tool-prepare=TRUE */
485496
*(iocontrol_data->tool_prep_pocket)=0; /* output, pin that holds the pocketno for the tool to be prepared, only valid when tool-prepare=TRUE */
497+
*(iocontrol_data->tool_from_pocket)=0; /* output, always 0 at startup */
486498
*iocontrol_data->tool_prep_index=0; /* output, pin that holds the internal index (idx) of the tool to be prepared, for debug */
487499
*(iocontrol_data->tool_change)=0; /* output, notifies a tool-change should happen (emc should be in the tool-change position) */
488500
}
@@ -623,13 +635,18 @@ static int read_tool_inputs(void)
623635
if (*iocontrol_data->tool_change && *iocontrol_data->tool_changed) {
624636
if(!random_toolchanger && emcioStatus.tool.pocketPrepped == 0) {
625637
emcioStatus.tool.toolInSpindle = 0;
638+
emcioStatus.tool.toolFromPocket = *(iocontrol_data->tool_from_pocket) = 0;
626639
} else {
627640
// the tool now in the spindle is the one that was prepared
628641
CANON_TOOL_TABLE tdata;
629642
if (tooldata_get(&tdata,emcioStatus.tool.pocketPrepped) != IDX_OK) {
630643
UNEXPECTED_MSG; return -1;
631644
}
632645
emcioStatus.tool.toolInSpindle = tdata.toolno;
646+
emcioStatus.tool.toolFromPocket = *(iocontrol_data->tool_from_pocket) = tdata.pocketno;
647+
}
648+
if (emcioStatus.tool.toolInSpindle == 0) {
649+
emcioStatus.tool.toolFromPocket = *(iocontrol_data->tool_from_pocket) = 0;
633650
}
634651
*(iocontrol_data->tool_number) = emcioStatus.tool.toolInSpindle; //likewise in HAL
635652
load_tool(emcioStatus.tool.pocketPrepped);
@@ -1030,6 +1047,9 @@ int main(int argc, char *argv[])
10301047
, emcioStatus.tool.toolInSpindle, idx, tdata.toolno);
10311048
//likewise in HAL
10321049
*(iocontrol_data->tool_number) = emcioStatus.tool.toolInSpindle;
1050+
if (emcioStatus.tool.toolInSpindle == 0) {
1051+
emcioStatus.tool.toolFromPocket = *(iocontrol_data->tool_from_pocket) = 0; // no tool in spindle
1052+
}
10331053
}
10341054
break;
10351055

src/emc/nml_intf/emc.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ void EMC_TOOL_STAT::update(CMS * cms)
901901
EMC_TOOL_STAT_MSG::update(cms);
902902
cms->update(pocketPrepped); // idx
903903
cms->update(toolInSpindle);
904+
cms->update(toolFromPocket);
904905
#ifdef TOOL_NML //{
905906
for (int i_toolTable = 0; i_toolTable < CANON_POCKETS_MAX; i_toolTable++)
906907
CANON_TOOL_TABLE_update(cms, &(toolTable[i_toolTable]));

src/emc/nml_intf/emc_nml.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,7 @@ class EMC_TOOL_STAT:public EMC_TOOL_STAT_MSG {
16661666

16671667
int pocketPrepped; // idx ready for loading from
16681668
int toolInSpindle; // tool loaded, 0 is no tool
1669+
int toolFromPocket; // tool was loaded from this pocket
16691670
#ifdef TOOL_NML //{
16701671
CANON_TOOL_TABLE toolTable[CANON_POCKETS_MAX];
16711672
#else //}{

src/emc/nml_intf/emcops.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ EMC_TOOL_STAT_MSG(EMC_TOOL_STAT_TYPE, sizeof(EMC_TOOL_STAT))
157157
{
158158
pocketPrepped = 0; // idx
159159
toolInSpindle = 0; // toolno
160+
toolFromPocket = 0; // tool_from_pocket
160161
#ifdef TOOL_NML //{
161162
int idx;
162163
for (idx = 0; idx < CANON_POCKETS_MAX; idx++) {
@@ -206,6 +207,7 @@ EMC_TOOL_STAT EMC_TOOL_STAT::operator =(EMC_TOOL_STAT s)
206207
{
207208
pocketPrepped = s.pocketPrepped; // idx
208209
toolInSpindle = s.toolInSpindle; // toolno
210+
toolFromPocket = s.toolFromPocket; // tool_from_pocket
209211

210212
#ifdef TOOL_NML //{
211213
int idx;

src/emc/usr_intf/axis/extensions/emcmodule.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ static PyMemberDef Stat_members[] = {
400400
{(char*)"tool_in_spindle", T_INT, O(io.tool.toolInSpindle), READONLY,
401401
(char*)"The tool number of the currently loaded tool, or 0 if no tool is loaded."
402402
},
403+
{(char*)"tool_from_pocket", T_INT, O(io.tool.toolFromPocket), READONLY,
404+
(char*)"The pocket number that the currently loaded tool was retrieved from,\n"
405+
"or 0 if no tool is loaded."
406+
},
403407

404408
// EMC_COOLANT_STAT io.cooland
405409
{(char*)"mist", T_INT, O(io.coolant.mist), READONLY},

tests/toolchanger/m61/mod_core_sim.hal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,5 @@ net tool-changed => iocontrol.0.tool-changed
5757
net tool-number <= iocontrol.0.tool-number
5858
net tool-prep-number <= iocontrol.0.tool-prep-number
5959
net tool-prep-pocket <= iocontrol.0.tool-prep-pocket
60+
net tool-from-pocket <= iocontrol.0.tool-from-pocket
6061

tests/toolchanger/m61/postgui.hal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ net tool-changed <= python-ui.tool-changed
88
net tool-number => python-ui.tool-number
99
net tool-prep-number => python-ui.tool-prep-number
1010
net tool-prep-pocket => python-ui.tool-prep-pocket
11+
net tool-from-pocket => python-ui.tool-from-pocket
1112

tests/toolchanger/m61/test-ui.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ def do_tool_change_handshake(tool_number, pocket_number):
128128
h.newpin("tool-number", hal.HAL_S32, hal.HAL_IN)
129129
h.newpin("tool-prep-number", hal.HAL_S32, hal.HAL_IN)
130130
h.newpin("tool-prep-pocket", hal.HAL_S32, hal.HAL_IN)
131+
h.newpin("tool-from-pocket", hal.HAL_S32, hal.HAL_IN)
131132

132133
h.newpin("tool-prepare", hal.HAL_BIT, hal.HAL_IN)
133134
h.newpin("tool-prepared", hal.HAL_BIT, hal.HAL_OUT)
@@ -230,7 +231,8 @@ def do_tool_change_handshake(tool_number, pocket_number):
230231
'tool-change': 0,
231232
'tool-prep-number': 0,
232233
'tool-prep-pocket': 0,
233-
'tool-prepare': 0
234+
'tool-prepare': 0,
235+
'tool-from-pocket': 1
234236
},
235237
duration=1
236238
)

0 commit comments

Comments
 (0)