moveit2
The MoveIt Motion Planning Framework for ROS 2.
transforms.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, 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 <geometric_shapes/check_isometry.h>
39 #include <rclcpp/logger.hpp>
40 #include <rclcpp/logging.hpp>
41 #include <tf2_eigen/tf2_eigen.hpp>
42 #include <boost/algorithm/string/trim.hpp>
43 #include <moveit/utils/logger.hpp>
44 
45 namespace moveit
46 {
47 namespace core
48 {
49 namespace
50 {
51 rclcpp::Logger getLogger()
52 {
53  return moveit::getLogger("transforms");
54 }
55 } // namespace
56 
57 Transforms::Transforms(const std::string& target_frame) : target_frame_(target_frame)
58 {
59  boost::trim(target_frame_);
60  if (target_frame_.empty())
61  {
62  RCLCPP_ERROR(getLogger(), "The target frame for MoveIt Transforms cannot be empty.");
63  }
64  else
65  {
66  transforms_map_[target_frame_] = Eigen::Isometry3d::Identity();
67  }
68 }
69 
70 bool Transforms::sameFrame(const std::string& frame1, const std::string& frame2)
71 {
72  if (frame1.empty() || frame2.empty())
73  return false;
74  return frame1 == frame2;
75 }
76 
77 Transforms::~Transforms() = default;
78 
79 const std::string& Transforms::getTargetFrame() const
80 {
81  return target_frame_;
82 }
83 
85 {
86  return transforms_map_;
87 }
88 
90 {
91  for (const auto& t : transforms)
92  {
93  ASSERT_ISOMETRY(t.second) // unsanitized input, could contain a non-isometry
94  }
95  transforms_map_ = transforms;
96 }
97 
98 bool Transforms::isFixedFrame(const std::string& frame) const
99 {
100  if (frame.empty())
101  {
102  return false;
103  }
104  else
105  {
106  return transforms_map_.find(frame) != transforms_map_.end();
107  }
108 }
109 
110 const Eigen::Isometry3d& Transforms::getTransform(const std::string& from_frame) const
111 {
112  if (!from_frame.empty())
113  {
114  FixedTransformsMap::const_iterator it = transforms_map_.find(from_frame);
115  if (it != transforms_map_.end())
116  return it->second;
117  // If no transform found in map, return identity
118  }
119 
120  RCLCPP_ERROR(getLogger(), "Unable to transform from frame '%s' to frame '%s'. Returning identity.",
121  from_frame.c_str(), target_frame_.c_str());
122 
123  // return identity
124  static const Eigen::Isometry3d IDENTITY = Eigen::Isometry3d::Identity();
125  return IDENTITY;
126 }
127 
128 bool Transforms::canTransform(const std::string& from_frame) const
129 {
130  if (from_frame.empty())
131  {
132  return false;
133  }
134  else
135  {
136  return transforms_map_.find(from_frame) != transforms_map_.end();
137  }
138 }
139 
140 void Transforms::setTransform(const Eigen::Isometry3d& t, const std::string& from_frame)
141 {
142  ASSERT_ISOMETRY(t) // unsanitized input, could contain a non-isometry
143  if (from_frame.empty())
144  {
145  RCLCPP_ERROR(getLogger(), "Cannot record transform with empty name");
146  }
147  else
148  transforms_map_[from_frame] = t;
149 }
150 
151 void Transforms::setTransform(const geometry_msgs::msg::TransformStamped& transform)
152 {
153  if (sameFrame(transform.child_frame_id, target_frame_))
154  {
155  // convert message manually to ensure correct normalization for double (error < 1e-12)
156  // tf2 only enforces float normalization (error < 1e-5)
157  const auto& trans = transform.transform.translation;
158  const auto& rot = transform.transform.rotation;
159  Eigen::Translation3d translation(trans.x, trans.y, trans.z);
160  Eigen::Quaterniond rotation(rot.w, rot.x, rot.y, rot.z);
161  rotation.normalize();
162 
163  setTransform(translation * rotation, transform.header.frame_id);
164  }
165  else
166  {
167  RCLCPP_ERROR(getLogger(), "Given transform is to frame '%s', but frame '%s' was expected.",
168  transform.child_frame_id.c_str(), target_frame_.c_str());
169  }
170 }
171 
172 void Transforms::setTransforms(const std::vector<geometry_msgs::msg::TransformStamped>& transforms)
173 {
174  for (const geometry_msgs::msg::TransformStamped& transform : transforms)
175  setTransform(transform);
176 }
177 
178 void Transforms::copyTransforms(std::vector<geometry_msgs::msg::TransformStamped>& transforms) const
179 {
180  transforms.resize(transforms_map_.size());
181  std::size_t i = 0;
182  for (FixedTransformsMap::const_iterator it = transforms_map_.begin(); it != transforms_map_.end(); ++it, ++i)
183  {
184  transforms[i] = tf2::eigenToTransform(it->second);
185  transforms[i].child_frame_id = target_frame_;
186  transforms[i].header.frame_id = it->first;
187  }
188 }
189 
190 } // end of namespace core
191 } // end of namespace moveit
void setTransforms(const std::vector< geometry_msgs::msg::TransformStamped > &transforms)
Set a transform in the transform tree (adding it if necessary)
Definition: transforms.cpp:172
const std::string & getTargetFrame() const
Get the planning frame corresponding to this set of transforms.
Definition: transforms.cpp:79
static bool sameFrame(const std::string &frame1, const std::string &frame2)
Check if two frames end up being the same once the missing / are added as prefix (if they are missing...
Definition: transforms.cpp:70
Transforms(const Transforms &)=delete
Transforms cannot be copy-constructed.
virtual ~Transforms()
Destructor.
std::string target_frame_
Definition: transforms.h:210
void setTransform(const Eigen::Isometry3d &t, const std::string &from_frame)
Set a transform in the transform tree (adding it if necessary)
Definition: transforms.cpp:140
const FixedTransformsMap & getAllTransforms() const
Return all the transforms.
Definition: transforms.cpp:84
virtual const Eigen::Isometry3d & getTransform(const std::string &from_frame) const
Get transform for from_frame (w.r.t target frame)
Definition: transforms.cpp:110
void copyTransforms(std::vector< geometry_msgs::msg::TransformStamped > &transforms) const
Get a vector of all the transforms as ROS messages.
Definition: transforms.cpp:178
void setAllTransforms(const FixedTransformsMap &transforms)
Set all the transforms: a map from string names of frames to corresponding Eigen::Isometry3d (w....
Definition: transforms.cpp:89
virtual bool isFixedFrame(const std::string &frame) const
Check whether a frame stays constant as the state of the robot model changes. This is true for any tr...
Definition: transforms.cpp:98
FixedTransformsMap transforms_map_
Definition: transforms.h:211
virtual bool canTransform(const std::string &from_frame) const
Check whether data can be transformed from a particular frame.
Definition: transforms.cpp:128
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
Definition: transforms.h:53
Main namespace for MoveIt.
Definition: exceptions.h:43
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition: logger.cpp:79