Go to the documentation of this file.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
00032 #ifndef _ENVIRONMENT_CHAIN3D_TYPES_H_
00033 #define _ENVIRONMENT_CHAIN3D_TYPES_H_
00034
00035 #include <vector>
00036 #include <planning_models/robot_model.h>
00037 #include <planning_models/angle_utils.h>
00038
00039 namespace sbpl_interface {
00040
00041 static unsigned int HASH_TABLE_SIZE = 32*1024;
00042
00043 static inline unsigned int intHash(unsigned int key)
00044 {
00045 key += (key << 12);
00046 key ^= (key >> 22);
00047 key += (key << 4);
00048 key ^= (key >> 9);
00049 key += (key << 10);
00050 key ^= (key >> 2);
00051 key += (key << 7);
00052 key ^= (key >> 12);
00053 return key;
00054 }
00055 struct EnvChain3DHashEntry
00056 {
00057 unsigned char dist;
00058 int stateID;
00059 int action;
00060 int xyz[3];
00061 std::vector<int> coord;
00062 std::vector<double> angles;
00063 };
00064
00066 struct EnvChain3DGoalPose
00067 {
00068 bool is_6dof_goal;
00069 int type;
00070 int xyz_disc_tolerance;
00071 int rpy_disc_tolerance;
00072 int xyz_disc[3];
00073 int rpy_disc[3];
00074 double xyz[3];
00075 double rpy[3];
00076 double q[4];
00077 double fangle;
00078 double xyz_tolerance[3];
00079 double rpy_tolerance[3];
00080 };
00081
00083 struct EnvChain3DPlanningData
00084 {
00085
00086 EnvChain3DPlanningData(std::vector<int*>& state_ID_to_index_mapping) :
00087 state_ID_to_index_mapping_(state_ID_to_index_mapping),
00088 goal_hash_entry_(NULL),
00089 start_hash_entry_(NULL),
00090 hash_table_size_(HASH_TABLE_SIZE)
00091 {
00092 coord_to_state_ID_table_.resize(hash_table_size_);
00093 }
00094
00095 ~EnvChain3DPlanningData() {
00096 for(unsigned int i = 0; i < state_ID_to_coord_table_.size(); i++) {
00097 delete state_ID_to_coord_table_[i];
00098 }
00099 }
00100
00101 unsigned int getHashBin(const std::vector<int>& coord) {
00102 unsigned int val = 0;
00103
00104 for(size_t i = 0; i < coord.size(); i++)
00105 val += intHash(coord[i]) << i;
00106
00107 return intHash(val) & (hash_table_size_-1);
00108 }
00109
00110 EnvChain3DHashEntry* addHashEntry(const std::vector<int>& coord,
00111 const std::vector<double>& angles,
00112 const int(&xyz)[3],
00113 int action)
00114 {
00115 EnvChain3DHashEntry* new_hash_entry = new EnvChain3DHashEntry();
00116 new_hash_entry->stateID = state_ID_to_coord_table_.size();
00117 new_hash_entry->coord = coord;
00118 new_hash_entry->angles = angles;
00119 memcpy(new_hash_entry->xyz, xyz, sizeof(int)*3);
00120 new_hash_entry->action = action;
00121 state_ID_to_coord_table_.push_back(new_hash_entry);
00122 unsigned int bin = getHashBin(coord);
00123 coord_to_state_ID_table_[bin].push_back(new_hash_entry);
00124
00125
00126
00127 int* entry = new int [NUMOFINDICES_STATEID2IND];
00128 memset(entry, -1, NUMOFINDICES_STATEID2IND*sizeof(int));
00129 state_ID_to_index_mapping_.push_back(entry);
00130 if(new_hash_entry->stateID != (int)state_ID_to_index_mapping_.size()-1) {
00131 ROS_ERROR_STREAM("Size mismatch between state mappings " << new_hash_entry->stateID << " " << state_ID_to_index_mapping_.size());
00132 }
00133 return new_hash_entry;
00134 }
00135
00136 EnvChain3DHashEntry* getHashEntry(const std::vector<int> &coord,
00137 int action)
00138 {
00139 unsigned int bin = getHashBin(coord);
00140 for(unsigned int i = 0; i < coord_to_state_ID_table_[bin].size(); i++) {
00141 if(coord_to_state_ID_table_[bin][i]->coord == coord) {
00142 return coord_to_state_ID_table_[bin][i];
00143 }
00144 }
00145 return NULL;
00146 }
00147
00148 bool convertFromStateIDsToAngles(const std::vector<int>& state_ids,
00149 std::vector<std::vector<double> >& angle_vector) const {
00150 angle_vector.resize(state_ids.size());
00151 for(unsigned int i = 0; i < state_ids.size(); i++) {
00152 if(state_ids[i] > (int) state_ID_to_coord_table_.size()-1) {
00153 return false;
00154 }
00155 angle_vector[i] = state_ID_to_coord_table_[state_ids[i]]->angles;
00156 }
00157 return true;
00158 }
00159
00160
00161 std::vector<int*>& state_ID_to_index_mapping_;
00162
00163 EnvChain3DHashEntry* goal_hash_entry_;
00164 EnvChain3DHashEntry* start_hash_entry_;
00165
00166 unsigned int hash_table_size_;
00167
00168 std::vector<std::vector<EnvChain3DHashEntry*> > coord_to_state_ID_table_;
00169
00170
00171 std::vector<EnvChain3DHashEntry*> state_ID_to_coord_table_;
00172
00173 };
00174
00175 class JointMotionWrapper {
00176 public:
00177
00178 JointMotionWrapper(const planning_models::RobotModel::JointModel* joint_model) :
00179 joint_model_(joint_model)
00180 {
00181 std::vector<moveit_msgs::JointLimits> limits = joint_model->getLimits();
00182 joint_limit_ = limits.front();
00183 }
00184
00185 bool getSuccessorValue(double start,
00186 double delta,
00187 double& end) {
00188 end = start+delta;
00189 if(joint_limit_.has_position_limits) {
00190 if(end < joint_limit_.min_position) {
00191 if(fabs(start-joint_limit_.min_position) > std::numeric_limits<double>::epsilon()) {
00192
00193 end = joint_limit_.min_position;
00194 } else {
00195
00196 return false;
00197 }
00198 } else if(end > joint_limit_.max_position) {
00199 if(fabs(start-joint_limit_.max_position) > std::numeric_limits<double>::epsilon()) {
00200
00201 end = joint_limit_.max_position;
00202 } else {
00203
00204 return false;
00205 }
00206 }
00207 } else {
00208 end = normalizeAngle(end);
00209 }
00210 return true;
00211 }
00212
00213 bool canGetCloser(double start,
00214 double goal,
00215 double delta) {
00216 double start_dist = getDoubleDistance(start,goal);
00217 double plus_value = 0.0;
00218 double minus_value = 0.0;
00219 if(getSuccessorValue(start, delta, plus_value)) {
00220 double succ_dist = getDoubleDistance(plus_value, goal);
00221 if(succ_dist < start_dist) {
00222 return true;
00223 }
00224 }
00225 if(getSuccessorValue(start, -delta, minus_value)) {
00226 double succ_dist = getDoubleDistance(minus_value, goal);
00227 if(succ_dist < start_dist) {
00228 return true;
00229 }
00230 }
00231 return false;
00232 }
00233
00234 double getDoubleDistance(double start,
00235 double end)
00236 {
00237 if(joint_limit_.has_position_limits) {
00238 return fabs(end-start);
00239 } else {
00240 return fabs(planning_models::shortestAngularDistance(start,end));
00241 }
00242 }
00243 int getIntegerDistance(double start,
00244 double end,
00245 double delta) {
00246 double val;
00247 if(joint_limit_.has_position_limits) {
00248 val = fabs(end-start)/delta;
00249 } else {
00250 val = fabs(planning_models::shortestAngularDistance(start,end))/delta;
00251 }
00252 if(val-floor(val) > std::numeric_limits<double>::epsilon()) {
00253 return ceil(val);
00254 } else {
00255 return floor(val);
00256 }
00257 }
00258 protected:
00259 const planning_models::RobotModel::JointModel* joint_model_;
00260 moveit_msgs::JointLimits joint_limit_;
00261 };
00262
00263 class JointMotionPrimitive {
00264 public:
00265 virtual bool generateSuccessorState(const std::vector<double>& start,
00266 std::vector<double>& end) = 0;
00267 };
00268
00269 class SingleJointMotionPrimitive : public JointMotionPrimitive {
00270 public:
00271 SingleJointMotionPrimitive(const boost::shared_ptr<JointMotionWrapper>& joint_motion_wrapper,
00272 unsigned int ind,
00273 double delta) :
00274 joint_motion_wrapper_(joint_motion_wrapper),
00275 ind_(ind),
00276 delta_(delta)
00277 {
00278 }
00279
00280 virtual bool generateSuccessorState(const std::vector<double>& start,
00281 std::vector<double>& end) {
00282 end = start;
00283 return joint_motion_wrapper_->getSuccessorValue(start[ind_], delta_, end[ind_]);
00284 }
00285 protected:
00286 boost::shared_ptr<JointMotionWrapper> joint_motion_wrapper_;
00287 unsigned int ind_;
00288 double delta_;
00289 };
00290
00291 }
00292
00293 #endif