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 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 */
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; // \todo make this a param
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_]; // need to allocate this here since ModelBasedStateSpace::allocState() is not called
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   // copy the state data
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   // compute additional stuff if needed
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   //  moveit::Profiler::ScopedBlock sblock("interpolate");
00121 
00122   // we want to interpolate in Cartesian space; we do not have a guarantee that from and to
00123   // have their poses computed, but this is very unlikely to happen (depends how the planner gets its input states)
00124 
00125   // interpolate in joint space
00126   ModelBasedStateSpace::interpolate(from, to, t, state);
00127 
00128   // interpolate SE3 components
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   // the call above may reset all flags for state; but we know the pose we want flag should be set
00133   state->as<StateType>()->setPoseComputed(true);
00134 
00135   /*
00136   std::cout << "*********** interpolate\n";
00137   printState(from, std::cout);
00138   printState(to, std::cout);
00139   printState(state, std::cout);
00140   std::cout << "\n\n";
00141   */
00142   
00143   // after interpolation we cannot be sure about the joint values (we use them as seed only)
00144   // so we recompute IK if needed
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     // if the joint value jumped too much
00152     if (d_from + d_to > std::max(0.2, dj)) // \todo make 0.2 a param
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   // read the values from the joint state, in the order expected by the kinematics solver
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   // compute forward kinematics for the link of interest
00188   std::vector<geometry_msgs::Pose> poses;
00189   if (!kinematics_solver_->getPositionFK(fk_link_, values, poses))
00190     return false;
00191   
00192   // copy the resulting data to the desired location in the state
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   // read the values from the joint state, in the order expected by the kinematics solver; use these as the seed
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   std::cout << "seed: ";
00213   for (std::size_t i = 0 ; i < seed_values.size() ; ++i)
00214     std::cout << seed_values[i] << " ";
00215   std::cout << std::endl;
00216   */
00217 
00218   // construct the pose
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   // run IK
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   std::cout << "COPY STATE IN:\n";
00340   printState(state, std::cout);
00341   std::cout << "---------- COPY STATE IN\n"; */
00342 }


ompl
Author(s): Ioan Sucan
autogenerated on Wed Sep 16 2015 04:42:27