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 const std::pair<robot_model::SolverAllocatorFn, robot_model::SolverAllocatorMapFn>& slv = spec.joint_model_group_->getSolverAllocators();
00047 if (slv.first)
00048 poses_.push_back(PoseComponent(spec.joint_model_group_));
00049 else
00050 if (!slv.second.empty())
00051 {
00052 for (std::map<const robot_model::JointModelGroup*, robot_model::SolverAllocatorFn>::const_iterator it = slv.second.begin() ; it != slv.second.end() ; ++it)
00053 poses_.push_back(PoseComponent(it->first));
00054 }
00055 if (poses_.empty())
00056 logError("No kinematics solvers specified. Unable to construct a PoseModelStateSpace");
00057 constructSpaceFromPoses();
00058 }
00059
00060 ompl_interface::PoseModelStateSpace::~PoseModelStateSpace()
00061 {
00062 }
00063
00064 void ompl_interface::PoseModelStateSpace::constructSpaceFromPoses()
00065 {
00066 std::sort(poses_.begin(), poses_.end());
00067 for (unsigned int i = 0 ; i < jointSubspaceCount_ ; ++i)
00068 weights_[i] = 0;
00069 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00070 addSubspace(poses_[i].state_space_, 1.0);
00071 setName(getJointModelGroupName() + "_" + PARAMETERIZATION_TYPE);
00072 lock();
00073 }
00074
00075 double ompl_interface::PoseModelStateSpace::distance(const ompl::base::State *state1, const ompl::base::State *state2) const
00076 {
00077 double total = 0;
00078 for (unsigned int i = jointSubspaceCount_ ; i < componentCount_ ; ++i)
00079 total += weights_[i] * components_[i]->distance(state1->as<StateType>()->components[i], state2->as<StateType>()->components[i]);
00080 return total;
00081 }
00082
00083 double ompl_interface::PoseModelStateSpace::getMaximumExtent() const
00084 {
00085 double total = 0.0;
00086 for (unsigned int i = jointSubspaceCount_ ; i < componentCount_ ; ++i)
00087 total += weights_[i] * components_[i]->getMaximumExtent();
00088 return total;
00089 }
00090
00091 ompl::base::State* ompl_interface::PoseModelStateSpace::allocState() const
00092 {
00093 StateType *state = new StateType();
00094 allocStateComponents(state);
00095 return state;
00096 }
00097
00098 void ompl_interface::PoseModelStateSpace::freeState(ompl::base::State *state) const
00099 {
00100 ModelBasedStateSpace::freeState(state);
00101 }
00102
00103 void ompl_interface::PoseModelStateSpace::copyState(ompl::base::State *destination, const ompl::base::State *source) const
00104 {
00105
00106 ModelBasedStateSpace::copyState(destination, source);
00107
00108
00109 computeStateK(destination);
00110 }
00111
00112 void ompl_interface::PoseModelStateSpace::sanityChecks() const
00113 {
00114 ModelBasedStateSpace::sanityChecks(std::numeric_limits<double>::epsilon(), std::numeric_limits<float>::epsilon(), ~ompl::base::StateSpace::STATESPACE_TRIANGLE_INEQUALITY);
00115 }
00116
00117 void ompl_interface::PoseModelStateSpace::interpolate(const ompl::base::State *from, const ompl::base::State *to, const double t, ompl::base::State *state) const
00118 {
00119
00120
00121
00122
00123 ModelBasedStateSpace::interpolate(from, to, t, state);
00124
00125
00126 state->as<StateType>()->setPoseComputed(true);
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 if (computeStateIK(state))
00139 {
00140 for (unsigned int i = 0 ; i < jointSubspaceCount_ ; ++i)
00141 {
00142 double dj = jump_factor_ * components_[i]->distance(from->as<StateType>()->components[i], to->as<StateType>()->components[i]);
00143 double d_from = components_[i]->distance(from->as<StateType>()->components[i], state->as<StateType>()->components[i]);
00144 double d_to = components_[i]->distance(state->as<StateType>()->components[i], to->as<StateType>()->components[i]);
00145
00146
00147 if (d_from + d_to > std::max(0.2, dj))
00148 {
00149 state->as<StateType>()->markInvalid();
00150 break;
00151 }
00152 }
00153 }
00154 }
00155
00156 void ompl_interface::PoseModelStateSpace::setPlanningVolume(double minX, double maxX, double minY, double maxY, double minZ, double maxZ)
00157 {
00158 ModelBasedStateSpace::setPlanningVolume(minX, maxX, minY, maxY, minZ, maxZ);
00159 ompl::base::RealVectorBounds b(3);
00160 b.low[0] = minX; b.low[1] = minY; b.low[2] = minZ;
00161 b.high[0] = maxX; b.high[1] = maxY; b.high[2] = maxZ;
00162 for (unsigned int i = jointSubspaceCount_ ; i < componentCount_ ; ++i)
00163 components_[i]->as<ompl::base::SE3StateSpace>()->setBounds(b);
00164 }
00165
00166 ompl_interface::PoseModelStateSpace::PoseComponent::PoseComponent(const robot_model::JointModelGroup *subgroup) :
00167 subgroup_(subgroup), kinematics_solver_(subgroup->getSolverAllocators().first(subgroup))
00168 {
00169 state_space_.reset(new ompl::base::SE3StateSpace());
00170 state_space_->setName(subgroup_->getName() + "_Workspace");
00171 fk_link_.resize(1, kinematics_solver_->getTipFrame());
00172 joint_names_ = kinematics_solver_->getJointNames();
00173 joint_val_count_.resize(joint_names_.size());
00174 for (std::size_t i = 0 ; i < joint_names_.size() ; ++i)
00175 joint_val_count_[i] = subgroup_->getJointModel(joint_names_[i])->getVariableCount();
00176 variable_count_ = subgroup_->getVariableCount();
00177 }
00178
00179 bool ompl_interface::PoseModelStateSpace::PoseComponent::computeStateFK(const ompl::base::StateSpace *full_state_space, ompl::base::State *full_state, ompl::base::State *state_part) const
00180 {
00181
00182 std::vector<double> values(variable_count_);
00183 unsigned int vindex = 0;
00184 for (std::size_t i = 0 ; i < joint_names_.size() ; ++i)
00185 {
00186 const double *v = full_state_space->getValueAddressAtName(full_state, joint_names_[i]);
00187 for (unsigned int j = 0 ; j < joint_val_count_[i] ; ++j)
00188 values[vindex++] = v[j];
00189 }
00190
00191
00192 std::vector<geometry_msgs::Pose> poses;
00193 if (!kinematics_solver_->getPositionFK(fk_link_, values, poses))
00194 return false;
00195
00196
00197 ompl::base::SE3StateSpace::StateType *se3_state = state_part->as<ompl::base::SE3StateSpace::StateType>();
00198 se3_state->setXYZ(poses[0].position.x, poses[0].position.y, poses[0].position.z);
00199 ompl::base::SO3StateSpace::StateType &so3_state = se3_state->rotation();
00200 so3_state.x = poses[0].orientation.x;
00201 so3_state.y = poses[0].orientation.y;
00202 so3_state.z = poses[0].orientation.z;
00203 so3_state.w = poses[0].orientation.w;
00204
00205 return true;
00206 }
00207
00208 bool ompl_interface::PoseModelStateSpace::PoseComponent::computeStateIK(const ompl::base::StateSpace *full_state_space, ompl::base::State *full_state, ompl::base::State *state) const
00209 {
00210
00211 std::vector<double> seed_values(variable_count_);
00212 std::vector<double*> jaddr(joint_names_.size());
00213 unsigned int vindex = 0;
00214 for (std::size_t i = 0 ; i < joint_names_.size() ; ++i)
00215 {
00216 double *v = jaddr[i] = full_state_space->getValueAddressAtName(full_state, joint_names_[i]);
00217 for (unsigned int j = 0 ; j < joint_val_count_[i] ; ++j)
00218 seed_values[vindex++] = v[j];
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 geometry_msgs::Pose pose;
00230 const ompl::base::SE3StateSpace::StateType *se3_state = state->as<ompl::base::SE3StateSpace::StateType>();
00231 pose.position.x = se3_state->getX();
00232 pose.position.y = se3_state->getY();
00233 pose.position.z = se3_state->getZ();
00234 const ompl::base::SO3StateSpace::StateType &so3_state = se3_state->rotation();
00235 pose.orientation.x = so3_state.x;
00236 pose.orientation.y = so3_state.y;
00237 pose.orientation.z = so3_state.z;
00238 pose.orientation.w = so3_state.w;
00239
00240
00241 std::vector<double> solution;
00242 moveit_msgs::MoveItErrorCodes err_code;
00243 if (!kinematics_solver_->getPositionIK(pose, seed_values, solution, err_code))
00244 {
00245 if (err_code.val != moveit_msgs::MoveItErrorCodes::TIMED_OUT ||
00246 !kinematics_solver_->searchPositionIK(pose, seed_values, kinematics_solver_->getDefaultTimeout() * 2.0, solution, err_code))
00247 return false;
00248 }
00249
00250
00251 vindex = 0;
00252 for (std::size_t i = 0 ; i < jaddr.size() ; ++i)
00253 for (unsigned int j = 0 ; j < joint_val_count_[i] ; ++j)
00254 jaddr[i][j] = solution[vindex++];
00255
00256 return true;
00257 }
00258
00259 bool ompl_interface::PoseModelStateSpace::computeStateFK(ompl::base::State *state) const
00260 {
00261 if (state->as<StateType>()->poseComputed())
00262 return true;
00263 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00264 if (!poses_[i].computeStateFK(this, state, state->as<StateType>()->components[componentCount_ - i - 1]))
00265 {
00266 state->as<StateType>()->markInvalid();
00267 return false;
00268 }
00269 state->as<StateType>()->setPoseComputed(true);
00270 return true;
00271 }
00272
00273 bool ompl_interface::PoseModelStateSpace::computeStateIK(ompl::base::State *state) const
00274 {
00275 if (state->as<StateType>()->jointsComputed())
00276 return true;
00277 for (std::size_t i = 0 ; i < poses_.size() ; ++i)
00278 if (!poses_[i].computeStateIK(this, state, state->as<StateType>()->components[componentCount_ - i - 1]))
00279 {
00280 state->as<StateType>()->markInvalid();
00281 return false;
00282 }
00283 state->as<StateType>()->setJointsComputed(true);
00284 return true;
00285 }
00286
00287 bool ompl_interface::PoseModelStateSpace::computeStateK(ompl::base::State *state) const
00288 {
00289 if (state->as<StateType>()->jointsComputed() && !state->as<StateType>()->poseComputed())
00290 return computeStateFK(state);
00291 if (!state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
00292 return computeStateIK(state);
00293 if (state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
00294 return true;
00295 state->as<StateType>()->markInvalid();
00296 return false;
00297 }
00298
00299 void ompl_interface::PoseModelStateSpace::afterStateSample(ompl::base::State *sample) const
00300 {
00301 ModelBasedStateSpace::afterStateSample(sample);
00302 sample->as<StateType>()->setJointsComputed(true);
00303 sample->as<StateType>()->setPoseComputed(false);
00304 computeStateFK(sample);
00305
00306
00307
00308
00309 }
00310
00311 void ompl_interface::PoseModelStateSpace::copyToOMPLState(ompl::base::State *state, const robot_state::JointStateGroup* jsg) const
00312 {
00313 ModelBasedStateSpace::copyToOMPLState(state, jsg);
00314 state->as<StateType>()->setJointsComputed(true);
00315 state->as<StateType>()->setPoseComputed(false);
00316 computeStateFK(state);
00317
00318
00319
00320
00321 }