Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is there a way to suppress arguments regardless of where they appear on a line?
I know read(X) can be used to suppress the X argument if it appears first in the line, but is there some way to suppress the X argument regardless of where in the line it appears? Alternatively is there some way to read all arguments and mark only certain ones "unread"?
Are you talking about G-Code or some other subprogram? I don't believe there is a method.

We often look at the mask in D0 after the read command, one bit will be true for each input received, and then use conditional logic to use the inputs we receive. If you were to issue G0 X5 for example, depending on how the sub program is written X5 may be an input to the subprogram used to issue something like X(D24) or if the subprogram does not read it may be ran as though it were on the next line.
Yes, I am talking about G-Code. So for example if I want to suppress the X-axis in G1, and my axes are X and Y, I could do:

read(X, Y)

if (ArgPassVar & YargMask)

But then if there are multiple axes, I have to check each axis argument, and have an if statement for every combination of axis arguments, which is messy. What I really want is something like



read(X, Y)
There is no "readall" or "unread" statement. You will need to have logic to check for all the combinations.
Because it looks like you are just trying to suppress motion, I am assuming that if the axis is in the G1 command then you want to move it, otherwise you do not want to move it. If you wanted to check something else, like a global variable the if statements below can be changed. I am also assuming absolute position is being used, otherwise if incremental is used Coord[1].CdPos[X] can be replaced with 0.

Because the variables that hold the inputs are writable, it is possible to replace them for all unused arguments. We just have to move the actual move commands inside the sub-program. We can take current positions from Coord[1].CdPos[X].

I've tested the following, and it works, although it is a bit bare bones compared to our full G-Code implementation.

#define ArgPassVar D0
#define XargMask $800000
#define YargMask $1000000
#define ZargMask $2000000



if ((ArgPassVar & XargMask)==0) {D24=Coord[1].CdPos[6]}
if ((ArgPassVar & YargMask)==0) {D25=Coord[1].CdPos[7]}
if ((ArgPassVar & ZargMask)==0) {D26=Coord[1].CdPos[8]}

x(D24) Y(D25) Z(D26)


Looking back at this, I doubt you are trying to only move included axes as that would be basically default, just swap the if statement to whatever condition you were trying to check. Or is there something else you were trying to do?
Let's say for example I had a CNC router and wanted to make a mode in which the machine only moves in X and Y but not in Z for dry run purposes. I want to run the same exact G-code but not actually plunge into the material. I also don't want to mess with coordinate or motor scaling factors.
One hack that will work for this is to do the following:

1) Motor[*].ServoMaxPosErr=0 //
2) Motor[*].FatalFeLimit =0 //disable following error trip

This will keep the * motor from running (although damping term may still run)
but, allow motion programs to keep running.

There is probably a more elegant way...but this works.

Another way is to use the Trajectory Pre-filter.

See page 353 in the User discusses the technique.
Eric's suggestion can be made to work for what you want to do, but it may not be the best way. To explain the reasoning behind it:

First, the "read(x,y,z)" statement causes the 3 position values to be read into D24, D25, and D26.

