Libbarrett
1.2.4
|
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_ */