cached_ik_kinematics_plugin.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Rice University
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 the Rice University 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: Mark Moll */
36 
37 #pragma once
38 
42 #include <tf2/LinearMath/Vector3.h>
45 #include <boost/filesystem.hpp>
46 #include <unordered_map>
47 #include <mutex>
48 #include <utility>
49 
51 {
53 class IKCache
54 {
55 public:
56  struct Options
57  {
59  {
60  }
61  unsigned int max_cache_size;
62  double min_pose_distance;
64  std::string cached_ik_path;
65  };
66 
74  struct Pose
75  {
76  Pose() = default;
77  Pose(const geometry_msgs::Pose& pose);
78  tf2::Vector3 position;
81  double distance(const Pose& pose) const;
82  };
83 
89  using IKEntry = std::pair<std::vector<Pose>, std::vector<double>>;
90 
91  IKCache();
92  ~IKCache();
93  IKCache(const IKCache&) = delete;
94 
96  const IKEntry& getBestApproximateIKSolution(const Pose& pose) const;
98  const IKEntry& getBestApproximateIKSolution(const std::vector<Pose>& poses) const;
100  void initializeCache(const std::string& robot_id, const std::string& group_name, const std::string& cache_name,
101  const unsigned int num_joints, const Options& opts = Options());
106  void updateCache(const IKEntry& nearest, const Pose& pose, const std::vector<double>& config) const;
111  void updateCache(const IKEntry& nearest, const std::vector<Pose>& poses, const std::vector<double>& config) const;
114 
115 protected:
117  double configDistance2(const std::vector<double>& config1, const std::vector<double>& config2) const;
119  void saveCache() const;
120 
122  unsigned int num_joints_;
123 
125  double min_pose_distance_;
127  double min_config_distance2_;
129  unsigned int max_cache_size_;
131  boost::filesystem::path cache_file_name_;
132 
139  mutable std::vector<IKEntry> ik_cache_;
143  mutable unsigned int last_saved_cache_size_{ 0 };
145  mutable std::mutex lock_;
146 };
147 
149 class IKCacheMap : public std::unordered_map<std::string, IKCache*>
150 {
151 public:
152  using IKEntry = IKCache::IKEntry;
154 
155  IKCacheMap(const std::string& robot_description, const std::string& group_name, unsigned int num_joints);
156  ~IKCacheMap();
161  const IKEntry& getBestApproximateIKSolution(const std::vector<std::string>& fixed,
162  const std::vector<std::string>& active,
163  const std::vector<Pose>& poses) const;
168  void updateCache(const IKEntry& nearest, const std::vector<std::string>& fixed,
169  const std::vector<std::string>& active, const std::vector<Pose>& poses,
170  const std::vector<double>& config);
171 
172 protected:
173  std::string getKey(const std::vector<std::string>& fixed, const std::vector<std::string>& active) const;
174  std::string robot_description_;
175  std::string group_name_;
176  unsigned int num_joints_;
177 };
178 
179 // Helper class to enable/disable initialize() methods with new/old API
180 // HasRobotModelApi<T>::value provides a true/false constexpr depending on KinematicsPlugin offers the new Api
181 // This uses SFINAE magic: https://jguegant.github.io/blogs/tech/sfinae-introduction.html
182 template <typename KinematicsPlugin, typename = bool>
183 struct HasRobotModelApi : std::false_type
184 {
185 };
186 
187 template <typename KinematicsPlugin>
188 struct HasRobotModelApi<KinematicsPlugin, decltype(std::declval<KinematicsPlugin&>().initialize(
189  std::declval<const moveit::core::RobotModel&>(), std::string(),
190  std::string(), std::vector<std::string>(), 0.0))> : std::true_type
191 {
192 };
193 
194 template <typename KinematicsPlugin, typename = bool>
195 struct HasRobotDescApi : std::false_type
196 {
197 };
198 
199 template <typename KinematicsPlugin>
200 struct HasRobotDescApi<KinematicsPlugin,
201  decltype(std::declval<KinematicsPlugin&>().KinematicsPlugin::initialize(
202  std::string(), std::string(), std::string(), std::vector<std::string>(), 0.0))>
203  : std::true_type
204 {
205 };
206 
208 template <class KinematicsPlugin>
209 class CachedIKKinematicsPlugin : public KinematicsPlugin
210 {
211 public:
212  using Pose = IKCache::Pose;
213  using IKEntry = IKCache::IKEntry;
216 
218 
219  ~CachedIKKinematicsPlugin() override;
220 
221  // virtual methods that need to be wrapped:
222 
223  bool initialize(const moveit::core::RobotModel& robot_model, const std::string& group_name,
224  const std::string& base_frame, const std::vector<std::string>& tip_frames,
225  double search_discretization) override
226  {
227  return initializeImpl(robot_model, group_name, base_frame, tip_frames, search_discretization);
228  }
229 
230  bool initialize(const std::string& robot_description, const std::string& group_name, const std::string& base_frame,
231  const std::string& tip_frame, double search_discretization) override
232  {
233  return initializeImpl(robot_description, group_name, base_frame, tip_frame, search_discretization);
234  }
235 
236  bool getPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
237  std::vector<double>& solution, moveit_msgs::MoveItErrorCodes& error_code,
238  const KinematicsQueryOptions& options = KinematicsQueryOptions()) const override;
239 
240  bool searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state, double timeout,
241  std::vector<double>& solution, moveit_msgs::MoveItErrorCodes& error_code,
242  const KinematicsQueryOptions& options = KinematicsQueryOptions()) const override;
243 
244  bool searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state, double timeout,
245  const std::vector<double>& consistency_limits, std::vector<double>& solution,
246  moveit_msgs::MoveItErrorCodes& error_code,
247  const KinematicsQueryOptions& options = KinematicsQueryOptions()) const override;
248 
249  bool searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state, double timeout,
250  std::vector<double>& solution, const IKCallbackFn& solution_callback,
251  moveit_msgs::MoveItErrorCodes& error_code,
252  const KinematicsQueryOptions& options = KinematicsQueryOptions()) const override;
253 
254  bool searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state, double timeout,
255  const std::vector<double>& consistency_limits, std::vector<double>& solution,
256  const IKCallbackFn& solution_callback, moveit_msgs::MoveItErrorCodes& error_code,
257  const KinematicsQueryOptions& options = KinematicsQueryOptions()) const override;
258 
259 private:
260  IKCache cache_;
261 
262  void initCache(const std::string& robot_id, const std::string& group_name, const std::string& cache_name);
263 
264  /* Using templates and SFINAE magic, we can selectively enable/disable methods depending on
265  availability of API in wrapped KinematicsPlugin class.
266  However, as templates and virtual functions cannot be combined, we need helpers initializeImpl(). */
267  template <class T = KinematicsPlugin>
268  typename std::enable_if<HasRobotModelApi<T>::value, bool>::type
269  initializeImpl(const moveit::core::RobotModel& robot_model, const std::string& group_name,
270  const std::string& base_frame, const std::vector<std::string>& tip_frames,
271  double search_discretization)
272  {
273  if (tip_frames.size() != 1)
274  {
275  ROS_ERROR_NAMED("cached_ik", "This solver does not support multiple tip frames");
276  return false;
277  }
278 
279  // call initialize method of wrapped class
280  if (!KinematicsPlugin::initialize(robot_model, group_name, base_frame, tip_frames, search_discretization))
281  return false;
282  initCache(robot_model.getName(), group_name, base_frame + tip_frames[0]);
283  return true;
284  }
285 
286  template <class T = KinematicsPlugin>
287  typename std::enable_if<!HasRobotModelApi<T>::value, bool>::type
288  initializeImpl(const moveit::core::RobotModel& /*unused*/, const std::string& /*unused*/,
289  const std::string& /*unused*/, const std::vector<std::string>& /*unused*/, double /*unused*/)
290  {
291  return false; // API not supported
292  }
293 
294  template <class T = KinematicsPlugin>
295  typename std::enable_if<HasRobotDescApi<T>::value, bool>::type
296  initializeImpl(const std::string& robot_description, const std::string& group_name, const std::string& base_frame,
297  const std::string& tip_frame, double search_discretization)
298  {
299  // call initialize method of wrapped class
300  if (!KinematicsPlugin::initialize(robot_description, group_name, base_frame, tip_frame, search_discretization))
301  return false;
302  initCache(robot_description, group_name, base_frame + tip_frame);
303  return true;
304  }
305 
306  template <class T = KinematicsPlugin>
307  typename std::enable_if<!HasRobotDescApi<T>::value, bool>::type
308  initializeImpl(const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/,
309  const std::string& /*unused*/, double /*unused*/)
310  {
311  return false; // API not supported
312  }
313 };
314 
326 template <class KinematicsPlugin>
327 class CachedMultiTipIKKinematicsPlugin : public CachedIKKinematicsPlugin<KinematicsPlugin>
328 {
329 public:
330  using Pose = IKCache::Pose;
331  using IKEntry = IKCache::IKEntry;
334 
335  bool initialize(const moveit::core::RobotModel& robot_model, const std::string& group_name,
336  const std::string& base_frame, const std::vector<std::string>& tip_frames,
337  double search_discretization) override;
338 
339  bool initialize(const std::string& robot_description, const std::string& group_name, const std::string& base_frame,
340  const std::vector<std::string>& tip_frames, double search_discretization) override;
341 
342  bool searchPositionIK(const std::vector<geometry_msgs::Pose>& ik_poses, const std::vector<double>& ik_seed_state,
343  double timeout, const std::vector<double>& consistency_limits, std::vector<double>& solution,
344  const IKCallbackFn& solution_callback, moveit_msgs::MoveItErrorCodes& error_code,
346  const moveit::core::RobotState* context_state = nullptr) const override;
347 };
348 } // namespace cached_ik_kinematics_plugin
349 
robot_model.h
cached_ik_kinematics_plugin::IKCache::Pose::Pose
Pose()=default
initialize
bool initialize(MeshCollisionTraversalNode< BV > &node, BVHModel< BV > &model1, Transform3< typename BV::S > &tf1, BVHModel< BV > &model2, Transform3< typename BV::S > &tf2, const CollisionRequest< typename BV::S > &request, CollisionResult< typename BV::S > &result, bool use_refit, bool refit_bottomup)
cached_ik_kinematics_plugin::IKCache::initializeCache
void initializeCache(const std::string &robot_id, const std::string &group_name, const std::string &cache_name, const unsigned int num_joints, const Options &opts=Options())
Definition: ik_cache.cpp:93
cached_ik_kinematics_plugin::IKCache::IKCache
IKCache()
Definition: ik_cache.cpp:76
cached_ik_kinematics_plugin
Definition: cached_ik_kinematics_plugin-inl.h:40
cached_ik_kinematics_plugin::IKCache::Options::Options
Options()
Definition: cached_ik_kinematics_plugin.h:154
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::initialize
bool initialize(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization) override
Definition: cached_ik_kinematics_plugin.h:255
cached_ik_kinematics_plugin::IKCacheMap::IKEntry
IKCache::IKEntry IKEntry
Definition: cached_ik_kinematics_plugin.h:184
cached_ik_kinematics_plugin::IKCacheMap::~IKCacheMap
~IKCacheMap()
Definition: ik_cache.cpp:322
cached_ik_kinematics_plugin::IKCacheMap::updateCache
void updateCache(const IKEntry &nearest, const std::vector< std::string > &fixed, const std::vector< std::string > &active, const std::vector< Pose > &poses, const std::vector< double > &config)
Definition: ik_cache.cpp:343
kdl_kinematics_plugin.h
cached_ik_kinematics_plugin::IKCache::min_config_distance2_
double min_config_distance2_
Definition: cached_ik_kinematics_plugin.h:191
cached_ik_kinematics_plugin::IKCache::Pose
class to represent end effector pose
Definition: cached_ik_kinematics_plugin.h:138
cached_ik_kinematics_plugin::IKCache::ik_nn_
NearestNeighborsGNAT< IKEntry * > ik_nn_
Definition: cached_ik_kinematics_plugin.h:205
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::KinematicsQueryOptions
kinematics::KinematicsQueryOptions KinematicsQueryOptions
Definition: cached_ik_kinematics_plugin.h:247
cached_ik_kinematics_plugin::IKCache::Options::min_pose_distance
double min_pose_distance
Definition: cached_ik_kinematics_plugin.h:158
cached_ik_kinematics_plugin::IKCacheMap::num_joints_
unsigned int num_joints_
Definition: cached_ik_kinematics_plugin.h:208
cached_ik_kinematics_plugin::IKCache::Pose::distance
double distance(const Pose &pose) const
Definition: ik_cache.cpp:312
moveit::core::RobotModel
cached_ik_kinematics_plugin::IKCache
A cache of inverse kinematic solutions.
Definition: cached_ik_kinematics_plugin.h:85
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::initCache
void initCache(const std::string &robot_id, const std::string &group_name, const std::string &cache_name)
Definition: cached_ik_kinematics_plugin-inl.h:85
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::IKEntry
IKCache::IKEntry IKEntry
Definition: cached_ik_kinematics_plugin.h:245
cached_ik_kinematics_plugin::IKCache::max_cache_size_
unsigned int max_cache_size_
Definition: cached_ik_kinematics_plugin.h:193
cached_ik_kinematics_plugin::IKCacheMap::IKCacheMap
IKCacheMap(const std::string &robot_description, const std::string &group_name, unsigned int num_joints)
Definition: ik_cache.cpp:317
cached_ik_kinematics_plugin::IKCache::configDistance2
double configDistance2(const std::vector< double > &config1, const std::vector< double > &config2) const
Definition: ik_cache.cpp:170
cached_ik_kinematics_plugin::IKCacheMap::getBestApproximateIKSolution
const IKEntry & getBestApproximateIKSolution(const std::vector< std::string > &fixed, const std::vector< std::string > &active, const std::vector< Pose > &poses) const
Definition: ik_cache.cpp:328
cached_ik_kinematics_plugin::IKCache::Options::max_cache_size
unsigned int max_cache_size
Definition: cached_ik_kinematics_plugin.h:157
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
moveit::core::RobotState
Vector3.h
cached_ik_kinematics_plugin::HasRobotModelApi
Definition: cached_ik_kinematics_plugin.h:215
kinematics::KinematicsBase::IKCallbackFn
boost::function< void(const geometry_msgs::Pose &, const std::vector< double > &, moveit_msgs::MoveItErrorCodes &)> IKCallbackFn
cached_ik_kinematics_plugin::IKCache::updateCache
void updateCache(const IKEntry &nearest, const Pose &pose, const std::vector< double > &config) const
Definition: ik_cache.cpp:203
cached_ik_kinematics_plugin::CachedMultiTipIKKinematicsPlugin::searchPositionIK
bool searchPositionIK(const std::vector< geometry_msgs::Pose > &ik_poses, const std::vector< double > &ik_seed_state, double timeout, const std::vector< double > &consistency_limits, std::vector< double > &solution, const IKCallbackFn &solution_callback, moveit_msgs::MoveItErrorCodes &error_code, const KinematicsQueryOptions &options=KinematicsQueryOptions(), const moveit::core::RobotState *context_state=nullptr) const override
Definition: cached_ik_kinematics_plugin-inl.h:248
cached_ik_kinematics_plugin::IKCache::num_joints_
unsigned int num_joints_
Definition: cached_ik_kinematics_plugin.h:186
cached_ik_kinematics_plugin::CachedMultiTipIKKinematicsPlugin::KinematicsQueryOptions
kinematics::KinematicsQueryOptions KinematicsQueryOptions
Definition: cached_ik_kinematics_plugin.h:365
cached_ik_kinematics_plugin::IKCache::saveCache
void saveCache() const
Definition: ik_cache.cpp:246
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::searchPositionIK
bool searchPositionIK(const geometry_msgs::Pose &ik_pose, const std::vector< double > &ik_seed_state, double timeout, std::vector< double > &solution, moveit_msgs::MoveItErrorCodes &error_code, const KinematicsQueryOptions &options=KinematicsQueryOptions()) const override
Definition: cached_ik_kinematics_plugin-inl.h:157
Quaternion.h
cached_ik_kinematics_plugin::IKCache::Options::cached_ik_path
std::string cached_ik_path
Definition: cached_ik_kinematics_plugin.h:160
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::cache_
IKCache cache_
Definition: cached_ik_kinematics_plugin.h:292
cached_ik_kinematics_plugin::IKCacheMap::group_name_
std::string group_name_
Definition: cached_ik_kinematics_plugin.h:207
cached_ik_kinematics_plugin::NearestNeighborsGNAT< IKEntry * >
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::CachedIKKinematicsPlugin
CachedIKKinematicsPlugin()
Definition: cached_ik_kinematics_plugin-inl.h:75
cached_ik_kinematics_plugin-inl.h
moveit::core::RobotModel::getName
const std::string & getName() const
cached_ik_kinematics_plugin::IKCache::getBestApproximateIKSolution
const IKEntry & getBestApproximateIKSolution(const Pose &pose) const
Definition: ik_cache.cpp:181
kdl_kinematics_plugin::KDLKinematicsPlugin
Specific implementation of kinematics using KDL. This version supports any kinematic chain,...
Definition: kdl_kinematics_plugin.h:72
cached_ik_kinematics_plugin::IKCacheMap
Definition: cached_ik_kinematics_plugin.h:181
cached_ik_kinematics_plugin::IKCache::Pose::orientation
tf2::Quaternion orientation
Definition: cached_ik_kinematics_plugin.h:143
cached_ik_kinematics_plugin::IKCache::cache_file_name_
boost::filesystem::path cache_file_name_
Definition: cached_ik_kinematics_plugin.h:195
NearestNeighborsGNAT.h
cached_ik_kinematics_plugin::IKCache::last_saved_cache_size_
unsigned int last_saved_cache_size_
Definition: cached_ik_kinematics_plugin.h:207
cached_ik_kinematics_plugin::IKCache::lock_
std::mutex lock_
Definition: cached_ik_kinematics_plugin.h:209
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin
Definition: cached_ik_kinematics_plugin.h:241
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::~CachedIKKinematicsPlugin
~CachedIKKinematicsPlugin() override
Definition: cached_ik_kinematics_plugin-inl.h:80
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::IKCallbackFn
kinematics::KinematicsBase::IKCallbackFn IKCallbackFn
Definition: cached_ik_kinematics_plugin.h:246
kinematics::KinematicsQueryOptions
std
cached_ik_kinematics_plugin::IKCache::ik_cache_
std::vector< IKEntry > ik_cache_
Definition: cached_ik_kinematics_plugin.h:203
cached_ik_kinematics_plugin::HasRobotDescApi
Definition: cached_ik_kinematics_plugin.h:227
kinematics_base.h
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::initializeImpl
std::enable_if< HasRobotModelApi< T >::value, bool >::type initializeImpl(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization)
Definition: cached_ik_kinematics_plugin.h:301
tf2::Quaternion
cached_ik_kinematics_plugin::IKCache::Options::min_joint_config_distance
double min_joint_config_distance
Definition: cached_ik_kinematics_plugin.h:159
cached_ik_kinematics_plugin::IKCache::~IKCache
~IKCache()
Definition: ik_cache.cpp:87
cached_ik_kinematics_plugin::IKCache::IKEntry
std::pair< std::vector< Pose >, std::vector< double > > IKEntry
Definition: cached_ik_kinematics_plugin.h:153
cached_ik_kinematics_plugin::IKCache::verifyCache
void verifyCache(kdl_kinematics_plugin::KDLKinematicsPlugin &fk) const
Definition: ik_cache.cpp:282
cached_ik_kinematics_plugin::IKCache::Pose::position
tf2::Vector3 position
Definition: cached_ik_kinematics_plugin.h:142
cached_ik_kinematics_plugin::IKCache::min_pose_distance_
double min_pose_distance_
Definition: cached_ik_kinematics_plugin.h:189
cached_ik_kinematics_plugin::CachedIKKinematicsPlugin::getPositionIK
bool getPositionIK(const geometry_msgs::Pose &ik_pose, const std::vector< double > &ik_seed_state, std::vector< double > &solution, moveit_msgs::MoveItErrorCodes &error_code, const KinematicsQueryOptions &options=KinematicsQueryOptions()) const override
Definition: cached_ik_kinematics_plugin-inl.h:141
cached_ik_kinematics_plugin::IKCacheMap::getKey
std::string getKey(const std::vector< std::string > &fixed, const std::vector< std::string > &active) const
Definition: ik_cache.cpp:360
cached_ik_kinematics_plugin::IKCacheMap::robot_description_
std::string robot_description_
Definition: cached_ik_kinematics_plugin.h:206
cached_ik_kinematics_plugin::CachedMultiTipIKKinematicsPlugin::initialize
bool initialize(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization) override
Definition: cached_ik_kinematics_plugin-inl.h:105


moveit_kinematics
Author(s): Dave Coleman , Ioan Sucan , Sachin Chitta
autogenerated on Sat Apr 27 2024 02:26:15