Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/gcode.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ tr.head td, tr.head th { background: black; color: white; }
<tr><td><a href="gcode/g-code.html#gcode:g10-l2">G10 L2</a></td><td>P R</td><td>Set Coordinate System</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g10-l20">G10 L20</a></td><td>P</td><td>Set Coordinate System</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g28-g28.1">G28, G28.1</a></td><td/><td>Go/Set Predefined Position</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g28.2">G28.2</a></td><td>P</td><td>Home from G-code</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g30-g30.1">G30, G30.1</a></td><td/><td>Go/Set Predefined Position</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g53">G53</a></td><td/><td>Move in Machine Coordinates</td></tr>
<tr><td><a href="gcode/g-code.html#gcode:g92">G52, G92</a></td><td/><td>Coordinate System Offset</td></tr>
Expand Down
76 changes: 76 additions & 0 deletions docs/src/gcode/g-code.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ as the 'L number', and so on for any other letter.
|<<gcode:g17-g19.1,G17 - G19.1>> |Plane Select
|<<gcode:g20-g21,G20 G21>> |Set Units of Measure
|<<gcode:g28-g28.1,G28 - G28.1>> |Go to Predefined Position
|<<gcode:g28.2,G28.2>> |Home from G-code
|<<gcode:g30-g30.1,G30 - G30.1>> |Go to Predefined Position
|<<gcode:g33,G33>> |Spindle Synchronized Motion
|<<gcode:g33.1,G33.1>> |Rigid Tapping
Expand Down Expand Up @@ -1070,6 +1071,81 @@ It is an error if :

* Cutter Compensation is turned on

[[gcode:g28.2]]
== G28.2 Home from G-code(((G28.2 Home from G-code)))

This non-modal code lets a program or MDI line reference the machine
instead of requiring the operator to use the GUI's *Home All* button. It
follows the same modal-group-0 pattern as `G28.1`/`G30.1`, takes no axis
words, and *requires* a `P` word saying what to home.

* 'G28.2 P-1' - runs the homing cycle on every joint, in `HOME_SEQUENCE`
order (the same operation as the GUI *Home All*). This form requires the
config to set `[JOINT_n]HOME_SEQUENCE`; exactly as with *Home All*, a
config with no `HOME_SEQUENCE` cannot home all joints at once and the
command fails, leaving the machine in joint mode.
* 'G28.2 Pn' - runs the homing cycle on joint 'n' only, where 'n' is the
Comment thread
grandixximo marked this conversation as resolved.
0-based joint number matching its `[JOINT_n]` INI section (the same
numbering used by `HOME_SEQUENCE` and by joint jogging). Other joints are
left as they are, and `HOME_SEQUENCE` is not required for the `Pn` form.
How many joints actually home depends on the `HOME_SEQUENCE` of joint 'n':
+
--
** a *negative* (synchronized) sequence homes the whole synchronized group -
`Pn` on either joint of a gantry pair homes both;
** a *positive* sequence shared with other joints homes only joint 'n' -
use `G28.2 P-1` to home the shared group together;
** no sequence, or a sequence not shared with any other joint, homes just
joint 'n'.
--

[WARNING]
There is no bare `G28.2`. Homing drives joints onto their switches at
homing speed, ignoring soft limits, from wherever the machine happens to
be, so homing the whole machine has to be asked for explicitly with `P-1`
rather than being what a truncated or mistyped line does. A `G28.2` with no
`P` word is an error and stops the program.

.G28.2 Example Lines
[source,ngc]
----
G28.2 P-1 (home all joints, in HOME_SEQUENCE order)
G28.2 P1 (home joint 1 only)
----

A queued `G28.2` dips motion into free mode for the duration of the homing
cycle and restores whatever mode (manual/MDI/auto) was active once it
finishes, so the mode dip is invisible at the task level. Motion still
enforces its own safety: the home is honored only when the machine is idle
(in position with no queued motion) or in joint mode, and a home is refused
mid-motion. Homing inhibits and per-joint limit handling are unchanged.

