00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 #ifndef __SERVO2_H
00043 #define __SERVO2_H
00044 
00045 #include "joint.h"
00046 #include "pid.h"
00047 
00048 namespace lpzrobots {
00049 
00050 
00051 
00052   class TwoAxisServo {
00053   public:
00054 
00055   
00056     TwoAxisServo(TwoAxisJoint* joint, double _min1, double _max1, double power1, 
00057                  double _min2, double _max2, double power2, 
00058                  double damp=0.2, double integration=2, double maxVel=10.0)
00059       : joint(joint),
00060         pid1(power1, integration, damp),
00061         pid2(power2, integration, damp),  
00062         maxVel(maxVel) { 
00063       assert(joint); 
00064       setMinMax1(_min1,_max1);
00065       setMinMax2(_min2,_max2);
00066       assert(min1<max1); assert(min2<max2);
00067       assert(min1 <= 0); assert(min2 <= 0);
00068       assert(max1 >= 0); assert(max2 >= 0);
00069       assert(power1 >=0 && power2 >=0 && damp >=0 && integration >=0);
00070     }
00071     virtual ~TwoAxisServo(){}
00072 
00073 
00074 
00075 
00076     virtual void set(double pos1, double pos2){
00077       if(pos1 > 0){
00078         pos1 *= max1; 
00079       }else{
00080         pos1 *= -min1;
00081       }
00082       pid1.setTargetPosition(pos1);  
00083       
00084       double force1 = pid1.step(joint->getPosition1(), joint->odeHandle.getTime());
00085       
00086       force1 = std::min(pid1.KP, std::max(-pid1.KP,force1));
00087 
00088       if(pos2 > 0){
00089         pos2 *= max2; 
00090       }else{
00091         pos2 *= -min2;
00092       }
00093       pid2.setTargetPosition(pos2);  
00094       
00095       double force2 = pid2.step(joint->getPosition2(), joint->odeHandle.getTime());
00096       
00097       force2 = std::min(pid2.KP, std::max(-pid2.KP,force2));
00098       joint->addForces(force1, force2);
00099       joint->getPart1()->limitLinearVel(maxVel);
00100       joint->getPart2()->limitLinearVel(maxVel);
00101     }
00102 
00103 
00104     virtual double get1(){
00105       double pos =  joint->getPosition1();
00106       if(pos > 0){
00107         pos /= max1; 
00108       }else{
00109         pos /= -min1;
00110       }
00111       return pos;    
00112     }
00113 
00114 
00115     virtual double get2(){
00116       double pos =  joint->getPosition2();
00117       if(pos > 0){
00118         pos /= max2; 
00119       }else{
00120         pos /= -min2;
00121       }
00122       return pos;    
00123     }
00124 
00125 
00126     void get(double& p1, double& p2){
00127       p1=get1();
00128       p2=get2();
00129     }
00130 
00131 
00132 
00133     virtual void setPower(double power1, double power2) { 
00134       pid1.KP = power1;
00135       pid2.KP = power2;
00136     };
00137 
00138     virtual double& power1() { 
00139       return pid1.KP;
00140     };
00141 
00142     virtual double& power2() { 
00143       return pid2.KP;
00144     };
00145 
00146 
00147     virtual double& damping1() { 
00148       return pid1.KD;
00149     };
00150 
00151 
00152     virtual double& damping2() { 
00153       return pid2.KD;
00154     };
00155 
00156 
00157     virtual double& offsetCanceling() { 
00158       return pid1.KI; 
00159     };
00160 
00161     virtual void setMinMax1(double _min, double _max){
00162       min1=_min;
00163       max1=_max;
00164       joint->setParam(dParamLoStop, _min * 1.3);
00165       joint->setParam(dParamHiStop, _max * 1.3);
00166     }
00167 
00168     virtual void setMinMax2(double _min, double _max){
00169       min2=_min;
00170       max2=_max;
00171       joint->setParam(dParamLoStop2, _min * 1.3);
00172       joint->setParam(dParamHiStop2, _max * 1.3);
00173     }
00174 
00175   
00176   private:
00177     TwoAxisJoint* joint;
00178     double min1;
00179     double max1;
00180     double min2;
00181     double max2;
00182     PID pid1;
00183     PID pid2;
00184     double maxVel;
00185   };
00186 
00187   typedef TwoAxisServo UniversalServo;
00188 }
00189 #endif