Libbarrett  1.2.4
sandbox/robust_cartesian.h
00001 #ifndef ROBUST_CARTESIAN_H_
00002 #define ROBUST_CARTESIAN_H_
00003 
00004 #include <barrett/units.h>
00005 #include <barrett/systems.h>
00006 
00007 using namespace barrett;
00008 
00009 // TorqueWatchdog monitoring system
00010 template<size_t DOF>
00011   class TorqueWatchdog : public systems::SingleIO<typename barrett::units::JointTorques<DOF>::type,
00012       typename barrett::units::JointTorques<DOF>::type>
00013   {
00014     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00015 
00016   public:
00017     explicit TorqueWatchdog(const std::string& sysName = "TorqueWatchdog") :
00018         barrett::systems::SingleIO<jt_type, jt_type>(sysName)
00019     {
00020       watching = false;
00021     }
00022 
00023     virtual ~TorqueWatchdog()
00024     {
00025       this->mandatoryCleanUp();
00026     }
00027 
00028     void activate()
00029     {
00030       watching = true;
00031     }
00032 
00033     void deactivate()
00034     {
00035       watching = false;
00036     }
00037 
00038     jt_type getCurrentTorque()
00039     {
00040       return torque;
00041     }
00042 
00043   protected:
00044     virtual void operate()
00045     {
00046       if (watching)
00047         torque = this->input.getValue();
00048     }
00049 
00050   public:
00051     bool watching;
00052     jt_type torque;
00053 
00054   private:
00055     DISALLOW_COPY_AND_ASSIGN(TorqueWatchdog);
00056   };
00057 
00058 // Joint VelocityWatchdog monitoring system
00059 template<size_t DOF>
00060   class VelocityWatchdog : public systems::SingleIO<typename barrett::units::JointVelocities<DOF>::type,
00061       typename barrett::units::JointVelocities<DOF>::type>
00062   {
00063     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00064 
00065   public:
00066     explicit VelocityWatchdog(const std::string& sysName = "VelocityWatchdog") :
00067         barrett::systems::SingleIO<jv_type, jv_type>(sysName)
00068     {
00069       watching = false;
00070     }
00071 
00072     virtual ~VelocityWatchdog()
00073     {
00074       this->mandatoryCleanUp();
00075     }
00076 
00077     void activate()
00078     {
00079       watching = true;
00080     }
00081 
00082     void deactivate()
00083     {
00084       watching = false;
00085     }
00086 
00087     jv_type getCurrentVelocity()
00088     {
00089       return velocity;
00090     }
00091 
00092   protected:
00093 
00094     virtual void operate()
00095     {
00096       if (watching)
00097         velocity = this->input.getValue();
00098     }
00099 
00100   public:
00101     bool watching;
00102     jv_type velocity;
00103 
00104   private:
00105     DISALLOW_COPY_AND_ASSIGN(VelocityWatchdog);
00106   };
00107 
00108 // Singularity Avoidance System
00109 template<size_t DOF>
00110   class SingularityAvoid : public systems::SingleIO<typename units::JointPositions<DOF>::type,
00111       typename units::JointTorques<DOF>::type>
00112   {
00113     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00114 
00115   public:
00116     SingularityAvoid(const jp_type& jointCenter, const double& spring_const = 10.0, const double& singularity_buffer =
00117                          0.17453,
00118                      const std::string& sysName = "SingularityAvoid") : // Hooke's law spring const. default 10, singularity buffer of 10 degrees
00119         systems::SingleIO<jp_type, jt_type>(sysName),jointRangeCenter(jointCenter), singularBoundary(false), lastBoundary(
00120             false), singularitySpringConst(spring_const), singularityBuffer(singularity_buffer)
00121     {
00122     }
00123 
00124     virtual ~SingularityAvoid()
00125     {
00126       this->mandatoryCleanUp();
00127     }
00128   protected:
00129 
00130     virtual void operate()
00131     {
00132       wamJP = this->input.getValue();
00133 
00134       singularBoundary = false;
00135       // Check if we meet conditions to turn on haptic singularity boundary
00136       if ((wamJP[1] > jointRangeCenter[1] - singularityBuffer && wamJP[1] < jointRangeCenter[1] + singularityBuffer)
00137           && (wamJP[2] > (jointRangeCenter[2] + M_PI / 2) - singularityBuffer
00138               && wamJP[2] < (jointRangeCenter[2] + M_PI / 2) + singularityBuffer))
00139       { // J2 is within +-10 degrees of J2=0 - singularity causing && J3 is within +-10 degrees of J2=+PI/2 - singularity causing
00140         singularBoundary = true;
00141         if (!lastBoundary)
00142         { // Create our spring to pull J1 to perturb the controller avoiding the singularity
00143           if (wamJP[0] > -M_PI / 2) // We will rotate in the negative direction unless we are near the j1 negative joint stop and do not want to rotate into the stop.
00144             hapticSpringOrigin[0] = wamJP[0] - 0.75;
00145           else
00146             hapticSpringOrigin[0] = wamJP[0] + 0.75;
00147         }
00148         // Command the force to J1 pulling the WAM out of the singularity
00149         jtSingularityAvoid[0] = (hapticSpringOrigin[0] - wamJP[0]) * singularitySpringConst;
00150       }
00151       else if ((wamJP[1] > jointRangeCenter[1] - singularityBuffer && wamJP[1] < jointRangeCenter[1] + singularityBuffer)
00152           && (wamJP[2] > (jointRangeCenter[2] - M_PI / 2) - singularityBuffer
00153               && wamJP[2] < (jointRangeCenter[2] - M_PI / 2) + singularityBuffer))
00154       { // J2 is within +-10 degrees of J2=0 - singularity causing && J3 is within +-10 degrees of J2=-PI/2 - singularity causing
00155         singularBoundary = true;
00156         if (!lastBoundary)
00157         { // Create our spring to pull J1 to perturb the controller avoiding the singularity
00158           if (wamJP[0] < M_PI / 2) // We will rotate in the positive direction moving J3 towards its center point unless we are near the j1 positive joint stop and do not want to rotate into the stop.
00159             hapticSpringOrigin[0] = wamJP[0] + 0.75;
00160           else
00161             hapticSpringOrigin[0] = wamJP[0] - 0.75;
00162         }
00163         // Command the force to J1 pulling the WAM out of the singularity
00164         jtSingularityAvoid[0] = (hapticSpringOrigin[0] - wamJP[0]) * singularitySpringConst;
00165       }
00166 
00167       lastBoundary = singularBoundary;
00168       this->outputValue->setData(&jtSingularityAvoid);
00169     }
00170 
00171   public:
00172     jp_type wamJP, hapticSpringOrigin, jointRangeCenter;
00173     jt_type jtSingularityAvoid;
00174     bool singularBoundary, lastBoundary;
00175     double singularitySpringConst, singularityBuffer;
00176   private:
00177     DISALLOW_COPY_AND_ASSIGN(SingularityAvoid);
00178   }
00179   ;
00180 
00181 // Joint Stop Avoidance Springs
00182 template<size_t DOF>
00183   class JointStopSprings : public systems::SingleIO<typename units::JointPositions<DOF>::type,
00184       typename units::JointTorques<DOF>::type>
00185   {
00186     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00187 
00188   public:
00189     JointStopSprings(const jp_type& jointCenter, const std::vector<double>& springs, const std::string& sysName =
00190                          "JointStopSprings") :
00191         systems::SingleIO<jp_type, jt_type>(sysName),jointRangeCenter(jointCenter), springConstants(springs)
00192     {
00193     }
00194 
00195     virtual ~JointStopSprings()
00196     {
00197       this->mandatoryCleanUp();
00198     }
00199   protected:
00200 
00201     virtual void operate()
00202     {
00203       wamSpringJP = this->input.getValue();
00204       for (size_t i = 0; i < DOF; i++)
00205       {
00206         if (i != 1 && i != 5)
00207           jtSpring[i] = (jointRangeCenter[i] - wamSpringJP[i]) * springConstants[i];
00208         else
00209         {
00210           if (wamSpringJP[1] > 0.0) // Spring for J2 will be at 1.0 or -1.0 radians, middle of joint range in either hemisphere to avoiding pulling J2 to 0.0 (singularity causing)
00211             jtSpring[1] = (1.0 - wamSpringJP[1]) * springConstants[1];
00212           else if (wamSpringJP[1] < 0.0)
00213             jtSpring[1] = (-1.0 - wamSpringJP[1]) * springConstants[1];
00214           if (DOF != 4)
00215           {
00216             if (wamSpringJP[5] > 0.0) // Spring for J6 will be at 0.8 or -0.8 radians, middle of joint range in either hemisphere to avoiding pulling J6 to 0.0 (singularity causing)
00217               jtSpring[5] = (0.8 - wamSpringJP[5]) * springConstants[5];
00218             else if (wamSpringJP[5] < 0.0)
00219               jtSpring[5] = (-0.8 - wamSpringJP[5]) * springConstants[5];
00220 
00221             //Spring force on J4 to avoid wrist making collision with inner link
00222             wamSpringDiff = wamSpringJP[3] - 2.78; // Make a vector between the WAMs CP and the center of the haptic sphere
00223             if (wamSpringDiff > 0)
00224               jtSpring[3] += -100 * (wamSpringDiff);
00225           }
00226         }
00227       }
00228       this->outputValue->setData(&jtSpring);
00229     }
00230 
00231   public:
00232     jp_type wamSpringJP, jointRangeCenter, hapticSpringOrigin;
00233     jt_type jtSpring;
00234     double wamSpringDiff;
00235     std::vector<double> springConstants;
00236     bool singularBoundary, lastBoundary;
00237   private:
00238     DISALLOW_COPY_AND_ASSIGN(JointStopSprings);
00239   }
00240   ;
00241 
00242 // Joint Velocity Damper System
00243 template<size_t DOF>
00244   class JVDamper : public systems::SingleIO<typename units::JointVelocities<DOF>::type,
00245       typename units::JointTorques<DOF>::type>
00246   {
00247     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00248 
00249   public:
00250     JVDamper(const std::vector<double>& damping, const std::string& sysName = "JVDamper") :
00251         systems::SingleIO<jv_type, jt_type>(sysName), dampingConstants(damping)
00252     {
00253     }
00254 
00255     virtual ~JVDamper()
00256     {
00257       this->mandatoryCleanUp();
00258     }
00259   protected:
00260 
00261     virtual void operate()
00262     {
00263       wamJV = this->input.getValue();
00264 
00265       for (size_t d = 0; d < DOF; d++)
00266         jtDamping[d] = -dampingConstants[d] * wamJV[d];
00267       this->outputValue->setData(&jtDamping);
00268     }
00269 
00270   public:
00271     jv_type wamJV;
00272     jt_type jtDamping;
00273     std::vector<double> dampingConstants;
00274   private:
00275     DISALLOW_COPY_AND_ASSIGN(JVDamper);
00276   }
00277   ;
00278 
00279 // Self Collision Haptic Boundary System
00280 template<size_t DOF>
00281   class HapticCollisionAvoid : public systems::SingleIO<typename units::CartesianPosition::type,
00282       typename units::CartesianForce::type>
00283   {
00284     BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00285 
00286   public:
00287     HapticCollisionAvoid(const double& kpIn = 3000, const double& sphereRad = 0.35, const std::string& sysName =
00288                              "HapticCollisionAvoid") :
00289         systems::SingleIO<cp_type, cf_type>(sysName), kp(kpIn), sphereRadius(sphereRad)
00290     {
00291     }
00292 
00293     virtual ~HapticCollisionAvoid()
00294     {
00295       this->mandatoryCleanUp();
00296     }
00297   protected:
00298 
00299     virtual void operate()
00300     {
00301       wamCP = this->input.getValue();
00302       collisionCP = wamCP;
00303 
00304       sphereCenter[2] = -0.18;
00305       collisionVec = collisionCP - sphereCenter; // Make a vector between the WAMs CP and the center of the haptic sphere
00306 
00307       if (collisionVec.norm() < sphereRadius)
00308         collisionCP = sphereCenter + sphereRadius * collisionVec / collisionVec.norm(); // Puts the position of the spring at the surface of the boundary at the collision point.
00309       cfHapticCmd = kp * (collisionCP - wamCP);
00310       this->outputValue->setData(&cfHapticCmd);
00311     }
00312 
00313   public:
00314     cp_type wamCP, collisionCP, sphereCenter, collisionVec;
00315     cf_type cfHapticCmd;
00316     double kp, sphereRadius;
00317   private:
00318     DISALLOW_COPY_AND_ASSIGN(HapticCollisionAvoid);
00319   }
00320   ;
00321 
00322 #endif /* ROBUST_CARTESIAN_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines