Jump to content
OMRON Forums

curtwilson

Members
  • Posts

    723
  • Joined

  • Last visited

  • Days Won

    1

curtwilson last won the day on November 10 2023

curtwilson had the most liked content!

2 Followers

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

curtwilson's Achievements

Proficient

Proficient (10/14)

  • First Post
  • Collaborator Rare
  • Posting Machine Rare
  • Week One Done
  • One Month Later

Recent Badges

2

Reputation

  1. To inject a swept sine ahead of the trajectory filter, I would use a motion program. The program would command full-circle moves in a loop, varying the move time each time through the loop. The cross axis for the circle would be a phantom motor.
  2. A few issues with your Question #4: I'm afraid the quick description of the DkillCoord() function is incorrect (the description of the actual Script DKILL command in the Software Reference Manual is correct). The DKILL function enables the brake first, then disables the servo after a delay. It’s meant for a controlled shutdown when you are already stopped, and you want the brake to fully engage before disabling the servo, so there is no motion on disabling. It is generally not appropriate to use when moving. I think a more appropriate function to use is AbortDkillCoord(), which implements the Script ADISABLE command. This implements an ABORT command followed by delayed kill for all motors in the coordinate system. The abort does a controlled closed-loop deceleration, bringing the motors to a stop faster than a kill would (and so in a shorter distance), and once stopped, the brakes can safely be enabled before the servos are disabled. Taking a step back, I don't see why you would need to disable at all. If I read you correctly, you are implementing a sophisticated software overtravel limit function. In our built-in software overtravel limit function, we always simply use the "abort" function for a controlled closed-loop deceleration to stop. We do not subsequently disable the servos, as there is generally no need to do so. Recovery is substantially quicker if you leave the motors in the enabled closed-loop zero-velocity state. This can be implemented with the AbortCoord() function.
  3. That looks like a 6-pole motor to me. A two-pole motor would have a single north pole and a single south pole on the rotor and one winding on the stator for each of the three phases. A four-pole motor would have two north poles and two south poles on the rotor and two windings on the stator for each of the three phases. A six-pole motor would have three north poles and three south poles on the rotor and three windings on the stator for each of the three phases. This stator fits into that last category.
  4. It should be emphasized that the inverse kinematic routine executes on the input to the segment buffer, not on the output. The input is always several segments ahead of the move execution from the output of the buffer, so if the kinematic subroutine is used to set outputs (like a laser on or off), it will not be synchronous with the execution of the motion segment calculated that cycle. If buffered lookahead is active, the difference between input to the buffer and output from the buffer can be very many segments. So even if the kinematics routine were called at even intervals, a commanded output would not be synchronous with the execution of the segment. Any kinematic routine that is trying to set outputs synchronous with the execution of segments must recognize this delay and compensate for it.
  5. David: You've got the sequence of calculations in the CK3E correct. The 32-bit rollover in the output of CSP mode is widely used successfully. I do not know any of the details of how the Copley drive handles these values.
  6. Whatever the details of the mechanism, changing parts of a register from multiple tasks that cannot be guaranteed to be fully separate in time is inherently problematic. The simplest fix is to use entire registers.
  7. Anton: To me, the big mystery of your results is this: The data gathering you use to analyze the problem is done in the same servo interrupt as the UWS that is supposed to set the bit. If the problem is that the background task resumes and clears the bit, this would not have happened yet when the gathering was done. Very strange!
  8. Anton: The problem can occur when a low-priority task has a multi-step operation that (1) reads a register; (2) does logical operations based on what it has read; and (3) writes back to that register based on what it read in (1) and what it decided in (2). The most common, but not the only, logical operation here is the modification of a subset of the register. The simple act of writing to a partial-word M-variable does this implicitly and automatically. It can also be done with explicit code. (Writing to a whole-word M-variable does not invoke this multi-step process.) The problem occurs when the low-priority task is interrupted between (1) and (3) by a high-priority task that writes to the same register. That task does write to the register successfully, but as soon as the low-priority task resumes, its step (3) will undo what the high-priority task has just done. Note that just having the low-priority task read the register at this time does not create the problem -- it is the write operation that creates the problem.
  9. Any time you do read/modify/write operations (whether explicit or implicit) on the same register from different priority levels, you can have the problem you are seeing. Let's say your background PLC has started to change the M-variable by reading the register, but is interrupted by the servo before it can write the modified value back to the register. The servo does its complete read/modify/write operation, then allows the background task to continue. The background task then finishes the modify-and-write operations (using what it read before the servo interrupt), and its write operation overwrites what the servo task just wrote, wiping out its change. (It is counter-intuitive for most people that the higher-priority task fails in this type of conflict.) Note that this does not happen with whole-word access that does not require this multi-step process. If memory is plentiful, the easiest thing is to devote an entire register to a variable, even if it is only using part of the register.
  10. To do this outside the motion program execution, you will want to have a PLC program scanning continually and issuing the "pread" command, which will return the axis positions in D-variables for the program (e.g. D0 for the A-axis position). Then you will explicitly compare the returned position values for each axis to your axis limits and abort motion if exceeded.
  11. You have a couple of possibilities. One is to do the calculations yourself in the kinematic subroutine -- e.g.: if (KinPosAxisA > MyMaxA || KinPosAxisA < MyMinA) … The other method is to assign an additional virtual motor that maps directly to the axis -- e.g.: KinPosMotor11 = KinPosAxisA Set your motor software limits for this virtual motor to the axis software limits you desire. You will need to define this as an inverse kinematic motor in the same coordinate system -- e.g.: &1 #11->I You will also need to disable other faults on this virtual motor: hardware limits, amplifier fault, following error.
  12. I am not able to duplicate your problem here. I get well-behaved "extensions" of programmed accel/decel times over a wide variety of settings. Here is one example with Ta & Td = 5 msec, and SegMoveTime = 0.5 msec as I suggested. My InvAmax stretched the accel and decel times out to 100 msec, keeping both at the rate set by InvAmax. This algorithm has been in successful use for over 20 years now. We will have to go into more detail to figure out why it is not working for you.
  13. In coordinated multi-axis motion, all axes must share the same acceleration times, so we can't have rate specification here like we do for single-axis moves. (We can have accel rate limiting, which stretches out the time for all axes in the CS if any motor violates its limit.) When we execute the segments (updating at servo rates), the splining algorithm we use guarantees continuity of acceleration at all segment boundaries, including at the very beginning and very end of a sequence. To do this, we add one segment at the beginning that starts at zero accel with jerk to bring up to accel, and similarly add one at the end to finish at zero accel. The net result is a segment at the beginning and one at the end that have an "S-curve" velocity profile. Jerk cannot be directly limited by lookahead, as the computations are far too complex and time-consuming to be done in real-time. Some users get the general effect by using the trajectory pre-filter after lookahead to "soften" the profiles. A second-order low-pass filter with a damping ratio of ~0.85 has been reported to work well for this purpose. The IDE tuning window control for the pre-filter makes it easy to add. You will have to experiment with the specification of the cutoff frequency to see what works for you in this application.
  14. First, some background. Initially, PMAC splits the programmed trajectory into uniform "segments", each of time Coord[x].SegMoveTime. Each segment has its own set of cubic coefficients that will be used at execution time to solve for instantaneous commanded position each servo cycle. The values of Motor[x].Desired.Pos, Vel, and Accel are the first three coefficients for the executing segment. They only represent the instantaneous values for the very beginning (t = 0) of the segment. Jerk is constant through the segment. In between these two steps, you can enable the lookahead algorithm, as you have. The algorithm evaluates the segments for possibility of exceeding motor limits -- in your example, the only relevant limit is acceleration as specified by the InvAmax parameter -- and extends segment times as needed to try to bring the trajectory within limits. The algorithm is very powerful, but it is not infinitely flexible. It works best if it has multiple segments over which to resolve features. So you want to set the SegMoveTime parameter as small as you can without overwhelming the computational capabilites, and do not set your Ta and Td times smaller than you really need. Remember that the Ta time is your minimum move time, and that lookahead never shortens the programmed Ta time, even if it would lead to an accel rate below the limit. In your case, try SegMoveTime = 0.5 and Ta = Td = 5, and see what happens. Remember to set Td after Ta if you want different values. Then you can optimize given your particular constraints. For plotting commanded trajectories, most users just gather Motor[x].DesPos, then let the IDE do single and double differencing for velocity and acceleration (and evaluating jerk as the slope of the acceleration plot).
  15. It looks like your fundamental problem is that you are trying to close your loop using a load encoder alone, which puts the compliance of the coupling between motor and load "inside the loop", leading to significant oscillations. It is quite common for people in this case to operate the motor open loop and use the load encoder just for end-of-move confirmation, as you propose. The open-loop control technique with the LV is called "direct microstepping" and it is explained in the manual. The end-of-move checking is done at the application level in user code, but it is not difficult. You command your move just as you would for true closed-loop control, add a short dwell to permit settling, then read the encoder value to compare it to what you ideally want, and issue a corrective move.
×
×
  • Create New...