00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __SERVO1_H
00025 #define __SERVO1_H
00026
00027 #include "joint.h"
00028 #include "pid.h"
00029 #include "angularmotor.h"
00030 #include <selforg/controller_misc.h>
00031
00032 namespace lpzrobots {
00033
00034
00035
00036 class OneAxisServo {
00037 public:
00038
00039
00040 OneAxisServo(OneAxisJoint* joint, double _min, double _max,
00041 double power, double damp=0.2, double integration=2, double maxVel=10.0,
00042 double jointLimit = 1.3, bool minmaxCheck = true)
00043 : joint(joint), pid(power, integration, damp), maxVel(maxVel), jointLimit(jointLimit) {
00044 assert(joint);
00045 setMinMax(_min,_max);
00046 assert(min<max);
00047 assert(!minmaxCheck || min <= 0);
00048 assert(!minmaxCheck || max >= 0);
00049 assert(power>=0 && damp >=0 && integration >=0);
00050 }
00051
00052 virtual ~OneAxisServo(){}
00053
00054
00055
00056
00057 virtual void set(double pos){
00058 pos = clip(pos, -1.0, 1.0);
00059 if(pos > 0){
00060 pos *= max;
00061 }else{
00062 pos *= -min;
00063 }
00064 pid.setTargetPosition(pos);
00065
00066 double force = pid.step(joint->getPosition1(), joint->odeHandle.getTime());
00067 force = std::min(pid.KP, std::max(-pid.KP,force));
00068 joint->addForce1(force);
00069 if(maxVel>0){
00070 joint->getPart1()->limitLinearVel(maxVel);
00071 joint->getPart2()->limitLinearVel(maxVel);
00072 }
00073 }
00074
00075
00076 virtual double get(){
00077 double pos = joint->getPosition1();
00078 if(pos > 0){
00079 pos /= max;
00080 }else{
00081 pos /= -min;
00082 }
00083 return pos;
00084 }
00085
00086 virtual void setMinMax(double _min, double _max){
00087 min=_min;
00088 max=_max;
00089 joint->setParam(dParamLoStop, min - abs(min) * (jointLimit-1));
00090 joint->setParam(dParamHiStop, max + abs(max) * (jointLimit-1));
00091 }
00092
00093
00094 virtual void setPower(double power) {
00095 pid.KP = power;
00096 };
00097
00098
00099 virtual double getPower() {
00100 return pid.KP;
00101 };
00102
00103
00104 virtual double getDamping() {
00105 return pid.KD;
00106 }
00107
00108 virtual void setDamping(double damp) {
00109 pid.KD = damp;
00110 };
00111
00112
00113 virtual double& offsetCanceling() {
00114 return pid.KI;
00115 };
00116
00117
00118 virtual void setMaxVel(double maxVel) {
00119 this->maxVel = maxVel;
00120 };
00121
00122 virtual double getMaxVel() {
00123 return maxVel;
00124 };
00125
00126
00127 protected:
00128 OneAxisJoint* joint;
00129 double min;
00130 double max;
00131 PID pid;
00132 double maxVel;
00133 double jointLimit;
00134 };
00135
00136 typedef OneAxisServo SliderServo;
00137 typedef OneAxisServo HingeServo;
00138 typedef OneAxisServo Hinge2Servo;
00139
00140
00141
00142
00143
00144 class OneAxisServoCentered : public OneAxisServo {
00145 public:
00146
00147
00148
00149 OneAxisServoCentered(OneAxisJoint* joint, double _min, double _max,
00150 double power, double damp=0.2, double integration=2,
00151 double maxVel=10.0, double jointLimit = 1.3)
00152 : OneAxisServo(joint, _min, _max, power, damp, integration, maxVel, jointLimit, false){
00153 }
00154 virtual ~OneAxisServoCentered(){}
00155
00156
00157
00158
00159
00160 virtual void set(double pos){
00161 pos = clip(pos, -1.0, 1.0);
00162 pos = (pos+1)*(max-min)/2 + min;
00163
00164 pid.setTargetPosition(pos);
00165 double force = pid.stepNoCutoff(joint->getPosition1(), joint->odeHandle.getTime());
00166 force = clip(force,-10*pid.KP, 10*pid.KP);
00167 joint->addForce1(force);
00168 if(maxVel>0){
00169 joint->getPart1()->limitLinearVel(maxVel);
00170 joint->getPart2()->limitLinearVel(maxVel);
00171 }
00172 }
00173
00174 virtual double get(){
00175 double pos = joint->getPosition1();
00176
00177 return 2*(pos-min)/(max-min) - 1;
00178 }
00179
00180 };
00181
00182
00183
00184
00185
00186
00187
00188 class OneAxisServoVel : public OneAxisServo {
00189 public:
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 OneAxisServoVel(const OdeHandle& odeHandle,
00201 OneAxisJoint* joint, double _min, double _max,
00202 double power, double damp=0.05, double maxVel=20,
00203 double jointLimit = 1.3)
00204 : OneAxisServo(joint, _min, _max, maxVel/2, 0, 0, 0, jointLimit, false),
00205
00206 motor(odeHandle, joint, power), power(power), damp(clip(damp,0.0,1.0))
00207 {
00208 }
00209
00210 virtual ~OneAxisServoVel(){}
00211
00212
00213 virtual void setPower(double _power) {
00214 power=_power;
00215 motor.setPower(power);
00216 };
00217
00218 virtual double getPower() {
00219 return power;
00220 };
00221 virtual double getDamping() {
00222 return damp;
00223 };
00224 virtual void setDamping(double _damp) {
00225 damp = clip(_damp,0.0,1.0);
00226 };
00227
00228 virtual double& offsetCanceling() {
00229 dummy=0;
00230 return dummy;
00231 };
00232
00233
00234 virtual void setMaxVel(double maxVel) {
00235 this->maxVel = maxVel;
00236 pid.KP=maxVel/2;
00237 };
00238
00239 virtual double getMaxVel() {
00240 return maxVel;
00241 };
00242
00243
00244
00245
00246
00247
00248 virtual void set(double pos){
00249 pos = clip(pos, -1.0, 1.0);
00250 pos = (pos+1)*(max-min)/2 + min;
00251 pid.setTargetPosition(pos);
00252 double vel = pid.stepVelocity(joint->getPosition1(), joint->odeHandle.getTime());
00253 double e = fabs(2.0*(pid.error)/(max-min));
00254 motor.set(0, vel);
00255
00256
00257
00258 motor.setPower(tanh(e+damp) * power);
00259 }
00260
00261
00262 virtual double get(){
00263 double pos = joint->getPosition1();
00264 return 2*(pos-min)/(max-min) - 1;
00265 }
00266 protected:
00267 AngularMotor1Axis motor;
00268 double dummy;
00269 double power;
00270 double damp;
00271 };
00272
00273 }
00274 #endif