Jump to content
OMRON Forums

curtwilson

Members
  • Posts

    723
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by curtwilson

  1. We looked seriously at methods of commanding motion without going through the Script language and the command parser. There were several reasons we did not implement such a method. One is the complexity of a general-purpose solution. A cs_moveX() function seems simple, but there are 32 single axis possibilities, about 500 two-axis possibilities, and I don't even want to think about how many 3-axis and higher possibilities there are. Obviously, we couldn't have a separate function for each possibility, or even for each number of axes, so now we have a very complex function requiring you to specify the number of axes, which axes, etc. We judged this to be more complex for the user than assembling a command string limited to his particular subset of desired functionality. Another issue is that the Script interpreter, especially its sequencing engine, performs a lot of under-the-hood tasks for motion that are not very well handled in C, managing the pipelining and blending of moves. The pipelining can go seven stages deep, with each stage handshaking with the next to keep the pipeline full, as necessary (with many special cases). A general-purpose solution in C would force these into the user application; we know from those controllers that have attempted this in the past for anything sophisticated that this is very difficult and confusing, even for sophisticated software people. You can set many of the move parameters directly from C: pshm->Coord[x].Ta // Accel time pshm->Coord[x].Ts // S-curve time pshm->Coord[x].Tm // Move time (if > 0); feedrate (if < 0) pshm->Coord[x].IncAxes // Bit field of incremental mode bits for axes The action of the Script text commands TA, TS, TM, F, ABS, and INC is simply to set the values of these parameters, which are then used in the computation of subsequent commanded moves.
  2. We have identified a problem in checking the soft limits in the position following routines. It gets rather involved with the possibility of accumulated excess due to speed and acceleration limiting in following. We expect to have this fixed very shortly. If you consider it urgent, we can get you update firmware (pre-release) very shortly. Otherwise, we expect to release the next firmware version, incorporating this fix, in March. The logic underneath for the limits is necessarily rather different for computed trajectories and for following. For computed trajectories, whether jog moves or motion program, we break into the computed trajectory and substitute a deceleration trajectory based on AbortTa and AbortTs (assuming we did not catch it ahead of time). For following, we have no way of anticipating what the master will be doing, so we refuse to increment the master position in the direction of the set limit on a servo cycle by servo cycle basis. But we do permit following in the opposite direction. If you want a well-controlled stop, you will need to set MasterMaxSpeed and MasterMaxAccel to non-zero values, enabling these limits and permitting a controlled deceleration with automatic reversal to the limit.
  3. Most people who home into a limit switch temporarily disable the limit-switch functionality for the duration of the homing-search move by setting Motor[x].pLimits to 0. After the finding the trigger, and settling at the end of the post-trigger move (which usually includes an offset out of the limit using Motor[x].HomeOffset), Motor[x].pLimits is restored to the address of the limit inputs.
  4. The easiest way is to use the "Command" function in the gplib.h library. You can do it with a literal -- e.g. Command("&1b1r"); or assemble a string variable.
  5. Motors in Power PMAC are always assigned to a coordinate system. By default (that is, on re-initialization), they are all assigned to C.S. 0. Effectively, they are "parked" here, awaiting an explicit assignment. Since they are in the same coordinate system, they will share fault response. To see where motors are assigned, simply issue a command like: #0..31-> and Power PMAC will report the axis definitions of all of the motors, including the coordinate systems in which they are defined. Note that a motor with a "null" definition (e.g. #5->0) in a coordinate system is still in that coordinate system for purposes of time base and fault response.
  6. If you want to command a single move of one or more axes without using a real motion program, you can utilize the "one-line/one-shot" motion program of the "cpx" command. For example, if you sent a command like: &1 cpx linear abs F20 ta100 X15 Power PMAC's CS1 would execute this just as if it had been a single-line motion program. (Try it from the terminal in the IDE!) So in your C program, you could use the sprintf function to assemble the string -- with three formatted variables in your example. Then you could use the "command" function out of our gplib.h to send this string to the command parser [of form: int Command (char *pinstr), where pinstr is the pointer to the string]. If you need to execute a motion program that cannot be expressed in a single line, the best way to set Q-variable values as "arguments" to the motion program is to use the following structure: pshm->Coord[x].Q For example: pshm->Coord[1].Q[100] = 20; pshm->Coord[1].Q[101] = 100; pshm->Coord[1].Q[102] = 15; could set the parameters in the motion program line; linear abs F(Q100) ta(Q101) X(Q102);
  7. Technically, the event that causes an encoder count error is the changing of state of both the A and B inputs to the ASIC decoder during the same encoder sample clock (SCLK) cycle. The decoder cannot make sense of this state change. There can be a variety of underlying causes, as mbalentine points out.
  8. With the ACC-51E, the subcount data is computed in software in the encoder conversion table. The best place to get this information is in EncTable[n].PrevEnc. The low 10 bits will be "sub-count"; the low 12 bits will be "sub-line" (4096 per line).
  9. In earlier posts, we were discussing (I thought) halting program execution and letting the already-calculated moves finish. A hold command stops execution of an already calculated move in the middle by bringing the "time base" value to 0. The program is technically still running in this mode (Coord[x].ProgRunning = 1), but not doing anything because there are no further move completions to trigger new program calculations (Coord[x].ProgProceeding = 0). In this state, the reason that the "q" command does not do what you want is that it does not get a chance to finish. The "q" command clears the ProgRunning bit so no further program calculations will be done, but it is not complete until the calculated moves finish executing. With the coordinate system in feed-hold, this does not happen. I have found an alternate method that works for me whether moves were stopped in the middle or at the end. Once stopped, if you issue the on-line "b{constant}" command (where {constant} is the program number) or the program "begin:{data}" (where {data} evaluates as the program number), the coordinate system is put in a status in which the program buffer can be cleared (Coord[x].ProgActive = 0). All this can be done while letting the spindle axis continue moving.
  10. Alternately, if you are compensating for a "pure" perpendicularity error, where the angle between the two motors is the same over all positions (or at least close enough that this is a good approximation), you can keep your 1D compensation tables for each motor, and do the perpendicularlity correction in the axis definitions for the coordinate system. The User's Manual chapter on setting up coordinate systems shows the example of correction for a 1 arc-minute perpendicularity error.
  11. Most of these commands -- on-line and buffered program -- are intended to come from outside of the motion program itself, either from the host computer (on-line) or from a PLC program (buffered). They are not part of the program sequence. Also, most of the commands are intended to give the operator the choice, once stopped, of either resuming program operation or ending it. For everyone else I have encountered in 20 years of doing this, the "abort" command issued when stopped is a satsifactory way of choosing to end program execution and permit the buffer to be reused. A "return" command in the top-level motion program points the program counter to the beginning, permitting the program to be restarted from there, or the buffer to be re-used. There is an implicit "return" at the end of every program. (This is what led me to suggest the "cpx return" command to let you open the buffer, and yes it will work after a q/pause command.) Unfortunately, this is not of use to you, because you are executing the command from an M-code subprogram. Right now, we are evaluating whether there would be any problems in changing the internal coordinate system status slightly after a "stop" command so the buffer could be opened. Probably this will be in the next release. We will also consider an on-line version of this command.
  12. Once again, I emphasize that the "abort" command is intended for abnormal program termination, as with a fault. In general, it will not stop at a programmed point, and will not decelerate to a stop along the programmed path. The on-line "q" command stops any further program calculations, and allows the already calculated moves to proceed. Motion will stop at a programmed point, and along the programmed path. In this state, it is possible to resume program calculation and move execution at this point, so it is not (yet) possible to open the program buffer. For those who want to open the program buffer now instead of resuming, we usually recommend issuing the "a" [abort] command. In your case, this would stop the spindle axis, so you could use the "cpx return" command, as recommended above. From the training slides, an overview of the different stopping commands: * q [pause] – No new program calculations, finish executing already calculated moves - Does not begin to stop immediately (in general) - Decel rate specified by programmed move rules - Stays on programmed path (but no blend at stopped point) - Stops at programmed point - Can resume from stopped point with r [run] or s [step] * s [step] – One additional move calculation, finish executing calculated moves * h [hold] – Feed hold: Ramp time base to zero (%0) starting immediately - Decel rate specified by Coord[x].FeedHoldSlew - Stays on programmed path - Does not stop at programmed point (in general) - Can resume from stopped point with r [run] or s [step] * %0 – Set time base value to zero, starting immediately - Decel rate specified by Coord[x].TimeBaseSlew - Stays on programmed path - Does not stop at programmed point (in general) - Can resume from stopped point with % value > 0 * \ [lh\] – Quick stop in segmented lookahead, starting immediately - Decel rate specified by Motor[x].InvAmax (one motor controls) - Stays on programmed path - Does not stop at programmed point (in general) - Acts as “feed hold” outside of segmented lookahead - Can resume from stopped point with > [lh>], < [lh<], r [run], or s [step] * a [abort] – Abort program execution and moves, starting immediately - Decel rates specified by Motor[x].AbortTa and AbortTs (per motor) - Does not stay on programmed path (in general) - Does not stop at programmed point (in general) - Cannot resume from stopped point
  13. I think I've figured it out. If you are using the kinematic-subroutine definitions for the axes in the coordinate system, the subroutines use their Ln for Motor n position when it has to perform a transformation. The forward-kinematic transformation after a jog or homing motor move to make sure the axis positions are right for the next programmed axis move. The subroutine's Ln is not necessarily the same as the motion program's Ln, and will only be the same if the motion program's "stack offset" is 0. The IDE's project manager automatically sets the stack offset to the number of local variables declared in the motion program -- you have none. If you declared at the top of the program: local Lvar0, Lvar1, Lvar2, and Lvar3; then the stack offset would be 4 and L0 for the kinematics routine would be equivalent to L4 of the motion program; L3 for the kinematics routine would be equivalent to L7 of the motion program.
  14. We have not been able to duplicate this so far. Still looking...
  15. The "abort" command is intended for abnormal program terminations, as in fault conditions. That is why it stops every motor in the coordinate system, including those not assigned to positioning axes. When a motion program or one of its subprograms executes a "stop" command, program execution is halted and the program counter is to the beginning of the top level program, as if it had gotten to the end of the program. At this point, if you want to open the part program to replace it, you can either force the program counter to a different program (e.g. "&1b2") or effectively reset the pointer with a "cpx return" command. Now in either case, you can open the program buffer you were running to download a new part program. Of course, you could also load the new part program into a program buffer with a different number, then set the program counter to it with the b command. Some users do this so they can download the next part program while the present program is still executing, saving a little time.
  16. Usually we get the opposite question -- "How do I make sure my spindle stops when my part program ends?" To move the axis as a spindle, it cannot be set up at that time as a positioning axis in the same coordinate system as the (remaining) positioning axes. When this is the case, there is nothing that automatically stops the spindle when the motion program ends. So we need to understand exactly how you are commanding your spindle axis here, because it seems that you would need to take explicit action to stop the spindle at the end of the motion program. Many users embed the functionality of the M05 spindle-stop code inside their M01 or M30 end-of-program code to ensure that the spindle stops when the motion program does, even if an M05 is "forgotten". Has this been done in your case? There are several strategies people use for setting up the spindle axis when it can also be a positioning axis. One strategy is to assign the motor to an axis into a separate coordinate system, where it can be commanded by a separate motion program. For example, if as a positioning axis in C.S. 1 it had the definition #4->C, you would first give it the "null" definition in C.S. 1: #4->0. Then you could assign it to an axis in another coordinate system, e.g. &2 #4->C. This is somewhat cumbersome, but having it as an axis in a separate coordinate system capable of running its own motion program facilitates features such as constant surface speed. A second strategy is just to give the motor the null definition in the same coordinate system as the positioning axes. This permits the motor to be jogged or commanded in open loop mode while the positioning axes are executing the part program. Having it in the same coordinate system provides automatic fault sharing (which most users want), and shared time-base (%) values (which some do not want). A third strategy, new in the V1.4 firmware released this past summer, is to assign the motor explicitly as a spindle axis in the same coordinate system as the positioning axes. This is similar the the null-definition strategy in that you can command the motor in closed-loop (jog) or open-loop mode even while the positioning axes are executing a motion program, but it has a couple of important advantages. First, it gives you several choices as to the % override value. If you define it as #x->S, it uses the same % value as the positioning axes. If you define it as #x->S0, it uses C.S.0's % value. If you define it as #x->S1, it uses a fixed 100% override. The second advantage of this feature comes if you are using the buffered lookahead function. The buffer is structured based on the number of motors assigned to axes in the coordinate system when the buffer is defined -- there is one "column" in the buffer for each such motor. If you change the number of motors assigned to axes in the C.S., as when you go between a null definition or a definition in another C.S. and a positioning axis in this C.S., you must delete and redefine the lookahead buffer, which can be cumbersome. However, a motor assigned as a spindle axis in the C.S. retains a column in the lookahead buffer, but it is not used for this definition. Note that in all of these strategies, there is nothing that automatically stops the spindle motion when the part program for the positioning axes ends.
  17. The surest way to deactivate the position compare output is to set Gate3.Chan[j].EquOutMask to 0 so that none of the internal compare states is used in that channel's output.
  18. I am unable to duplicate this on my systems. Please doublecheck everything and poll all relevant elements in the watch window. Can you duplicate this by hand moving the motor back and forth across the position?
  19. The only caveat is that if you access a 64-bit floating-point variable using two 32-bit operations in your code, this is not guaranteed to be atomic. And yes, someone found this out the hard way...
  20. Long-term position lock to the master frequency does not get any worse with a lower frequency. Ultimately we are just counting pulses. However, the cycle-to-cycle quantization noise (which completely cancels out over the long term) does get worse, and this can lead to rougher motion. It may require some detuning of the feedback gains, which could hurt your ability to reject disturbances. You would probably notice first that you cannot use feedforward as aggressively (but Power PMAC has a new low-pass filter into the feedforward section that is meant to ameliorate this).
  21. This is the kind of feature that made me skeptical that you could just use position following. I agree that you will probably need to use external time base with programmed trajectories, and the position capture feature to register the time for change triggers.
  22. CAM software vendors have told us that they must write a custom post-processor for each controller's 3D tool-radius compensation algorithm. However, every 3D algorithm we have seen must provide information about the surface normal vector and the tool orientation vector somehow. It is basic to how these algorithms work.
  23. A more selective way of doing this is to set an initial value in the variable declaration statement. For example, with: global MyGlobalVar = 0; ptr MyOutput->u.io:$A0000C.8.1 = 1; each time the project is loaded into active memory, whether downloaded from the IDE or copied from the saved version in flash on power-up/reset, the declared variable is forced to the (constant) value used in the declaration. This is also more flexible and better self-documenting.
  24. To answer your questions: 1) While there is not a specific triggered position following function, you could use the triggered time base entry as the master encoder for position following. For the slave motor, Motor[x].pMasterEnc = EncTable[n].a (not EncTable[n].DeltaPos.a). While the entry is in the frozen or armed states, there is no change in the output value. For the entry scale factor on this one, you probably will not want to divide by an RTIF factor. For the slave motor, Motor[x].MasterPosSf is set to the number of motor units you want per table entry output unit. 2) Without this, if you use a software-based "trigger", you could be off by up to one period of the software routine that is monitoring. It is easy to get this down to a servo cycle. I don't know if that would be good enough. 3) You cannot guarantee recovering a position lock if you control the rate of change of the gear ratio with SlewMasterPosSf, because we don't keep track of how far the master moves each servo cycle as the ratio is changing. That is why I did not suggest that for the startup of following. Instead, disable the slew rate control by setting SlewMasterPosSf to 0, so you get a step change in the gear ratio, but limit the response with MasterMaxSpeed and MasterMaxAccel, so it can recover and re-establish position lock, as it does on the start.
  25. Setup variables in the Gate3 such as EncCtrl are write protected. With our older ASICs, we had many users express concern that these setup variables were too easy to change during operation, when the results could be very dangerous (changing the decode sense for an encoder could easily lead to a catastrophic runaway). So in this ASIC, setup elements like this that are likely to remain constant for an application are write protected. For the write protection, the hardware register Gate3.WpKey must be set to the proper value before writing to a protected element. The act of writing to the protected element automatically clears the WpKey element to $0. To make the setup easier, in the Script environment, a command to write to a protected element first copies the value of software element Sys.WpKey to hardware element Gate3.WpKey, then writes to the protected element. This clears the hardware element, but not the software element. In this way, you only need to write once to Sys.WpKey to permit changes to all of the protected elements. The motor setup controls in the IDE automatically put the proper key into Sys.WpKey.
×
×
  • Create New...