Jump to content
OMRON Forums

erikj

Members
  • Posts

    34
  • Joined

  • Last visited

erikj's Achievements

Explorer

Explorer (4/14)

  • Conversation Starter
  • Week One Done
  • One Month Later
  • One Year In
  • First Post

Recent Badges

0

Reputation

  1. Thanks, Charles, that's exactly what I needed. BTW, for the Gate cards, the variable to look at is Sys.OffsetGateN, not Sys.OffsetCardGateN as you show (attempting to read Sys.OffsetCardGate1[0] crashed my PPMAC!). This will allow me to determine which I/O careds are present and how many of each. Thanks! Erik
  2. Hi DT support, Is there a way to query via the command line over gpascii which boards are installed in a PPMAC crate? For example, I have systems with either an ACC-65E or an ACC-14E I/O board. Is there a way I can determine which board is installed by querying the system? Thanks, Erik
  3. Hi Brad, Thanks very much for your reply. It sounds like position following more closely fits our application. We want to start a motor running and let it run for extended periods of time, possibly for several hours at a time. Regarding the absolute position: it is easy to make sure the motor is in the proper position before the master pulse train starts. It will be harder to start the pulse train at precisely the right instant so that the motor is automatically slaved to the correct absolute position time trajectory (although it may be possible). I am not sure I understand your comment about correcting the absolute position after startup: using the position capture of master and slave and then applying an incremental jog. How do you do that on a motor that is already running? One idea I had is to have a slow outer servo loop that compares actual and desired absolute positions at some rate (possibly triggered by a HW pulse once per revolution). I could then use the servo to tweak the follow scale factor, which would effectively speed up or slow down the motor until the absolute position error is minimized. Is that a reasonable approach? Thanks, Erik
  4. Hi DT Support, I have an application where I want to synchronize a motor to an external hardware pulse train generated by a timing board. The goal is to control the speed and position of the motor very precisely using this external pulse train. The speed will be constant and needs to be very stable (we want to be able to measure instantaneous position error if we can as well). Once the motor is started it will run at the desired constant speed for long periods of time. We can easily program the pulse train so that we can have one pulse per encoder count so that the number of pulses per revolution matches the number of encoder counts per revolution of the motor. It appears that the ACC-24E can easily accept the pulse train and use a counter to generate an external encoder input for this purpose. We also want the absolute position to match a desired absolute position trajectory (in addition to the speed being constant, we want the position to correspond to known positions in time). We can provide an external pulse once per revolution for this purpose (e.g., the motor should be at encoder position zero, or top dead center, every time this pulse occurs). I have read the user manual chapter on synchronizing to external events, but I am still unclear if this is best solved as a position following or external time-base control application. In one sense it seems as though we are following an input pulse stream but it also seems as though we are providing a real-time input frequency (RTIF), as discussed in the external time base control section. Any guidance you can provide is greatly appreciated. Erik
  5. [quote='CharlesP' pid='1505' dateline='1299625432'] Are you trying to define an M-Variable to this location? If so, no, you cannot dynamically change the assignment of the bit number. The best idea would be to just point to the whole word and dynamically mask to get the bit you desire. Regarding gateio[0].datareg[0].0 vs. gateio[0].datareg[0].0.1, yes, they are equivalent. When you omit the .1 at the end, PMAC assumes you wanted to just look at 1 bit. [/quote] Hi Charles, Thanks for your reply. No, not trying to define an M-variable. I just want to be able to access a particular bit but I won't know which particular bit until run-time. I thought about dynamically masking as you mention. That works fine for reads, but if you only want to write to a single bit, then you have to do a read-modify-write on an entire register to make it work (that's probably how it is done underneath in the PPMAC anyway). So I need to read the register to find the values of the other bits that I don't want to change, change my particular bit, and then write the entire word back to the register, which should only change my particular bit. Thanks, Erik
  6. Hi Brad, Is there a way to use a local variable to specify the bit to be accessed within a motion program or plc? I tried these statements, neither of which work: gateio[0].datareg[L1].L2.1 gateio[0].datareg[L1].(L2).1 It works to use L1 to specify the data register, but it does not work to use L2 to specify the bit number. Is there a simple way to do this, or do I have to use L2 to create a mask and then read or read-modify-write the entire register? Also, I noticed that accessing the individual bits seems to work fine without the trailing ".1": if you enter gateio[0].datareg[0].0 at the gpascii command line, it returns the value of the input. gateio[0].datareg[0].0.1 works as well. Thanks, Erik
  7. Hi Curt, Thanks very much for the reply. One interesting problem is that for a long move the SoftwareLimit flag can go active long before the plus or minus limit flag is set. The motor will keep moving until the plus or minus limit is encountered. If you poll either of these flags while the motor is still moving but before a limit is hit, both flags will read zero, which can be confusing. On another note: do you have any documentation for the output of geterrors? So far I have had to look at what comes out to try and infer possible outputs. I need to parse the strings that come out in order to notify the higher level control system of any problems. Most are pretty straightforward ([x].=), but others are less regularly oriented (CoordExecStatus, ErrorStatus, etc.). Also, there are some status variables printed out at the beginning of a geterrors session (see below). Can you tell me what these mean? Thanks, Erik root@192.168.0.200:/opt/ppmac# geterrors -g0xffffffff -c0x201ffc -m0xc01ffd -r0x1e -t1.000000 Addendum: Interestingly, the scenario I describe above regarding the SoftLimit flag occurring before the PlusSoftLimit or MinusSoftLimit flags going active will only occur for an indefinite jog (J+ or j-). A programmed move or jog to a specified position will fail with a SoftLimit error and will not be executed in the first place.
  8. Hi Curt, Thanks very much for the reply. One interesting problem is that for a long move the SoftwareLimit flag can go active long before the plus or minus limit flag is set. The motor will keep moving until the plus or minus limit is encountered. If you poll either of these flags while the motor is still moving but before a limit is hit, both flags will read zero, which can be confusing. On another note: do you have any documentation for the output of geterrors? So far I have had to look at what comes out to try and infer possible outputs. I need to parse the strings that come out in order to notify the higher level control system of any problems. Most are pretty straightforward ([x].=), but others are less regularly oriented (CoordExecStatus, ErrorStatus, etc.). Also, there are some status variables printed out at the beginning of a geterrors session (see below). Can you tell me what these mean? Thanks, Erik root@192.168.0.200:/opt/ppmac# geterrors -g0xffffffff -c0x201ffc -m0xc01ffd -r0x1e -t1.000000
  9. Hi Curt and Charles, Thanks for yout replies. I am still seeing this interesting behavior where the motor is stopped on a soft limit but the servo position is oscillating by 1 count (this is 1 count out of 8192 for a full revolution, so it is a very small amount). Motor[x].inPos is 1 the entire time so the motor is in position. However, because the servo is oscillating slightly, moving above and below the limit by 0.5 counts, the SoftPlusLimit flag oscillates as well (see geterrors output below). Is it possible to supress this somehow so that there is only a single notification and the flag reads one constantly to show that the motor is sitting on the limit? Otherwise I will end up sending multiple error notifications in my software for a single limit violation, which is not desired. Also, when the flag temporarily goes to zero, it gives the misleading impression that the motor is no longer on the limit. Thanks, Erik Motor[1].SoftLimit=1 // Initial limit notification because move will cause a limit violation Coord[1].SoftPlusLimit=1 // actual limit violation Motor[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=0 // Subsequent flag oscillations due to servo moving above and below the limit position Coord[1].SoftPlusLimit=0 Coord[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=1 Coord[1].SoftPlusLimit=0 Motor[1].SoftPlusLimit=0 Coord[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=1 Coord[1].SoftPlusLimit=0 Motor[1].SoftPlusLimit=0 Coord[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=1 Coord[1].SoftPlusLimit=0 Motor[1].SoftPlusLimit=0 Coord[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=1 Coord[1].SoftPlusLimit=0 Motor[1].SoftPlusLimit=0 Coord[1].SoftPlusLimit=1 Motor[1].SoftPlusLimit=1 Coord[1].SoftPlusLimit=0 Motor[1].SoftPlusLimit=0
  10. Hi DT Support, I noticed some interesting behavior with soft limits. If I set up soft limits and then initiate a move that will violate one of the limits, the Motor[x].SoftLimit flag is set almost immediately, long before the move is complete. This disagrees with the description in the manual, which says the motor has stopped on a limit. The SoftPlusLimit and SoftMunusLimit forms of the flag do not activate until the limit violation actually occurs. Is this the normal behavior? Also, when the plus or minus soft limit flag is set, the motor stops and the servo loop remains closed. In my particular case, the servo is now closed on the soft limit position and the position value oscillates by +/- 0.5 encoder counts about the limit as the servo works to maintian its position. This causes the limit flag to oscillate as it clears when the position is off the limit and then resets when it moves past the limit. The flag changes at approximately 1 Hz, but appears to be dependent on the hunting of the servo. Is there a way to set bands on the limit violation to avoid the flag oscillating? Thanks, Erik
  11. Hi DT Support, I noticed the following behavior wrt Motor[x].DesVelZero which disagrees with the PPMAC SW Reference manual (Power PMAC Status Data Structure Elements). The manual says: The Motor[x].DesVelZero status bit is set to 1 if the motor is in closed-loop control and the commanded velocity is zero (i.e. it is trying to hold position). It is zero either if the motor is in closed-loop mode with non-zero commanded velocity, or if it is in open-loop mode (enabled or disabled). It is bit 14 of 32-bit element Motor[x].Status[0]. I am seeing that the value is 1 (true) if the servo loop is open. See the example below. First status is for the loop closed, second one is for loop open. You can see the closedLoop and ampEna flags change state, but the desVelZero flag remains the same. Servo loop is closed at start: Status: Motor[1].pos: -0.5 Status: Motor[1].vel: 0 Status: Motor[1].desVelZero: true Status: Motor[1].closedLoop: true Status: Motor[1].ampEna: true Status: Motor[1].inPos: true Opening the loop... Status: Motor[1].pos: 1.07031 Status: Motor[1].vel: 0 Status: Motor[1].desVelZero: true Status: Motor[1].closedLoop: false Status: Motor[1].ampEna: false Status: Motor[1].inPos: false Is this behavior correct? Thanks, Erik
  12. Hi KEJR, Thanks very much for your reply. Let me give you some background on my application and then I will answer/comment on your points and questions. Background: We have designed a distributed control system using component-based software to be used to control a telescope and its instrumentation. We are in the process of designing standard motion control SW components for the control system that can be used to control the positioning of optics and other components within the instruments. These motion control components provide an abstraction layer between the user and the underlying motion control hardware. We can, in principle, support several different types of motion control hardware using these components and maintain a standard motion control interface throughout our system. I am writing the software layer that interfaces these higher level components to the Delta Tau hardware and am attempting to provide functionality based on a relatively generic interface (open servo loop, close servo loop, move to a position, park, index, etc.). The interface includes the ability to control the power on/off state of the amplifier, control the brakes, measure the current and torque being applied to the motor, which is the genesis of my questions. These are standard functions our team has used on previous projects with other motion control hardware and software. Now to your questions and comments: Regarding the configuration of our motors and drives: The groups designing the instruments have not yet specifed their particular motors. For development purposes I have a setup in the lab using a Power PMAC and DT PWM amplifiers to drive brushless DC servo motors from KollMorgen. I am using the PPMAC to do the commutation as well as the servo control. Our particular motors do not have brakes, but I need to understand how to implement that functionality in any case. I understand about enabling/disabling the motors and amps as you discuss and have already used these functions to implement parts of my interface. However, these functions don't seem to be the same as controlling the power on/off state of an amplifier. Perhaps it cannot be done for a DT system, short of using a programmable power supply to the amp. I will look at the motor[].iq and other related variables to see what I can find regarding torque and current. Thanks again for your reply and help. Erik
  13. Hi DT Support, I have a few questions regarding motor control and status functions. I have searched through the documentation, including the Turbo-PMAC manual, but am still confused on a few issues. Keep in mind that I don't have a lot of Turbo PMAC experience to apply to these questions for PPMAC: 1. Is there any kind of direct support for controlling a brake on a motor (e.g., controlling whether the brakes are engaged or not when opening the servo-loop)? The only thing I could find is a discussion about setting Motor[x].pBrakeOut to the address of a brake-output register, and setting the Motor[x].BrakeOnDelay setting, but no discussion of how to control a brake. 2. Is there a way to read the amount of current being applied to a motor at any given time? 3. Is there a way to read the current torque produced by a motor, or a simple way to calculate it based on how much current is being applied and knowledge of the motor specifics? 4. Is there a way to directly control the power state of an amplifier (e.g., turn the amplifier output on/off)? I have read the discussions of the kill and disable commands and see that they open the servo loop and set the amplifier enable to off, but it also mentions that bias values (voltages?) are still applied. Short of disabling the power input to the amplifier, is there a way to ensure no voltage out of the amp? These functions have been used by members of our design team on previous projects with other motion control HW/SW and they would like to see the same functionality here. Finally, is there any documentation on the various data structures used for PPMAC? I have seen the training slide that discusses this and I have used the pop-up selectors in the IDE, but that only tells you the name of the data structure members. Their meaning and proper use is not always clear or intuitive (at least to me :-)). Thanks in advance for your help, Erik
  14. [quote='bradp' pid='1305' dateline='1297206087'] I just tested 2000 sends and did not get any skips. I modified your code a little and did the test from script language. Here I just start plc2 and let it run awhile and let the IDE capture the sends. Of course the IDE gets very far behind but sooner or later all the data comes out. open prog 2 rapid abs X(Q1) q2++ send0"M[%d]:inPos %d",Ldata.coord,(Q2) dwell0 p1=1 close open plc 2 if(Coord[1].TimerEnabled == 0 && P1 == 1.0) cmd"p1=-1 &1b2r" close [/quote] Hi Brad, Your PLC program is essentially doing the equivalent of what my Java code is doing on the remote host, except it gets the completion notification by monitoring p1. I tried your sendall idea, and that seems to have fixed it. Presumably that forces the buffers to be flushed and the information sent so that getsends can pick it up. I have tried it several times and have not missed a callback yet. Thanks again for your help! Erik
  15. [quote='bradp' pid='1303' dateline='1297203898'] [quote='erikj' pid='1301' dateline='1297201438'] Hi DT Support, I have been testing my Java motion control codes using gpascii and getsends and have experienced some interesting behavior, which leads me to some questions: 1. At the motion program level, is the sendN command thread safe? If I have multiple programs writing with the send0 command, can they clobber each other? I am guessing they can. --- Yes its thread safe because the PPmac can only do one task at a time. So one send will be done before the next program executes and does its send. This does not mean the send is sent and recieved by getsends. It means it is in a buffer waiting to go out. 2. I am using send0 and getsends to indicate completion of a move. I write a completion message using send0 and then I have a thread on my remote host that reads the output of getsends to get the completion message. I find that if I command my motor repeatedly to move to its current position in rapid succession that getsends does not receive all the completion messages. I am commanding a single motor and I wait until the motion program is complete before executing the next move command. It appears that I may be writing to the send0 buffer faster than getsends can pick it up. Can you tell me what the maximum rate is that I can expect getsends to reliably pick up new messages? Note that I do not expect to use the system in this way for normal operations, but testing like this helps to simulate what might happen if commands for multiple motors arrive asynchronously at nearly the same time. --- Are you saying you are sometimes missing data or that sometimes you get one send string and other times you get two or three from the sendgetsends(). I would expect the later. You can try with a sendall after the send in the motion program. I have included a listing of my motion program below. The value in Q1 is the new position to move to. The value in Q2 is the iteration number so I can track which response I am receiving in getsends (for testing purposes only). Thanks, --- It will take me awhile to get a test going. Perhaps the above info will help you in the meantime. Erik list prog2 rapid abs X(Q1) send0"M[%d]:inPos %d",Ldata.coord,(Q2) [/quote] [/quote] Hi Brad, Thanks for the reply. It looks like I am getting the latter response you describe, where multiple sends are combined in a single getsends response: Iteration: 63 getsends: -0: M[1]:inPos 63 Iteration: 64 Missed callback for iter: 64 Iteration: 65 getsends: -0: M[1]:inPos 64M[1]:inPos 65 Iteration: 66 getsends: -0: M[1]:inPos 66 I will try parsing for this. Thanks, Erik
×
×
  • Create New...