AnthonyLH Posted March 19, 2015 Posted March 19, 2015 Dear all, I fill a rotary buffer from the RTICPLC, 1 rotary position line every N RTI cycle (our goal is to set a rotary position every RTICPLC). My issue: my RTI and my rotary "unfilling" (Coord.TM) seems to use different clocks as the number of lines in the rotary keeps decreasing or increasing when it should stay stable. Side (decreasing or increasing) depends on the hardware. From my understanding, the rotary is read every RTI interrupt before the RTICPLC. Moves in the rotary use the following parameters "Linear TM=t TA=t TS=0" (TM=TA) where "t" can take value from 2ms to 20ms. Our RTI is setted to run at 1KHz, so every 1ms. I use a counter in the RTI and send a line in the rotary every 2.. to 20 cycles depending on the "t". I use Coord[].SegMoveTime=1 (ms). I do not use the lookahead. ((Just for info, we need such high frequencies not for trajectory quality but for control reactivity, as our system can be part of a higher lever external position control-looped system)) I said it depends on the hardware... My theoretical servo cycle is 0.250ms When i have a real Sys.Servoperiod > 0.250 (for example 0.2500152587890625), the number of lines in the rotary keeps decreasing. When i have a real Sys.Servoperiod < 0.250 (for example 0.249986455578319972), the number of lines in the rotary keeps increasing. So it seems that rotary unfill, which also depends on TM, use the CPU clock to act, even if the rotary unfill task is called every RTI interrupt. To avoid this, i tried to set a TM="t" * Sys.Servoperiod*(Sys.RtIntPeriod+1). It seems to work for systems using a Sys.Servoperiod < 0.250, but it gets worse for systems using a Sys.Servoperiod > 0.250. Could someone help me understanding which clock are used in the rotary to act every TM ? Does someone see another way of synchronising RTI and rotary? We are able to the value we want in TM, without regards of SegMoveTime or RTI interrupt time... How is the link done between TM and SegMoveTime calculations? The only information i found (training slides) says: If move time < Sys.ServoPeriod servo update time, move will be calculated, but then skipped over by trajectory servo interpolation. In segmentation mode, if move time < Coord[x].SegMoveTime, move will be calculated, but then skipped over by trajectory segment interpolation. But this does not explain me, when it is skipped, what will be the target position for SegMoveTime calculation... Thank you all
Omron Forums Support Posted March 19, 2015 Posted March 19, 2015 How exactly are you filling the rotary buffer? Can you post your code?
curtwilson Posted March 20, 2015 Posted March 20, 2015 Each RTI, the coordinate system checks whether it is time to calculate the next move in the program buffer. During a continuous sequence of motion, the trigger for it to do this computation is the transition in move execution from one move to the next. This sets a flag telling the CS algorithms it is time to fill the move equation pipeline again. For example, if you have an RTI period of 1 msec and moves of 10 msec, new move calculations from the buffer will only be done 1 out of every 10 RTIs. It appears that you are not doing any handshaking between your program generation algorithm and the program execution. Whatever the reason for the drift between the two that you are seeing, a lack of handshaking is not wise. A simple fix would be to add a numeric line label to the beginning of each program line you create (e.g. N475). When the motion program calculates that line, it sets Coord[x].Ncalc to the value of the number. When it starts the actual execution of the move from that line, it sets Coord[x].Nsync to the value of the number. Your code-generating algorithm could monitor one or both of these elements to stay the desired amount in front of calculation and execution.
AnthonyLH Posted March 20, 2015 Author Posted March 20, 2015 Thank you Charles, thank you Curt, In fact using TM="t" * Sys.Servoperiod*(Sys.RtIntPeriod+1) did solve my issue... i had an additionnal cadencing issue in my RTCPLC during my tests. Charles, I fill the rotary using the command "Command(...)". I also post a question on this part: "http://forums.deltatau.com/showthread.php?tid=1855". I also asked once how to be more real-time than using the command "Command" which seems to use a gpascii-2. Curt, thank you for the explainations on move calculation from buffer. Would you have some documentation on it? I would like to be sure to really understand what the PPMAC does. Let's take few configuration exemple: - Case1 : RTI=1, SegMoveTime=1ms, TM 1ms, TA=TM - Case2 : RTI=2, SegMoveTime=1.4ms, TM 1.4ms, TA=TM - Case3 : RTI=1, SegMoveTime=1.4ms, TM 1.4ms, TA=TM - Case4 : RTI=1, SegMoveTime=1.4ms, TM 1ms, TA=TM From my understanding, every RTI, the following task are called: Segmentation calculation (coarse interp, kinematic calls, lookahead), motion prog, foreground script plc, foreground c plc. What is the execution order (sequential time order) in the RTI task? For the RTI<->SegMoveTime interraction: - Can 2 or more SegMoveTime calculation be done in 1 RTI call ? - Or maybe my question should be : what if RTI cycle time > SegMoveTime ? The SegMoveTime<->TM interraction seems clear: The software documentation gives: ""While it is possible to execute programmed moves (“blocks”) of a shorter time than this segmentation time, the segmentation algorithm will automatically skip over these blocks, effectively performing a smoothing function over multiple blocks."" The documentation also says : ""If Coord[x].SegMoveTime is 0.0, ......, inverse-kinematic calculations are only performed at move-end positions"". What are the "move-end position" here? Is SegMoveTime necessary when we use linear mode with TM <= the SegMoveTime i would like to set? About Coord[x].Nsync... Yes i use it. I incremenent a counter in the RTI when i send a line in the rotary and then check that the difference "RTI_RotarySendCounter - Nsync" stay stable. The issue was precisely that the difference was not stable. I can not use Nsync to trigger a new point sending because : 1/ i need constant time between acquisitions, 2/ i want to send a position every single RTI (every 1ms). Thank you!!
curtwilson Posted March 20, 2015 Posted March 20, 2015 To answer your questions: Yes, it is possible for multiple segments to be processed in a single RTI (provided of course, that the CPU has enough time to do the computations!). So it is possible, but maybe not wise, to have the RTI time larger than the segmentation time. You are correct in your guess of the order of calculations within an RTI. Unless you are doing kinematic transformations or circular interpolation, and since you are not using lookahead, I don't think that segmenting the moves is adding any functionality for you -- just adding complexity and computational overhead. By computing very short move sections, you are effectively already performing segmentation yourself. Most people who want this kind of functionality do this straight from a looping Script motion program. For example: linear abs while (Looping) { MyMoveNum++; MyXpos = {whatever} MyYpos = {whatever} MyMoveTime = {whatever} N(MyMoveNum) X(MyXpos) Y(MyYpos) TM(MyMoveTime) TA (MyMoveTime) TS0 } The sequencing engine of PMAC's Script environment will automatically execute a loop once per move. This eliminates all of the handshaking complexity you are struggling with. If you want to do your calculations in C, you can call the "CfromScript" subroutine each time through the loop.
Recommended Posts