moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
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>
44
45namespace moveit
46{
47namespace core
48{
49namespace
50{
51rclcpp::Logger getLogger()
52{
53 return moveit::getLogger("moveit.core.transforms");
54}
55} // namespace
56
57Transforms::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
70bool 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
77Transforms::~Transforms() = default;
78
79const std::string& Transforms::getTargetFrame() const
80{
81 return target_frame_;
82}
83
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
98bool 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
110const 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
128bool 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
140void 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
151void 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
172void 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
178void 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)
const std::string & getTargetFrame() const
Get the planning frame corresponding to this set of transforms.
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...
Transforms(const Transforms &)=delete
Transforms cannot be copy-constructed.
virtual ~Transforms()
Destructor.
void setTransform(const Eigen::Isometry3d &t, const std::string &from_frame)
Set a transform in the transform tree (adding it if necessary)
const FixedTransformsMap & getAllTransforms() const
Return all the transforms.
virtual const Eigen::Isometry3d & getTransform(const std::string &from_frame) const
Get transform for from_frame (w.r.t target frame)
void copyTransforms(std::vector< geometry_msgs::msg::TransformStamped > &transforms) const
Get a vector of all the transforms as ROS messages.
void setAllTransforms(const FixedTransformsMap &transforms)
Set all the transforms: a map from string names of frames to corresponding Eigen::Isometry3d (w....
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...
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.
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