Jump to content
OMRON Forums

"Calling" Motion program and making sure it ran to completion


KEJR
 Share

Recommended Posts

Hello, I would like to develop a generic C function call that starts a script motion program and then monitors for the motion program to be completed and with no errors. One could say it is simple as the following: - command motion via command interpreter - wait for motion to start by monitoring some status - wait for motion program to be ended. - Check for errors and optionally in-position. There is kind of a catch 22 situation with motion controllers when the motor happens to already be at the end point. Depending on timing if you use the above method your motion program could end before your calling thread can recognize the "motion start" or "motion in process" signal. Alternatively a short motion might have the same problem. On other "primitive" motion controllers I've had the motion program delay 10ms or so if it was already at the end point when the program was called. Besides making the motion prog more complicated than it needs to it adds time delay for no reason. So my question is that is there a tried and true method for doing what I described above without having to declare additional handshake interlock variables? Thanks, KEJR
Link to comment
Share on other sites

  • Replies 7
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

The way I like to do this is to have some variable at the beginning of each of my programs that just gets set to the program number and again at the end that gets set to the negative of the program number right after a dwell0. If I used p1 then I just start the program with p1=0 &1b1r and the rest is clear. PPmac has some features that could replace this method, look at the Ncalc and Nsynch labels. The status bit to check is Coord[].TimerEnabled. It will get set the RTI after the command to run is given. So you could also send the command and then wait one RTI and make a decision based on the value of Coord[].TimerEnabled. A function to help with this is: void WaitNServoCounts (int n) Wait n Servo Counts Parameters: n - number of servo counts To check for errors the easiest thing to do is use the GetErrors AppWare. To see how this works use the IDE Error Display Window. If you run /opt/ppmac/geterrors/geterrors you will see the error responses come to your session. The program starts with default set of filters but if you do not want to use them here is the list. //--------------------------------------------------------------------------- // Project PowerPMAC Firmware // Delta Tau Data Systems, Inc. // Copyright 2008. All Rights Reserved. // // SUBSYSTEM: Linux Data Get PMAC SEND commands // FILE: geterrors.c // AUTHOR: Ed Lay // // OVERVIEW // ~~~~~~~~ // This program is the linux application that detects transitions: // 1. Motor Status on active motors (Ixx00=1) // 2. Coord Status // 3. Global Status // 4. Coord Execution Status (on an active program in CS) // 5. Plc Execution Status (on an active Plc) // It prints to the STDOUT the strings used in the: // 1. "Backup Motor[n].Status" // 2. "Backup Coord[n].Status" // 3. "Backup Sys.Status" // -t allows the user to adjust the scan rate in ss.ss seconds (default = 0.5) // Range is 0.01 to 1.0 seconds // To set the mask run the "Backup" command for their status messages. // Each mask bit is set == 1 if you want to detect that staus message change. // where Bit #0 is for the 1st sent status message. // -c allows changing of default coord status mask bits // -m allows changing of default motor status mask bits // -r allows changing of default ring status mask bits // -g allows changing of default Global status mask bits // mask data must be hex format preceeded by a "0x": // 0x100 produces a mask of 0x100 // '$' or integer types aren't allowed // -C Sent to PMAC CmdProcessor on Coord fault transition. // -M Sent to PMAC CmdProcessor on Motor fault transition. // -R Sent to PMAC CmdProcessor on Macro Ring fault transition. // -G Sent to PMAC CmdProcessor on Global fault transition. // -S LINUX "system" cmd string (will exit this program also) // -#n Selects Only Motor[n].Status to be processed. Only the selected Motor, its "-M" PMAC command // and the "-S" "system" command are processed. // Strings // include file name and path. // Long string names with spaces must be enclose in quotes ie. "my long filename.txt" // // To terminate the program send any character with a "\n" // // NOTES // ~~~~~ //--------------------------------------------------------------------------------
Link to comment
Share on other sites

Brad, I like your method of using a handshake variable. It is clever but simple. In other systems I've used it was not possible because we were using bit flags and IO lines. If possible I would still like to use the built in methods so that we can develop our library such that a Machine programmer (including me) doesn't have to think about it. It looks like the possibility is there. I'm taking away from your reply that the status of Coord[].TimerEnabled is true when a motion program is running in the specified C.S? So yes if we wait one RTI and then wait for Coord[].TimerEnabled to be reset it will tell us that the motion program completed and that we are either completed the motion prog or bailed out of the motion prog due to an error. If we then check for errors we will cover all bases. While the Appware you mentioned seems like a good thing for diagnostics and such I would prefer to use a method that is in the C library or through the data structures if possible. The code I'm writing will be called from realtime threads. Is it just a matter of inspecting certain elements in the coordinate system data structures? Any advice on which ones to inspect would be appreciated. Thank you for your help, KEJR
Link to comment
Share on other sites

You may consider using a Q-Variable, since that is coordinate system specific. This is useful because multiple coordinate systems could possibly be running the same motion program. In this case, using a P-Variable would not help you, because all instances of the program could be accessing the same P-Variable. However, if using Q-Variables, each coordinate system would be using its own Q-Variables, and there would be no overlap. I.e., use the Q-Variable as a flag that the motion program is running in that particular coordinate system.
Link to comment
Share on other sites

