hannsx Posted June 28, 2019 Share Posted June 28, 2019 Using a PowerBrickLV 5/15A Hi, we realized that we do not reach the same accuracy when tuning a motor and scaling motor units to user units. It becomes worse as the the scaling increases. In the worst case we have ~26222 motor units per user unit. We assume that there are rounding errors causing the problem. Therefore we wondered if there is a function which allows us to work in raw motor units and get the position output in user units. Ideally we would also like to be able to input the acceleration and speed parameters in user units. If it is not possible my workaround would be to have a plc running in the background which does the conversion, or is there maybe a best practice? Best regards, hannsx Link to comment Share on other sites More sharing options...
Eric Hotchkiss Posted July 1, 2019 Share Posted July 1, 2019 Are you adjusting your gains to compensate for changing your position scale factor? If you halve Motor[x].PosSf and Motor[x].Pos2Sf, then you should double all the servo loop gains besides Ki and Kfff. It is generally a good idea to scale position units before tuning. Link to comment Share on other sites More sharing options...
hannsx Posted July 2, 2019 Author Share Posted July 2, 2019 I tried to tune the motors In scaled units. From earlier experiments I learned that the scaling of the servo-parameters is not always inverse to the scaling. But maybe it was because of my bad tuning. So do the equations give an exact inverse relationship between PosSf, Pos2Sf and the servo - parameters? I did not expect that because the equations usually turns into one with the servo-parameters showing up in the nominator and denominator and maybe not in a linear way. Link to comment Share on other sites More sharing options...
curtwilson Posted July 2, 2019 Share Posted July 2, 2019 Both the scale factors PosSf and Pos2Sf, and the gain terms are simple multiplications. For example, if you have Pos2Sf=1.0 and Kvfb=400, if you change Pos2Sf to 0.001 and Kvfb to 400,000, you will get the same result. The double-precision (64-bit) floating-point math used here has so much resolution and range that there are no numerical issues in doing this type of change. Link to comment Share on other sites More sharing options...
hannsx Posted July 3, 2019 Author Share Posted July 3, 2019 Both the scale factors PosSf and Pos2Sf, and the gain terms are simple multiplications. For example, if you have Pos2Sf=1.0 and Kvfb=400, if you change Pos2Sf to 0.001 and Kvfb to 400,000, you will get the same result. The double-precision (64-bit) floating-point math used here has so much resolution and range that there are no numerical issues in doing this type of change. Ok, thanks - that should make it a lot easier. Link to comment Share on other sites More sharing options...
hannsx Posted August 6, 2019 Author Share Posted August 6, 2019 I tried that now and I do not get the same Performance when I scale the motor units. I guess there is an error in the way I scale the parameters. This is my setup code. Let me know if you see any errors or flaws in it. // ULT127-A-45-A-N-001 ///////////////////////////////////////////////////////////////////////////////// // Motor[4] // Brushless-Motor 9,440,000 cts/rev / 12 pole pairs /////// ///////////////////////////////////////////////////////////////////////////////// Motor[4].pLimits = 0 Motor[4].LimitBits = 9 Motor[4].AdcMask = $FFFC0000 Motor[4].AmpFaultLevel = 1 Motor[4].PhaseCtrl = 4 Motor[4].PhaseOffset = 683 Motor[4].PwmSf = 0.95 * 16384 Motor[4].PosSf = 360/9440000 Motor[4].Pos2Sf = 360/9440000 global Mtr4ScaleFactor = Motor[4].PosSf // Einstellungen fuer die Kommutierung Motor[4].pPhaseEnc=PowerBrick[0].Chan[3].PhaseCapt.a Motor[4].PhaseEncLeftshift = 0 Motor[4].PhaseEncRightshift = 0 Motor[4].PhasePosSf = 2048 / ( Mtr4CtsPerCommCycle * 256 ) PowerBrick[0].Chan[3].EncCtrl = 3 Motor[4].pAmpFault = PowerBrick[0].Chan[3].Status.a Motor[4].MaxDac = Ch4PeakCur * 28378 / Ch4MaxAdc Motor[4].I2tSet = Ch4ContCur * 28378 / Ch4MaxAdc Motor[4].I2tTrip = ( pow(Motor[4].MaxDac,2) - pow(Motor[4].I2TSet,2) ) * Ch4TimeAtPeak Motor[4].PhaseFindingDac = Motor[4].I2TSet / 2 Motor[4].PhaseFindingTime = Mtr4PhasingTime * 5 Motor[4].AbsPhasePosOffset = 2048 / 12000 Motor[4].IiGain = 3.2463031 Motor[4].IpfGain = 0 Motor[4].IpbGain = 46.935429 Motor[4].Servo.Kp = 1.8 / Mtr4ScaleFactor Motor[4].Servo.Kvfb = 150 / Mtr4ScaleFactor Motor[4].Servo.Ki = 0.0015 / Mtr4ScaleFactor // Here I transform the values which I set in [sec] in the settings file Motor[4].jogspeed= ( Mtr4JogSpeed * Mtr4ScaleFactor ) / ( 1000 ) Motor[4].JogTa= -( ( 1000 * 1000 ) / ( Mtr4Accel * Mtr4ScaleFactor ) ) Motor[4].JogTs= -( (1000 * 1000 * 1000) / ( Mtr4Jerk * Mtr4ScaleFactor ) ) Motor[4].MaxSpeed= ( Mtr4MaxJogSpeed * Mtr4ScaleFactor ) / 1000 Motor[4].InvAmax= ( 1000 * 1000 ) / ( Mtr4MaxAccel * Mtr4ScaleFactor ) Motor[4].InvDmax= ( 1000 * 1000 ) / ( Mtr4MaxAccel * Mtr4ScaleFactor ) Motor[4].InvJmax= ( 1000 * 1000 * 1000 ) / ( Mtr4MaxJerk * Mtr4ScaleFactor ) Motor[4].HomeVel = Motor[4].JogSpeed Motor[4].WarnFeLimit=40000 * Mtr4ScaleFactor Motor[4].FatalFeLimit=80000 * Mtr4ScaleFactor Motor[4].FeFatal=1 Motor[4].Servo.MaxPosErr=40000 * Mtr4ScaleFactor Motor[4].Servo.MaxInt=40000 * Mtr4ScaleFactor Motor[4].InPosBand= 0.5 * Mtr4ScaleFactor Motor[4].Servo.BreakPosErr = 0 * Mtr4ScaleFactor Motor[4].Servo.Kbreak = 0 motor[4].servo.swzvint=0 Link to comment Share on other sites More sharing options...
Eric Hotchkiss Posted August 6, 2019 Share Posted August 6, 2019 I believe this line is a mistake, the integral gain does not need to be scaled. Motor[4].Servo.Ki = 0.0015 / Mtr4ScaleFactor Are you using Motor[4].Servo.Kvff or Motor[4].Servo.Kaff? Link to comment Share on other sites More sharing options...
hannsx Posted August 7, 2019 Author Share Posted August 7, 2019 I believe this line is a mistake, the integral gain does not need to be scaled. Motor[4].Servo.Ki = 0.0015 / Mtr4ScaleFactor Are you using Motor[4].Servo.Kvff or Motor[4].Servo.Kaff? Thank you for your tip, but it did not improve the performance. Before I thought I had to scale all parameters, I did not examine the Servo-Block-Diagram for it. I do not use either Kvff or Kaff. Link to comment Share on other sites More sharing options...
Eric Hotchkiss Posted August 7, 2019 Share Posted August 7, 2019 It looks like, if the motor worked in counts you should have the right information in your post (as long as ki is not scaled) to use it with the scale factor. Can you share the project? Link to comment Share on other sites More sharing options...
hannsx Posted August 8, 2019 Author Share Posted August 8, 2019 It looks like, if the motor worked in counts you should have the right information in your post (as long as ki is not scaled) to use it with the scale factor. Can you share the project? Yes, of course. I cannot attach it as a zip-file. What kind of files can I attach? I would not want to attach each file byitself. Link to comment Share on other sites More sharing options...
hannsx Posted August 9, 2019 Author Share Posted August 9, 2019 You can download the compressed project-directory from this link: https://syncandshare.desy.de/index.php/s/FYSXYfwkHeoW3xj Link to comment Share on other sites More sharing options...
Eric Hotchkiss Posted August 23, 2019 Share Posted August 23, 2019 I'm a little confused looking at this. It doesn't look like the working version with PosSf=1, it's applied to some places but not to the motor gains. Does open loop work? PhasePosSf looks fishy to me for serial. Link to comment Share on other sites More sharing options...
hannsx Posted November 21, 2019 Author Share Posted November 21, 2019 I'm a little confused looking at this. It doesn't look like the working version with PosSf=1, it's applied to some places but not to the motor gains. Does open loop work? PhasePosSf looks fishy to me for serial. Hi, sorry for not answering. I see that my file looks confusing. In that file I also made the mistake of applying the scaling to the motor[x].ki value. However I corrected this and still had the same problem. So yes, open loop works and the motor moves, but it does not reach the same precision any more. I guess our requirements also are a bit out of the ordinary. We have an ultraprecise actuator for which one Encoder coutn equals 0.325nm. Then we want to operate it on micro meter scale and therefore want it to precise to 0.001 counts. Link to comment Share on other sites More sharing options...
Recommended Posts