bradp Posted June 7, 2010 Share Posted June 7, 2010 To setup a phantom motor follow the instructions in the attached application note. Running Simulated Motors on Power PMAC 2010-08.doc Also, here is some code to directly paste into an IDE solution. #define Mtr0DacOutReg Sys.Idata[1].a Motor[0].Ctrl = Sys.PidCtrl // only need simple PID loop Motor[0].ServoCtrl = 1 Motor[0].pDac = Mtr0DacOutReg // do not use Sys.pushm + 0 (Sys.Idata[0]) as it is used by default by many things Motor[0].pAmpEnable = 0 Motor[0].pAmpFault = 0 Motor[0].pLimits = 0 Motor[0].CaptureMode = 1 // software capture // Homing setup. Only needed if the phantom motor will use real IO for homing // otherise skip this and use HMZ for home command Motor[0].pCaptFlag = Acc24E2A[4].Chan[2].Status.a // use real IO from channel 3 Motor[0].pCaptPos = Acc24E2A[4].Chan[2].HomeCapt.a // Make this setting since Gate1[4].Chan[2].HomeCapt must be read to reset Gate1[4].Chan[2].PosCapt otherwise home is instant as captured flag is not cleared Gate1[4].Chan[2].CaptFlagSel = 0 // use homeflag input Gate1[4].Chan[2].CaptCtrl = 2 // capture on flag high // needed gains Motor[0].Servo.Kp = 1 Motor[0].Servo.Kvfb = 0 Motor[0].Servo.Kvff = 0 Motor[0].Servo.Kaff = 0 Motor[0].Servo.Ki = 0 // process Dac data EncTable[0].type = 1 EncTable[0].ScaleFactor = 1/65536 EncTable[0].pEnc = Mtr0DacOutReg EncTable[0].index4 = 1 // Integerate once Link to comment Share on other sites More sharing options...
pennells Posted December 6, 2012 Share Posted December 6, 2012 Is there an equivalent way to do the simulated motors using an ACC-24E3 board to take the simulated servo output and feed back the results since it does not have the TimeBetweenCts element. I can't seem to figure out how to do it without that variable and this is actually an important test for us as it simulated the backplane traffic before we get all of our motors. Is there somewhere else that I can point the pEnc1 so that the phantom joint actually moves? Link to comment Share on other sites More sharing options...
bradp Posted December 7, 2012 Author Share Posted December 7, 2012 In this case the equivalent setup is described in the ACC24E3 hardware manual in the section about stepper motors. Below is a copy of the text. Pulse-and-Direction Amplifiers Pulse-and-direction outputs can be obtained either on the digital amplifier-interface mezzanine board using the Phase D outputs or on the digital feedback mezzanine board using the auxiliary flag (T, U, V, and W) lines. To enable output of these signals on the digital feedback mezzanine board, the element Gate3.Chan[j].OutFlagD must be set to 1. This is not a saved element, so it must be set to 1 after every power-on or reset – this is usually done in a “power-on PLC program”. Pulse-and-direction outputs are typically used for traditional stepper motor drives where the motors operate open loop. These outputs can also be used for “stepper-replacement” servo drives, where the position loop is closed in the drive. In both cases, the Power PMAC motor commanding the pulse output will require a simulated feedback to close a loop and ensure that the correct number of pulses have been generated. IC Hardware Setup To obtain signals from the pulse-frequency modulation (PFM) circuitry on the Phase D outputs of the IC, bit 3 (value 8) of Gate3.Chan[j].OutputMode must be set to 1, making the value of the 4-bit element 8 or higher (depending on the desired mode – if any – for Phases A, B, and C). Gate3.Chan[j].PackOutData must be set to 0 (not the default) so that the Phase D output comes from the Phase D register Gate3.Chan[j].Pfm, and not the low 16 bits of the Phase B register. This permits the full use of the 24 active bits of the Pfm register (which appear in the high 24 bits of the 32-bit bus). Gate3.Chan[j].PfmFormat must be set to the default value of 0 so that the PFM signals are output in pulse-and-direction (and not quadrature) format. Generally, bit 1 of Gate3.Chan[j].OutputPol is set to the default value of 0 for high-true pulses on the PULSE+ line. The polarity can be inverted either by using the PULSE- line or by setting this bit to 1. The single-bit element Gate3.Chan[j].PfmDirPol can be used to invert the sense of the direction output in software. There are several possibilities for providing the feedback value for Power PMAC to close a position loop and ensure that the correct number of pulses have been output. In the preferred method, Gate3.Chan[j].TimerMode should be set to 3 to use the channel’s timer as a pulse counter for the generated pulse train. In this mode, the accumulated pulse count can be read in Gate3.Chan[j].TimerA. Note that this setup leaves the channel’s encoder circuitry available to process a real encoder, which could be used for confirmation of position. It is not recommended to use real encoder feedback to close the loop in this mode of operation. In an alternate method, Gate3.Chan[j].EncCtrl is set to 8 and the pulse train is fed into the channel’s encoder counter. In this mode, Gate3.Chan[j].ServoCapt contains the accumulated pulse count in units of 1/256 count (8 bits of fractional count information). If Gate3.Chan[j].TimerMode is set to its default value of 0, the low 8 bits will contain a timer-based fractional count estimation, which can provide slightly smoother trajectories, but may lead to dithering at rest. If TimerMode is set to 2 or 3, there is no fractional count estimation (the fractional component is fixed at ½ count). Note that in this method, the encoder decode and count circuitry for the channel is not available for use with an external encoder. Encoder Conversion Table Setup To process the resulting position value in the preferred method for servo-loop feedback, a “Type 1” single-register-read conversion should be specified in the encoder conversion table. EncTable[n].pEnc, which specifies the address of this register, should be set to Gate3.Chan[j].TimerA.a. (EncTable[n].pEnc1, which specifies a second source, is not used in this mode; its setting does not matter.) In the alternate method, EncTable[n].pEnc should be set to Gate3.Chan[j].ServoCapt.a to use the latched encoder counter value Conversion parameters EncTable[n].index1, .index2, .index3, .index4, and .MaxDelta are generally all set to 0 to use this register. To get the output of the conversion table in units of pulses (most common) in the preferred method, EncTable[n].ScaleFactor should be set to 1.0. In the alternate method using the ServoCapt register, it should be set to 1/256 to get the output in units of counts. Motor Addressing and Mode Setup The motor element Motor[x].pDac should be set to Gate3.Chan[j].Pfm.a to specify the use of the channel’s Phase D PFM output. Motor[x].pEnc and Motor[x].pEnc2 should be set to EncTable[n].a, where “n” is the index of the table entry that processed the TimerA register used as a pulse counter. It is recommended that the following servo gain values be used to close a simulated loop: Motor[x].Servo.Kp = 40 Motor[x].Servo.Kvfb = 0 Motor[x].Servo.Kvff = 40 Motor[x].Servo.Ki = 0.001 Many users will want to create a half count of deadband in the servo loop to prevent dithering between adjacent steps at rest if the command value stopped in between them. To do this, set Motor[x].BreakPosErr to 0.5 (if the motor units are equal to pulses), and Motor[x].Kbreak to 0.0. Link to comment Share on other sites More sharing options...
pennells Posted December 7, 2012 Share Posted December 7, 2012 Thanks, BradP. I was so close but missed the fact that it was Phase D (not Phase C) that output the PFM on the card so I had not set bit 3 of OutputMode (was 3 now set to $B). Setting that bit solved all my issues. Link to comment Share on other sites More sharing options...
Sina.Sattari Posted January 2, 2014 Share Posted January 2, 2014 If you need to have a virtual (simulated or phantom) motor without using any hardware channels, only as a software motor, you can use the following settings. Note that you can have multiple simulated motors with these settings by only changing the L0 value at the beginning of each copy and paste block. The servo tuning should be sufficient for most applications and servo frequencies. // Virtual Motor Setup for Power PMAC // Assign the desired motor number to L0 // If more than one virtual motor is needed, repeat the copy and paste process for the following code // and only change the L0 value for each section //***********************************************************************************// L0=1 // Copy the following lines without modification Ldata.Motor=L0 DKILL Motor[L0].Ctrl=Sys.PidCtrl // This can be set to Sys.ServoCtrl for using advanced filters. Sys.PidCtrl adds less CPU load in comparison. Motor[L0].ServoCtrl=1 Motor[L0].pAmpEnable=0 Motor[L0].pAmpFault=0 Motor[L0].pLimits=0 Motor[L0].pEnc=EncTable[L0].a Motor[L0].pEnc2=EncTable[L0].a Motor[L0].pDac=Sys.Idata[L0].a EncTable[L0].type=11 EncTable[L0].pEnc=Motor[L0].IqCmd.a EncTable[L0].pEnc1=Sys.pushm EncTable[L0].index1=0 EncTable[L0].index2=0 EncTable[L0].index3=0 EncTable[L0].index4=1 EncTable[L0].index5=255 EncTable[L0].ScaleFactor=1/(256*(EncTable[L0].index5+1)) Motor[L0].PosSf=360/(24*exp2(20)) Motor[L0].Pos2Sf=360/(24*exp2(20)) Motor[L0].Pos=0 Motor[L0].HomePos=0 Motor[L0].Ctrl=Sys.ServoCtrl Motor[L0].FatalFeLimit=10 Motor[L0].WarnFeLimit=5 // Adjust the following values based upon the application Motor[L0].MotorTa=-1.5E-6 Motor[L0].MotorTs=-1.5E-6 Motor[L0].MaxSpeed=0.172 Motor[L0].JogSpeed=0.005 Motor[L0].InvAmax=1/5.471960662E-4 Motor[L0].InvJmax=1/5.471960662E-4 Motor[L0].InvDmax=1/5.471960662E-4 Motor[L0].JogTa=0 Motor[L0].JogTs=250 Motor[L0].InPosBand=0.0005 Motor[L0].InPosTime=9 Motor[L0].Servo.Ke1=0 Motor[L0].Servo.Ke2=0 Motor[L0].Servo.Kf1=0 Motor[L0].Servo.Kf2=0 Motor[L0].Servo.Ka0=1 Motor[L0].Servo.Ka1=0 Motor[L0].Servo.Ka2=0 Motor[L0].Servo.Ka3=0 Motor[L0].Servo.Ka4=0 Motor[L0].Servo.Ka5=0 Motor[L0].Servo.Ka6=0 Motor[L0].Servo.Ka7=0 Motor[L0].Servo.Kb0=1 Motor[L0].Servo.Kb1=0 Motor[L0].Servo.Kb2=0 Motor[L0].Servo.Kb3=0 Motor[L0].Servo.Kb4=0 Motor[L0].Servo.Kb5=0 Motor[L0].Servo.Kb6=0 Motor[L0].Servo.Kb7=0 Motor[L0].Servo.Kc1=0 Motor[L0].Servo.Kc2=0 Motor[L0].Servo.Kc3=0 Motor[L0].Servo.Kc4=0 Motor[L0].Servo.Kc5=0 Motor[L0].Servo.Kc6=0 Motor[L0].Servo.Kc7=0 Motor[L0].Servo.Kd1=0 Motor[L0].Servo.Kd2=0 Motor[L0].Servo.Kd3=0 Motor[L0].Servo.Kd4=0 Motor[L0].Servo.Kd5=0 Motor[L0].Servo.Kd6=0 Motor[L0].Servo.Kd7=0 Motor[L0].Servo.Kp=8000 Motor[L0].Servo.Kvifb=0 Motor[L0].Servo.Kviff=0 Motor[L0].Servo.Kvfb=0 Motor[L0].Servo.Kvff=69905.055 Motor[L0].Servo.Kafb=0 Motor[L0].Servo.Kaff=69905.055 Motor[L0].Servo.Ki=9.9999997e-5 Motor[L0].Servo.Kfff=0 Motor[L0].Servo.MaxPosErr=10000 Motor[L0].Servo.MaxInt=28000 Motor[L0].Servo.BreakPosErr=0 Motor[L0].Servo.Kbreak=0 Motor[L0].Servo.OutDbOn=0 Motor[L0].Servo.OutDbOff=0 Motor[L0].Servo.OutDbSeed=0 Motor[L0].Servo.SwPoly7=0 Motor[L0].Servo.SwFffInt=0 Motor[L0].Servo.SwZvInt=0 Motor[L0].Servo.Kxpg=0 Motor[L0].Servo.Kxvg=0 Motor[L0].Servo.Kxig=0 Motor[L0].Servo.EstTime=0 Motor[L0].Servo.EstMinDac=0 Motor[L0].Servo.NominalGain=0 Motor[L0].Servo.MinGainFactor=1 Motor[L0].Servo.MaxGainFactor=1 Motor[L0].Servo.MaxW=0 Motor[L0].Servo.MaxDR=0 Motor[L0].Servo.MinW=0 Motor[L0].Servo.MinDR=0 //***********************************************************************************// Link to comment Share on other sites More sharing options...
xuantran Posted June 26, 2018 Share Posted June 26, 2018 Does this method work for Power Clipper only? Link to comment Share on other sites More sharing options...
steve.milici Posted June 26, 2018 Share Posted June 26, 2018 Does this method work for Power Clipper only? Yes this is a virtual (simulated or phantom) motor without using any hardware channels, only as a software motor usable on any Power PMAC platform. Link to comment Share on other sites More sharing options...
xuantran Posted June 28, 2018 Share Posted June 28, 2018 Does this method work for Power Clipper only? Yes this is a virtual (simulated or phantom) motor without using any hardware channels, only as a software motor usable on any Power PMAC platform. As quoted in the document, there are two methods: 1. Pulse-and-Direction Stepper-Motor 2. Virtual Motor with No ASIC Hardware I have tried both on a Clipper. Only the Virtual Motor with No ASIC Hardware is working. The PFM method doesn't work. I assume that it lacks some hardware to run PFM. Am I right and what do I need more to run PFM? Link to comment Share on other sites More sharing options...
steve.milici Posted June 28, 2018 Share Posted June 28, 2018 There is downloadable code in the “Power PMAC Clipper User Manual” for this – see the section “Pulse Frequency Modulation Output (Step and Direction)” starting on page 68. Link to comment Share on other sites More sharing options...
khalil-yazji Posted March 25, 2019 Share Posted March 25, 2019 If you need to have a virtual (simulated or phantom) motor without using any hardware channels, only as a software motor, you can use the following settings. Note that you can have multiple simulated motors with these settings by only changing the L0 value at the beginning of each copy and paste block. The servo tuning should be sufficient for most applications and servo frequencies. // Virtual Motor Setup for Power PMAC // Assign the desired motor number to L0 // If more than one virtual motor is needed, repeat the copy and paste process for the following code // and only change the L0 value for each section //***********************************************************************************// L0=1 // Copy the following lines without modification Ldata.Motor=L0 DKILL Motor[L0].Ctrl=Sys.PidCtrl // This can be set to Sys.ServoCtrl for using advanced filters. Sys.PidCtrl adds less CPU load in comparison. Motor[L0].ServoCtrl=1 Motor[L0].pAmpEnable=0 Motor[L0].pAmpFault=0 Motor[L0].pLimits=0 Motor[L0].pEnc=EncTable[L0].a Motor[L0].pEnc2=EncTable[L0].a Motor[L0].pDac=Sys.Idata[L0].a EncTable[L0].type=11 EncTable[L0].pEnc=Motor[L0].IqCmd.a EncTable[L0].pEnc1=Sys.pushm EncTable[L0].index1=0 EncTable[L0].index2=0 EncTable[L0].index3=0 EncTable[L0].index4=1 EncTable[L0].index5=255 EncTable[L0].ScaleFactor=1/(256*(EncTable[L0].index5+1)) Motor[L0].PosSf=360/(24*exp2(20)) Motor[L0].Pos2Sf=360/(24*exp2(20)) Motor[L0].Pos=0 Motor[L0].HomePos=0 Motor[L0].Ctrl=Sys.ServoCtrl Motor[L0].FatalFeLimit=10 Motor[L0].WarnFeLimit=5 // Adjust the following values based upon the application Motor[L0].MotorTa=-1.5E-6 Motor[L0].MotorTs=-1.5E-6 Motor[L0].MaxSpeed=0.172 Motor[L0].JogSpeed=0.005 Motor[L0].InvAmax=1/5.471960662E-4 Motor[L0].InvJmax=1/5.471960662E-4 Motor[L0].InvDmax=1/5.471960662E-4 Motor[L0].JogTa=0 Motor[L0].JogTs=250 Motor[L0].InPosBand=0.0005 Motor[L0].InPosTime=9 Motor[L0].Servo.Ke1=0 Motor[L0].Servo.Ke2=0 Motor[L0].Servo.Kf1=0 Motor[L0].Servo.Kf2=0 Motor[L0].Servo.Ka0=1 Motor[L0].Servo.Ka1=0 Motor[L0].Servo.Ka2=0 Motor[L0].Servo.Ka3=0 Motor[L0].Servo.Ka4=0 Motor[L0].Servo.Ka5=0 Motor[L0].Servo.Ka6=0 Motor[L0].Servo.Ka7=0 Motor[L0].Servo.Kb0=1 Motor[L0].Servo.Kb1=0 Motor[L0].Servo.Kb2=0 Motor[L0].Servo.Kb3=0 Motor[L0].Servo.Kb4=0 Motor[L0].Servo.Kb5=0 Motor[L0].Servo.Kb6=0 Motor[L0].Servo.Kb7=0 Motor[L0].Servo.Kc1=0 Motor[L0].Servo.Kc2=0 Motor[L0].Servo.Kc3=0 Motor[L0].Servo.Kc4=0 Motor[L0].Servo.Kc5=0 Motor[L0].Servo.Kc6=0 Motor[L0].Servo.Kc7=0 Motor[L0].Servo.Kd1=0 Motor[L0].Servo.Kd2=0 Motor[L0].Servo.Kd3=0 Motor[L0].Servo.Kd4=0 Motor[L0].Servo.Kd5=0 Motor[L0].Servo.Kd6=0 Motor[L0].Servo.Kd7=0 Motor[L0].Servo.Kp=8000 Motor[L0].Servo.Kvifb=0 Motor[L0].Servo.Kviff=0 Motor[L0].Servo.Kvfb=0 Motor[L0].Servo.Kvff=69905.055 Motor[L0].Servo.Kafb=0 Motor[L0].Servo.Kaff=69905.055 Motor[L0].Servo.Ki=9.9999997e-5 Motor[L0].Servo.Kfff=0 Motor[L0].Servo.MaxPosErr=10000 Motor[L0].Servo.MaxInt=28000 Motor[L0].Servo.BreakPosErr=0 Motor[L0].Servo.Kbreak=0 Motor[L0].Servo.OutDbOn=0 Motor[L0].Servo.OutDbOff=0 Motor[L0].Servo.OutDbSeed=0 Motor[L0].Servo.SwPoly7=0 Motor[L0].Servo.SwFffInt=0 Motor[L0].Servo.SwZvInt=0 Motor[L0].Servo.Kxpg=0 Motor[L0].Servo.Kxvg=0 Motor[L0].Servo.Kxig=0 Motor[L0].Servo.EstTime=0 Motor[L0].Servo.EstMinDac=0 Motor[L0].Servo.NominalGain=0 Motor[L0].Servo.MinGainFactor=1 Motor[L0].Servo.MaxGainFactor=1 Motor[L0].Servo.MaxW=0 Motor[L0].Servo.MaxDR=0 Motor[L0].Servo.MinW=0 Motor[L0].Servo.MinDR=0 //***********************************************************************************// Hi I used this code to simulate 26 virtual motors in my application. I want to do some software testing before implementing the code to the real thing. I found that I can trigger Motor[x].FeFetal by setting motor[x].FatalFeLimit to zero. is there any way to trigger other faults like Motor[x].AmpFault, I2TFault or EncLoss, by changing some software variables? Link to comment Share on other sites More sharing options...
curtwilson Posted March 25, 2019 Share Posted March 25, 2019 "Is there any way to trigger other faults like Motor[x].AmpFault, I2TFault or EncLoss, by changing some software variables?" If the status register pointed to by Motor[x].pAmpFault, pEncLoss, etc. provides consistent readings even if nothing is wired into them, then you can trigger faults by changing Motor[x].AmpFaultLevel, EncLossLevel, etc. A more flexible approach is to set the address variables to a user buffer register (e.g. Motor[x].pAmpFault=Sys.Udata[100].a). Then you can write to individual bits in the register to trigger faults. Link to comment Share on other sites More sharing options...
Omron Forums Support Posted March 26, 2019 Share Posted March 26, 2019 I found that I can trigger Motor[x].FeFetal by setting motor[x].FatalFeLimit to zero. This is a little funny, 0 should disable amp faults entirely, you should need to set this to a small non-zero value. is there any way to trigger other faults like Motor[x].AmpFault, I2TFault or EncLoss, by changing some software variables? Status bits that pull their information from pointers can be set manually by pointing at Sys.UData addresses, here are a couple examples: // Amp Fault Motor[1].pAmpFault=Sys.Udata[10].a Motor[1].AmpFaultBit=0 Motor[1].AmpFaultLevel=1 // Fault Sys.Udata[10]=1 // Recover Sys.Udata[10]=0 // Enc Loss Motor[1].pEncLoss=Sys.Udata[11].a Motor[1].EncLossBit=0 // Fault Sys.Udata[11]=0 // Recover Sys.Udata[11]=1 // Limits Motor[1].pLimits=Sys.Udata[12].a Motor[1].LimitBits=0 // Plus Fault Sys.Udata[12]=1 // Minus Fault Sys.Udata[12]=2 // Recover Sys.Udata[12]=0 For an I2T fault, you would probably want to set I2tSet and I2tTrip low enough that any current will cause a fault. Motor[x].I2TSet=1 Motor[x].I2TTrip=1 Link to comment Share on other sites More sharing options...
Recommended Posts