Jump to content
OMRON Forums

curtwilson

Members
  • Posts

    723
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by curtwilson

  1. For EtherCAT I/O, your definition will be something like: Motor[x].pCaptFlag = ECAT[0].IO[4].Data.a
  2. The correct syntax for this would be: Motor[x].pCaptFlag=sys.piom+$A00000 Here the "sys.piom", which is the value of the base I/O address in Power PMAC memory, performs the same effective function as "u.io:" in the M-variable definition. As an old card, the ACC-11E does not have the circuitry for auto-detection by the CPU, so you have not been able to use Acc11E or GateIo data structures. But in V2.0 firmware, we added the capability for you to "manually detect" older cards like this, so you can access them through these data structures. If you make the following assignments: GateIo[0].PartNum=603307 // ACC-11E part number GateIo[0].PartType=8 // IO card and issue a save command, then your ACC-11E can be used just like newer cards (ACC-65E, ACC-68E) that have the auto-detect circuitry. So then you could use: Motor[x].pCaptFlag=Acc11E[0].DataReg[0].a and: ptr TouchSensor->Acc11E[0].DataReg[0].3.1 // DataReg starts at bit 8 on 32-bit bus
  3. Yes, that is how you would want to use the "pread" command. For the center-finding algorithm, you may want to look at this Turbo PMAC application note that is on the forum: http://www.deltatau.com/Common/technotes/Probing%20for%20Dimensional%20Analysis.pdf It uses 3 move-until-triggers, with each post-trigger move coming back to the trigger position, and the X and Y final positions are read each time. From these 3 points, the center can be derived. Rather than using a single motion program, you could if you want command each move individually from C.
  4. From within a motion program, the pread command would be the best way of getting present axis positions. But I'm still trying to figure out why you are not using our triggered move constructs, which do this automatically for you. It seems to me you are trying to re-invent the wheel...
  5. Yes, you could do it that way. Remember that PMAC is computing an extra move ahead so that it can blend moves together properly, so there is an extra little move already in the queue when you drop out of the loop.
  6. Ken, We do have those types of constructs in the motion program syntax. For example, you could use: do { inc X10 tm100 } while (MyGlobalVar == 1) ... But we think that providing an integrated structure like: X1234^0 is much simpler for most uses for most people, even those who do not need the precision of hardware capture.
  7. Each top level program in Power PMAC (each PLC program, each coordinate system for a motion program) has its own stack of local variables. But for a given top-level program, it is the same stack when different subroutines are called. This explains the behavior you are seeing. It is good general practice -- and needed in your case -- not to expect that subroutines can retain a value from one call to the next in a local variable.
  8. Above post edited to indicate Motor[x].CaptureMode should be = 1 from hardware trigger, software capture.
  9. I think you are going to want to use our "move until trigger" functionality, either a motor jog-until-trigger, or an axis rapid-mode move-until trigger. These work like a homing search move except they do not reset motor zero position. Since you are OK with software capture accuracy, you do NOT need to use one of the channel flags that is capable of hardware trigger -- you can use a general-purpose I/O point. The trigger DOES have to be on the 0-to-1 transition of the input bit. (That said, many people use the encoder channel's USER flag input for this type of functionality. In that case, the only change from default you need for this is to set Gaten.Chan[j].CaptFlagSel to 3.) To use a general-purpose input for this, you will want to have setup element values like the following for the motor: Motor[x].CaptureMode = 1; // Hardware trigger, software capture Motor[x].pCaptFlag = Acc68E[0].DataReg[2].a; // Address of input trigger bit Motor[x].CaptFlagBit = 11; // Bit number of trigger on 32-bit bus Then, for a motor command, you just need to issue a jog-until-trigger command something like: jog=1234^0 This would go to motor position 1234 in the absence of a trigger, but if a trigger is found, it would return to the trigger position with offset 0. Or for an axis command, you would issue a command like: &1 cpx rapid abs x1.234^0
  10. Yes, you've got it. Remember that JogSpeed is used in the computation of each move in addition to JogTa and JogTs. When you are breaking into existing moves, it is strongly recommended that you specify acceleration and jerk by rate, not time (JogTa < 0, JogTs < 0).
  11. When you issue a jog command to a motor, Power PMAC uses the instantaneous values for commanded position, velocity, acceleration, and jerk as its starting condition. Of course, when the motor is stopped, commanded velocity, acceleration, and jerk are all zero.
  12. In Power PMAC, simply write your value into Motor[x].MasterPos. This is a floating-point register, with the position units of Motor x. Make sure that Motor[x].MasterCtrl bit 0 is set to 0, so the automatic position following function does not also try to write to this register.
  13. The ECT's "right shift" operation uses C's built-in right-shift operation, which "sign extends" the value as it shifts. That is, if the MSB of the source value is 0, all of the high bits of the right-shifted value will be 0; if the MSB of the source value is 1, all of the high bits will be 1. By adding 8 high bits of 0 to your source data, you are ensuring that the right shifted value will have a 0 as its high bit, and so when interpreted as a signed value (which PrevEnc is) will report as positive. If you are happy with your solution, by all means keep it. But it is not necessary to do this for successful use as a master. Because the actual output of the ECT entry is the differential "DeltaPos" value, which will have the proper difference even when the source value "rolls over", and the master following function also handles rollover properly, you could use the standard method successfully. The way PrevEnc reports the value -- signed instead of unsigned -- is not relevant to the success of the operation.
  14. Our experience with conversion programs of the type you ask for, including ones from other vendors that we have tried to use ourselves, is that they do not actually help. They will never get 100% of the conversion correct, and you spend more time trying to find the few issues converted improperly than you would with a totally manual conversion. The Software Reference Manual contains a chapter showing the necessary conversion for all Turbo PMAC I-variables, including unit differences. There is also a chapter of similar conversions for Turbo PMAC suggested M-variables.
  15. Historically, the "pulse-stream" time-base input is how most observatory users have kept the PMAC synchronized to an external reference time. There is timer-based interpolation on the pulse counting, so PMAC can calculate, for instance, that 23 and 47/256 pulses have been received in the most recent servo cycle. With or without the interpolation, there is no long-term drift regardless of the input frequency relative to the servo frequency, because over the long term, it is just a counting process. We do generally recommend that the input frequency be substantially higher than the servo frequency, but that is for smoothness of motion executed under the time base, as higher frequency reduces quantization noise in computing the pulses received per servo cycle. The "trigger" feature abeard talks about can be very important, as it sets a very accurate starting time (T0), latching the counter value in PMAC at the instant it is received, so all subsequent times can be referenced to this. I will call the above technique the "hardware method". It is probably the simplest. As to the "software method": The Sys.TimeOfDay element references a standard Linux function. It can be written to using a C API call (but not from the Script environment). It can be tied to an external time using standard Network Time Protocol (NTP) functionality, just as your PC's time is likely tied to your network server using this method. We have a number of users doing this. This communication happens through the standard Ethernet "host port" on the PMAC. To do what you want, we will have to keep both the Linux time and the servo time in the PMAC synchronized to your external source. The servo heartbeat can automatically be tied to the EL6688 through the "distributed clock" EtherCAT feature we have implemented. Many users utilize this feature to keep PMAC's servo software properly synchronized with the hardware on the EtherCAT network. What has not been done yet is to implement any software to utilize the numerical absolute time information that would come in from the module to keep Sys.TimeOfDay (or something similar) from drifting off, and to make this information accessible from the servo software in a way you can properly utilize it -- I presume for functions like data gathering to properly time stamp the logged data. This looks like a substantial task requiring knowledge of EtherCAT, the module, Linux, and Power PMAC.
  16. We will have to gather our Linux jocks and EtherCAT jocks when they return to the office to answer this one. Many users have used the EtherCAT distributed clock feature to keep the PPMAC servo update in sync with the signal returned from the EtherCAT source (we modulate the setting of the circuitry that creates our internal clock to keep it from drifting off). But you are correct -- that is relative time. Note that this technique can modify the physical time between consecutive servo interrupts. Many of our observatory users have fed a precision pulse stream into an input on an axis card like the ACC-24E2A as a "time-base input", as you note. This technique does not change the physical time between consecutive servo clocks, but allows us to count the number of pulses between consecutive clock cycles, and make the velocity of the programmed moves proportional to the number of pulses received. This has worked very well to keep moves from drifting off over time -- but again, this is relative time. We will have to be very careful to distinguish, but still coordinate, the external reference time from "Linux time" (which updates based on processor clock cycles), and PMAC move time, which updates based on hardware-generated servo clock updates.
  17. Thank you for finding and reporting this issue. The logic gets out of sequence if the delay is already "over" when the algorithm begins. We have fixed the logic and it will be part of the next maintenance release, scheduled for this summer. If you want a pre-release version with the fix sooner, contact tech support.
  18. In firmware versions older than V1.6, if calculation of moves from the rotary motion program "caught up" with the loading of the buffer, program execution would stop with an error. That is, if the program went to calculate the next move from the buffer and that move wasn't there, that would be an error. Starting in V1.6, which was released in February 2014, if this happened, the program would go into a suspended mode, effectively dwelling until the next move was loaded. Often, this is still undesirable, especially if you wanted the moves to be blended on the fly. I think the key is to make sure your program loading stays well ahead of your move calculation. This means you want to load multiple program lines before you even start program execution. When you issue the "b0r" command and then start loading, PPMAC will calculate the first move as soon as you load it, then see that the buffer is empty. Even with the newer firmware, it would not blend the first move into the second. It is more efficient in loading the program if you execute a single "open rotary" command, then send a whole set of program lines, followed by a single "close" command.
  19. We will evaluate this request, but it is not something that can be done immediately. It would add computation time to all F-based moves, even if just to check whether it is used or not, so we have to be very careful.
  20. To go into a little more detail, the on-line "t" and buffered "tread" commands use the data in the Coord[x].TPExec structure to obtain their results. Coord[x].TPExec.Pos[j] (j=6,7,8 for X,Y,Z) contains that commanded position for the axis for the presently executing move. Coord[x].TPExec.XYZPos[j] (j=0,1,2 for X,Y,Z) contains the commanded position with offset from cutter comp for the presently executing move. (Earlier versions of the manual said that it was the offset, but it is the position with offset.)
  21. Yes, the root issue is very likely that in 1.6 firmware, each motor uses the AdaptiveCtrl algorithm with its own feedback, which is a superset of the ServoCtrl algorithm used in 1.5 firmware. We had many requests for the capability of adapting the gains of the individual gantry motors as movement of the cross axis transferred the inertial load from one motor to the other. Our testing showed that if the adaptive control gains were at factory default values, the GantryXCtrl algorithm should work identically in 1.6 to 1.5 (without adaptation active). When you next try this, double check all these gains that are now "in play". After you get your old performance going, you may want to experiment with the adaptation features.
  22. I want to emphasize again that, because the motor feedback algorithms use "delta" values (whether the delta is computed in the ECT or by the motor), that just switching back to the absolute encoder will NOT correct for any slippage that occurred when using the motor incremental encoder for feedback. If you want to get back to the correct position value after you switch back to the absolute encoder, you will need to do another specific absolute position read, just as was done at power-on/reset.
  23. A little bit of background here: In the older PMAC and Turbo PMAC controllers, the encoder conversion table put out a sensor position value. When the motor read this value for feedback, it subtracted the previous servo cycle's stored value to get the "delta", checked for possible rollover, and added this delta to the motor position (which could have a different zero position). If you wanted to change feedback on the fly in these systems, you had to overwrite the motor's stored "previous position" value in the same cycle as you changed the source address for the feedback. In the Power PMAC, the ECT puts out the "delta position" of the sensor, not the sensor position value itself. So when the motor picks up this value for its feedback, it just adds this delta (multiplied by the motor scale factor) to the motor position. But in both cases, the motor position is just incremented by the delta value each servo cycle. In your case, this means that if one of your sensors (incremental) "slips" relative to the true physical position, going back to the other (absolute) sensor that has not slipped will NOT cause the motor position to be corrected. You will need another strategy.
  24. A simple routine to provide "deadband" on the ADC from the joystick global DbSize = 100; // Size of deadband in LSBs of 16-bit ADC global DbAdc; // Modified reading open plc 0 DbAdc = RawAdc >> 16; // Take top 16 bits of 32-bit register containing ADC if (DbAdc > DbSize) DbAdc -= DbSize; else if (DbAdc < - DbSize) DbAdc += DbSize; else DbAdc = 0; // Now filter modified ADC; simple 1st order filter example FiltAdc = 0.95 * FiltAdc + 0.05 * DbAdc; close
  25. This should get you started: Declare: ptr RawAdc->PowerBrick[0].Chan[0].AdcAmp[2]; // 32-bit register with ADC data in high 16 bits ptr FiltAdc->Sys.Idata[2]; // 32-bit integer register in user shared memory buffer open plc 0 // Real-time PLC executing under real-time interrupt // Basic first order filter shown for simplicity FiltAdc = 0.95 * FiltAdc + 0.05 * RawAdc / 65536; // Exponential low-pass filter on top 16 bits of input register close // Process filtered ADC data to prepare for motor // Use 9th entry if first 8 entries auto-assigned EncTable[9].type = 1; // Single-register integer read EncTable[9].pEnc = Sys.Idata[2].a; // Address of source data EncTable[9].index1 = 0; // No shift EncTable[9].index2 = 0; // No shift EncTable[9].index3 = 0; // No change limiting EncTable[9].index4 = 1; // Integrate once EncTable[9].EncBias = 0; // ? Possible offset before integration EncTable[9].ScaleFactor = 1.0; // User-selectable output scaling Motor[1].pMasterEnc = EncTable[9].a Motor[1].MasterPosSf = 0.001; // User-selectable "gear ratio"; set low to start for safety Motor[1].MasterCtrl = 1; // To enable following, set to 0 to disable Motor[1].MasterMaxSpeed = ? // Possible speed clamp for safety Motor[1].MasterMaxAccel = ? // Possible accel clamp for safety ********************** You have indicated that you want to use a higher-order filter in your PLC program, which would be easy to do. Many joystick users want to create a "deadband" around the 0 input voltage, so there is no drift when the joystick is in its rest position. This is also easy to do in the PLC program.
×
×
  • Create New...