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
00030
00031
00032
00033
00034
00035
00036
00037 #include <moveit/ompl_interface/parameterization/work_space/pose_model_state_space.h>
00038 #include <ompl/base/spaces/SE3StateSpace.h>
00039 #include <moveit/profiler/profiler.h>
00040
00041 const std::string ompl_interface::PoseModelStateSpace::PARAMETERIZATION_TYPE = "PoseModel";
00042
00043 ompl_interface::PoseModelStateSpace::PoseModelStateSpace(const ModelBasedStateSpaceSpecification &spec) : ModelBasedStateSpace(spec)
00044 {
00045 jump_factor_ = 3;
00046
00047 if (spec.joint_model_group_->getGroupKinematics().first)
00048 poses_.push_back(PoseComponent(spec.joint_model_group_, spec.joint_model_group_->getGroupKinematics().first));
00049 else
00050 if (!spec.joint_model_group_->getGroupKinematics().second.empty())
00051 {
00052 const robot_model::JointModelGroup::KinematicsSolverMap &m = spec.joint_model_group_->getGroupKinematics().second;
00053 for (robot_model::JointModelGroup::KinematicsSolverMap::const_iterator it = m.begin() ; it != m.end() ; ++it)
00054 poses_.push_back(PoseComponent(it->first, it->second));
00055 }
00056 if (poses_.empty())
00057 logError("No kinematics solvers specified. Unable to construct a PoseModelStateSpace");
00058 else
00059 std::sort(poses_.begin(), poses_.end());
00060 setName(getName() + "_" + PARAMETERIZATION_TYPE);
00061 }
00062
00063 ompl_interface::PoseModelStateSpace::~PoseModelStateSpace()
00064 {
00065 }
00066
00067 double ompl_interface::PoseModelStateSpace::distance(const ompl::base::State *state1, const ompl::base::State *state2) const
00068 {
00069 double total = 0;
00070 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00071 total += poses_[i].state_space_->distance(state1->as<StateType>()->poses[i], state2->as<StateType>()->poses[i]);
00072 return total;
00073 }
00074
00075 double ompl_interface::PoseModelStateSpace::getMaximumExtent() const
00076 {
00077 double total = 0.0;
00078 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00079 total += poses_[i].state_space_->getMaximumExtent();
00080 return total;
00081 }
00082
00083 ompl::base::State* ompl_interface::PoseModelStateSpace::allocState() const
00084 {
00085 StateType *state = new StateType();
00086 state->values = new double[variable_count_];
00087 state->poses = new ompl::base::SE3StateSpace::StateType*[poses_.size()];
00088 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00089 state->poses[i] = poses_[i].state_space_->allocState()->as<ompl::base::SE3StateSpace::StateType>();
00090 return state;
00091 }
00092
00093 void ompl_interface::PoseModelStateSpace::freeState(ompl::base::State *state) const
00094 {
00095 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00096 poses_[i].state_space_->freeState(state->as<StateType>()->poses[i]);
00097 delete[] state->as<StateType>()->poses;
00098 ModelBasedStateSpace::freeState(state);
00099 }
00100
00101 void ompl_interface::PoseModelStateSpace::copyState(ompl::base::State *destination, const ompl::base::State *source) const
00102 {
00103
00104 ModelBasedStateSpace::copyState(destination, source);
00105
00106 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00107 poses_[i].state_space_->copyState(destination->as<StateType>()->poses[i], source->as<StateType>()->poses[i]);
00108
00109
00110 computeStateK(destination);
00111 }
00112
00113 void ompl_interface::PoseModelStateSpace::sanityChecks() const
00114 {
00115 ModelBasedStateSpace::sanityChecks(std::numeric_limits<double>::epsilon(), std::numeric_limits<float>::epsilon(), ~ompl::base::StateSpace::STATESPACE_TRIANGLE_INEQUALITY);
00116 }
00117
00118 void ompl_interface::PoseModelStateSpace::interpolate(const ompl::base::State *from, const ompl::base::State *to, const double t, ompl::base::State *state) const
00119 {
00120
00121
00122
00123
00124
00125
00126 ModelBasedStateSpace::interpolate(from, to, t, state);
00127
00128
00129 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00130 poses_[i].state_space_->interpolate(from->as<StateType>()->poses[i], to->as<StateType>()->poses[i], t, state->as<StateType>()->poses[i]);
00131
00132
00133 state->as<StateType>()->setPoseComputed(true);
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 if (computeStateIK(state))
00146 {
00147 double dj = jump_factor_ * ModelBasedStateSpace::distance(from, to);
00148 double d_from = ModelBasedStateSpace::distance(from, state);
00149 double d_to = ModelBasedStateSpace::distance(state, to);
00150
00151
00152 if (d_from + d_to > std::max(0.2, dj))
00153 state->as<StateType>()->markInvalid();
00154 }
00155 }
00156
00157 void ompl_interface::PoseModelStateSpace::setPlanningVolume(double minX, double maxX, double minY, double maxY, double minZ, double maxZ)
00158 {
00159 ModelBasedStateSpace::setPlanningVolume(minX, maxX, minY, maxY, minZ, maxZ);
00160 ompl::base::RealVectorBounds b(3);
00161 b.low[0] = minX; b.low[1] = minY; b.low[2] = minZ;
00162 b.high[0] = maxX; b.high[1] = maxY; b.high[2] = maxZ;
00163 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00164 poses_[i].state_space_->as<ompl::base::SE3StateSpace>()->setBounds(b);
00165 }
00166
00167 ompl_interface::PoseModelStateSpace::PoseComponent::PoseComponent(const robot_model::JointModelGroup *subgroup,
00168 const robot_model::JointModelGroup::KinematicsSolver &k)
00169 : subgroup_(subgroup)
00170 , kinematics_solver_(k.allocator_(subgroup))
00171 , bijection_(k.bijection_)
00172 {
00173 state_space_.reset(new ompl::base::SE3StateSpace());
00174 state_space_->setName(subgroup_->getName() + "_Workspace");
00175 fk_link_.resize(1, kinematics_solver_->getTipFrame());
00176 if (!fk_link_[0].empty() && fk_link_[0][0] == '/')
00177 fk_link_[0] = fk_link_[0].substr(1);
00178 }
00179
00180 bool ompl_interface::PoseModelStateSpace::PoseComponent::computeStateFK(StateType *full_state, unsigned int idx) const
00181 {
00182
00183 std::vector<double> values(bijection_.size());
00184 for (unsigned int i = 0 ; i < bijection_.size() ; ++i)
00185 values[i] = full_state->values[bijection_[i]];
00186
00187
00188 std::vector<geometry_msgs::Pose> poses;
00189 if (!kinematics_solver_->getPositionFK(fk_link_, values, poses))
00190 return false;
00191
00192
00193 ompl::base::SE3StateSpace::StateType *se3_state = full_state->poses[idx];
00194 se3_state->setXYZ(poses[0].position.x, poses[0].position.y, poses[0].position.z);
00195 ompl::base::SO3StateSpace::StateType &so3_state = se3_state->rotation();
00196 so3_state.x = poses[0].orientation.x;
00197 so3_state.y = poses[0].orientation.y;
00198 so3_state.z = poses[0].orientation.z;
00199 so3_state.w = poses[0].orientation.w;
00200
00201 return true;
00202 }
00203
00204 bool ompl_interface::PoseModelStateSpace::PoseComponent::computeStateIK(StateType *full_state, unsigned int idx) const
00205 {
00206
00207 std::vector<double> seed_values(bijection_.size());
00208 for (std::size_t i = 0 ; i < bijection_.size() ; ++i)
00209 seed_values[i] = full_state->values[bijection_[i]];
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 geometry_msgs::Pose pose;
00220 const ompl::base::SE3StateSpace::StateType *se3_state = full_state->poses[idx];
00221 pose.position.x = se3_state->getX();
00222 pose.position.y = se3_state->getY();
00223 pose.position.z = se3_state->getZ();
00224 const ompl::base::SO3StateSpace::StateType &so3_state = se3_state->rotation();
00225 pose.orientation.x = so3_state.x;
00226 pose.orientation.y = so3_state.y;
00227 pose.orientation.z = so3_state.z;
00228 pose.orientation.w = so3_state.w;
00229
00230
00231 std::vector<double> solution(bijection_.size());
00232 moveit_msgs::MoveItErrorCodes err_code;
00233 if (!kinematics_solver_->getPositionIK(pose, seed_values, solution, err_code))
00234 {
00235 if (err_code.val != moveit_msgs::MoveItErrorCodes::TIMED_OUT ||
00236 !kinematics_solver_->searchPositionIK(pose, seed_values, kinematics_solver_->getDefaultTimeout() * 2.0, solution, err_code))
00237 return false;
00238 }
00239
00240 for (std::size_t i = 0 ; i < bijection_.size() ; ++i)
00241 full_state->values[bijection_[i]] = solution[i];
00242
00243 return true;
00244 }
00245
00246 bool ompl_interface::PoseModelStateSpace::computeStateFK(ompl::base::State *state) const
00247 {
00248 if (state->as<StateType>()->poseComputed())
00249 return true;
00250 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00251 if (!poses_[i].computeStateFK(state->as<StateType>(), i))
00252 {
00253 state->as<StateType>()->markInvalid();
00254 return false;
00255 }
00256 state->as<StateType>()->setPoseComputed(true);
00257 return true;
00258 }
00259
00260 bool ompl_interface::PoseModelStateSpace::computeStateIK(ompl::base::State *state) const
00261 {
00262 if (state->as<StateType>()->jointsComputed())
00263 return true;
00264 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00265 if (!poses_[i].computeStateIK(state->as<StateType>(), i))
00266 {
00267 state->as<StateType>()->markInvalid();
00268 return false;
00269 }
00270 state->as<StateType>()->setJointsComputed(true);
00271 return true;
00272 }
00273
00274 bool ompl_interface::PoseModelStateSpace::computeStateK(ompl::base::State *state) const
00275 {
00276 if (state->as<StateType>()->jointsComputed() && !state->as<StateType>()->poseComputed())
00277 return computeStateFK(state);
00278 if (!state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
00279 return computeStateIK(state);
00280 if (state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
00281 return true;
00282 state->as<StateType>()->markInvalid();
00283 return false;
00284 }
00285
00286 ompl::base::StateSamplerPtr ompl_interface::PoseModelStateSpace::allocDefaultStateSampler() const
00287 {
00288 class PoseModelStateSampler : public ompl::base::StateSampler
00289 {
00290 public:
00291 PoseModelStateSampler(const ompl::base::StateSpace *space,
00292 const ompl::base::StateSamplerPtr &sampler)
00293 : ompl::base::StateSampler(space)
00294 , sampler_(sampler)
00295 {
00296 }
00297
00298 virtual void sampleUniform(ompl::base::State *state)
00299 {
00300 sampler_->sampleUniform(state);
00301 afterStateSample(state);
00302 }
00303
00304 virtual void sampleUniformNear(ompl::base::State *state, const ompl::base::State *near, const double distance)
00305 {
00306 sampler_->sampleUniformNear(state, near, distance);
00307 afterStateSample(state);
00308 }
00309
00310 virtual void sampleGaussian(ompl::base::State *state, const ompl::base::State *mean, const double stdDev)
00311 {
00312 sampler_->sampleGaussian(state, mean, stdDev);
00313 afterStateSample(state);
00314 }
00315
00316 protected:
00317
00318 void afterStateSample(ompl::base::State *sample) const
00319 {
00320 sample->as<StateType>()->setJointsComputed(true);
00321 sample->as<StateType>()->setPoseComputed(false);
00322 space_->as<PoseModelStateSpace>()->computeStateFK(sample);
00323 }
00324
00325 ompl::base::StateSamplerPtr sampler_;
00326 };
00327
00328 return ompl::base::StateSamplerPtr(static_cast<ompl::base::StateSampler*>
00329 (new PoseModelStateSampler(this, ModelBasedStateSpace::allocDefaultStateSampler())));
00330 }
00331
00332 void ompl_interface::PoseModelStateSpace::copyToOMPLState(ompl::base::State *state, const robot_state::RobotState &rstate) const
00333 {
00334 ModelBasedStateSpace::copyToOMPLState(state, rstate);
00335 state->as<StateType>()->setJointsComputed(true);
00336 state->as<StateType>()->setPoseComputed(false);
00337 computeStateFK(state);
00338
00339
00340
00341
00342 }