maxvoxel8 Posted February 20, 2019 Share Posted February 20, 2019 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 More sharing options...
Omron Forums Support Posted February 21, 2019 Share Posted February 21, 2019 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 More sharing options...
maxvoxel8 Posted February 22, 2019 Author Share Posted February 22, 2019 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 More sharing options...
steve.milici Posted February 25, 2019 Share Posted February 25, 2019 There is no "readall" or "unread" statement. You will need to have logic to check for all the combinations. Link to comment Share on other sites More sharing options...
Omron Forums Support Posted February 25, 2019 Share Posted February 25, 2019 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 More sharing options...
maxvoxel8 Posted February 27, 2019 Author Share Posted February 27, 2019 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 More sharing options...
DaveBarnett Posted February 27, 2019 Share Posted February 27, 2019 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 More sharing options...
DaveBarnett Posted February 27, 2019 Share Posted February 27, 2019 Another way is to use the Trajectory Pre-filter. See page 353 in the User Manual...it discusses the technique. Link to comment Share on other sites More sharing options...
curtwilson Posted February 27, 2019 Share Posted February 27, 2019 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 More sharing options...
Omron Forums Support Posted February 28, 2019 Share Posted February 28, 2019 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 More sharing options...
maxvoxel8 Posted March 8, 2019 Author Share Posted March 8, 2019 Thanks, the trajectory filter approach looks like it could work, I'm testing it now. Link to comment Share on other sites More sharing options...
maxvoxel8 Posted March 15, 2019 Author Share Posted March 15, 2019 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 More sharing options...
Omron Forums Support Posted March 20, 2019 Share Posted March 20, 2019 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 Link to comment Share on other sites More sharing options...
maxvoxel8 Posted March 22, 2019 Author Share Posted March 22, 2019 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 More sharing options...
Omron Forums Support Posted March 22, 2019 Share Posted March 22, 2019 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 More sharing options...
maxvoxel8 Posted April 1, 2019 Author Share Posted April 1, 2019 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 Link to comment Share on other sites More sharing options...
Omron Forums Support Posted April 2, 2019 Share Posted April 2, 2019 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 More sharing options...
maxvoxel8 Posted April 4, 2019 Author Share Posted April 4, 2019 Thanks, I think that solved the problem. Link to comment Share on other sites More sharing options...
Recommended Posts