Skip to content

interp, motion: the point-to-point moves and the tool orientation codes, G53.1 to G53.7 and G68.3 - #4730

Open
grandixximo wants to merge 24 commits into
LinuxCNC:masterfrom
grandixximo:robot-machine-frame
Open

grandixximo wants to merge 24 commits into
LinuxCNC:masterfrom
grandixximo:robot-machine-frame

Conversation

@grandixximo

Copy link
Copy Markdown
Contributor

This is item 5 of the multiaxis roadmap in #4374, the next lane after #4702 (modules callable outside realtime) and #4600 (the tilted work plane). It is the part of the roadmap a five axis user sees: the codes that point the tool at a tilted plane, and moves that go through a singularity or flip a head without leaving the program's coordinates.

#4600 gave the plane, G68.2/G68.4/G69. What a program needs next is to stand the tool normal to it. Fanuc, Heidenhain and Siemens all do that with codes that ask the kinematics where the rotaries go. Here the interpreter asks the same module motion runs, through the loader from #4702, so nothing carries a second copy of the machine's maths.

What changes

  • Point-to-point moves. A new motion segment has a Cartesian endpoint and is interpolated in joint space. The inverse runs once, at the endpoint, and every joint goes there together, the slowest setting the pace. Nothing blends into or out of it. While it runs, motion reports the tool from the forward; where the forward fails (as an iterating one can at the singularity the move is there to cross) the last solved position stays, with carte_pos_cmd_ok cleared. The canon calls are JOINT_TRAVERSE and JOINT_FEED; NML has EMC_TRAJ_JOINT_MOVE. External offsets wait while one is queued.
  • G53.4, G53.5, G53.7. Non-modal modifiers of G0 and G1, like G53:
    • G53.4 takes a program point through the offsets.
    • G53.5 reads the letters in the machine frame: the slides on a machine whose slides line up with it, no offset, no tool, no orientation.
    • G53.7 takes joints as J<n>=<value>.
    • With G1 the move takes the time the straight move would at the programmed feed.
  • G53.1, G53.3, G53.6, G53.2. These solve where the rotaries go for the tool to be normal to the plane, through the module's tool frame inverse:
    • G53.1 turns the rotaries only.
    • G53.6 holds the tool tip.
    • G53.3 X Y Z goes to a point in the plane with the tool oriented.
    • G53.2 solves and moves nothing. It publishes the pose on #<_orient_*> and #5071 to #5080, so one G0 can turn the head and travel together (Heidenhain's STAY).
    • P picks the pose (nearest, or by the sign of the secondary rotary, Heidenhain's SEQ+/SEQ-). Q frees or holds the joints that carry the work (Heidenhain's TABLE ROT/COORD ROT).
    • Poses are unwrapped onto the turn nearest where the rotary stands that lies inside [JOINT_n] travel, so a looped G68.4 with G53.6 never winds a rotary into its limit.
  • G68.3 takes the plane from the tool as the joints have it.
  • The interpreter seeds the inverse from the joints the machine stands in, through a new canon call the preview answers too. Before, every inverse started from zeros, the singular pose of a serial arm. Each end of a point-to-point move keeps the joints it asked for, so a robot wrist does not flip back on the next move.
  • A tool offset change under a tilt keeps the joints. With the head tilted, G43 moves the programmed point, not the machine. Motion reads the point back from the joints under the new tool. The interpreter predicts the same point through the loader, and motion aborts if the two disagree.
  • A tool offset's X and Y turn with the tool frame, where every TCP module left them on the work axes (4.2 mm off on 5axiskins at B-22.5 C45 for a 4, 3 offset). Reported by Sigma1912.
  • G43.5 is G43.4 with the tool axis given as I J K on G0/G1 in place of rotary words (Fanuc's tool centre point control type 2). No configuration names the rotaries, so the same program orients a head, a table and a robot.
  • G28.5 and G30.5 are to G28/G30 what G53.5 is to G53.
  • [RS274NGC] MACHINE_MOVES_IN_MACHINE_FRAME, off by default. When it is set and the kinematics in force is not the machine frame type, G53, G28 and G30 run as G53.5, G28.5 and G30.5. The slides then land in the same place whatever the tool and the head angle. The five axis sims set it. The preview reads stat.kins_type/stat.kins_type_flags (new) so it runs on the machine's type, not type 0.
  • Frames. maxkins, xyzab_tdr_kins and genserkins report their tool and work frames. pumakins and genserkins declare their arm type both primary and machine frame, so G13.1 and G49 leave a robot on its arm kinematics, as robot controllers do.
  • Configs. The two nutating-head sims drop their python remap of the plane and orientation codes. The interpreter does all of it, with nothing to restore on abort. The bridgemill sim drills its sphere with G53.2 and with G53.6.

Fixed on the way

  • genserkins' inverse took the whole Newton step. It could converge whole turns away (joint 0 at -3263.962, nine turns out, for a reachable point). The step is now capped.
  • Motion checked a move's joint limits from the joints the machine stands in, not where the queue leaves them. A robot parked with one wrist had a later point refused.
  • G68.3 with axis words and a modal G0 emitted a stray move.
  • The preview never reset its tool offset between parses. Under TCP with a tilted tool, two previews of one program started apart.

Visible to configs

  • No existing G-code, pin or INI entry changes meaning; MACHINE_MOVES_IN_MACHINE_FRAME is opt-in.
  • The two *_trsrn_twp sims no longer carry remap_funcs_twp.py wrappers for these codes.
  • On a robot, G13.1 and G49 now stay on the arm kinematics instead of the identity; the identity is reached by number.

Tests

  • tests/kins-twp checks the nutating head module against the python plane maths.
  • tests/twp-native runs the xyzacb nutating head through the plane, the orientation codes and the point-to-point moves against those maths. A reversed joint interpolation fails three of its checks.
  • tests/ptp-robot and tests/ptp-iterative put pumakins and genserkins through the point-to-point codes, the seed and the preview.
  • tests/ptp-machine-frame checks G53.5 and the option on an out-of-tree module with a slanted slide, and the preview against the run.
  • tests/kins-switch covers the tool offset under a tilt and G43.5.
  • tests/kins-frames and tests/kins-params cover the new frames and the offset across the tool.

The full suite passes on this branch alone and on the multiaxis stack, apart from tests/blendmath, which fails on master with GCC 14 and is fixed by #4676.

Neither module reported its frames, so everything that needs them refused or did without on these two machines: the tilted work plane's orienting codes, the preview's tool marker, the tool jog frame and the turn of an offset across the tool.

maxkins tilts the head about y by B and turns the table about z by C. The table turns the work by +C into the pose, so the work frame is Rz(-C); the head's tool frame is Ry(con*B), con the sign the conventional-directions pin selects, since the pin flips the tilt in the forward and the frame has to follow it: the W joint runs the tip out along (-con*sin(B), 0, -cos(B)), the tool axis reversed. xyzab_tdr_kins carries the work on both rotaries, so its tool frame is the identity and its work frame the transpose of the forward's coefficients of the X, Y and Z joints, as the trt modules do it.

tests/kins-frames takes xyzab_tdr_kins and maxkins with the pin either way, and its quill check reads the tool axis from the work, which on a head over a turning table is where the forward reports the W joint's run; on 5axiskins the work frame is the identity and the check is unchanged. tests/kins-params expects their orientation joints. The kinematics conventions chapter says which in-tree modules still report no frames: genserkins, scorbot-kins, genhexkins and pentakins.
genserkins reported no frames, so an arm described by its DH chain got none of the orientation codes, the tool marker or the tool jog frame, where pumakins, the same arm in closed form, had them all.

The arm carries the tool and nothing turns the work, so the work frame is the identity. The tool frame is the flange frame the chain ends in, z along the last joint axis and out of the flange, declared with the same half turn to the convention as pumakins. The forward already reports that frame as roll, pitch and yaw in A B C, so the tool frame is that rotation, written out rather than taken through gomath or a posemath call the module does not link.

scorbot-kins stays without: its controlled point is the wrist centre and A and B are the wrist joints passed through, so there is no tool frame to report. The kinematics conventions chapter says so.

tests/kins-frames takes genserkins as it takes pumakins, and both gain a check that the tool frame turned back by the half turn is the rotation the forward's A B C describe; with the defaults, which are the PUMA of pumakins, the two modules give the same tool frame at the same joints. tests/kins-params expects genserkins to report a frame.
… maths

The two trsrn configs carry their orientation maths in python, written apart from the kinematics modules, and nothing had compared the two. tests/kins-twp loads each module in realtime with a small component answering frame and inverse requests over HAL pins and drives it from python holding the twp functions. Over a grid of primary, secondary and table angles the module's tool frame equals the python transformation matrix to 1e-9; for a set of requested tool axes with the table held as the remap holds it, the joint pairs the module finds are the python's candidates and the spin it reports is the python's virtual rotation. With nothing held the module may turn the table, which the python never does, so there each side is judged by the other's maths.
A segment whose endpoint is Cartesian but whose interpolation is in joint space: the inverse runs once, at the endpoint, when the move is queued, and the planner runs every joint from where the queue ends to there together, the slowest setting the pace. Its length is the joint space distance with the tightest per-joint velocity, acceleration and jerk limits scaled onto it. Nothing blends into or out of it. While it runs the servo thread takes the joints from the planner and reports the tool from the forward kinematics; a forward that fails, as an iterating one can at the singularity the move is there to cross, leaves the last solved position and carte_pos_cmd_ok cleared. This is how a program crosses a singularity or flips a head without leaving its coordinate system.

The move is a rapid with the rapid override or a feed that takes a given time with the feed override; the endpoint can also be given as joints, whose world position motion finds with the forward. Canon JOINT_TRAVERSE and JOINT_FEED, NML EMC_TRAJ_JOINT_MOVE and EMCMOT_SET_JOINT_LINE carry it; the preview draws the straight line between its ends. An external offset cannot ride on a joint segment: the queue refuses the segment while one is applied, and a request arriving while one is queued waits until the last joint segment is done. A queue reset forgets the joint-space bookkeeping with the queue.
… G53.1 to G53.6, and G68.3

The interpreter evaluates the kinematics module ahead of motion through the loader in kinematics_userspace, opened on first use on a HAL component of its own, so G53.n can ask the tool frame inverse where the rotaries go, G68.3 can read the tool direction, and the point-to-point codes can tell where their joints put the tool.

G53.4, G53.5 and G53.7 are point-to-point moves, non-modal modifiers of G0 and G1 like G53: the path is interpolated in joint space, only the endpoint is defined. G53.4 takes a program point through the offsets. G53.5 reads the axis letters as a point in the machine frame with the orientation left out, XYZ the carriage in machine coordinates and the rotary letters the rotary joints, no offset applied: the world of the type the module flags KINSTYPE_MACHINE, the identity type where the slides line up with the frame, so there a letter names the joints the module's identity mapping gives it, and on a module with a slanted or composite slide the point goes through that module's own machine frame maths, a letter not given holding its machine coordinate. Where that type is a plain identity it is refused on a machine whose letters name joints of the other unit class, as a serial robot's X; a module that declares no types is read as letters = joints. G53.7 takes joint values as J<n>=<value> words, a form the lexer reads when the J value is followed by an equals sign, the joint's own position in its own units, which works on every machine. With G1 the move takes the time the straight move would at the programmed feed. The inverse ahead of motion is run to a fixed point, because a module may read the joints it is handed.

G53.1 moves the rotaries to the plane's normal with the linear joints where they are; G53.6 does the same holding the tool centre point, a Cartesian move; G53.3 X Y Z goes to a point in the plane with the tool oriented. P picks among the poses: nearest by default, P1 and P2 by the sign of the secondary rotary, the one whose axis the other carries, found by turning each rotary through the module's tool frame, Heidenhain's SEQ+ and SEQ-. Q says whether the joints that carry the work take part: Q0 holds them, COORD ROT, falling back to everything free; Q1 frees them, TABLE ROT. G68.3 takes the plane from the tool, Z the tool axis as the joints have it, X the default tool X of the conventions chapter.

tests/twp-native runs the xyzacb nutating head through all of it against the python maths in tests/kins-twp; tests/ptp-robot puts pumakins through the point-to-point codes; tests/ptp-machine-frame builds a module with a slanted Y slide out of tree and checks G53.5 holds machine X across a Y move, which the slides would not. Reversing the joint interpolation fails three checks in twp-native.
The two trsrn_twp configs drop the python remap of G68.2, G68.3, G68.4, G69, G53.1, G53.3 and G53.6, its ngc wrappers, the abort handler that unwound it and the twp-status analog pin: the interpreter does all of it now, with nothing to restore on abort. The helper component that feeds the vismach model reads the plane from status. The demos select the TCP kinematics up front, since the orientation codes need it, and put kinematics 0 back at the end; square.ngc loses its G52, which a plane refuses.
Every plane in the frame test was one rotation of ninety degrees about a single axis, written four ways. With two angles zero, composing about the frame as it turns and about the fixed axes give the same matrix, so the difference between G68.2 P0 and P1, the whole reason they are separate codes, went unobserved. One plane at 25, 40 and -15 degrees instead, still written four ways, with the points and vectors derived from it; G68.4 and R take odd angles too, and G53 inside the plane lands somewhere that is not a permutation of the axes. Caught now: P0 composing the way P1 does, R composed before the plane rotation, the three-point form taking Y as X cross Z.
The chapter and the G-code reference described the two angle forms but never said whose conventions they are: P0 is Heidenhain's PLANE EULER, P1 its PLANE SPATIAL, the numbering is Fanuc's, and Fanuc's fifth form is not implemented. Two differences from the control they borrow from are stated: P1 and P2 refuse where a control offering SEQ falls back to the nearer pose, and P names a pose only where a rotary turns the tool, so a machine whose rotaries all carry the work has only the nearest form; the G53.1 section read as though a tilting table had a pose to name.
A point does not name one joint set: a robot wrist reaches it again with the forearm turned half a revolution, and both ends of a point-to-point move read the joints back from the point. The interpreter keeps its seed while it still explains where the machine is, instead of inverting the point every time and reporting joints the machine is not standing in, which had the next G53.7 refused on a joint limit. Motion holds the joints a joint segment ended on while the planner stays there, instead of inverting again the next cycle and undoing the move. tests/ptp-robot drives a wrist joint through zero and back and checks the joints not named stay put.
The interpreter works out the joints behind a point by inverting it, and
had nothing to start the first inverse from but zeros.  A module that
answers the inverse by iterating cannot be started anywhere: genserkins
takes the Jacobian at the seed, and a serial arm with every joint at zero
stands in a singular pose, so on a robot every G53.5 and G53.7 was refused
with "the kinematics cannot invert the current position".

Canon now reports the joint positions, and the interpreter falls back on
them when its own seed no longer explains where the machine is.  They also
name the arm the machine is standing in, which the inverse of a point
cannot: a robot reaches the same point again with the elbow the other way
up.
The preview has a machine to ask, through the status buffer it already
reads for the tool table and the offsets, so it can answer for the joints
as well.  Without them every inverse started from zeros, which previewed a
point-to-point move from a pose the machine is not standing in, and on a
serial arm could not be inverted at all.

The one method on the mixin covers AXIS, gremlin and the Qt screens, which
all take their canon from it.
pumakins answers the inverse in closed form and never looks at the joints
it is handed, so tests/ptp-robot says nothing about the seed.  genserkins
takes the Jacobian at those joints: the machine here homes well away from
all zeros, so the seed has to come from where the machine stands, and all
zeros is the singular pose it cannot come from at all.

The same program goes through the interpreter and through the preview, and
the two have to agree on where it ends up.  Then the arm is parked in the
singular pose, where the module reports through the HAL library it prints
with: the preview refuses, rather than the process going down.
The inverse took the whole Newton step the Jacobian asked for, and the Jacobian holds only near the estimate: an endpoint far from the seed asked for many radians, the arm landed somewhere unrelated and converged on a pose reached through whole turns. Seeded at 90 -90 0 0 90 -17.7 and asked for X450 Y-200 Z150 it answered joint 0 at -3263.962, the right pose nine turns out, which the joint limits refuse on a move the arm could make. Cap the step at GENSER_MAX_ANGLE_STEP and scale the whole vector so its direction survives, measured on the rotary links; a servo cycle asks for far less and is untouched.
The joint limit check inverted a move's endpoint from the joints the machine stands in. The reading runs far ahead, so every endpoint of a short program was checked from the starting pose, and an iterating inverse answers nearest whatever it is handed: park a robot at J4=-90, run a program that takes it to J4=90 and asks for a point, and the point is refused because it was inverted from the parked pose with the other wrist. Seed from the end of the queue instead: a joint segment knows its own end and the rest carry the answer the last endpoint came out with; with nothing queued the machine is the reference. The joint interpolated path already worked this way and shares the helper.
G53.2 asks where the rotaries have to go for the tool to be normal to the active plane, like G53.1, and moves nothing: it publishes the pose on #<_orient_x> and kin and on #5071 to #5079, with #<_orient_valid> and #5080 saying a pose is held, so the program reaches it with a move of its own, for instance one G0 naming the linear and rotary words together, a single Cartesian move under TCP. Heidenhain's STAY. Reading the parameters before the first G53.2 is an error.

Two fixes found on the way: a G68.3 block with axis words and a modal G0 emitted a stray move; and the solver's answers in (-180, 180] are unwrapped onto the turn nearest the present rotary position before the nearest-first ranking, or a rotary crossing 180 swings the long way round.
The orientation codes took each pose the solver reported onto the turn nearest where the rotaries stood and ranked them by travel, without asking whether that turn was inside the joint's limits. A program that winds a rotary, a G68.4 incremental plane in a loop with G53.6, walked it past its limit, and motion refused the move in the middle of the program: "Linear move on line 9 would exceed joint 5's positive limit". The tilted work plane remap it replaces checked the limits and went the long way round.

The interpreter reads [JOINT_n] MIN_LIMIT and MAX_LIMIT beside TYPE. Each angular joint of each pose goes onto the turn nearest where it stands that lies inside its travel, which is the long way round where the short way runs out, and a pose no turn brings inside is dropped before the ranking, so P0 takes the next nearest and P1 or P2 refuse. Under Q0 the table is freed before a pose is refused, as when nothing reaches the direction with it held. Where every pose that reaches the direction is outside the travel, the code refuses with that reason, at plan time rather than in motion.

tests/twp-native stands C at 300 with a travel of 320, picks a plane whose nearest pose is the turn past the limit, and checks that G53.6 ends on the nearest pose inside the travel, with C inside it all the way.
The old 5axisgui.ngc "drilled" a sphere with W words, W standing in for a tool length: the W axis of 5axiskins never drove a physical joint, the stroke folds into the XYZ slides, and the model's drawn quill hid that by cancelling the very motion that makes a W word work. The quill and its drawing lock go, so a W word shows the slides plunging, and 5axisgui.ngc keeps its name with comments saying what the controller cannot see. The sphere is then drilled two honest ways: g532-fused-orient-move.ngc, where G53.2 solves each plane and one fused G0 turns the head and travels to the hole, and g536-orient-then-move.ngc, where G53.6 reorients about the tip and a separate move travels in the plane. The demos and the M428 remap select the TCP kinematics with G12.1 P0, since on 5axiskins G13.1 lands on the identity. The AXIS GEOMETRY drops W: under TCP a W word never moves the tip, so W in the live plot only ever lied.
A module that applies the tool length itself reads it from motion, so a G43 with the head tilted moves the programmed point, not the joints; motion, task and the interpreter each did something else. Motion re-reads the point from the joints under the new tool, as after a kinematics switch, takes the external offsets off, moves the planner onto it and latches the joint hold there. The interpreter predicts the same point through the loader, from the joints the machine stands on, or for a G43.4 that switches on the same line from the joints read in the old kinematics before the switch, evaluating with the tool offset the program is under rather than the one motion has reached; the point rides along with the offset on EMC_TRAJ_SET_OFFSET, and motion aborts when its own answer differs. Under the identity, and where the module cannot be evaluated, the interpreter shifts by the offset difference as before and motion aborts only if the point moved. Task issues the offset once the queue has drained, so no queue busting is needed.

tests/kins-switch applies G43.4 and a zero length in a tilted pose and after a point-to-point move: the joints hold, the point moves by the tilt term, and a move of nothing from the interpreter's point goes nowhere.
The X and Y of a tool offset, a tool held off the spindle axis, stayed
on the work axes under every kinematics.  Canon adds the whole offset
along them; a module that applies the tool takes the length back off
and applies it along the tool axis, but leaves X and Y where canon put
them.  With the head or the table turned the tip landed off the
programmed point by (I - R)(x, y, 0), R the tool frame in work
coordinates: on 5axiskins at B-22.5 C45 a 4, 3 offset put it 4.2 mm
off.

The offset is the tool's own, given against the machine with the
rotaries at zero, so the shared code turns X and Y with the tool frame
the module reports.  kinsOpsForward() adds (I - R)(x, y, 0) to the pose
the maths answers, kinsOpsInverse() takes it off the pose it hands the
maths, settled on the joints the inverse finds, and kinsOpsJacobian()
adds the term the turn contributes.  Realtime and the loader make the
same calls, so motion, the interpreter's prediction of a tool offset
change and the segment cap agree.  Nothing is turned without an X or Y,
on a type flagged identity or machine, which leave the tool out of
their maths, or for a module that reports no tool frame (scorbot-kins,
genhexkins, pentakins), where X and Y stay on the work
axes as before.

tests/kins-params evaluates 5axiskins, the trt modules and the trsrn
modules under a 4, 3 offset across the tool, the same in realtime and
through the loader, and checks that each module's length lies along its
own tool axis, that the tip is the point the tool hangs from less the
offset turned with the tool, and the Jacobian against differences of
the inverse.  tests/kins-switch puts the tip on a programmed point
through motion with the head tilted.  Both fail without the change.

Reported by Sigma1912.
G43.5 is G43.4 with one thing more: while it is in effect a G0 or G1 line may give the tool axis as I J K in place of rotary words, the form of a five-axis program written for the tool rather than the machine, Fanuc's tool center point control type 2. The rotaries are solved through the module's tool frame inverse, the solver G53.1 uses, split out as orient_solve(): every orienting joint free, the pose nearest the present one, so a path of vectors runs continuous; on the pole of the primary rotary the free joint stays. The pose enters the move as program rotary words through machine_pose_to_program(), so rotary offsets are right by construction and the move interpolates like any other. The vector is read in the coordinate system the line's X Y Z are in, the tilted plane where one is active, the machine's on a G53 line. A direction is never incremental, so G91 applies to the axis words only, and I J K alone turns the tool in place. No configuration names the rotaries: the same program orients a head, a table and a robot.

Refused: a vector with a rotary word, a zero vector, the identity kinematics, a vector on a G53.5 or G53.7 line. Left out: Fanuc's interpolation of the vector between lines, which needs the kinematics inside the planner. The semantics follow the G43.5 greatEndian built for xyzab_tdr_kins on the fork, including that the vector is absolute under G91; this is the generic form.

tests/kins-switch covers the vector against rotary words, G91, the pole, a rotary offset and the refusals; docs in g-code.adoc.
…MACHINE_MOVES_IN_MACHINE_FRAME

G53, G28 and G30 move in the world of the kinematics in force with the offsets removed, and on a table-side kinematics that world turns with the table: G53 X0 Y0 Z0 under TCP with the table at A10 takes the tool tip to the turned origin, which the slides reach elsewhere. Under a tool centre point kinematics G53 also takes the tool length off along machine Z, where the kinematics carries it along the tool, so with the tool tilted the slides land where the tool and the head angle put them. That is what the existing switchkins configs rely on, so it stays; the G53 section says so now, and points at G53.5 for the machine frame.

G28.5 and G30.5 are to G28 and G30 what G53.5 is to G53: the stored position is read in the machine frame with the orientation left out, the way G53.5 reads its words, the slides on a machine whose slides line up with its frame, and the move is a joint-space traverse there, with no offset, tool length or work plane. Axis words on the line are a machine frame waypoint, and then only those letters go to their stored values, as G28 does with its words. The stored position has to be saved on the machine frame type, where the world is that frame, or with the option below.

[RS274NGC] MACHINE_MOVES_IN_MACHINE_FRAME, off by default, is for a configuration that wants the machine codes to mean that frame: whenever the kinematics in force is not the machine frame type, G53, G28 and G30 run as G53.5, G28.5 and G30.5, and G28.1 and G30.1 store the machine frame position those read back. The slides then go to the words or the stored position whatever the tool, the head and the table are doing. The codes are swapped as the block is read, so the checks and the errors are the machine frame codes'. The decision is the flags the module declares for the selected type, with the machine's kinematics type as the fallback for a module that switches nothing; a plain identity type that is not the machine frame is read in the machine frame like any other, and on the machine frame type G53 stays a straight move.

The letter mapping and the joint move come out of convert_ptp_joints into slide_joints and ptp_joint_move, shared by the three codes, and the check that each letter names joints of its own unit class into letters_name_joints, which the store shares. The twp-native test stores a position on the identity, checks G28.5 and G30.5 with the head tilted under TCP, the waypoint included, sets the option and checks that under TCP G53 lands where G53.5 does on one joint-space move, that G28 and G30 go back to the slides G28.1 and G30.1 stored with the head tilted, and that on the identity the codes are the world's. The ptp-machine-frame test does the same on the slanted module, where G28.5 with the head tilted lands the carriage, and checks the option under the tip and under the plain identity, where G53 Y10 holds machine X. The waypoint check wants the joint to reach its turn, and a status snapshot per task cycle misses a turn by up to 9e-3 mm at the test's deceleration, which failed on a loaded runner: the twp-native test now reads the path of every move from a sampler on the servo thread, logged by halsampler, where the turn falls inside one cycle.
With [RS274NGC] MACHINE_MOVES_IN_MACHINE_FRAME set, a GUI's preview read every G53 in the machine frame whatever type the machine was on, the GUI's own first. A GUI starts its preview by restating where the machine stands, with G53 G0 to the position in the status buffer: a block per axis in AXIS, one block in the other screens. The preview could not tell which kinematics type was in force, since its canon answered type 0 and no flags for every type, so it ran on type 0 and the decision fell back on the machine's kinematics type, which for a switchable module is never the identity.

The status buffer carries the type motion runs and what the module declares each type to be, as the interpreter in task reads them. The Python status now reports them as kins_type and kins_type_flags, with the KINSTYPE_ constants, and the status mixin the preview canons are built on hands them to the preview, read once a parse because the interpreter asks for the flags on every block. The preview then starts on the type the machine is on and follows the program's G12.1, G13.1, G43.4 and G49 as the interpreter in task does, so a program's G53, G28 and G30 land where running it would land them. A canon with no machine to ask answers as before.

The restating codes are a different matter whenever the machine stands on another type than the machine frame, under a tool centre point type say: the position they restate is in the world of that type, and G53 is the only way to say it. They are the GUI's codes, not the program's, so the preview holds the option off until the program starts.

The preview also kept the tool offset the last parse ended on, which the interpreter reads as it starts. AXIS restates the offset after the position, and under a tool centre point type with the tool tilted the restated G53 depends on the offset in force, so two previews of the same program could start apart. Each parse now starts with no offset, which the GUI's restating codes then set.

The ptp-machine-frame test previews a program with a G53 through both forms of the restating codes, AXIS's with the tool offset in force, which under the tip type the kinematics evaluates in the GUI's own process, on the machine frame type, under the tip type and on the plain identity, and one that selects the machine frame type with G13.1 before its G53 under the tip, and checks that each ends where the same program with G53.5 does. A move that goes nowhere reads back the restated position, which has to be the one the machine reports, and on the plain identity the preview has to end where running the program ends. Without the type from the status buffer the run check fails, without the hold the restated position does, and without the offset reset the second preview under the tip starts elsewhere.

Reported by Sigma1912.
The bridgemill, table-dual-rotary, table-rotary-tilting and both table-rotary_spindle-rotary-nutating sims set MACHINE_MOVES_IN_MACHINE_FRAME, with a comment saying what it does, so a new user starting from one gets G53, G28 and G30 that put the slides in the same place whatever the tool and the head angle, and anyone copying the config sees the setting and where it is documented. None of their programs or remaps uses those codes under the TCP kinematics: the boat demo's G53 lines carry G49 or follow it, which cancels to the machine frame kinematics first.

The G43.4 section and the switchable kinematics chapter now point at the setting too, where someone setting up a TCP machine reads.
A robot's working transform reports the flange in the base frame, ABB's tool0 and KUKA's $NULLFRAME: the tool is applied on top by the interpreter, not by the maths, so the type G43.4 switches to is also the machine with the tool left out, the frame G13.1 and G49 cancel to and G53.5 moves in. pumakins and genserkins declare that one type both primary and machine. G13.1 and G49 leave a robot on its arm kinematics, where a robot controller leaves it, and the identity type, joints as axes, is reached by number; G53.5 moves the flange along a base axis and holds the rest, the orientation included, interpolated in joint space, and G28.5 and G30.5 with it. A machine frame type does not read the tool offset in the parameter block, so a module whose working transform does read it declares a type without it.

The machine frame is described as the frame with the tool left out rather than with the orientation left out, since on a robot the rotary letters are the flange angles the module reports, not joints; the G13.1, G49 and G43.4 descriptions say machine frame where they said identity. tests/ptp-robot checks that G53.5 moves the flange from the arm kinematics and from the identity alike, and that G13.1, G43.4 and G49 all leave the robot on the arm kinematics, in place of the refusal it checked before.
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.

1 participant