Jump to content
OMRON Forums

Is there a way to suppress arguments regardless of where they appear on a line?


maxvoxel8

Recommended Posts

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"?
Link to comment
Share on other sites

  • Replies 17
  • Created
  • Last Reply

Top Posters In This Topic

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.

Link to comment
Share on other sites

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:

 

n1000:

linear

read(X, Y)

 

if (ArgPassVar & YargMask)

Y(Yarg)

 

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

 

n1000:

linear

readAll(X)

 

or

 

n1000:

linear

read(X, Y)

unread(Y)

Link to comment
Share on other sites

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

OPEN SUBPROG 1000

n1000:
linear

read(X,Y,Z)
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)

CLOSE

 

Edit:

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?

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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.

 

-DB

Link to comment
Share on other sites

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

return;

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

return;

/*********************************/

Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 2 weeks later...

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

G54

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

  • 2 weeks later...

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

G54

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.

sample.zip

Figure_1.png.9bdc7aed95df324dd6de0574ec6b5199.png

Link to comment
Share on other sites

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:

DWELL 0
Motor[3].Desired.Pos=Motor[3].DesPos
PMATCH
DWELL 0

 

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.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

×
×
  • Create New...