[NOTE]
When the homing cycle finishes, the interpreter resyncs its model of the
current position from the machine (the same way it does after probing or a
tool change), so a following move made in incremental distance mode
(`G91`), or an arc whose center is given with `I`/`J`/`K`, is computed from
where the machine actually is after homing. `G28.2` is a queue point: read
ahead stops at it and resumes once the cycle has run. `G5x`/`G92` offsets
that were active before the `G28.2` are still applied afterward and now
refer to the newly established machine zero; clear or re-establish them if
that is not what you want.

[NOTE]
There is no G-code unhome. Clearing a joint's reference is done from the
GUI, halui or linuxcncrsh.

[NOTE]
`G28.2` is a LinuxCNC extension; there is no standard Fanuc equivalent.

It is an error if:

* Cutter radius compensation is active (`G41`, `G41.1`, `G42` or `G42.1`).
* An axis word is present ('G28.2' takes no axis words).
* The 'P' word is missing.
* The 'P' word is not a whole number, or is negative other than `P-1`.
* The 'P' word names a joint number the machine does not have.

[[gcode:g30-g30.1]]
== G30, G30.1 Go/Set Predefined Position(((G30 Go/Set Predefined Position)))

Expand Down
2 changes: 1 addition & 1 deletion docs/src/gcode/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ The modal groups are shown in the following Table.
[width="80%",cols="4,6",options="header"]
|===
|Modal Group Meaning | Member Words
|Non-modal codes (Group 0) | G4, G10 G28, G30, G52, G53, G92, G92.1, G92.2, G92.3,
|Non-modal codes (Group 0) | G4, G10 G28, G28.2, G30, G52, G53, G92, G92.1, G92.2, G92.3,
|Motion (Group 1) | G0, G1, G2, G3, G33, G38.n, G73, G76, G80, G81
G82, G83, G84, G85, G86, G87, G88, G89
|Plane selection (Group 2) | G17, G18, G19, G17.1, G18.1, G19.1
Expand Down
2 changes: 1 addition & 1 deletion docs/src/remap/remap.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1851,7 +1851,7 @@ All the listed G-codes are already defined in the current implementation of Linu
|25 | | | | | | | | | |
|26 | | | | | | | | | |
|27 | | | | | | | | | |
|28 |G28 |G28.1 | | | | | | | |
|28 |G28 |G28.1 |G28.2 | | | | | | |
|29 | | | | | | | | | |
|===

Expand Down
2 changes: 1 addition & 1 deletion lib/python/common/hal_glib.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class _GStat(GObject.GObject):
STATE_ON = linuxcnc.STATE_ON
STATE_OFF = linuxcnc.STATE_OFF

group0 = ('G4', 'G10','G28', 'G30', 'G52', 'G53', 'G92', 'G92.1', 'G92.2', 'G92.3')
group0 = ('G4', 'G10','G28', 'G28.2', 'G30', 'G52', 'G53', 'G92', 'G92.1', 'G92.2', 'G92.3')
group1 = ('G0', 'G1', 'G2', 'G3', 'G33', 'G38.n', 'G73', 'G76', 'G80', 'G81',\
'G82', 'G83', 'G84', 'G85', 'G86', 'G87', 'G88', 'G89')
group2 = ('G17', 'G18', 'G19', 'G17.1', 'G18.1', 'G19.1')
Expand Down
25 changes: 25 additions & 0 deletions lib/python/qtvcp/lib/mdi_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def gcode_titles():
'G21': 'Set Units to Millimeters',
'G28': 'Go to Predefined Position',
'G28.1': 'Set Predefined Position',
'G28.2': 'Home from G-code',
'G30': 'Go to Predefined Position',
'G30.1': 'Set Predefined Position',
'G33': 'Spindle Synchronized Motion',
Expand Down Expand Up @@ -209,6 +210,7 @@ def gcode_descriptions(gcode):
'G21': G21,
'G28': G28,
'G28.1': G28_1,
'G28.2': G28_2,
'G30': G30,
'G30.1': G30_1,
'G33': G33,
Expand Down Expand Up @@ -467,6 +469,29 @@ def gcode_descriptions(gcode):
G28.1 - stores the current absolute position into
parameters 5161-5166.
"""

G28_2 = """G28.2 Home from G-code
Runs the homing cycle, the same operation as the GUI
Home All button, so a program or MDI line can
reference the machine. Takes no axis words, and
requires a P word saying what to home.

