pose_model_state_space.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Ioan Sucan */
36 
38 #include <ompl/base/spaces/SE3StateSpace.h>
40 
41 #include <utility>
42 
43 namespace ompl_interface
44 {
45 constexpr char LOGNAME[] = "pose_model_state_space";
46 } // namespace ompl_interface
47 
49 
51  : ModelBasedStateSpace(spec)
52 {
53  jump_factor_ = 3; // \todo make this a param
54 
55  if (spec.joint_model_group_->getGroupKinematics().first)
56  poses_.emplace_back(spec.joint_model_group_, spec.joint_model_group_->getGroupKinematics().first);
57  else if (!spec.joint_model_group_->getGroupKinematics().second.empty())
58  {
60  for (const auto& it : m)
61  poses_.emplace_back(it.first, it.second);
62  }
63  if (poses_.empty())
64  ROS_ERROR_NAMED(LOGNAME, "No kinematics solvers specified. Unable to construct a "
65  "PoseModelStateSpace");
66  else
67  std::sort(poses_.begin(), poses_.end());
68  setName(getName() + "_" + PARAMETERIZATION_TYPE);
69 }
70 
72 
73 double ompl_interface::PoseModelStateSpace::distance(const ompl::base::State* state1,
74  const ompl::base::State* state2) const
75 {
76  double total = 0;
77  for (std::size_t i = 0; i < poses_.size(); ++i)
78  total += poses_[i].state_space_->distance(state1->as<StateType>()->poses[i], state2->as<StateType>()->poses[i]);
79  return total;
80 }
81 
83 {
84  double total = 0.0;
85  for (const auto& pose : poses_)
86  total += pose.state_space_->getMaximumExtent();
87  return total;
88 }
89 
91 {
92  auto* state = new StateType();
93  state->values =
94  new double[variable_count_]; // need to allocate this here since ModelBasedStateSpace::allocState() is not called
95  state->poses = new ompl::base::SE3StateSpace::StateType*[poses_.size()];
96  for (std::size_t i = 0; i < poses_.size(); ++i)
97  state->poses[i] = poses_[i].state_space_->allocState()->as<ompl::base::SE3StateSpace::StateType>();
98  return state;
99 }
100 
101 void ompl_interface::PoseModelStateSpace::freeState(ompl::base::State* state) const
102 {
103  for (std::size_t i = 0; i < poses_.size(); ++i)
104  poses_[i].state_space_->freeState(state->as<StateType>()->poses[i]);
105  delete[] state->as<StateType>()->poses;
107 }
108 
109 void ompl_interface::PoseModelStateSpace::copyState(ompl::base::State* destination,
110  const ompl::base::State* source) const
111 {
112  // copy the state data
113  ModelBasedStateSpace::copyState(destination, source);
114 
115  for (std::size_t i = 0; i < poses_.size(); ++i)
116  poses_[i].state_space_->copyState(destination->as<StateType>()->poses[i], source->as<StateType>()->poses[i]);
117 
118  // compute additional stuff if needed
119  computeStateK(destination);
120 }
121 
123 {
124  ModelBasedStateSpace::sanityChecks(std::numeric_limits<double>::epsilon(), std::numeric_limits<float>::epsilon(),
125  ~ompl::base::StateSpace::STATESPACE_TRIANGLE_INEQUALITY);
126 }
127 
128 void ompl_interface::PoseModelStateSpace::interpolate(const ompl::base::State* from, const ompl::base::State* to,
129  const double t, ompl::base::State* state) const
130 {
131  // moveit::Profiler::ScopedBlock sblock("interpolate");
132 
133  // we want to interpolate in Cartesian space; we do not have a guarantee that from and to
134  // have their poses computed, but this is very unlikely to happen (depends how the planner gets its input states)
135 
136  // interpolate in joint space
137  ModelBasedStateSpace::interpolate(from, to, t, state);
138 
139  // interpolate SE3 components
140  for (std::size_t i = 0; i < poses_.size(); ++i)
141  poses_[i].state_space_->interpolate(from->as<StateType>()->poses[i], to->as<StateType>()->poses[i], t,
142  state->as<StateType>()->poses[i]);
143 
144  // the call above may reset all flags for state; but we know the pose we want flag should be set
145  state->as<StateType>()->setPoseComputed(true);
146 
147  /*
148  std::cout << "*********** interpolate\n";
149  printState(from, std::cout);
150  printState(to, std::cout);
151  printState(state, std::cout);
152  std::cout << "\n\n";
153  */
154 
155  // after interpolation we cannot be sure about the joint values (we use them as seed only)
156  // so we recompute IK if needed
157  if (computeStateIK(state))
158  {
159  double dj = jump_factor_ * ModelBasedStateSpace::distance(from, to);
160  double d_from = ModelBasedStateSpace::distance(from, state);
161  double d_to = ModelBasedStateSpace::distance(state, to);
162 
163  // if the joint value jumped too much
164  if (d_from + d_to > std::max(0.2, dj)) // \todo make 0.2 a param
165  state->as<StateType>()->markInvalid();
166  }
167 }
168 
169 void ompl_interface::PoseModelStateSpace::setPlanningVolume(double minX, double maxX, double minY, double maxY,
170  double minZ, double maxZ)
171 {
172  ModelBasedStateSpace::setPlanningVolume(minX, maxX, minY, maxY, minZ, maxZ);
173  ompl::base::RealVectorBounds b(3);
174  b.low[0] = minX;
175  b.low[1] = minY;
176  b.low[2] = minZ;
177  b.high[0] = maxX;
178  b.high[1] = maxY;
179  b.high[2] = maxZ;
180  for (auto& pose : poses_)
181  pose.state_space_->as<ompl::base::SE3StateSpace>()->setBounds(b);
182 }
183 
186  : subgroup_(subgroup), kinematics_solver_(k.allocator_(subgroup)), bijection_(k.bijection_)
187 {
188  state_space_ = std::make_shared<ompl::base::SE3StateSpace>();
189  state_space_->setName(subgroup_->getName() + "_Workspace");
190  fk_link_.resize(1, kinematics_solver_->getTipFrame());
191  if (!fk_link_[0].empty() && fk_link_[0][0] == '/')
192  fk_link_[0] = fk_link_[0].substr(1);
193 }
194 
196 {
197  // read the values from the joint state, in the order expected by the kinematics solver
198  std::vector<double> values(bijection_.size());
199  for (unsigned int i = 0; i < bijection_.size(); ++i)
200  values[i] = full_state->values[bijection_[i]];
201 
202  // compute forward kinematics for the link of interest
203  std::vector<geometry_msgs::Pose> poses;
204  if (!kinematics_solver_->getPositionFK(fk_link_, values, poses))
205  return false;
206 
207  // copy the resulting data to the desired location in the state
208  ompl::base::SE3StateSpace::StateType* se3_state = full_state->poses[idx];
209  se3_state->setXYZ(poses[0].position.x, poses[0].position.y, poses[0].position.z);
210  ompl::base::SO3StateSpace::StateType& so3_state = se3_state->rotation();
211  so3_state.x = poses[0].orientation.x;
212  so3_state.y = poses[0].orientation.y;
213  so3_state.z = poses[0].orientation.z;
214  so3_state.w = poses[0].orientation.w;
215 
216  return true;
217 }
218 
220 {
221  // read the values from the joint state, in the order expected by the kinematics solver; use these as the seed
222  std::vector<double> seed_values(bijection_.size());
223  for (std::size_t i = 0; i < bijection_.size(); ++i)
224  seed_values[i] = full_state->values[bijection_[i]];
225 
226  /*
227  std::cout << "seed: ";
228  for (std::size_t i = 0 ; i < seed_values.size() ; ++i)
229  std::cout << seed_values[i] << " ";
230  std::cout << std::endl;
231  */
232 
233  // construct the pose
234  geometry_msgs::Pose pose;
235  const ompl::base::SE3StateSpace::StateType* se3_state = full_state->poses[idx];
236  pose.position.x = se3_state->getX();
237  pose.position.y = se3_state->getY();
238  pose.position.z = se3_state->getZ();
239  const ompl::base::SO3StateSpace::StateType& so3_state = se3_state->rotation();
240  pose.orientation.x = so3_state.x;
241  pose.orientation.y = so3_state.y;
242  pose.orientation.z = so3_state.z;
243  pose.orientation.w = so3_state.w;
244 
245  // run IK
246  std::vector<double> solution(bijection_.size());
247  moveit_msgs::MoveItErrorCodes err_code;
248  if (!kinematics_solver_->getPositionIK(pose, seed_values, solution, err_code))
249  {
250  if (err_code.val != moveit_msgs::MoveItErrorCodes::TIMED_OUT ||
251  !kinematics_solver_->searchPositionIK(pose, seed_values, kinematics_solver_->getDefaultTimeout() * 2.0,
252  solution, err_code))
253  return false;
254  }
255 
256  for (std::size_t i = 0; i < bijection_.size(); ++i)
257  full_state->values[bijection_[i]] = solution[i];
258 
259  return true;
260 }
261 
262 bool ompl_interface::PoseModelStateSpace::computeStateFK(ompl::base::State* state) const
263 {
264  if (state->as<StateType>()->poseComputed())
265  return true;
266  for (std::size_t i = 0; i < poses_.size(); ++i)
267  if (!poses_[i].computeStateFK(state->as<StateType>(), i))
268  {
269  state->as<StateType>()->markInvalid();
270  return false;
271  }
272  state->as<StateType>()->setPoseComputed(true);
273  return true;
274 }
275 
276 bool ompl_interface::PoseModelStateSpace::computeStateIK(ompl::base::State* state) const
277 {
278  if (state->as<StateType>()->jointsComputed())
279  return true;
280  for (std::size_t i = 0; i < poses_.size(); ++i)
281  if (!poses_[i].computeStateIK(state->as<StateType>(), i))
282  {
283  state->as<StateType>()->markInvalid();
284  return false;
285  }
286  state->as<StateType>()->setJointsComputed(true);
287  return true;
288 }
289 
290 bool ompl_interface::PoseModelStateSpace::computeStateK(ompl::base::State* state) const
291 {
292  if (state->as<StateType>()->jointsComputed() && !state->as<StateType>()->poseComputed())
293  return computeStateFK(state);
294  if (!state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
295  return computeStateIK(state);
296  if (state->as<StateType>()->jointsComputed() && state->as<StateType>()->poseComputed())
297  return true;
298  state->as<StateType>()->markInvalid();
299  return false;
300 }
301 
303 {
304  class PoseModelStateSampler : public ompl::base::StateSampler
305  {
306  public:
307  PoseModelStateSampler(const ompl::base::StateSpace* space, ompl::base::StateSamplerPtr sampler)
308  : ompl::base::StateSampler(space), sampler_(std::move(sampler))
309  {
310  }
311 
312  void sampleUniform(ompl::base::State* state) override
313  {
314  sampler_->sampleUniform(state);
315  afterStateSample(state);
316  }
317 
318  void sampleUniformNear(ompl::base::State* state, const ompl::base::State* near, const double distance) override
319  {
320  sampler_->sampleUniformNear(state, near, distance);
321  afterStateSample(state);
322  }
323 
324  void sampleGaussian(ompl::base::State* state, const ompl::base::State* mean, const double stdDev) override
325  {
326  sampler_->sampleGaussian(state, mean, stdDev);
327  afterStateSample(state);
328  }
329 
330  protected:
331  void afterStateSample(ompl::base::State* sample) const
332  {
333  sample->as<StateType>()->setJointsComputed(true);
334  sample->as<StateType>()->setPoseComputed(false);
335  space_->as<PoseModelStateSpace>()->computeStateFK(sample);
336  }
337 
338  ompl::base::StateSamplerPtr sampler_;
339  };
340 
341  return ompl::base::StateSamplerPtr(static_cast<ompl::base::StateSampler*>(
342  new PoseModelStateSampler(this, ModelBasedStateSpace::allocDefaultStateSampler())));
343 }
344 
346  const moveit::core::RobotState& rstate) const
347 {
349  state->as<StateType>()->setJointsComputed(true);
350  state->as<StateType>()->setPoseComputed(false);
351  computeStateFK(state);
352  /*
353  std::cout << "COPY STATE IN:\n";
354  printState(state, std::cout);
355  std::cout << "---------- COPY STATE IN\n"; */
356 }
ompl_interface::ModelBasedStateSpace::StateType::values
double * values
Definition: model_based_state_space.h:195
ompl_interface::PoseModelStateSpace::distance
double distance(const ompl::base::State *state1, const ompl::base::State *state2) const override
Definition: pose_model_state_space.cpp:73
moveit::core::JointModelGroup::KinematicsSolver
ompl_interface::PoseModelStateSpace::PoseComponent::subgroup_
const moveit::core::JointModelGroup * subgroup_
Definition: pose_model_state_space.h:196
ompl_interface::PoseModelStateSpace::computeStateK
bool computeStateK(ompl::base::State *state) const
Definition: pose_model_state_space.cpp:290
ompl_interface::ModelBasedStateSpace::freeState
void freeState(ompl::base::State *state) const override
Definition: model_based_state_space.cpp:111
moveit::core::JointModelGroup::getGroupKinematics
const std::pair< KinematicsSolver, KinematicsSolverMap > & getGroupKinematics() const
ompl_interface::PoseModelStateSpace::StateType
Definition: pose_model_state_space.h:113
ompl_interface::PoseModelStateSpace::computeStateFK
bool computeStateFK(ompl::base::State *state) const
Definition: pose_model_state_space.cpp:262
ompl_interface::PoseModelStateSpace::PARAMETERIZATION_TYPE
static const std::string PARAMETERIZATION_TYPE
Definition: pose_model_state_space.h:111
ompl_interface::PoseModelStateSpace::StateType::poses
ompl::base::SE3StateSpace::StateType ** poses
Definition: pose_model_state_space.h:153
ompl_interface::PoseModelStateSpace::allocDefaultStateSampler
ompl::base::StateSamplerPtr allocDefaultStateSampler() const override
Definition: pose_model_state_space.cpp:302
ompl_interface::ModelBasedStateSpace::interpolate
void interpolate(const ompl::base::State *from, const ompl::base::State *to, const double t, ompl::base::State *state) const override
Definition: model_based_state_space.cpp:199
getName
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
ompl_interface::ModelBasedStateSpaceSpecification
Definition: model_based_state_space.h:84
ompl_interface::PoseModelStateSpace::StateType::jointsComputed
bool jointsComputed() const
Definition: pose_model_state_space.h:127
ompl_interface::ModelBasedStateSpace::distance
double distance(const ompl::base::State *state1, const ompl::base::State *state2) const override
Definition: model_based_state_space.cpp:169
ompl_interface
The MoveIt interface to OMPL.
Definition: constrained_goal_sampler.h:46
ompl_interface::PoseModelStateSpace::PoseComponent::fk_link_
std::vector< std::string > fk_link_
Definition: pose_model_state_space.h:200
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
moveit::core::RobotState
ompl_interface::PoseModelStateSpace::computeStateIK
bool computeStateIK(ompl::base::State *state) const
Definition: pose_model_state_space.cpp:276
ompl_interface::PoseModelStateSpace::StateType::poseComputed
bool poseComputed() const
Definition: pose_model_state_space.h:132
ompl_interface::ModelBasedStateSpace::copyToOMPLState
virtual void copyToOMPLState(ompl::base::State *state, const moveit::core::RobotState &rstate) const
Copy the data from a set of joint states to an OMPL state.
Definition: model_based_state_space.cpp:328
ompl_interface::PoseModelStateSpace::allocState
ompl::base::State * allocState() const override
Definition: pose_model_state_space.cpp:90
ompl_interface::PoseModelStateSpace::~PoseModelStateSpace
~PoseModelStateSpace() override
ompl_interface::ModelBasedStateSpaceSpecification::joint_model_group_
const moveit::core::JointModelGroup * joint_model_group_
Definition: model_based_state_space.h:100
moveit::core::JointModelGroup::getName
const std::string & getName() const
ompl_interface::PoseModelStateSpace::PoseComponent::kinematics_solver_
kinematics::KinematicsBasePtr kinematics_solver_
Definition: pose_model_state_space.h:197
pose_model_state_space.h
moveit::core::JointModelGroup::KinematicsSolverMap
std::map< const JointModelGroup *, KinematicsSolver > KinematicsSolverMap
ompl_interface::PoseModelStateSpace::freeState
void freeState(ompl::base::State *state) const override
Definition: pose_model_state_space.cpp:101
ompl_interface::LOGNAME
constexpr char LOGNAME[]
Definition: constrained_goal_sampler.cpp:78
ompl_interface::PoseModelStateSpace::interpolate
void interpolate(const ompl::base::State *from, const ompl::base::State *to, const double t, ompl::base::State *state) const override
Definition: pose_model_state_space.cpp:128
ompl_interface::ModelBasedStateSpace::allocDefaultStateSampler
ompl::base::StateSamplerPtr allocDefaultStateSampler() const override
Definition: model_based_state_space.cpp:251
ompl_interface::PoseModelStateSpace::copyState
void copyState(ompl::base::State *destination, const ompl::base::State *source) const override
Definition: pose_model_state_space.cpp:109
ompl_interface::PoseModelStateSpace::poses_
std::vector< PoseComponent > poses_
Definition: pose_model_state_space.h:203
ompl_interface::ModelBasedStateSpace::copyState
void copyState(ompl::base::State *destination, const ompl::base::State *source) const override
Definition: model_based_state_space.cpp:117
ompl_interface::ModelBasedStateSpace
Definition: model_based_state_space.h:106
ompl_interface::PoseModelStateSpace::PoseModelStateSpace
PoseModelStateSpace(const ModelBasedStateSpaceSpecification &spec)
Definition: pose_model_state_space.cpp:50
ompl_interface::PoseModelStateSpace::copyToOMPLState
void copyToOMPLState(ompl::base::State *state, const moveit::core::RobotState &rstate) const override
Copy the data from a set of joint states to an OMPL state.
Definition: pose_model_state_space.cpp:345
ompl_interface::PoseModelStateSpace::getMaximumExtent
double getMaximumExtent() const override
Definition: pose_model_state_space.cpp:82
values
std::vector< double > values
ompl_interface::PoseModelStateSpace::sanityChecks
void sanityChecks() const override
Definition: pose_model_state_space.cpp:122
ompl_interface::PoseModelStateSpace::PoseComponent::PoseComponent
PoseComponent(const moveit::core::JointModelGroup *subgroup, const moveit::core::JointModelGroup::KinematicsSolver &k)
Definition: pose_model_state_space.cpp:184
ompl_interface::PoseModelStateSpace::PoseComponent::computeStateIK
bool computeStateIK(StateType *full_state, unsigned int idx) const
Definition: pose_model_state_space.cpp:219
ompl_interface::PoseModelStateSpace::jump_factor_
double jump_factor_
Definition: pose_model_state_space.h:204
moveit::core::JointModelGroup
profiler.h
ompl_interface::ModelBasedStateSpace::setPlanningVolume
virtual void setPlanningVolume(double minX, double maxX, double minY, double maxY, double minZ, double maxZ)
Set the planning volume for the possible SE2 and/or SE3 components of the state space.
Definition: model_based_state_space.cpp:229
ompl_interface::PoseModelStateSpace
Definition: pose_model_state_space.h:76
ompl_interface::PoseModelStateSpace::PoseComponent::computeStateFK
bool computeStateFK(StateType *full_state, unsigned int idx) const
Definition: pose_model_state_space.cpp:195
t
geometry_msgs::TransformStamped t
ompl_interface::PoseModelStateSpace::setPlanningVolume
void setPlanningVolume(double minX, double maxX, double minY, double maxY, double minZ, double maxZ) override
Set the planning volume for the possible SE2 and/or SE3 components of the state space.
Definition: pose_model_state_space.cpp:169
ompl_interface::PoseModelStateSpace::PoseComponent::state_space_
ompl::base::StateSpacePtr state_space_
Definition: pose_model_state_space.h:199


ompl
Author(s): Ioan Sucan
autogenerated on Fri May 3 2024 02:29:39