Both coordinate systems happen to agree.
The planned physical carriage position is MCS Z100. With no work or tool translation in this simplified trace, the WCS readout also says Z100.
A visual, source-grounded trace through Smoothieware’s tool selection, coordinate conversion, planned machine position, and the two real offset-setting bugs that can make a later G91 move look suspicious.
Scope: current edge, Robot.cpp and ToolManager.cpp. No firmware behaviour is inferred without a source path.
Most confusion disappears once each number has one job. The tool offset does not move the carriage. It changes how a work coordinate is translated into a carriage target.
The carriage’s planned physical position. Smoothieware stores this in machine_position. It is the reference for a G91 delta.
The coordinate system the G-code author sees. It includes the selected work offset, G92 and tool offset.
The vector between the machine reference and the active tool’s effective point. It shifts WCS interpretation, not the current carriage.
“Move from here by this much.” A displacement is unchanged by a constant translation. That is basic coordinate geometry, not a Smoothie special case.
The signs below match the current implementation: WCS offsets and tool offset are added when converting an absolute WCS endpoint into MCS, while G92 is subtracted.
This is for an absolute endpoint: “go to WCS Z 50.”
This is for a relative move: “move Z by −5.” Every constant offset cancels.
To find that destination in machine space, Smoothie must apply the active coordinate translations.
target = requested_WCS + offsetsIt begins at the already-planned machine position and adds only the requested displacement.
target = machine_position + deltaClick each step. The blue marker is MCS carriage position. The amber marker is the currently displayed WCS coordinate. The physical move remains exactly five millimetres.
The planned physical carriage position is MCS Z100. With no work or tool translation in this simplified trace, the WCS readout also says Z100.
Every source writer and reader supports one state model. A tool switch replaces tool_offset; it does not touch machine_position. The relative branch starts from that machine position and adds the requested delta.
if (absolute_mode) { // point conversion: offsets apply target[Z_AXIS] = param[Z_AXIS] + wcs_offset - g92_offset + tool_offset; } else { // displacement: translations do not apply target[Z_AXIS] = param[Z_AXIS] + machine_position[Z_AXIS]; }
process_move has one tool-offset use for absolute XYZ endpoints. The G91 branch never reads it.
ToolManager waits for the conveyor to become idle before deselecting the old tool and replacing the offset.
After a move is accepted, Smoothie copies the target into machine_position. Coordinate settings alone do not mutate it.
Suppose the carriage is at MCS Z100 and the new tool offset is +10. The desired relative command is G91 G1 Z-5.
This treats a change in coordinate origin as if it were a physical displacement. The new target would move to MCS Z105, five millimetres in the wrong direction.
100 + (-5) + 10 = 105G91 says “from the current planned machine position, move by minus five.” The target is MCS Z95. The WCS readout follows the new tool translation naturally.
100 + (-5) = 95The relative transform is sound. The offset supplied to that transform can still be wrong. These two paths create a shifted WCS, so a correct relative displacement begins from an unexpected displayed coordinate.
The handler starts with the existing tool_offset and adds supplied axes. Under LinuxCNC semantics, G43.1 changes or replaces the named current offsets. Repeating a measured value should not add it again.
G43.1 Z10
G43.1 Z12
= 22G43.1 Z10
G43.1 Z12
= 12ToolManager stores raw get_value() axis words. All motion and G43 paths use to_millimeters(). In inch mode, Z1 becomes 1 mm in this path instead of 25.4 mm.
G20
G10 L1 ... Z1
= 1 mmG20
G10 L1 ... Z1
= 25.4 mmSmoothie’s non-standard G43.2 adds the given offset and calls delta_move(deltas, ...). That deliberately moves the carriage by the same amount, preserving the current WCS readout. A subsequent G91 is still a normal delta from the new machine position.
Command carries an offset increment.
tool_offset receives the increment.
delta_move physically plans the matching move.
The two translations cancel in the displayed WCS coordinate.
The next relative value is still only a displacement.
Adjust the planned MCS position, then set a tool offset and issue a fixed G91 Z-5. Watch the blue MCS endpoint move by exactly five regardless of the amber WCS translation.
This is the same scalar equation Smoothie uses per primary axis. It is intentionally a coordinate test, not a motion simulator.
These checks separate geometry, command semantics, and unit handling. That boundary makes a failing test point to one layer instead of blaming G91 generically.
Set MCS to 100, set tool offset to +10, issue G91 Z-5. Assert planned MCS is 95 and displayed WCS is 85.
With the same offset, issue G90 Z50. Assert planned MCS is 60. This proves offset application stays in point conversion.
Apply Z10 then Z12. Assert the named active offset becomes 12, not 22, once the replacement semantics are chosen.
Set inch mode and program Z1. Assert the active tool offset becomes 25.4 mm, matching all other distance-bearing commands.
Assert that its paired offset and delta move leave the WCS number unchanged while MCS advances by the increment.
Jim’s G91 branch has the right shape. The next useful work is to make the offset-setting paths match their stated command semantics, then lock this coordinate contract down with focused regression tests.