1 #ifndef TRANSFORMER_HPP
2 #define TRANSFORMER_HPP
13 template <
typename msg_t>
14 std_msgs::Header Transformer::getHeader(
const msg_t& msg)
19 template <
typename pt_t>
20 std_msgs::Header Transformer::getHeader(
const pcl::PointCloud<pt_t>& cloud)
23 pcl_conversions::fromPCL(cloud.header, ret);
31 template <
typename msg_t>
32 void Transformer::setHeader(msg_t& msg,
const std_msgs::Header& header)
37 template <
typename pt_t>
38 void Transformer::setHeader(pcl::PointCloud<pt_t>& cloud,
const std_msgs::Header& header)
40 pcl_conversions::toPCL(header, cloud.header);
48 T Transformer::copyChangeFrame(
const T& what,
const std::string& frame_id)
51 if constexpr (has_header_member_v<T>)
53 std_msgs::Header new_header = getHeader(what);
54 new_header.frame_id = frame_id;
55 setHeader(ret, new_header);
65 std::optional<T> Transformer::transformImpl(
const geometry_msgs::TransformStamped& tf,
const T& what)
68 const std::string to_frame =
frame_to(tf);
70 if (from_frame == to_frame)
71 return copyChangeFrame(what, from_frame);
73 const std::string latlon_frame_name = resolveFrameImpl(LATLON_ORIGIN);
77 if constexpr (UTMLL_exists_v<Transformer, T>)
80 if (from_frame == latlon_frame_name)
82 const std::optional<T> tmp = LLtoUTM(what, getFramePrefix(from_frame));
85 return doTransform(tmp.value(), tf);
88 else if (to_frame == latlon_frame_name)
90 const std::optional<T> tmp = doTransform(what, tf);
93 return UTMtoLL(tmp.value(), getFramePrefix(to_frame));
99 if (from_frame == latlon_frame_name || to_frame == latlon_frame_name)
101 ROS_ERROR_STREAM_THROTTLE(1.0,
"[" << node_name_ <<
"]: Transformer: cannot transform message of this type (" <<
typeid(T).name() <<
") to/from latitude/longitude coordinates!");
107 return doTransform(what, tf);
115 std::optional<T> Transformer::doTransform(
const T& what,
const geometry_msgs::TransformStamped& tf)
120 tf2::doTransform(what, result, tf);
123 catch (tf2::TransformException& ex)
125 ROS_WARN_THROTTLE(1.0,
"[%s]: Transformer: Error during transform from \"%s\" frame to \"%s\" frame.\n\tMSG: %s", node_name_.c_str(),
frame_from(tf).c_str(),
140 const std_msgs::Header orig_header = getHeader(what);
141 return transformSingle(orig_header.frame_id, what, to_frame_raw, orig_header.stamp);
145 std::optional<T>
Transformer::transformSingle(
const std::string& from_frame_raw,
const T& what,
const std::string& to_frame_raw,
const ros::Time& time_stamp)
147 std::scoped_lock lck(mutex_);
151 ROS_ERROR_THROTTLE(1.0,
"[%s]: Transformer: cannot transform, not initialized", node_name_.c_str());
155 const std::string from_frame = resolveFrameImpl(from_frame_raw);
156 const std::string to_frame = resolveFrameImpl(to_frame_raw);
157 const std::string latlon_frame = resolveFrameImpl(LATLON_ORIGIN);
160 const auto tf_opt = getTransformImpl(from_frame, to_frame, time_stamp, latlon_frame);
161 if (!tf_opt.has_value())
163 const geometry_msgs::TransformStamped& tf = tf_opt.value();
166 const geometry_msgs::TransformStamped tf_resolved = create_transform(from_frame, to_frame, tf.header.stamp, tf.transform);
167 return transformImpl(tf_resolved, what);
177 std::scoped_lock lck(mutex_);
181 ROS_ERROR_THROTTLE(1.0,
"[%s]: Transformer: cannot transform, not initialized", node_name_.c_str());
185 const std::string from_frame = resolveFrameImpl(
frame_from(tf));
186 const std::string to_frame = resolveFrameImpl(
frame_to(tf));
187 const geometry_msgs::TransformStamped tf_resolved = create_transform(from_frame, to_frame, tf.header.stamp, tf.transform);
189 return transformImpl(tf_resolved, what);
196 #endif // TRANSFORMER_HPP