From a7b43c305e3f4c02222e5ad3df258b3c74cff8b8 Mon Sep 17 00:00:00 2001 From: Alejandro Hernandez Cordero Date: Wed, 17 Jun 2026 22:49:48 +0200 Subject: [PATCH 1/2] Move implementation from hpp to cpp Signed-off-by: Alejandro Hernandez Cordero --- tf2/CMakeLists.txt | 8 +- tf2/include/tf2/buffer_core.hpp | 27 ++--- tf2/include/tf2/convert.hpp | 29 +---- tf2/include/tf2/exceptions.hpp | 43 ++----- tf2/include/tf2/transform_storage.hpp | 29 +---- tf2/src/buffer_core.cpp | 40 +++++++ tf2/src/cache.cpp | 29 +++++ tf2/src/convert.cpp | 65 +++++++++++ tf2/src/exceptions.cpp | 83 +++++++++++++ tf2_ros/CMakeLists.txt | 5 + .../tf2_ros/async_buffer_interface.hpp | 30 ++--- tf2_ros/include/tf2_ros/buffer.hpp | 42 ++----- tf2_ros/include/tf2_ros/buffer_client.hpp | 25 +--- tf2_ros/include/tf2_ros/buffer_interface.hpp | 83 ++++--------- .../tf2_ros/create_timer_interface.hpp | 10 +- tf2_ros/include/tf2_ros/message_filter.hpp | 25 +--- tf2_ros/include/tf2_ros/qos.hpp | 18 +-- tf2_ros/src/async_buffer_interface.cpp | 64 ++++++++++ tf2_ros/src/buffer.cpp | 61 ++++++++++ tf2_ros/src/buffer_client.cpp | 25 ++++ tf2_ros/src/buffer_interface.cpp | 110 ++++++++++++++++++ tf2_ros/src/create_timer_interface.cpp | 47 ++++++++ tf2_ros/src/message_filter.cpp | 60 ++++++++++ tf2_ros/src/qos.cpp | 59 ++++++++++ 24 files changed, 735 insertions(+), 282 deletions(-) create mode 100644 tf2/src/convert.cpp create mode 100644 tf2/src/exceptions.cpp create mode 100644 tf2_ros/src/async_buffer_interface.cpp create mode 100644 tf2_ros/src/buffer_interface.cpp create mode 100644 tf2_ros/src/create_timer_interface.cpp create mode 100644 tf2_ros/src/message_filter.cpp create mode 100644 tf2_ros/src/qos.cpp diff --git a/tf2/CMakeLists.txt b/tf2/CMakeLists.txt index 74107e6b4..0f4cff8e7 100644 --- a/tf2/CMakeLists.txt +++ b/tf2/CMakeLists.txt @@ -20,7 +20,13 @@ find_package(rosidl_runtime_cpp REQUIRED) # export user definitions #CPP Libraries -add_library(tf2 src/cache.cpp src/buffer_core.cpp src/static_cache.cpp src/time.cpp) +add_library(tf2 + src/cache.cpp + src/buffer_core.cpp + src/convert.cpp + src/exceptions.cpp + src/static_cache.cpp + src/time.cpp) target_include_directories(tf2 PUBLIC "$" "$") diff --git a/tf2/include/tf2/buffer_core.hpp b/tf2/include/tf2/buffer_core.hpp index 0c2ea46a9..dc8edfb27 100644 --- a/tf2/include/tf2/buffer_core.hpp +++ b/tf2/include/tf2/buffer_core.hpp @@ -264,10 +264,10 @@ class BufferCore : public BufferCoreInterface // Tell the buffer that there are multiple threads servicing it. // This is useful for derived classes to know if they can block or not. TF2_PUBLIC - void setUsingDedicatedThread(bool value) {using_dedicated_thread_ = value;} + void setUsingDedicatedThread(bool value); // Get the state of using_dedicated_thread_ TF2_PUBLIC - bool isUsingDedicatedThread() const {return using_dedicated_thread_;} + bool isUsingDedicatedThread() const; /* Backwards compatibility section for tf::Transformer you should not use these @@ -292,36 +292,23 @@ class BufferCore : public BufferCoreInterface TF2_PUBLIC - CompactFrameID _lookupFrameNumber(const std::string & frameid_str) const - { - return lookupFrameNumber(frameid_str); - } + CompactFrameID _lookupFrameNumber(const std::string & frameid_str) const; TF2_PUBLIC - CompactFrameID _lookupOrInsertFrameNumber(const std::string & frameid_str) - { - return lookupOrInsertFrameNumber(frameid_str); - } + CompactFrameID _lookupOrInsertFrameNumber(const std::string & frameid_str); TF2_PUBLIC tf2::TF2Error _getLatestCommonTime( CompactFrameID target_frame, CompactFrameID source_frame, - TimePoint & time, std::string * error_string) const - { - std::unique_lock lock(frame_mutex_); - return getLatestCommonTime(target_frame, source_frame, time, error_string); - } + TimePoint & time, std::string * error_string) const; TF2_PUBLIC CompactFrameID _validateFrameId( const char * function_name_arg, - const std::string & frame_id) const - { - return validateFrameId(function_name_arg, frame_id); - } + const std::string & frame_id) const; /**@brief Get the duration over which this transformer will cache */ TF2_PUBLIC - tf2::Duration getCacheLength() {return cache_time_;} + tf2::Duration getCacheLength(); /** \brief Backwards compatibilityA way to see what frames have been cached * Useful for debugging diff --git a/tf2/include/tf2/convert.hpp b/tf2/include/tf2/convert.hpp index c58b5a752..64a3206a3 100644 --- a/tf2/include/tf2/convert.hpp +++ b/tf2/include/tf2/convert.hpp @@ -33,7 +33,6 @@ #ifndef TF2__CONVERT_HPP_ #define TF2__CONVERT_HPP_ -#include #include #include @@ -166,38 +165,18 @@ void convert(const A & a1, A & a2) * \param row_major A row-major array of 36 covariance values. * \return A nested array representation of 6x6 covariance values. */ -inline +TF2_PUBLIC std::array, 6> covarianceRowMajorToNested( - const std::array & row_major) -{ - std::array, 6> nested_array; - std::array::const_iterator ss = row_major.begin(); - for (std::array & dd : nested_array) { - std::copy_n(ss, dd.size(), dd.begin()); - ss += dd.size(); - } - return nested_array; -} + const std::array & row_major); /**\brief Function that converts from a nested array representation of a 6x6 * covariance matrix to a row-major representation. * \param nested_array A nested array representation of 6x6 covariance values. * \return A row-major array of 36 covariance values. */ -inline +TF2_PUBLIC std::array covarianceNestedToRowMajor( - const std::array, 6> & nested_array) -{ - std::array row_major = {}; - size_t counter = 0; - for (const auto & arr : nested_array) { - for (const double & val : arr) { - row_major[counter] = val; - counter++; - } - } - return row_major; -} + const std::array, 6> & nested_array); } // namespace tf2 #endif // TF2__CONVERT_HPP_ diff --git a/tf2/include/tf2/exceptions.hpp b/tf2/include/tf2/exceptions.hpp index e94ba07d6..edea4a86c 100644 --- a/tf2/include/tf2/exceptions.hpp +++ b/tf2/include/tf2/exceptions.hpp @@ -66,10 +66,7 @@ class TransformException : public std::runtime_error { public: TF2_PUBLIC - explicit TransformException(const std::string errorDescription) - : std::runtime_error(errorDescription) - { - } + explicit TransformException(const std::string errorDescription); }; @@ -82,10 +79,7 @@ class ConnectivityException : public TransformException { public: TF2_PUBLIC - explicit ConnectivityException(const std::string errorDescription) - : tf2::TransformException(errorDescription) - { - } + explicit ConnectivityException(const std::string errorDescription); }; @@ -101,10 +95,7 @@ class LookupException : public TransformException { public: TF2_PUBLIC - explicit LookupException(const std::string errorDescription) - : tf2::TransformException(errorDescription) - { - } + explicit LookupException(const std::string errorDescription); }; /** \brief An exception class to notify that the requested value would have required extrapolation beyond current limits. @@ -114,10 +105,7 @@ class ExtrapolationException : public TransformException { public: TF2_PUBLIC - explicit ExtrapolationException(const std::string errorDescription) - : tf2::TransformException(errorDescription) - { - } + explicit ExtrapolationException(const std::string errorDescription); }; /** \brief An exception class to notify that the requested value would have required extrapolation in the past. @@ -127,10 +115,7 @@ class BackwardExtrapolationException : public ExtrapolationException { public: TF2_PUBLIC - explicit BackwardExtrapolationException(const std::string errorDescription) - : ExtrapolationException(errorDescription) - { - } + explicit BackwardExtrapolationException(const std::string errorDescription); }; /** \brief An exception class to notify that the requested value would have required extrapolation in the future. @@ -140,10 +125,7 @@ class ForwardExtrapolationException : public ExtrapolationException { public: TF2_PUBLIC - explicit ForwardExtrapolationException(const std::string errorDescription) - : ExtrapolationException(errorDescription) - { - } + explicit ForwardExtrapolationException(const std::string errorDescription); }; /** \brief An exception class to notify that the requested value would have required extrapolation, but only zero or one data is available, so not enough for extrapolation. @@ -153,10 +135,7 @@ class NoDataForExtrapolationException : public ExtrapolationException { public: TF2_PUBLIC - explicit NoDataForExtrapolationException(const std::string errorDescription) - : ExtrapolationException(errorDescription) - { - } + explicit NoDataForExtrapolationException(const std::string errorDescription); }; /** \brief An exception class to notify that one of the arguments is invalid @@ -168,8 +147,7 @@ class InvalidArgumentException : public TransformException { public: TF2_PUBLIC - explicit InvalidArgumentException(const std::string errorDescription) - : tf2::TransformException(errorDescription) {} + explicit InvalidArgumentException(const std::string errorDescription); }; /** \brief An exception class to notify that a timeout has occurred @@ -180,10 +158,7 @@ class TimeoutException : public TransformException { public: TF2_PUBLIC - explicit TimeoutException(const std::string errorDescription) - : tf2::TransformException(errorDescription) - { - } + explicit TimeoutException(const std::string errorDescription); }; } // namespace tf2 #endif // TF2__EXCEPTIONS_HPP_ diff --git a/tf2/include/tf2/transform_storage.hpp b/tf2/include/tf2/transform_storage.hpp index ab01a6422..f0ae9ad95 100644 --- a/tf2/include/tf2/transform_storage.hpp +++ b/tf2/include/tf2/transform_storage.hpp @@ -55,37 +55,16 @@ class TransformStorage CompactFrameID child_frame_id); TF2_PUBLIC - TransformStorage(const TransformStorage & rhs) - { - *this = rhs; - } + TransformStorage(const TransformStorage & rhs); TF2_PUBLIC - TransformStorage & operator=(const TransformStorage & rhs) - { - rotation_ = rhs.rotation_; - translation_ = rhs.translation_; - stamp_ = rhs.stamp_; - frame_id_ = rhs.frame_id_; - child_frame_id_ = rhs.child_frame_id_; - return *this; - } + TransformStorage & operator=(const TransformStorage & rhs); TF2_PUBLIC - bool operator==(const TransformStorage & rhs) const - { - return (this->rotation_ == rhs.rotation_) && - (this->translation_ == rhs.translation_) && - (this->stamp_ == rhs.stamp_) && - (this->frame_id_ == rhs.frame_id_) && - (this->child_frame_id_ == rhs.child_frame_id_); - } + bool operator==(const TransformStorage & rhs) const; TF2_PUBLIC - bool operator!=(const TransformStorage & rhs) const - { - return !(*this == rhs); - } + bool operator!=(const TransformStorage & rhs) const; tf2::Quaternion rotation_; tf2::Vector3 translation_; diff --git a/tf2/src/buffer_core.cpp b/tf2/src/buffer_core.cpp index d5572f26d..c9baae5e2 100644 --- a/tf2/src/buffer_core.cpp +++ b/tf2/src/buffer_core.cpp @@ -1425,6 +1425,46 @@ void BufferCore::cancelTransformableRequest(TransformableRequestHandle handle) transformable_requests_.erase(remove_it, transformable_requests_.end()); } +void BufferCore::setUsingDedicatedThread(bool value) +{ + using_dedicated_thread_ = value; +} + +bool BufferCore::isUsingDedicatedThread() const +{ + return using_dedicated_thread_; +} + +CompactFrameID BufferCore::_lookupFrameNumber(const std::string & frameid_str) const +{ + return lookupFrameNumber(frameid_str); +} + +CompactFrameID BufferCore::_lookupOrInsertFrameNumber(const std::string & frameid_str) +{ + return lookupOrInsertFrameNumber(frameid_str); +} + +tf2::TF2Error BufferCore::_getLatestCommonTime( + CompactFrameID target_frame, CompactFrameID source_frame, + TimePoint & time, std::string * error_string) const +{ + std::unique_lock lock(frame_mutex_); + return getLatestCommonTime(target_frame, source_frame, time, error_string); +} + +CompactFrameID BufferCore::_validateFrameId( + const char * function_name_arg, + const std::string & frame_id) const +{ + return validateFrameId(function_name_arg, frame_id); +} + +tf2::Duration BufferCore::getCacheLength() +{ + return cache_time_; +} + // backwards compatibility for tf methods bool BufferCore::_frameExists(const std::string & frame_id_str) const { diff --git a/tf2/src/cache.cpp b/tf2/src/cache.cpp index 651795e90..ab21b9871 100644 --- a/tf2/src/cache.cpp +++ b/tf2/src/cache.cpp @@ -59,6 +59,35 @@ TransformStorage::TransformStorage( { } +TransformStorage::TransformStorage(const TransformStorage & rhs) +{ + *this = rhs; +} + +TransformStorage & TransformStorage::operator=(const TransformStorage & rhs) +{ + rotation_ = rhs.rotation_; + translation_ = rhs.translation_; + stamp_ = rhs.stamp_; + frame_id_ = rhs.frame_id_; + child_frame_id_ = rhs.child_frame_id_; + return *this; +} + +bool TransformStorage::operator==(const TransformStorage & rhs) const +{ + return (this->rotation_ == rhs.rotation_) && + (this->translation_ == rhs.translation_) && + (this->stamp_ == rhs.stamp_) && + (this->frame_id_ == rhs.frame_id_) && + (this->child_frame_id_ == rhs.child_frame_id_); +} + +bool TransformStorage::operator!=(const TransformStorage & rhs) const +{ + return !(*this == rhs); +} + TimeCache::TimeCache(tf2::Duration max_storage_time) : max_storage_time_(max_storage_time) {} diff --git a/tf2/src/convert.cpp b/tf2/src/convert.cpp new file mode 100644 index 000000000..96e457224 --- /dev/null +++ b/tf2/src/convert.cpp @@ -0,0 +1,65 @@ +// Copyright 2026, Open Source Robotics Foundation, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include + +#include "tf2/convert.hpp" + +namespace tf2 +{ + +std::array, 6> covarianceRowMajorToNested( + const std::array & row_major) +{ + std::array, 6> nested_array; + std::array::const_iterator ss = row_major.begin(); + for (std::array & dd : nested_array) { + std::copy_n(ss, dd.size(), dd.begin()); + ss += dd.size(); + } + return nested_array; +} + +std::array covarianceNestedToRowMajor( + const std::array, 6> & nested_array) +{ + std::array row_major = {}; + size_t counter = 0; + for (const auto & arr : nested_array) { + for (const double & val : arr) { + row_major[counter] = val; + counter++; + } + } + return row_major; +} + +} // namespace tf2 diff --git a/tf2/src/exceptions.cpp b/tf2/src/exceptions.cpp new file mode 100644 index 000000000..1a1138da7 --- /dev/null +++ b/tf2/src/exceptions.cpp @@ -0,0 +1,83 @@ +// Copyright 2026, Open Source Robotics Foundation, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include + +#include "tf2/exceptions.hpp" + +namespace tf2 +{ + +TransformException::TransformException(const std::string errorDescription) +: std::runtime_error(errorDescription) +{ +} + +ConnectivityException::ConnectivityException(const std::string errorDescription) +: tf2::TransformException(errorDescription) +{ +} + +LookupException::LookupException(const std::string errorDescription) +: tf2::TransformException(errorDescription) +{ +} + +ExtrapolationException::ExtrapolationException(const std::string errorDescription) +: tf2::TransformException(errorDescription) +{ +} + +BackwardExtrapolationException::BackwardExtrapolationException(const std::string errorDescription) +: ExtrapolationException(errorDescription) +{ +} + +ForwardExtrapolationException::ForwardExtrapolationException(const std::string errorDescription) +: ExtrapolationException(errorDescription) +{ +} + +NoDataForExtrapolationException::NoDataForExtrapolationException( + const std::string errorDescription) +: ExtrapolationException(errorDescription) +{ +} + +InvalidArgumentException::InvalidArgumentException(const std::string errorDescription) +: tf2::TransformException(errorDescription) +{ +} + +TimeoutException::TimeoutException(const std::string errorDescription) +: tf2::TransformException(errorDescription) +{ +} + +} // namespace tf2 diff --git a/tf2_ros/CMakeLists.txt b/tf2_ros/CMakeLists.txt index e391c27a5..287cb74f6 100644 --- a/tf2_ros/CMakeLists.txt +++ b/tf2_ros/CMakeLists.txt @@ -24,11 +24,16 @@ find_package(tf2_msgs REQUIRED) # tf2_ros library add_library(${PROJECT_NAME} SHARED + src/async_buffer_interface.cpp src/buffer.cpp + src/buffer_interface.cpp + src/create_timer_interface.cpp src/create_timer_ros.cpp src/transform_listener.cpp src/buffer_client.cpp src/buffer_server.cpp + src/message_filter.cpp + src/qos.cpp src/transform_broadcaster.cpp src/static_transform_broadcaster.cpp ) diff --git a/tf2_ros/include/tf2_ros/async_buffer_interface.hpp b/tf2_ros/include/tf2_ros/async_buffer_interface.hpp index 047d38e5a..8499945d3 100644 --- a/tf2_ros/include/tf2_ros/async_buffer_interface.hpp +++ b/tf2_ros/include/tf2_ros/async_buffer_interface.hpp @@ -51,28 +51,22 @@ class TransformStampedFuture : public std::shared_future(t.time_since_epoch()); - std::chrono::seconds s = - std::chrono::duration_cast(t.time_since_epoch()); - builtin_interfaces::msg::Time time_msg; - time_msg.sec = static_cast(s.count()); - time_msg.nanosec = static_cast(ns.count() % 1000000000ull); - return time_msg; -} +TF2_ROS_PUBLIC +builtin_interfaces::msg::Time toMsg(const tf2::TimePoint & t); -inline tf2::TimePoint fromMsg(const builtin_interfaces::msg::Time & time_msg) -{ - int64_t d = time_msg.sec * 1000000000ull + time_msg.nanosec; - std::chrono::nanoseconds ns(d); - return tf2::TimePoint(std::chrono::duration_cast(ns)); -} +TF2_ROS_PUBLIC +tf2::TimePoint fromMsg(const builtin_interfaces::msg::Time & time_msg); -inline builtin_interfaces::msg::Duration toMsg(const tf2::Duration & t) -{ - std::chrono::nanoseconds ns = - std::chrono::duration_cast(t); - std::chrono::seconds s = - std::chrono::duration_cast(t); - builtin_interfaces::msg::Duration duration_msg; - duration_msg.sec = static_cast(s.count()); - duration_msg.nanosec = static_cast(ns.count() % 1000000000ull); - return duration_msg; -} +TF2_ROS_PUBLIC +builtin_interfaces::msg::Duration toMsg(const tf2::Duration & t); -inline tf2::Duration fromMsg(const builtin_interfaces::msg::Duration & duration_msg) -{ - int64_t d = duration_msg.sec * 1000000000ull + duration_msg.nanosec; - std::chrono::nanoseconds ns(d); - return tf2::Duration(std::chrono::duration_cast(ns)); -} +TF2_ROS_PUBLIC +tf2::Duration fromMsg(const builtin_interfaces::msg::Duration & duration_msg); -inline double timeToSec(const builtin_interfaces::msg::Time & time_msg) -{ - auto ns = std::chrono::duration(time_msg.nanosec); - auto s = std::chrono::duration(time_msg.sec); - return (s + std::chrono::duration_cast>(ns)).count(); -} +TF2_ROS_PUBLIC +double timeToSec(const builtin_interfaces::msg::Time & time_msg); -inline tf2::TimePoint fromRclcpp(const rclcpp::Time & time) -{ - // tf2::TimePoint is a typedef to a system time point, but rclcpp::Time may be ROS time. - // Ignore that, and assume the clock used from rclcpp time points is consistent. - return tf2::TimePoint(std::chrono::nanoseconds(time.nanoseconds())); -} +TF2_ROS_PUBLIC +tf2::TimePoint fromRclcpp(const rclcpp::Time & time); -inline rclcpp::Time toRclcpp(const tf2::TimePoint & time) -{ - // tf2::TimePoint is a typedef to a system time point, but rclcpp::Time may be ROS time. - // Use whatever the default clock is. - return rclcpp::Time(std::chrono::nanoseconds(time.time_since_epoch()).count()); -} +TF2_ROS_PUBLIC +rclcpp::Time toRclcpp(const tf2::TimePoint & time); -inline tf2::Duration fromRclcpp(const rclcpp::Duration & duration) -{ - return tf2::Duration(std::chrono::nanoseconds(duration.nanoseconds())); -} +TF2_ROS_PUBLIC +tf2::Duration fromRclcpp(const rclcpp::Duration & duration); -inline rclcpp::Duration toRclcpp(const tf2::Duration & duration) -{ - return rclcpp::Duration(std::chrono::duration_cast(duration)); -} +TF2_ROS_PUBLIC +rclcpp::Duration toRclcpp(const tf2::Duration & duration); /** \brief Abstract interface for wrapping tf2::BufferCoreInterface in a ROS-based API. * Implementations include tf2_ros::Buffer and tf2_ros::BufferClient. @@ -353,9 +311,8 @@ class BufferInterface return out; } - virtual ~BufferInterface() - { - } + TF2_ROS_PUBLIC + virtual ~BufferInterface(); }; } // namespace tf2_ros diff --git a/tf2_ros/include/tf2_ros/create_timer_interface.hpp b/tf2_ros/include/tf2_ros/create_timer_interface.hpp index b7d32c982..4ee45213c 100644 --- a/tf2_ros/include/tf2_ros/create_timer_interface.hpp +++ b/tf2_ros/include/tf2_ros/create_timer_interface.hpp @@ -51,20 +51,14 @@ class CreateTimerInterfaceException : public std::runtime_error { public: TF2_ROS_PUBLIC - explicit CreateTimerInterfaceException(const std::string & errorDescription) - : std::runtime_error(errorDescription) - { - } + explicit CreateTimerInterfaceException(const std::string & errorDescription); }; class InvalidTimerHandleException : public std::runtime_error { public: TF2_ROS_PUBLIC - explicit InvalidTimerHandleException(const std::string & description) - : std::runtime_error(description) - { - } + explicit InvalidTimerHandleException(const std::string & description); }; /** diff --git a/tf2_ros/include/tf2_ros/message_filter.hpp b/tf2_ros/include/tf2_ros/message_filter.hpp index 7053d0334..9d6062a89 100644 --- a/tf2_ros/include/tf2_ros/message_filter.hpp +++ b/tf2_ros/include/tf2_ros/message_filter.hpp @@ -57,6 +57,7 @@ #include "tf2/time.hpp" #include "tf2_ros/async_buffer_interface.hpp" #include "tf2_ros/buffer.hpp" +#include "tf2_ros/visibility_control.hpp" #include "builtin_interfaces/msg/time.hpp" #include "rclcpp/rclcpp.hpp" @@ -102,24 +103,9 @@ enum FilterFailureReason } // namespace filter_failure_reasons -static std::string get_filter_failure_reason_string( - filter_failure_reasons::FilterFailureReason reason) -{ - switch (reason) { - case filter_failure_reasons::OutTheBack: - return - "the timestamp on the message is earlier than all the data in the transform cache"; - case filter_failure_reasons::EmptyFrameID: - return "the frame id of the message is empty"; - case filter_failure_reasons::NoTransformFound: - return "did not find a valid transform, this usually happens at startup ..."; - case filter_failure_reasons::QueueFull: - return "discarding message because the queue is full"; - case filter_failure_reasons::Unknown: // fallthrough - default: - return "unknown"; - } -} +TF2_ROS_PUBLIC +std::string get_filter_failure_reason_string( + filter_failure_reasons::FilterFailureReason reason); typedef filter_failure_reasons::FilterFailureReason FilterFailureReason; @@ -128,7 +114,8 @@ class MessageFilterBase public: typedef std::vector V_string; - virtual ~MessageFilterBase() {} + TF2_ROS_PUBLIC + virtual ~MessageFilterBase(); virtual void clear() = 0; virtual void setTargetFrame(const std::string & target_frame) = 0; virtual void setTargetFrames(const V_string & target_frames) = 0; diff --git a/tf2_ros/include/tf2_ros/qos.hpp b/tf2_ros/include/tf2_ros/qos.hpp index 75fa6a8eb..4727ac947 100644 --- a/tf2_ros/include/tf2_ros/qos.hpp +++ b/tf2_ros/include/tf2_ros/qos.hpp @@ -39,35 +39,25 @@ namespace tf2_ros class TF2_ROS_PUBLIC DynamicListenerQoS : public rclcpp::QoS { public: - explicit DynamicListenerQoS(size_t depth = 100) - : rclcpp::QoS(depth) {} + explicit DynamicListenerQoS(size_t depth = 100); }; class TF2_ROS_PUBLIC DynamicBroadcasterQoS : public rclcpp::QoS { public: - explicit DynamicBroadcasterQoS(size_t depth = 100) - : rclcpp::QoS(depth) {} + explicit DynamicBroadcasterQoS(size_t depth = 100); }; class TF2_ROS_PUBLIC StaticListenerQoS : public rclcpp::QoS { public: - explicit StaticListenerQoS(size_t depth = 100) - : rclcpp::QoS(depth) - { - transient_local(); - } + explicit StaticListenerQoS(size_t depth = 100); }; class TF2_ROS_PUBLIC StaticBroadcasterQoS : public rclcpp::QoS { public: - explicit StaticBroadcasterQoS(size_t depth = 1) - : rclcpp::QoS(depth) - { - transient_local(); - } + explicit StaticBroadcasterQoS(size_t depth = 1); }; } // namespace tf2_ros diff --git a/tf2_ros/src/async_buffer_interface.cpp b/tf2_ros/src/async_buffer_interface.cpp new file mode 100644 index 000000000..999f6a2fa --- /dev/null +++ b/tf2_ros/src/async_buffer_interface.cpp @@ -0,0 +1,64 @@ +// Copyright 2027, Open Source Robotics Foundation, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include + +#include "tf2_ros/async_buffer_interface.hpp" + +namespace tf2_ros +{ + +TransformStampedFuture::TransformStampedFuture(BaseType && future) noexcept +: BaseType(std::move(future)) +{ +} + +TransformStampedFuture::TransformStampedFuture(const TransformStampedFuture & ts_future) noexcept +: BaseType(ts_future), + handle_(ts_future.handle_) +{ +} + +TransformStampedFuture::TransformStampedFuture(TransformStampedFuture && ts_future) noexcept +: BaseType(std::move(ts_future)), + handle_(std::move(ts_future.handle_)) +{ +} + +void TransformStampedFuture::setHandle(const tf2::TransformableRequestHandle handle) +{ + handle_ = handle; +} + +tf2::TransformableRequestHandle TransformStampedFuture::getHandle() const +{ + return handle_; +} + +} // namespace tf2_ros diff --git a/tf2_ros/src/buffer.cpp b/tf2_ros/src/buffer.cpp index 44aaa6818..933791018 100644 --- a/tf2_ros/src/buffer.cpp +++ b/tf2_ros/src/buffer.cpp @@ -349,4 +349,65 @@ rclcpp::Logger Buffer::getLogger() const "tf2_buffer"); } +geometry_msgs::msg::TransformStamped +Buffer::lookupTransform( + const std::string & target_frame, const std::string & source_frame, + const rclcpp::Time & time, const rclcpp::Duration timeout) const +{ + return lookupTransform(target_frame, source_frame, fromRclcpp(time), fromRclcpp(timeout)); +} + +geometry_msgs::msg::TransformStamped +Buffer::lookupTransform( + const std::string & target_frame, const rclcpp::Time & target_time, + const std::string & source_frame, const rclcpp::Time & source_time, + const std::string & fixed_frame, const rclcpp::Duration timeout) const +{ + return lookupTransform( + target_frame, fromRclcpp(target_time), + source_frame, fromRclcpp(source_time), + fixed_frame, fromRclcpp(timeout)); +} + +bool +Buffer::canTransform( + const std::string & target_frame, const std::string & source_frame, + const rclcpp::Time & time, const rclcpp::Duration timeout, + std::string * errstr) const +{ + return canTransform(target_frame, source_frame, fromRclcpp(time), fromRclcpp(timeout), errstr); +} + +bool +Buffer::canTransform( + const std::string & target_frame, const rclcpp::Time & target_time, + const std::string & source_frame, const rclcpp::Time & source_time, + const std::string & fixed_frame, const rclcpp::Duration timeout, + std::string * errstr) const +{ + return canTransform( + target_frame, fromRclcpp(target_time), + source_frame, fromRclcpp(source_time), + fixed_frame, fromRclcpp(timeout), + errstr); +} + +TransformStampedFuture +Buffer::waitForTransform( + const std::string & target_frame, const std::string & source_frame, + const rclcpp::Time & time, const rclcpp::Duration & timeout, + TransformReadyCallback callback) +{ + return waitForTransform( + target_frame, source_frame, + fromRclcpp(time), fromRclcpp(timeout), + callback); +} + +void +Buffer::setCreateTimerInterface(CreateTimerInterface::SharedPtr create_timer_interface) +{ + timer_interface_ = create_timer_interface; +} + } // namespace tf2_ros diff --git a/tf2_ros/src/buffer_client.cpp b/tf2_ros/src/buffer_client.cpp index e09f0e2e6..78fb3de57 100644 --- a/tf2_ros/src/buffer_client.cpp +++ b/tf2_ros/src/buffer_client.cpp @@ -45,6 +45,31 @@ namespace tf2_ros { +LookupTransformGoalException::LookupTransformGoalException(const std::string & message) +: std::runtime_error(message) +{ +} + +GoalRejectedException::GoalRejectedException(const std::string & message) +: LookupTransformGoalException(message) +{ +} + +GoalAbortedException::GoalAbortedException(const std::string & message) +: LookupTransformGoalException(message) +{ +} + +GoalCanceledException::GoalCanceledException(const std::string & message) +: LookupTransformGoalException(message) +{ +} + +UnexpectedResultCodeException::UnexpectedResultCodeException(const std::string & message) +: LookupTransformGoalException(message) +{ +} + geometry_msgs::msg::TransformStamped BufferClient::lookupTransform( const std::string & target_frame, const std::string & source_frame, diff --git a/tf2_ros/src/buffer_interface.cpp b/tf2_ros/src/buffer_interface.cpp new file mode 100644 index 000000000..b234f9110 --- /dev/null +++ b/tf2_ros/src/buffer_interface.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2026, Open Source Robotics Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "tf2_ros/buffer_interface.hpp" + +namespace tf2_ros +{ + +builtin_interfaces::msg::Time toMsg(const tf2::TimePoint & t) +{ + std::chrono::nanoseconds ns = + std::chrono::duration_cast(t.time_since_epoch()); + std::chrono::seconds s = + std::chrono::duration_cast(t.time_since_epoch()); + builtin_interfaces::msg::Time time_msg; + time_msg.sec = static_cast(s.count()); + time_msg.nanosec = static_cast(ns.count() % 1000000000ull); + return time_msg; +} + +tf2::TimePoint fromMsg(const builtin_interfaces::msg::Time & time_msg) +{ + int64_t d = time_msg.sec * 1000000000ull + time_msg.nanosec; + std::chrono::nanoseconds ns(d); + return tf2::TimePoint(std::chrono::duration_cast(ns)); +} + +builtin_interfaces::msg::Duration toMsg(const tf2::Duration & t) +{ + std::chrono::nanoseconds ns = + std::chrono::duration_cast(t); + std::chrono::seconds s = + std::chrono::duration_cast(t); + builtin_interfaces::msg::Duration duration_msg; + duration_msg.sec = static_cast(s.count()); + duration_msg.nanosec = static_cast(ns.count() % 1000000000ull); + return duration_msg; +} + +tf2::Duration fromMsg(const builtin_interfaces::msg::Duration & duration_msg) +{ + int64_t d = duration_msg.sec * 1000000000ull + duration_msg.nanosec; + std::chrono::nanoseconds ns(d); + return tf2::Duration(std::chrono::duration_cast(ns)); +} + +double timeToSec(const builtin_interfaces::msg::Time & time_msg) +{ + auto ns = std::chrono::duration(time_msg.nanosec); + auto s = std::chrono::duration(time_msg.sec); + return (s + std::chrono::duration_cast>(ns)).count(); +} + +tf2::TimePoint fromRclcpp(const rclcpp::Time & time) +{ + // tf2::TimePoint is a typedef to a system time point, but rclcpp::Time may be ROS time. + // Ignore that, and assume the clock used from rclcpp time points is consistent. + return tf2::TimePoint(std::chrono::nanoseconds(time.nanoseconds())); +} + +rclcpp::Time toRclcpp(const tf2::TimePoint & time) +{ + // tf2::TimePoint is a typedef to a system time point, but rclcpp::Time may be ROS time. + // Use whatever the default clock is. + return rclcpp::Time(std::chrono::nanoseconds(time.time_since_epoch()).count()); +} + +tf2::Duration fromRclcpp(const rclcpp::Duration & duration) +{ + return tf2::Duration(std::chrono::nanoseconds(duration.nanoseconds())); +} + +rclcpp::Duration toRclcpp(const tf2::Duration & duration) +{ + return rclcpp::Duration(std::chrono::duration_cast(duration)); +} + +BufferInterface::~BufferInterface() +{ +} + +} // namespace tf2_ros diff --git a/tf2_ros/src/create_timer_interface.cpp b/tf2_ros/src/create_timer_interface.cpp new file mode 100644 index 000000000..f6eeb279c --- /dev/null +++ b/tf2_ros/src/create_timer_interface.cpp @@ -0,0 +1,47 @@ +// Copyright 2026, Open Source Robotics Foundation, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include + +#include "tf2_ros/create_timer_interface.hpp" + +namespace tf2_ros +{ + +CreateTimerInterfaceException::CreateTimerInterfaceException(const std::string & errorDescription) +: std::runtime_error(errorDescription) +{ +} + +InvalidTimerHandleException::InvalidTimerHandleException(const std::string & description) +: std::runtime_error(description) +{ +} + +} // namespace tf2_ros diff --git a/tf2_ros/src/message_filter.cpp b/tf2_ros/src/message_filter.cpp new file mode 100644 index 000000000..88f6be254 --- /dev/null +++ b/tf2_ros/src/message_filter.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2026, Open Source Robotics Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "tf2_ros/message_filter.hpp" + +namespace tf2_ros +{ + +std::string get_filter_failure_reason_string( + filter_failure_reasons::FilterFailureReason reason) +{ + switch (reason) { + case filter_failure_reasons::OutTheBack: + return + "the timestamp on the message is earlier than all the data in the transform cache"; + case filter_failure_reasons::EmptyFrameID: + return "the frame id of the message is empty"; + case filter_failure_reasons::NoTransformFound: + return "did not find a valid transform, this usually happens at startup ..."; + case filter_failure_reasons::QueueFull: + return "discarding message because the queue is full"; + case filter_failure_reasons::Unknown: // fallthrough + default: + return "unknown"; + } +} + +MessageFilterBase::~MessageFilterBase() +{ +} + +} // namespace tf2_ros diff --git a/tf2_ros/src/qos.cpp b/tf2_ros/src/qos.cpp new file mode 100644 index 000000000..b665b3095 --- /dev/null +++ b/tf2_ros/src/qos.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2026, Open Source Robotics Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "tf2_ros/qos.hpp" + +namespace tf2_ros +{ + +DynamicListenerQoS::DynamicListenerQoS(size_t depth) +: rclcpp::QoS(depth) +{ +} + +DynamicBroadcasterQoS::DynamicBroadcasterQoS(size_t depth) +: rclcpp::QoS(depth) +{ +} + +StaticListenerQoS::StaticListenerQoS(size_t depth) +: rclcpp::QoS(depth) +{ + transient_local(); +} + +StaticBroadcasterQoS::StaticBroadcasterQoS(size_t depth) +: rclcpp::QoS(depth) +{ + transient_local(); +} + +} // namespace tf2_ros From 69988b7d39a724db187c4e18aed6aaa177a5f478 Mon Sep 17 00:00:00 2001 From: Alejandro Hernandez Cordero Date: Fri, 19 Jun 2026 16:51:12 +0200 Subject: [PATCH 2/2] make linters happy Signed-off-by: Alejandro Hernandez Cordero --- tf2/src/convert.cpp | 2 +- tf2/src/exceptions.cpp | 2 +- tf2_ros/src/buffer_interface.cpp | 2 +- tf2_ros/src/message_filter.cpp | 2 +- tf2_ros/src/qos.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tf2/src/convert.cpp b/tf2/src/convert.cpp index 96e457224..490d584c6 100644 --- a/tf2/src/convert.cpp +++ b/tf2/src/convert.cpp @@ -1,4 +1,4 @@ -// Copyright 2026, Open Source Robotics Foundation, Inc. +// Copyright 2026, Open Source Robotics Foundation, Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/tf2/src/exceptions.cpp b/tf2/src/exceptions.cpp index 1a1138da7..78a5e7a1e 100644 --- a/tf2/src/exceptions.cpp +++ b/tf2/src/exceptions.cpp @@ -1,4 +1,4 @@ -// Copyright 2026, Open Source Robotics Foundation, Inc. +// Copyright 2026, Open Source Robotics Foundation, Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/tf2_ros/src/buffer_interface.cpp b/tf2_ros/src/buffer_interface.cpp index b234f9110..9d04f4c77 100644 --- a/tf2_ros/src/buffer_interface.cpp +++ b/tf2_ros/src/buffer_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2026, Open Source Robotics Foundation, Inc. + * Copyright 2026, Open Source Robotics Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tf2_ros/src/message_filter.cpp b/tf2_ros/src/message_filter.cpp index 88f6be254..2032427d4 100644 --- a/tf2_ros/src/message_filter.cpp +++ b/tf2_ros/src/message_filter.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2026, Open Source Robotics Foundation, Inc. + * Copyright 2026, Open Source Robotics Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tf2_ros/src/qos.cpp b/tf2_ros/src/qos.cpp index b665b3095..b74bc6c1c 100644 --- a/tf2_ros/src/qos.cpp +++ b/tf2_ros/src/qos.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2026, Open Source Robotics Foundation, Inc. + * Copyright 2026, Open Source Robotics Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without