pose_model_state_space.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2012, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan, Sachin Chitta */
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   // copy the state data
00106   ModelBasedStateSpace::copyState(destination, source);
00107 
00108   // compute additional stuff if needed
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   //  moveit::Profiler::ScopedBlock sblock("interpolate");
00120 
00121   // we want to interpolate in Cartesian space; we do not have a guarantee that from and to
00122   // have their poses computed, but this is very unlikely to happen (depends how the planner gets its input states)
00123   ModelBasedStateSpace::interpolate(from, to, t, state);
00124 
00125   // the call above may reset all flags for state; but we know the pose we want flag should be set
00126   state->as<StateType>()->setPoseComputed(true);
00127 
00128   /*
00129   std::cout << "*********** interpolate\n";
00130   printState(from, std::cout);
00131   printState(to, std::cout);
00132   printState(state, std::cout);
00133   std::cout << "\n\n";
00134   */
00135 
00136   // after interpolation we cannot be sure about the joint values (we use them as seed only)
00137   // so we recompute IK if needed
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       // if the joint value jumped too much
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   // read the values from the joint state by name, in the order expected by the kinematics solver
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   // compute forward kinematics for the link of interest
00192   std::vector<geometry_msgs::Pose> poses;
00193   if (!kinematics_solver_->getPositionFK(fk_link_, values, poses))
00194     return false;
00195 
00196   // copy the resulting data to the desired location in the state
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   // read the values from the joint state by name, in the order expected by the kinematics solver; use these as the seed
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   std::cout << "seed: ";
00223   for (std::size_t i = 0 ; i < seed_values.size() ; ++i)
00224     std::cout << seed_values[i] << " ";
00225   std::cout << std::endl;
00226   */
00227 
00228   // construct the pose
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   // run IK
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   // copy solution to the joint state
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   std::cout << "SAMPLE:\n";
00307   printState(sample, std::cout);
00308   std::cout << "---------- SAMPLE\n"; */
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   std::cout << "COPY STATE IN:\n";
00319   printState(state, std::cout);
00320   std::cout << "---------- COPY STATE IN\n"; */
00321 }


ompl
Author(s): Ioan Sucan
autogenerated on Mon Oct 6 2014 11:12:03