Then, if an "axis inhibit" flag is set for an axis, the D-variable value is overwritten with the present axis position, thus suppressing motion of the axis. (This assumes ABS mode; for INC mode, it would be overwritten with a 0.

You would need to put the G-code call (G00, G01, etc.) on every line to do it this way (or a "conditional call" ccall1 on every line).

Dave's suggestion of using the motor trajectory pre-filter to lock an axis is probably better. You can configure the filter not to let any changes through, thus freezing the motor at its present position (retaining closed loop control).

The only tricky thing is properly disabling the filter. In general, the output of the filter (the "locked" motor position) will not agree with the input (where it was commanded while locked). If you simply disable the filter, it will try to jump immediately to where it had to be commanded. So you have to force the value of the input to the filter to that of the output. Then you have to make sure the axis position value matches that of the motor position so it can compute the start of the next axis move properly.

Here is code that does it for Motor 3 and the Z axis -- what most people are interested in. It is easily generalized if you need. This code does it as a G46 subroutine locking the Z axis, and G47 unlocking it. You probably will want to issue the commands from a different source, but the concept is the same.

n46000: // Lock Z-axis with trajectory pre-filter
dwell 0; // Stop all pre-calculation
Motor[3].Pn0 = 1.0; // Setting to block input changes
Motor[3].Pd1 = -1.0; // Ditto
Motor[3].PreFilterEna = 1; // Enable blocking filter
n47000: // Unlock Z-axis by disabling trajectory pre-filter
dwell 0; // Stop all pre-calculation
Motor[3].Desired.Pos = Motor[3].DesPos; // Value at start of blocking
Motor[3].PreFilterEna = 0; // Turn off filter
pmatch; // Compute present axis pos
(02-27-2019, 03:42 PM)curtwilson Wrote: You would need to put the G-code call (G00, G01, etc.) on every line to do it this way (or a "conditional call" ccall1 on every line).

I just want to expand this because it seemed important, but quick to miss.

G1 is modal so if you want two linear moves, you probably only have 1 G1, like below.
G1 X1 Y1 Z1
X2 Y2 Z2

Altering G1 in the G-Code Library could suppress a move in the first line, but not the second. All moves that might be suppressed would have to start with G1
Thanks, the trajectory filter approach looks like it could work, I'm testing it now.
I have tried the trajectory filter approach and it seems to have a problem. Let's say I'm suppressing Z motion and I have a program like

G1 Z10
G1 X5
G1 X10

A strange pause occurs in the last line, where the machine moves in X very slowly for a while, and then begins to move at normal speed again. I believe this must be caused by the pmatch inside the default implementation of G54, which I confirmed by trying the same program with just pmatch instead of G54 and seeing the same behavior. Without the trajectory filter, the same program runs fine. Perhaps there is some slew rate that I need to adjust to fix this?
I am not able to replicate this issue. Are you using kinematics? That might complicate the PMATCH.

If this gets too specific for a public post feel free to email me at EHotchkiss AT DeltaTau DOT com
We are not using kinematics, but we are using a transformation matrix as defined in the work offsets (I noticed the release notes mention that the pmatch command didn't use to work with that).

In general, when pmatch is called, what is the rate at which it tries to match the coordinates with the motor positions? Is this a value that we can control?
If there is nothing you consider secret, I'm fine answering questions here. Sorry if I've had a hard time keeping up the last couple days.

There shouldn't be any associated slew rate. PMATCH sets axis positions based on motor positions. We do need to figure out what's going on with your system though. What is the firmware version since we are talking about an old bug that may be relevant?
I reproduced this problem on my Power PMAC Clipper with a minimal configuration. I had no actual motion hardware attached to the Clipper. I used the NC UI to run the Gcode, but also reproduced it just running from the IDE (Set RunOptions = 8 to enable dry run).

The following plot shows this GCode running:

G1 X10 F10
G1 Z300
G1 X20
G1 X0
G1 Z0

With dry run off, everything is fine. With dry run on, everything is the same, except for a strange pause at the start of the "G1 X0" line.

I've attached the PMAC source code that should allow you to reproduce this.

Attached Files Image(s)

.zip (Size: 277.41 KB / Downloads: 4)
It looks like the PMATCH works a little funny with the dry run filter.

The filter works by allowing Motor[3].Desired.Pos to change and track the program position, while Motor[3].DesPos stays constant so that PMAC does not move the motor.

PMATCH grabs the motor's true position from Motor[3].DesPos. The next program line with a move has an implicit move to this current position. Now the program thinks it's moving from the axis position Motor[3].Desired.Pos (which was tracking the program) to the position the actual motor is locked at Motor[3].DesPos in a single segment (Coord[x].SegMoveTime). Lookahead then greatly stretches the move time for the locked axis. This extends the move time for all motors to keep positions synced up.

To solve this problem we can issue Motor[3].Desired.Pos=Motor[3].DesPos before PMATCH, if the dry run filter is active. It looks like you have 2 PMATCH statements, one in the ComputeNCTransform(XformNum) subprogram and one in G511, which runs after the dry run filter is disabled. We can ignore G511. In the sub program, we want a block like this:

Using this method may increase or decrease the time that PMAC is waiting for the locked motor in the first move after the PMATCH, as it is changing the axis level starting position and thus travel distance.
Thanks, I think that solved the problem.

Forum Jump:

Users browsing this thread: 1 Guest(s)