pennells Posted February 15, 2012 Posted February 15, 2012 Is there a way to keep the existing Power PMAC PID loop but substitute a user-defined specialized velocity feed forward function or do I have to replace the entire PID loop?
bradp Posted February 15, 2012 Posted February 15, 2012 If your code can work on the data before it goes to our PID or after our PID has worked on it then it is not hard in a normal user servo. double user_pid_ctrl(MotorData *Mptr) { // Your custom super duper filter probable more than incrementing a P variable pshm->P[100] += 1.0; // The default servo algo. pshm->ServoCtrl(Mptr); }
curtwilson Posted February 15, 2012 Posted February 15, 2012 I think the best place to do this is in a custom servo algorithm for a virtual Motor 0. This algorithm's result will be written into Motor[x].CompDac for the target Motor x. When Motor x runs its own servo algorithm, this offset in the CompDac register (which usually would come from a torque compensation table) will automatically be added to the motor's own servo command. The units of this "double" floating-point register are those of a 16-bit DAC (+/-32,768). The Motor 0 servo algorithm will run after all motors have updated their commanded positions, but before any real motors have closed their servo loops, so no delay is created.
Omron Forums Support Posted February 15, 2012 Posted February 15, 2012 You may also have feed the output of the user written servo output of the feedforward routine to the motor's dac bias or compensation table. e.g. user written servo for motor number n for computing the special feedforward routine for motor number x double feedforward_routine(MotorData *Mptr) { //here is a nonlinear feedforward term using a trigonometric function double fforward=pshm->Motor[x].DesVel*sin(Motor[x].ActPos) pshm->Motor[x].DacBias=fforward; return 0; }
pennells Posted February 24, 2012 Author Posted February 24, 2012 If your code can work on the data before it goes to our PID or after our PID has worked on it then it is not hard in a normal user servo. double user_pid_ctrl(MotorData *Mptr) { // Your custom super duper filter probable more than incrementing a P variable pshm->P[100] += 1.0; // The default servo algo. pshm->ServoCtrl(Mptr); } Thanks, that is exactly what I needed. I had problems for a bit because my routine had a return (of zero) which trashed all the motor data but I've resolved that and this solution works just as desired.
Recommended Posts