Jump to content
OMRON Forums

curtwilson

Members
  • Posts

    723
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by curtwilson

  1. On the motor going open loop at high velocity, it sounds like there is either a following error fault or amplifier fault stemming from the inability of the system to maintain the commanded speed. Both "kill" the motor automatically, leaving it in open-loop mode with the amplifier disabled. Look at the motor status window in the Executive or use the ? query command to find out what type of fault occurred. On your loss of synchronization issue, we will need to know more about what you are trying to do, how you are trying to do it, and what happens when you lose sync.
  2. Yes, you do appear to be integrating the outer loop command before injecting it into the inner loop. In this case, even though the outer loop command saturates, its integral should continue to increase and move the inner loop motor. A couple of things I note. You have I106=0. This would disable the coupling to the inner loop. I presume this is 1 or 3 when the loops are actively cascaded. Correct? Your feedback for the force virtual motor looks to be the sum of a position count and a filtered analog feedback. I don't understand this at all? Why are you including position here?
  3. When there is the possibility that the outer-loop command output will saturate, you want to integrate this value in the conversion table (method 5 instead of method 1) before injecting it into the inner loop. When you use this you can go indefinitely, as in web tensioning on a system that is moving all day in the same direction. This integration does change the dynamics of the system. Start with an extremely low Ix30 gain in your outer loop (below 10 -- seriously), then ramp it up to see how much it can take.
  4. What is your value of saved setup element Coord[2].SyncOps? This specifies the size of the buffer for these assignments. Could you have set it to 0? I don't need parentheses to use a negative number without a leading zero. I'll have to check into the IDE's error checking, sometimes it is overly sensitive, tagging things that Power PMAC itself does not care about. What IDE version and what Power PMAC firmware version (vers) are you using?
  5. Is your coordinate system in incremental mode? Do you want it to be? (When I tried your code, I got a move the first time, then it wouldn't move again, because I was in absolute mode commanding it to the same position.) I'm not getting any problems when I specify the .2 number without the leading zero, either in getting Power PMAC to accept the command or to execute it properly.
  6. That should not matter. Setting the TM time inside the loop as you had in your original example should work fine. Many people do this, especially if they need to change the time each loop. In your case, with a constant time, it would make a little more sense to put the TM command above the loop, saving a little calculation time, but it should not affect the trajectory at all? Did you change anything else? What are your TA and TS times? (If not set in the program, they rely on the saved values of Isx87 and Isx88, respectively.)
  7. The intent of the gantry leader/follower algorithm is to provide identical commanded trajectories to both leader and follower motors without having to recompute for each motor. By identical, I mean that it will provide the same numerical position command value to both/all motors every servo cycle. So it will servo the follower motor to the same numerical position value as for the leader motor (no matter what that number means physically). I assumed that you wanted the same physical position value but had different measurement resolution. It appears from your latest comment that you want the follower motor to move a different physical distance from that of the leader motor. To do this, you would have to define motor units on the follower motor (by setting the value of its PosSf element) that are different from that of the leader motor, because the numerical command values for both motors (in their respective motor units) will be the same.
  8. Here's the experiment I just ran with two identical motors on my demo box. First I set Motor 2 to follow Motor 1, both with PosSf of 1.0. I got the 1-to-1 following I desired. Next, I changed the encoder decode on the Motor 2 encoder from "times 4" to "times 2", so a count on Motor 2 is twice as big as on Motor 1. Leaving PosSf at 1.0 for the motor, it now "follows" Motor 1 at a 2-to-1 ratio -- its physical distance traveled is twice as far as Motor 1 goes. Then, I changed PosSf for Motor 2 to 2.0 (Pos2Sf as well so inner loop and outer loop scaling is the same, but that is not really necessary). Motor 2 now follows Motor 1 at a 1-to-1 physical ratio again. Remember that these scale factor terms act as gains in the servo loop, so you would need to retune. I kept the gains low for my experimentation. (I am assuming here that your goal is to take two motors with different feedback resolutions and tie them together with a 1-to-1 physical relationship.)
  9. It looks like you will be doing very intensive calculations in your kinematics routines -- the actual kinematics plus (I expect) the collision detection. If you start running out of processing power here, you can convert this code to C through the new "CfromScript" subroutine feature. The actual kinematics routines just become a shell to pass off the calculations to the C routine. Equivalent calculations will execute over 10 times faster in compiled C as opposed to the Script. Probably your haptic feedback will be done at servo rate. This also should be done in C, probably as a user-written servo for an extra "virtual" motor.
  10. In a gantry leader/follower pair, the follower motor simply uses the leader motor's trajectory, so this trajectory is assumed to be in the motor units of the follower motor as well. For any practical system, this means that the follower motor's position units must have the same resolution as the leader motor's. If the two motors have different encoder resolutions, the Motor[x].PosSf saved setup element that scales the encoder position into motor position for the two motors must be different so they end up with the same motor units.
  11. The blending is controlled by the acceleration time parameters, which you have not specified in your provided code. When you use Linear mode for smooth contouring, the TA time should be set equal to the TM time, and the TS time should be set equal to 0. If the TM time is greater than the acceleration time, you will get "flats" in between blends in your contour. I notice you are using PI explicitly in your angle calculations to convert radians to degrees. If you set I15 to 1, the trig functions will use radians directly.
  12. I think the first thing is not to have too high expectations of what you can accomplish. For about 20 years now, I have been hearing claims that the problem of tight position control of pneumatic systems has been "solved", but I've never really seen it pan out. If I were tackling this, I would consider it like a motor/load system with a very compliant motor coupling. With very soft control implemented, I would characterize the resonant frequency at various points of travel, including both extremes. For my first cut, I would implement a notch filter to compensate for the lowest frequency resonance. It may work well enough over the entire range of frequencies. If it works well at the design frequency but not for significantly higher frequencies, then you will need to consider a gain scheduling regime that changes the filter as a function of position. Remember that when you are changing gains, you need to make sure that you change all 5 parameters -- the 4 notch coefficients plus the Ix30 proportional gain -- in the same servo cycle, so this will need to be done in a foreground task.
  13. In the Power PMAC, any access to a "double" (64-bit floating-point) variable is guaranteed to be atomic, a feature of the hardware floating-point engine in the processor.
  14. M-codes in a PMAC are simply subroutine calls, because every machine requires a different implementation of these codes. Mxx specifies a jump to PROG 1001, line label Nxx000. M00 is therefore a jump to PROG 1001, line label N0, and there is an implicit N0 at the top of a program, so an M00 code will cause the code in PROG 1001 from the top to the first RETURN command to execute. The M-code subroutines are typically written by the system integrator for the machine, and will vary from implementation to implementation. If the system is one of our PMAC-NC systems, using our CNC HMI software on the PC, integrators usually start with our template for the M-code subroutines. Typically, there is very little in an M00 end-of-program subroutine, as PMAC handles most end-of-program issues automatically. Some users will put an explicit STOP command in the program, so if the M00 is not at the end of the part program, it will still halt execution. Some users will put a DWELL command in to make sure that any pending synchronous outputs are fired. Others will make sure that certain outputs (e.g. coolant) are turned off, even if the part program "forgets" to do this. But that's about it.
  15. drzong: The particular trick you used in Turbo PMAC -- feeding the desired position through the conversion table into the master position with a "gain" of -1 to cancel out the net position command into the servo loop, is not available in Power PMAC, because the trajectory desired position is a floating-point and the conversion table requires fixed-point inputs. I think the equivalent trick in the Power PMAC is to use the trajectory pre-filter to cancel out any changes to the net position command. This filter works on changes to the computed trajectory. Most people use it as a band-reject filter or low-pass filter to take certain frequencies out of the desired trajectory, but it can be set up to take out the whole trajectory in effect. If Motor[x].Pn0 is set to 1.0, and Motor[x].Pd1 is set to -1.0, with all other filter coefficients set to 0.0, the filter (when active) integrates the position changes from the computed trajectory, then subtracts these from the computed trajectory. The net result is no change in net position command to the servo, but the servo is active at the position where this mode was enabled. The filter is enabled by setting Motor[x].PreFilterEna to 1. When you want to command real motion, you can either set Motor[x].PreFilterEna to 0 to disable the filter, or set the coefficients Pn0 and Pd1 back to their default values of 0.0 to make the active filter do nothing. I'm not sure which is better. The computed trajectory position can be found in Motor[x].Desired.Pos whether or not the filter is active. It is copied into Motor[x].Ppos if the filter is active. The output of the filter -- the net command to the servo -- can be found in Motor[x].DesPos. Try this first with bare motors, because mistakes in the filter can cause violent motion. Make sure you can switch between modes safely and reliably.
  16. I've had a chance to check this here on a Turbo PMAC. The exponential filter works fine when bit 16 of the source address is 1. I'm worried about the possibility of "random data" in the high 8 bits of your source register. This may be the real source of the crazy results you are getting.
  17. I'm puzzled as to how this could be the case. A tracking filter (which is simply an exponential filter plus an integral gain term) is a 5-line entry in the table, so if it were a tracking filter, the result would be at the address matching I8012, not I8010. And the integral gain term, which has to be greater than zero for the filter to act as a tracking filter, would be in I8012. What happens if you use one ECT entry to process the analog input into an intermediate result in the table, then execute the exponential filter on this intermediate value? This is how the filter is usually used.
  18. I don't see anything wrong in the setup here. Using just the Gate3 hardware setup variables (no active motor trying to write to the PFM register), can you get any output signals by writing non-zero values directly to the Pfm element? Do your Gate3 element settings "take" (i.e. can you read back the values you wrote)? Does the channel's ServoCapt element change steadily when non-zero values are written to Pfm? (This wrap back occurs inside the ASIC.) Query it in the Watch Window. The direction outputs are on the same pins as the U and V input flags for the channel. Can you see the value of the UVW element for the channel change as you put positive and negative commands in the Pfm element?
  19. We have never had a real G93 "inverse time" mode in any of our PMACs, including the Power PMAC (although our TM mode is similar). We do not support cutter comp in TM mode because there are too many "undefined" issues as to what should happen to the move time when the compensated move length is changed, and how an added move at a sharp outside corner should be executed. Also, G93 mode seems to be dying out in general. Most of my newer CNC manuals from mainstream vendors do not show this mode.
  20. It will probably be best to use the new Power PMAC program commands cskip (conditional skip) and/or cexec (conditional execution). These were added to Power PMAC to facilitate functions such as this.
  21. tzqdo: In Turbo PMAC, register X:$0 (suggested M-variable M0->X:$0,0,24) counts up once per servo cycle starting at power-on/reset. This is what most people use for the running time. Note that as a 24-bit register, it rolls over after 16 million servo cycles -- about 2 hours at the default servo update rate. I am not sure what you mean by logging. Can you clarify please?
  22. The segment positions in motor coordinates are stored in the "motor target position" register (suggested M-variable Mxx63). If the coordinate system is set up with axis definition statements, these positions are not stored in axis coordinates, but as Sina points out above, if you define the C.S. with kinematic routines, they will be in Q-variables. Curt Wilson
  23. Dave: We got feedback from Turbo PMAC users that the "program running" status bit did not cover from a user's point of view all the cases where the program might be considered to be "running" or "not running". For example, after it has finished calculating the last move, this bit goes to 0, even while the last move is still executing. Users would commonly "OR" this bit with a motor "timer-enabled" bit to cover this case. So in Power PMAC, we created a few "user-viewpoint" status bits that are logical functions of multiple internal status bits. These do a much better job of telling the user what he wants to know. In the Script environment, we can hide the fact that these are actually function calls, but not in C. Between ProgRunning and ProgActive, which you want to use depends on what you want to know. ProgActive stays true even when the program is suspended in a way that permits resumption (as from a q or s command). Both will stay true as the last move(s) are executing, even though program computation is completed. Presently I see two ways of querying these from a C program. One is to use a generic "getResponse" function and look at the text response. The second is to have a Script PLC copy the bit value into something a C program can access. Before too long, we will have a C API call for these bits to permit more direct access. Curt
  24. Dave: The mechanism we intended for providing common access in C and Script to the same variables is the user shared memory buffer. To ensure that both C and Script access the same register, you specify the register directly, and use pointers in both environments to access that register. From the Script side, you make definitions like these: ptr MyDoubleVar->d.user:$100; ptr MyIntVar->i.user:$108; ptr MyIntConstant->i.user:$10C = 42; // Value set on download, power-up, reset From the C side, you declare these variables: double *MyDoubleVar; int *MyIntVar, *MyIntConstant; and set the addresses with statements: MyDoubleVar = (int *) pushm + 0x100; MyIntVar = (int *) pushm + 0x108; MyIntConstant = (int *) pushm + 0x10C; One of the software guys will explain how you can also provide C access to global (P) variables you define in the Script environment. This is easier, and you can pull the same trick of assigning a value in the declaration to use the variable as a constant: global MyGlobalVar; global MyGlobalConst = 42;
  25. I'm having trouble duplicating this. I will need some more detail as to how you are doing this and what you are trying to do. Curt
×
×
  • Create New...