Libbarrett
1.2.4
|
00001 /* 00002 Copyright 2009, 2010, 2011, 2012 Barrett Technology <support@barrett.com> 00003 00004 This file is part of libbarrett. 00005 00006 This version of libbarrett is free software: you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License as 00008 published by the Free Software Foundation, either version 3 of the 00009 License, or (at your option) any later version. 00010 00011 This version of libbarrett is distributed in the hope that it will be 00012 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this version of libbarrett. If not, see 00018 <http://www.gnu.org/licenses/>. 00019 00020 Further, non-binding information about licensing is available at: 00021 <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes> 00022 */ 00023 00024 /* 00025 * haptic_ball.h 00026 * 00027 * Created on: Feb 19, 2010 00028 * Author: dc 00029 */ 00030 00031 #ifndef BARRETT_SYSTEMS_HAPTIC_BALL_H_ 00032 #define BARRETT_SYSTEMS_HAPTIC_BALL_H_ 00033 00034 00035 #include <cmath> 00036 00037 #include <Eigen/Core> 00038 00039 #include <barrett/detail/ca_macro.h> 00040 #include <barrett/units.h> 00041 #include <barrett/math.h> 00042 #include <barrett/systems/abstract/haptic_object.h> 00043 00044 00045 namespace barrett { 00046 namespace systems { 00047 00048 00049 class HapticBall : public HapticObject { 00050 BARRETT_UNITS_FIXED_SIZE_TYPEDEFS; 00051 00052 public: 00053 HapticBall(const cp_type& center, double radius, const std::string& sysName = "HapticBall") : 00054 HapticObject(sysName), 00055 c(center), r(radius), keepOutside(true) /* doesn't matter how this is initialized, it'll fix itself */, 00056 depth(0.0), error(0.0) {} 00057 virtual ~HapticBall() { mandatoryCleanUp(); } 00058 00059 void setCenter(const cp_type& newCenter){ 00060 BARRETT_SCOPED_LOCK(getEmMutex()); 00061 c = newCenter; 00062 } 00063 void setRadius(double newRadius){ 00064 BARRETT_SCOPED_LOCK(getEmMutex()); 00065 r = newRadius; 00066 } 00067 00068 const cp_type& getCenter() const { return c; } 00069 double getRadius() const { return r; } 00070 00071 protected: 00072 virtual void operate() { 00073 error = input.getValue() - c; 00074 double mag = error.norm(); 00075 00076 bool outside = mag > r; 00077 00078 // if we are inside the ball and we shouldn't be, or we are outside the ball and we shouldn't be 00079 if ((keepOutside && !outside) || (!keepOutside && outside)) { 00080 depth = r - mag; 00081 if (math::abs(depth) > 0.02) { 00082 keepOutside = !keepOutside; 00083 00084 depth = 0.0; 00085 error.setZero(); 00086 } else { 00087 // unit vector pointing towards the surface of the ball 00088 error /= mag; 00089 } 00090 } else { 00091 depth = 0.0; 00092 error.setZero(); 00093 } 00094 00095 depthOutputValue->setData(&depth); 00096 directionOutputValue->setData(&error); 00097 } 00098 00099 cp_type c; 00100 double r; 00101 bool keepOutside; 00102 00103 double depth; 00104 cf_type error; 00105 00106 private: 00107 DISALLOW_COPY_AND_ASSIGN(HapticBall); 00108 00109 public: 00110 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00111 }; 00112 00113 00114 } 00115 } 00116 00117 00118 #endif /* BARRETT_SYSTEMS_HAPTIC_BALL_H_ */