G28.2 P-1 - homes all joints, in HOME_SEQUENCE order
(the config must set HOME_SEQUENCE).

G28.2 Pn - homes joint n only, where n is the
0-based joint number matching its [JOINT_n] INI
section. On a synchronized (negative HOME_SEQUENCE)
joint pair, Pn on either joint homes both.

There is no bare G28.2: homing the whole machine has
to be asked for with P-1.

It is an error if cutter compensation is on, if the P
word is missing or is not -1 or a whole joint number,
or if Pn names a joint the machine does not have.
"""

G30 = """G30 Go to Predefined Position
G30 uses the values stored in parameters 5181-5189
as the X Y Z A B C U V W final point to move to.
Expand Down
19 changes: 17 additions & 2 deletions src/emc/motion/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,8 +1505,23 @@ void emcmotCommandHandler_locked(void *arg, long servo_period)
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_HOME");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);

if (emcmotStatus->motion_state != EMCMOT_MOTION_FREE) {
/* can't home unless in free mode */
/* Normally homing requires free (joint) mode. The queued G28.2 path
* (emctaskmain EMC_TASK_EXEC::WAITING_FOR_HOMING) dips motion into
* FREE before issuing this command; while that transition is still
* settling motion_state can read non-FREE for a cycle. Accept the
* command in exactly that window -- in position, nothing queued, and
* a FREE transition already pending (teleop and coord both cleared)
* -- so a G-code-triggered home from MDI / a program is honored.
*
* Do NOT accept it merely because motion is idle: an immediate home
* (halui, linuxcncrsh, c.home(n)) on an already-homed machine sitting
* in TELEOP is idle too, and do_homing() only advances in FREE
* (control.c), so accepting it there would silently drop the
* request (found in review of PR #4172). */
if (emcmotStatus->motion_state != EMCMOT_MOTION_FREE
&& !(GET_MOTION_INPOS_FLAG() && emcmotStatus->depth == 0
&& !emcmotInternal->teleoperating
&& !emcmotInternal->coordinating)) {
reportError(_("must be in joint mode to home"));
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/emc/motion/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -2273,6 +2273,7 @@ static void update_status(void)
}

emcmotStatus->jogging_active = hal_get_bool(emcmot_hal_data->jog_is_active);
emcmotStatus->homing_active = get_homing_is_active();

/*! \todo FIXME - the rest of this function is stuff that was apparently
dropped in the initial move from emcmot.c to control.c. I
Expand Down
4 changes: 4 additions & 0 deletions src/emc/motion/motion.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,10 @@ Suggestion: Split this in to an Error and a Status flag register..
int numExtraJoints;
int stepping;
bool jogging_active;
bool homing_active; /* homing state machine is running (get_homing_is_active()).
Aggregate: stays true across the gap between
HOME_SEQUENCE groups, when every joint's per-joint
.homing flag is momentarily false. */

int switchkins_seq; /* echoes the config counter once acted on */
int switchkins_type; /* switchkins type now in force */
Expand Down
7 changes: 7 additions & 0 deletions src/emc/nml_intf/canon.hh
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ extern void SET_G92_OFFSET(double x, double y, double z,

extern void SET_XY_ROTATION(double t);

/* G28.2: trigger the machine homing cycle from G-code (bare form = all
* joints, in HOME_SEQUENCE order). Maps to EMC_JOINT_HOME(-1). */
extern void HOME_CYCLE(void);
/* G28.2 Pn: home a single joint by its 0-based joint number (matching
* [JOINT_n] INI section numbering). Maps to EMC_JOINT_HOME(joint). */
extern void HOME_CYCLE_JOINT(int joint);

/* Offset the origin to the point with absolute coordinates x, y, z,
a, b, c, u, v, and w. Values of x, y, z, a, b, c, u, v, and w are real
numbers. The units are whatever length units are being used at the time
Expand Down
1 change: 1 addition & 0 deletions src/emc/nml_intf/emc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,7 @@ void EMC_MOTION_STAT::update(CMS * cms)
EmcPose_update(cms, &eoffset_pose);
cms->update(numExtraJoints);
cms->update(jogging_active);
cms->update(homing_active);
cms->update(heartbeat);
}

Expand Down
3 changes: 2 additions & 1 deletion src/emc/nml_intf/emc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ enum class EMC_TASK_EXEC {
WAITING_FOR_DELAY = 8,
WAITING_FOR_SYSTEM_CMD = 9,
WAITING_FOR_SPINDLE_ORIENTED = 10,
WAITING_FOR_KINS_SWITCH = 11
WAITING_FOR_KINS_SWITCH = 11,
WAITING_FOR_HOMING = 12
};

// types for EMC_TASK interpState
Expand Down
6 changes: 6 additions & 0 deletions src/emc/nml_intf/emc_nml.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,12 @@ class EMC_MOTION_STAT:public EMC_MOTION_STAT_MSG {
EmcPose eoffset_pose;
int numExtraJoints;
bool jogging_active;
// Aggregate "the homing state machine is running", from
// get_homing_is_active() in motion. Unlike the per-joint EMC_JOINT_STAT
// .homing flags, this stays true across the gap between HOME_SEQUENCE
// groups, where every joint momentarily reads .homing == false while the
// machine is still homing (see the race note in motion/homing.c).
bool homing_active;
uint64_t heartbeat; // motion controller's heartbeat counter

};
Expand Down
1 change: 1 addition & 0 deletions src/emc/nml_intf/emcops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ EMC_MOTION_STAT::EMC_MOTION_STAT()
eoffset_pose{},
numExtraJoints(0),
jogging_active(0),
homing_active(false),
heartbeat(0)
{
}
Expand Down
3 changes: 3 additions & 0 deletions src/emc/rs274ngc/gcodemodule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,9 @@ void SELECT_PLANE(CANON_PLANE pl) {
parse_state.canon->set_plane(static_cast<int>(pl));
}

void HOME_CYCLE(void) {}
void HOME_CYCLE_JOINT(int) {}

void SET_TRAVERSE_RATE(double rate) {
parse_state.canon->set_traverse_rate(rate);
}
Expand Down
2 changes: 1 addition & 1 deletion src/emc/rs274ngc/interp_array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const int Interp::gees[] = {
/* 220 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 240 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 260 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 280 */ 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 280 */ 0, 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 282=G28.2
/* 300 */ 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 320 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,
/* 340 */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
Expand Down
3 changes: 3 additions & 0 deletions src/emc/rs274ngc/interp_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ int Interp::check_g_codes(block_pointer block, //!< pointer to a block to be c
} else if (mode1 == G_5_2){
} else if (mode1 == G_6_2){
} else if (mode0 == G_28_1 || mode0 == G_30_1) {
} else if (mode0 == G_28_2) { // G-code homing
} else if (mode0 == G_52) {
} else if (mode0 == G_53) {
CHKS(((block->motion_to_be != G_0) && (block->motion_to_be != G_1)),
Expand Down Expand Up @@ -331,12 +332,14 @@ int Interp::check_other_codes(block_pointer block) //!< pointer to a block
(motion != G_6) && (motion != G_6_2) &&
(motion != G_2) && (motion != G_3) &&
(motion != G_74) && (motion != G_84) &&
(block->g_modes[GM_MODAL_0] != G_28_2) &&
(block->m_modes[9] != 50) && (block->m_modes[9] != 51) && (block->m_modes[9] != 52) &&
(block->m_modes[9] != 53) && (block->m_modes[5] != 62) && (block->m_modes[5] != 63) &&
(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 G12.1 G64 G5 G5.2 G6, G6.2, G76 G82 G86 G88 G89"
" G28.2"
" 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);
Expand Down
Loading
Loading