I'll keep the Q var in mind if we go that route. I've been trying to find information on Ncalc and Nsynch but they don't appear in the online command or program command help or C library help. What are these features and where would I go to find the information about using them? Thanks, KEJR
Link to comment
Share on other sites

You can use Coord[n].TimerEnabled but perhaps the bits described here are better http://forums.deltatau.com/showthread.php?tid=113&highlight=ldata.status Look in the motor, coord, and global status words to decide which errors you want to monitor. We have the command backup motor[1].status which gives all bits in one command or you can get to individual elements with their structure names. The ones I think you should consider just for error checking are: backup coord[1].Status MinusLimit=False PlusLimit=False FeFatal=False LimitStop=False AmpFault=False SoftMinusLimit=False SoftPlusLimit=False I2tFault=False ErrorStatus=NoError EncLoss=False backup motor[1].Status MinusLimit=False PlusLimit=False FeFatal=False LimitStop=False AmpFault=False SoftMinusLimit=False SoftPlusLimit=False I2tFault=False SoftLimit=False EncLoss=False backup sys.Status NoClocks=False Default=True FileConfigErr=False HWChangeErr=False ConfigLoadErr=False ProjectLoadErr=False PwrOnFault=False WDTFault=NoFault
Link to comment
Share on other sites

[quote='KEJR' pid='1073' dateline='1294953516'] I'll keep the Q var in mind if we go that route. I've been trying to find information on Ncalc and Nsynch but they don't appear in the online command or program command help or C library help. What are these features and where would I go to find the information about using them? Thanks, KEJR [/quote] They are in the program command manual but I used the name we call them based on the coord structure used to view them. Here are the manual pages. N{constant}: Function: Program line jump label Syntax: N{constant}: where: • {constant} is an unsigned 32-bit integer (range of 0 to 4,294,967,295) This is a numeric “jump” line label that permits the flow of execution of a motion program to jump to that line with a goto, gosub, callsub, call, G, M, T, or D program command or a B on-line command. Note that a colon must immediately follow the constant (no spaces) for this to be treated as a jump label. Without the colon, this is treated as “synchronizing status” label. It is valid to have both types of labels on a single line if both functionalities are desired. A line only needs a jump label if the user wishes to be able to jump to that line. Line labels do not have to be in any sort of numerical order. The label must be at the beginning of a line. By default, a program has address pointers reserved for 1024 line jump labels. If more line jump labels are desired, the number of address pointers to reserve must explicitly be declared in the open prog or open plc command that initiates the downloading of the program. It is also possible to reserve a number smaller than the default to save memory or quicken the search on a variable jump. There is by default an implied N0: at the beginning of every motion program. However, if you put an explicit N0: any other place in the program, the explicit N0: will be used for jumps instead of the beginning. N{data} Function: Program synchronizing status label Syntax: N{data} where: • {data} is a constant (no parentheses) or an expression (in parentheses) representing the label value This is a numeric “synchronizing status” label that cause Power PMAC to automatically set two pre-defined data-structure elements to the value of {data}, one at the time program calculation reaches the label, the other at the time that execution of the next move actually begins. This permits easy monitoring of program and move-execution status by the user. Note that no colon follows a “synchronizing status” label. If a label is followed by a colon character, it is treated as a “jump” label instead. It is valid to have both types of labels on a single line if both functionalities are desired. At the time that program calculation encounters the synchronizing status label, it evaluates the value in {data}. If necessary, it truncates this value to an unsigned 32-bit integer. It immediately sets the data-structure element Coord[x].Ncalc to this value. It also places an instruction for the synchronous assignment of data-structure element Coord[x].Nsync to this value in the synchronous-assignment queue. At the time when the actual execution of the next move in the motion program begins, this instruction will be pulled from the queue and executed. If the program is looking ahead in a blended move sequence, the synchronous assignment can occur substantially after the initial assignment. User monitoring of these two data elements makes it very easy to see where the program calculation and move execution points are at any instant.
Link to comment
Share on other sites

  • 3 weeks later...
FYI, I seem to have gotten this working but with one modification that I thought others might want to note. You need to consider RtIntPeriod in the WaitNServoCounts() function. Here is the whole code to start a motion prog and wait for its completion. I haven't added error checking yet. The Yield() function is just a call to pthread_wait_np(NULL). PmacCmd() is an error checked call to the command interpreter call "Command()" with a formatted message display to our HMI if the command failed. [code] int PmacCallMotionProgAndWait(unsigned CoordSys, const char * Prog) { char buf[CMD_MAX]; //Build command, e.g. "&2b4r" snprintf(buf, CMD_MAX, "&%d b %s r",CoordSys, Prog); if(!PmacCmd(buf)) { WaitNServoCounts(pshm->RtIntPeriod + 1); //Coord[].TimerEnabled gets set one RTI after prog start command issued. //Should be set if our prog is running .. Also check for in position. while((pshm->Coord[CoordSys].TimerEnabled != 0) || (pshm->Coord[CoordSys].InPos != 1)) { //Add code for error checking... Yield(); } return 0; } else { return -1; } } [/code]
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share


×
×
  • Create New...