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