Jump to content
OMRON Forums

curtwilson

Members
  • Posts

    723
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by curtwilson

  1. Things that look straightforward on a basic controller become much more involved when interacting with other advanced control features. One of these features is the kinematic transformations. These permit the user to define mathematically non-linear relationships between the programmed axis coordinates and the underlying motor coordinates. Once you implement this, all sorts of factors that made axis jog capabilities straightforward go out the window. A conceptually simple move in the tool-tip coordinates becomes very complex in the underlying motor coordinates, with dramatically different profiles on the individual motors that contribute to the single-axis move. Because of the non-linear transformations in kinematic routines, you cannot simply head in a certain "direction" on the motors (that is, keep a certain ratio of velocities of the motors), as you could with mathematically linear transformations, and keep a "pure" axis move -- that is no other axis positions change. Instead, you must compute the transformation at many small intervals along the move to keep the move right on the axis path. This rules out our RAPID mode (which uses the same underlying algorithms as jog moves and so would be the first strategy most people consider) because it only computes the transformation at the programmed endpoint. This can be desirable in some cases in kinematic applications, as to get from Point A to Point B in minimum time, but the path between the points will not in general move only the specified axis. LINEAR mode moves can provide a straight-line axis (tool-tip) path even through the underlying non-linear transformation because they compute the transformation from axis to motor coordinate systems very frequently (each segment) along the path, so in general each motor can move a difference each segment to keep the tool-tip moving in a straight line at constant speed. Unfortunately, many of the features that make LINEAR mode attractive to users -- good path control, pre-calculated blending, lookahead acceleration limiting -- make it incompatible with most methods of breaking into a move to change the destination (as with a "jog stop" command). What some users have done to get the best of both worlds is to create a looping program structure around a short linear move, e.g.: inc linear tm(LoopTime) while... { ... X(Xdist) Y(Ydist) Z(Zdist) } The distances Xdist, Ydist, Zdist can be recalculated each time through the loop based on the operator input. If that axis is not being jogged, the distance is 0. If it is being jogged, it is a positive value -- the distance to move in the loop time for the desired "jog speed" -- for "jog plus" or the equivalent negative value for "jog minus". I believe you have an extra complication in that you want to superimpose these jog moves on top of programmed moves from a part program. Now you need dual trajectory generators for each motor. This will require that you perform the tasks in a separate coordinate system with virtual motors and add the two trajectories together to superimpose them.
  2. If all you want to do is to move at a constant speed proportional to the input frequency, you can just use the "position following" function for the motor. The following function has special features to permit this kind of controlled syncing to the master. If you set Motor[x].MasterMaxSpeed to a non-zero value (higher than you need to move) to activate the limiting, and Motor[x].MasterMaxAccel to a non-zero value (that you intend to use), then when you engage the following with the master signal going at a high frequency, the motor will automatically accelerate at the specified limit rate, overspeed until it catches up, and then decelerate at the limit rate to achieve proper position lock. However, I think that what you will want to do in your application will be more complex than this, so the more flexible external time base with programmed trajectories will be your preferred strategy.
  3. Assuming that what you want is to end up tracking the signal as if you could have accelerated immediately to your target speed, since you will spend some time below this speed to achieve a properly controlled acceleration, you will then need to spend some time above this speed in order to catch up. Typically, this is done with an initial programmed move slightly above the tracking speed, followed by a move or moves at the tracking speed. The "overage" in the initial move should match what the lag would be due to the acceleration slope (a bunch of fun algebra). This needs to be done with blended programmed moves, as it is not feasible with jog moves.
  4. Yes, you have an 80 msec acceleration ramp on your jog move (8.192mu/msec * 10msec^2/mu). So in the first 80 msec of motion, the commanded profile only advances as far as it would in 40 msec at top speed. Hence, you are a constant 40 msec behind what you want. Since this is in the commanded profile, which provides the set point to the servo, the servo cannot overcome this. Set JogTa and JogTs to 0 to get a pure step in commanded velocity. Of course, the physical system cannot track this perfectly, but now the servo loop can cause it to catch up. You may have to play with some servo loop settings to handle the initial transient reasonably.
  5. A couple of things to look at: First, do you have significant following error in your servo loop for the motor? The time base feature ties the commanded trajectory very tightly to the external signal, but the compare pulses are generated off the actual position. There is potentially a difference here. You should make sure your velocity feedforward gain is set to minimize following error at speed. You will probably want to make sure your servo loop integrator is active during the move by setting Motor[x].Servo.SwZvInt to 0. This will ensure zero average steady-state error during the move. Second, have you accounted for the acceleration time in the jog profile? If your acceleration time were 80msec (whether specified directly or from speed/accel rate) and your calculations assumed that the commanded jog profile instantly hit top speed, you would think you were 40 msec behind.
  6. The Geo Brick LV has 4 half bridges per motor in its power stage, which can be organized as 2 full (H) bridges for 2-phase motors with electrically independent phases. Alternately, you can use 3 of the half bridges for 3-phase motors that are Y or Delta wound. Most servo amplifiers (such as our higher voltage Geo Brick) have only 3 half bridges per motor, so you cannot drive 2-phase motors while keeping the phases independent. However, it is possible to run them with the phases connected. You can connect one phase between the U and V phase outputs, and the other phase between the V and W phase outputs. This has been done successfully with, for example, the Swiss Etel 2-phase brushless servo motors. The disadvantage of this technique is that your effective bus voltage is reduced by 30% compared to independent phases. (You can use only 1/sqrt(2) of the supply voltage.) In PMAC, the issues of 2-phase versus 3-phase motors and stepper versus servo motors are independent questions. The number of phases is dealt with by the power-stage wiring and the value of Ixx72 (1/4 or 1/3 of a cycle). The issue of stepper versus servo (really open-loop versus closed loop control) is dealt with by selecting simulated versus real feedback. However, the vast majority of stepper motors are 2-phase, and the vast majority of servo motors are 3-phase, so these issues sometimes get confused.
  7. Hmmm. A 1.2% error. Something is way off. I will note that the difference between a 32us period/31.25kHz signal and a 31.25us period/32kHz signal is 2.4% -- exactly double this. Could there be confusion on the signal frequency?
  8. "I have to run tests and tweak this ScaleFactor until I get the accuracy I need. Correct?" No. You have a very accurate clock signal, with a much smaller frequency error than our internally generated clock signal. When you compare the performance of the two (by comparing DeltaPos to Sys.ServoPeriod), the error will be from our clock, not yours. If you were to adjust the ScaleFactor to make them match better, you would be defeating the high accuracy of your source. When you say you have found an accumulated 36msec difference over some time period, that is the error you have corrected with your external time signal. That is, if you had used our internal time base over this period, there would have been 36msec of drift over this period, with a position error of 36msec times your velocity. By using your accurate external time base, you have prevented this error. Thanks for catching the error in the manual. (There is a different register that holds 10 bits of fraction.)
  9. Probably the best way to handle this is to run a second motor with the identical trajectory but without the filter. You can tie both motors to the same axis (e.g. #1->X, #2->X) so they automatically use the same trajectory. If you want, you can subtract the filtered command position of the first motor from the unfiltered of the second motor by treating the first motor's command position register like an absolute encoder used as a "master" for the second motor. To do this, add an encoder conversion table entry that processes this command position register as "Parallel Y-word no filtering, unshifted" (Method $2, mode bit 1). For Motor 1's command position register, the first setup word would be $210088 (read Y:$88, process unshifted). The second setup word would be $018000 (use 24 bits starting at bit 0). Fundamentally, this just shifts the data into an X-register where it can be used as a master position. If Motor 2 is the "high-pass" motor, I205 would be set to the address of the result ($35nn, or entered as @I80mm, for the address of the I-variable of the second setup word.) Set I207 to -1 to feed this into the second motor's net desired position register as a subtraction of the same scaling (this assumes that I108 and I208 scale factors are equal). Set I206 to 3 to enable the following superimposed on the commanded trajectory. Note that the reported position of this motor will show the trajectory commanded position only.
  10. Following the examples in the User's Manual, you should set your encoder table scale factor to: 1 / [(2^N) * RTIF] where N is the number of fractional bits of timer-based interpolation the table is producing and RTIF (real-time input frequency) is the nominal input count frequency in cts/msec. With a period of 32usec, your RTIF is 31.25 cts/msec (kHz). If you are using a PMAC2 ASIC and the Type 3 software 1/T count extension, you have 9 bits of fractional count estimation, so ScaleFactor = 1 / [512 * 31.25] = 0.0000625 It looks like your number should be twice this (0.000125). I'm not sure what hardware you are using, and if you truly have a count frequency of 31.25 cts/msec. Remember that you probably don't want to be matching Sys.ServoPeriod exactly. The whole reason you are doing this is that Sys.ServoPeriod, which is set to the nominal servo clock period, is not correct to the accuracy you require.
  11. I think you should try to build on top of our automatic safety features; presently you are fighting them. On one of our "killing" faults (following error, amp fault, I2T, encoder loss, optionally HW limit without previous SW limit), the program is automatically aborted, the offending motor is automatically killed, and the other motors in the coordinate system are either brought to a controlled stop (default) or killed (if bit 0 of Motor[x].FaultMode for the offending motor is 1). You must decide what to do with motors in other coordinate systems, and what to do with motors once they reach a controlled stop. Remember the program commands for coordinate systems "abort" and "disable", which cause all motors in the coordinate system to be brought to a controlled stop or killed, respectively. You may want to monitor the status bits Motor[x].DesVelZero to see when the controlled deceleration has finished.
  12. I am completely puzzled by what you were attempting to do with the PLC. Re-enabling an automatically "killed" motor not only makes it difficult to figure out why there was a problem, but is EXTREMELY dangerous, as it can lead to the runaway condition that the fault was designed to protect against. Our "killing" faults, such as fatal following error trips, disable the motor completely because under these conditions, we believe that attempts to bring the motor to a controlled stop will fail, and in an unsafe manner. Yet you are trying to do just that. If you re-enable a motor that was killed due to following error from lost or reversed feedback, you are almost guaranteed a full-out runaway. You have a choice as to what you want done to the other motors in the coordinate system on a "killing" fault of each motor. If bit 0 of Motor[x].FaultMode is 0, the other motors are automatically "aborted" (brought to a controlled closed-loop stop). If this bit is 1, the other motors are automatically killed as well. This choice covers just about every one. Coord[x].ErrorStatus is just part of Coord[x].Status[0]. The ErrorStatus component is essentially for program execution type errors. You should be monitoring all of the error bits in Status[0], as KEJR is doing. Instantly removing disabled motors from a coordinate system defeats many of our coordination, fault-sharing, and status-reporting features. You may want to rethink that strategy.
  13. Parameter Ixx40 for Motor xx implements a simple first-order low-pass filter on the commanded trajectory for the motor. Does this do what you want?
  14. What you are measuring here is the time between computation of successive moves, not between the start of execution of these moves. +/-20ms is a little higher than I would have expected, but the key with this measurement is the long term drift. When is the accumulated time (and error) in a series of 1000 moves? If you change your assignment commands to "m2023 == 0" and "m2023 == 1", the actual assignment to the output is delayed until the beginning of actual execution of the next commanded move. You should see a lot less jitter in this case -- down to the servo cycle level, or to the segment level if Coord[x].SegMoveTime > 0. Still, the true measure is not between individual moves, but in the long term -- how much accumulated error is seen. One test you will definitely want to do is to vary the physical servo update time -- if you are using PMAC2 style ASICs to generate the clocks, you will vary the value of Gaten.PwmPeriod slightly. You should see no effect in the long term timing.
  15. It sounds like you are writing to the PID parameter from your PLC program instead of reading (monitoring) its value. Please check your code. You cannot open a PMAC program while it is enabled.
  16. We do have an automatic feature that does what you need. Many of our observatory users implement it. It's called "external time base" and it is explained in the User's Manual chapter "Synchronizing Power PMAC to External Events". In this mode, Power PMAC gets its time sense for trajectory updates from counting the external pulses coming in, not from its own clock crystal. A quick summary: 1. Feed the pulse signal into an encoder input channel A input. For you, set up the decode for this channel to "pulse and direction" (= 0 or 4, whichever causes the counter to count up. It is best to have a signal frequency at least an order of magnitude higher than the servo frequency to reduce quantization noise that can cause jitter. Since this is hardware, we can accept frequencies into the MHz range. 2. Process the count value in the Encoder Conversion Table with "1/T" sub-count extension entry (for smoothness). This entry should be present by default. Set the scale factor of the entry so that when the input frequency is at its ideal nominal value, the change in pulse count per servo cycle (found in EncTable[n].DeltaPos) is the number of milliseconds in a servo cycle at its ideal nominal frequency (which should be the value in Sys.ServoPeriod). 3. Tell your coordinate system(s) to use this value for the time base by setting Coord[x].pDesTimeBase to EncTable[n].DeltaPos.a 4. Write your motion program trajectory assuming that everything is operating at the ideal nominal frequencies. PMAC will automatically handle any deviations. If the true servo frequency is slightly higher than nominal, the value of DeltaPos will be slightly less than nominal, so the trajectory will increment a little less each servo cycle. Once you have done this setup, everything happens automatically. You don't need to write any PLCs or anything to do adjustments.
  17. What happens if you issue a "reboot" command instead? This command restarts the computer itself and not just the Power PMAC application in the computer.
  18. If you have a spare hardware servo channel, you can use the pulse frequency modulation (PFM) feature of the channel to very accurately specify a pulse interval. This can be fed back to the channel's counter inside the ASIC (Gate1.Chan[j].EncCtrl = 8) and some software task can read the counter value to decide whether to trigger motion. In this case the hardware generation probably has far more accuracy than the software can use. You could also just monitor status element Sys.ServoCount, which incrments each servo cycle, and decide when enough servo cycles have elapsed for you to trigger your next move. Since the software that will command the move operates on the servo cycle, this is probably enough accuracy.
  19. No we do not. Most of the people who cannot tolerate 50ppm cannot tolerate, say, 20ppm either. Those who need very high time accuracy for trajectory motion, which includes many observatory users, feed in a very accurate clock into a spare encoder channel and set up the motion to use "external time base". But that involves the clocks on the axis boards, not the CPU. What do you need higher time accuracy on the CPU for?
  20. The clock on the Power PMAC CPU board has a listed tolerance of 50ppm. However, it is the clock crsytal on the ACC-24E board that is the source of the system servo and phase clocks that determines the time accuracy of trajectory motion. The tolerance for these is 100ppm on the ACC-24E2x boards, and 50ppm on the newer ACC-24E3 board.
  21. Yes, your ECT entry for the integrated "analog" value is correct. The result of the ECT entry in X:$3509 is the 24-bit integrated value, which can roll over. If I106 bit 0 is 1, enabling following on Motor 1, then each cycle, the M167 48-bit master position register will take the difference in X:$3509 from the previous cycle, multiply it by I107, and add this to its own value from the previous cycle. This is where you can see the integration go continuously.
  22. These do not have direct equivalents: i1: Serial Port Mode -- not applicable, no serial port communications i2: Control Panel Port Activation -- not applicable, no control panel port i6: Error Reporting Mode -- not applicable, fixed reporting mode i11: Move Calculation Time -- not applicable, fixed at equivalent of i11=0 on Turbo i14 (non-Turbo): PMATCH on Start -- not applicable, always done on start in Turbo and Power PMAC i52: CPU Frequency Control -- not applicable, fixed by hardware i53: Auxiliary Serial Port Baud Rate Control -- not applicable, no auxiliary serial port i68: Coordinate System Activation Control -- Sys.MaxCoords provides same concept
  23. These string functions are truly functions, which means they have a return value, which must be "put" somewhere. Your first PLC program line: strcpy(256,"123") gives a syntax error. It is no more valid than cosd(30) as a program line. You need to make it something like: p3=strcpy(256,"123") Function names are not presently included in the Intellisense.
  24. When the PMAC is controlling the motor with a torque-command output to the amplifier, it does not see any measurement of the motor current. A torque-mode amplifier is comparing the command value to the measured current internally, and setting a voltage to the motor to try to match the command and actual current levels. Your best estimate of the motor current is the numerical torque command output from the servo loop to the amplifier in this mode.
  25. I think you're getting confused as to what does what. You are processing your analog force feedback for your outer loop motor first as and ADC in Entry 2, then filtering the Entry 2 result in Entry 3, then changing the sign of this value in Entry 5 by subtracting it from 0. The Entry 5 result is your feedback from virtual Motor 5, compared to your commanded force value. Presently you are writing your Motor 5 servo loop command to holding register X:$10FF. It's an X-register instead of the usual Y-register because I501=2. This was done so Motor 1 could pick up this value directly as a "master position" by setting I105 to $10FF (this always specifies an X-register). However, when you saturate the servo command output of Motor 5, it cannot force movement of Motor 1 any more, which is your problem that brings you here. I would set I501 to 0, so you are writing to Y:$10FF. This value can be picked up by Entry 4 in the conversion table (which reads the Y-register at the address and integrates it. I would set the bias term in Entry 4 to 0, at least to start -- I see no reason for the huge bias that you have there. Motor 1 can then pick up the integrated result from Entry 4 by setting I105 to $3509. As I said before, when the inner loop is picking up an integrated result from the outer loop, the outer loop gain Ix30 should be set extremely small, at least to start.
×
×
  • Create New...