17#include <rclcpp/rclcpp.hpp>
19#include <tf2_ros/transform_listener.h>
20#include <tf2_ros/buffer.h>
21#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
23#include <mrs_msgs/msg/reference_stamped.hpp>
24#include <geometry_msgs/msg/pose_stamped.hpp>
25#include <geometry_msgs/msg/vector3_stamped.hpp>
27#include <std_msgs/msg/header.hpp>
31#ifdef PCL_SPECIALIZATION
32#include <pcl_ros/point_cloud.hpp>
33#include <pcl_ros/transforms.hpp>
34#include <pcl_conversions/pcl_conversions.h>
38#include <experimental/type_traits>
42#ifdef PCL_SPECIALIZATION
47 template <
typename pt_t>
48 void doTransform(
const pcl::PointCloud<pt_t>& cloud_in, pcl::PointCloud<pt_t>& cloud_out,
const geometry_msgs::msg::TransformStamped& transform)
50 pcl_ros::transformPointCloud(cloud_in, cloud_out, transform.transform);
51 pcl_conversions::toPCL(transform.header.stamp, cloud_out.header.stamp);
52 cloud_out.header.frame_id = transform.header.frame_id;
62 static const std::string UTM_ORIGIN =
"utm_origin";
63 static const std::string LATLON_ORIGIN =
"latlon_origin";
117 Transformer(
const rclcpp::Node::SharedPtr& node,
const rclcpp::Clock::SharedPtr& clock,
118 const rclcpp::Duration& cache_time = rclcpp::Duration(tf2::BUFFER_CORE_DEFAULT_CACHE_TIME),
const rclcpp::QoS& qos = rclcpp::ServicesQoS());
147 std::scoped_lock lck(mutex_);
148 default_frame_id_ = frame_id;
170 std::scoped_lock lck(mutex_);
174 prefix_ = prefix +
"/";
191 void setLatLon(
const double lat,
const double lon);
208 std::scoped_lock lck(mutex_);
209 lookup_timeout_ = timeout;
228 std::scoped_lock lck(mutex_);
229 retry_lookup_newest_ = retry;
245 std::scoped_lock lck(mutex_);
265 std::scoped_lock lck(mutex_);
266 return resolveFrameImpl(frame_id);
281 [[nodiscard]] std::optional<T>
transformSingle(
const T& what,
const std::string& to_frame);
294 [[nodiscard]] std::optional<std::shared_ptr<T>>
transformSingle(
const std::shared_ptr<T>& what,
const std::string& to_frame)
310 [[nodiscard]] std::optional<std::shared_ptr<T>>
transformSingle(
const std::shared_ptr<const T>& what,
const std::string& to_frame)
313 if (ret == std::nullopt)
316 return std::make_shared<T>(std::move(ret.value()));
332 [[nodiscard]] std::optional<T>
transformSingle(
const std::string& from_frame,
const T& what,
const std::string& to_frame,
333 const rclcpp::Time& time_stamp = rclcpp::Time(0));
348 [[nodiscard]] std::optional<std::shared_ptr<T>>
transformSingle(
const std::string& from_frame,
const std::shared_ptr<T>& what,
const std::string& to_frame,
349 const rclcpp::Time& time_stamp = rclcpp::Time(0))
351 return transformSingle(from_frame, std::shared_ptr<const T>(what), to_frame, time_stamp);
367 [[nodiscard]] std::optional<std::shared_ptr<T>>
transformSingle(
const std::string& from_frame,
const std::shared_ptr<const T>& what,
368 const std::string& to_frame,
const rclcpp::Time& time_stamp = rclcpp::Time(0))
371 if (ret == std::nullopt)
374 return std::make_shared<T>(std::move(ret.value()));
390 [[nodiscard]] std::optional<T>
transform(
const T& what,
const geometry_msgs::msg::TransformStamped& tf);
403 [[nodiscard]] std::optional<std::shared_ptr<T>>
transform(
const std::shared_ptr<const T>& what,
const geometry_msgs::msg::TransformStamped& tf)
406 if (ret == std::nullopt)
409 return std::make_shared<T>(std::move(ret.value()));
423 [[nodiscard]] std::optional<std::shared_ptr<T>>
transform(
const std::shared_ptr<T>& what,
const geometry_msgs::msg::TransformStamped& tf)
425 return transform(std::shared_ptr<const T>(what), tf);
441 [[nodiscard]] std::optional<Eigen::Vector3d>
transformAsVector(
const Eigen::Vector3d& what,
const geometry_msgs::msg::TransformStamped& tf);
455 [[nodiscard]] std::optional<Eigen::Vector3d>
transformAsVector(
const std::string& from_frame,
const Eigen::Vector3d& what,
const std::string& to_frame,
456 const rclcpp::Time& time_stamp = rclcpp::Time(0));
470 [[nodiscard]] std::optional<Eigen::Vector3d>
transformAsPoint(
const Eigen::Vector3d& what,
const geometry_msgs::msg::TransformStamped& tf);
484 [[nodiscard]] std::optional<Eigen::Vector3d>
transformAsPoint(
const std::string& from_frame,
const Eigen::Vector3d& what,
const std::string& to_frame,
485 const rclcpp::Time& time_stamp = rclcpp::Time(0));
499 [[nodiscard]] std::optional<geometry_msgs::msg::TransformStamped>
getTransform(
const std::string& from_frame,
const std::string& to_frame,
500 const rclcpp::Time& time_stamp = rclcpp::Time(0));
517 [[nodiscard]] std::optional<geometry_msgs::msg::TransformStamped>
getTransform(
const std::string& from_frame,
const rclcpp::Time& from_stamp,
518 const std::string& to_frame,
const rclcpp::Time& to_stamp,
519 const std::string& fixed_frame);
529 bool initialized_ =
false;
530 rclcpp::Node::SharedPtr node_;
532 std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
533 std::unique_ptr<tf2_ros::TransformListener> tf_listener_ptr_;
536 std::string default_frame_id_ =
"";
537 std::string prefix_ =
"";
539 rclcpp::Duration lookup_timeout_ = rclcpp::Duration(0, 0);
540 bool retry_lookup_newest_ =
false;
542 bool got_utm_zone_ =
false;
543 std::array<char, 10> utm_zone_ = {};
546 std::string getFramePrefix(
const std::string& frame_id);
549 std::optional<T> transformImpl(
const geometry_msgs::msg::TransformStamped& tf,
const T& what);
550 std::optional<mrs_msgs::msg::ReferenceStamped> transformImpl(
const geometry_msgs::msg::TransformStamped& tf,
const mrs_msgs::msg::ReferenceStamped& what);
551 std::optional<Eigen::Vector3d> transformImpl(
const geometry_msgs::msg::TransformStamped& tf,
const Eigen::Vector3d& what);
553 [[nodiscard]] std::optional<geometry_msgs::msg::TransformStamped> getTransformImpl(
const std::string& from_frame,
const std::string& to_frame,
554 const rclcpp::Time& time_stamp,
const std::string& latlon_frame);
556 [[nodiscard]] std::optional<geometry_msgs::msg::TransformStamped> getTransformImpl(
const std::string& from_frame,
const rclcpp::Time& from_stamp,
557 const std::string& to_frame,
const rclcpp::Time& to_stamp,
558 const std::string& fixed_frame,
const std::string& latlon_frame);
560 std::string resolveFrameImpl(
const std::string& frame_id);
563 std::optional<T> doTransform(
const T& what,
const geometry_msgs::msg::TransformStamped& tf);
577 static constexpr const std::string&
frame_from(
const geometry_msgs::msg::TransformStamped& msg)
579 return msg.child_frame_id;
590 static constexpr std::string&
frame_from(geometry_msgs::msg::TransformStamped& msg)
592 return msg.child_frame_id;
601 static constexpr const std::string&
frame_to(
const geometry_msgs::msg::TransformStamped& msg)
603 return msg.header.frame_id;
614 static constexpr std::string&
frame_to(geometry_msgs::msg::TransformStamped& msg)
616 return msg.header.frame_id;
625 static geometry_msgs::msg::TransformStamped
inverse(
const geometry_msgs::msg::TransformStamped& msg)
628 tf2::fromMsg(msg.transform, tf2);
630 return create_transform(
frame_to(msg),
frame_from(msg), msg.header.stamp, tf2::toMsg(tf2));
636 static geometry_msgs::msg::TransformStamped create_transform(
const std::string& from_frame,
const std::string& to_frame,
const rclcpp::Time& time_stamp)
638 geometry_msgs::msg::TransformStamped ret;
641 ret.header.stamp = time_stamp;
645 static geometry_msgs::msg::TransformStamped create_transform(
const std::string& from_frame,
const std::string& to_frame,
const rclcpp::Time& time_stamp,
646 const geometry_msgs::msg::Transform& tf)
648 geometry_msgs::msg::TransformStamped ret;
651 ret.header.stamp = time_stamp;
660 template <
typename T>
661 using has_header_member_chk =
decltype(std::declval<T&>().header);
663 template <
typename T>
664 static constexpr bool has_header_member_v = std::experimental::is_detected<has_header_member_chk, T>::value;
666 template <
typename msg_t>
667 std_msgs::msg::Header getHeader(
const msg_t& msg);
669#ifdef PCL_SPECIALIZATION
670 template <
typename pt_t>
671 std_msgs::msg::Header getHeader(
const pcl::PointCloud<pt_t>& cloud);
673 template <
typename pt_t>
674 void setHeader(pcl::PointCloud<pt_t>& cloud,
const std_msgs::msg::Header& header);
677 template <
typename msg_t>
678 void setHeader(msg_t& msg,
const std_msgs::msg::Header& header);
680 template <
typename T>
681 T copyChangeFrame(
const T& what,
const std::string& frame_id);
686 geometry_msgs::msg::Point LLtoUTM(
const geometry_msgs::msg::Point& what,
const std::string& prefix);
687 geometry_msgs::msg::PointStamped LLtoUTM(
const geometry_msgs::msg::PointStamped& what,
const std::string& prefix);
688 geometry_msgs::msg::Pose LLtoUTM(
const geometry_msgs::msg::Pose& what,
const std::string& prefix);
689 geometry_msgs::msg::PoseStamped LLtoUTM(
const geometry_msgs::msg::PoseStamped& what,
const std::string& prefix);
691 std::optional<geometry_msgs::msg::Point> UTMtoLL(
const geometry_msgs::msg::Point& what,
const std::string& prefix);
692 std::optional<geometry_msgs::msg::PointStamped> UTMtoLL(
const geometry_msgs::msg::PointStamped& what,
const std::string& prefix);
693 std::optional<geometry_msgs::msg::Pose> UTMtoLL(
const geometry_msgs::msg::Pose& what,
const std::string& prefix);
694 std::optional<geometry_msgs::msg::PoseStamped> UTMtoLL(
const geometry_msgs::msg::PoseStamped& what,
const std::string& prefix);
697 template <
class Class,
typename Message>
698 using UTMLL_method_chk =
decltype(std::declval<Class>().UTMtoLL(std::declval<const Message&>(),
""));
700 template <
class Class,
typename Message>
701 using LLUTM_method_chk =
decltype(std::declval<Class>().LLtoUTM(std::declval<const Message&>(),
""));
703 template <
class Class,
typename Message>
704 static constexpr bool UTMLL_exists_v =
705 std::experimental::is_detected<UTMLL_method_chk, Class, Message>::value && std::experimental::is_detected<LLUTM_method_chk, Class, Message>::value;
713#ifndef TRANSFORMER_HPP
714#include <mrs_lib/impl/transformer.hpp>
Defines useful geometry utilities and functions.
All mrs_lib functions, classes, variables and definitions are contained in this namespace.
Definition attitude_converter.h:24