Program Listing for File transform.h
↰ Return to documentation for file (/tmp/ws/src/marti_common/swri_transform_util/include/swri_transform_util/transform.h
)
// *****************************************************************************
//
// Copyright (c) 2014, Southwest Research Institute® (SwRI®)
// 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 Southwest Research Institute® (SwRI®) 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 <COPYRIGHT HOLDER> 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.
//
// *****************************************************************************
#ifndef TRANSFORM_UTIL_TRANSFORM_H_
#define TRANSFORM_UTIL_TRANSFORM_H_
#include <boost/shared_ptr.hpp>
#include <geometry_msgs/msg/transform_stamped.hpp>
#ifdef USE_TF2_H_FILES
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#else
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
#endif
#include <rclcpp/rclcpp.hpp>
#include <tf2/transform_datatypes.h>
#include <tf2/LinearMath/Vector3.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2/LinearMath/Transform.h>
namespace swri_transform_util
{
class StampInterface
{
public:
virtual tf2::TimePoint GetStamp() const = 0;
virtual void SetStamp(const tf2::TimePoint&) = 0;
};
class StampedTransformStampInterface : virtual public StampInterface
{
public:
tf2::TimePoint GetStamp() const final
{
return tf2_ros::fromMsg(transform_.header.stamp);
}
void SetStamp(const tf2::TimePoint& time) final
{
transform_.header.stamp = tf2_ros::toMsg(time);
};
tf2::Stamped<tf2::Transform> GetStampedTransform() const
{
tf2::Stamped<tf2::Transform> tf;
tf2::fromMsg(transform_, tf);
return tf;
}
protected:
geometry_msgs::msg::TransformStamped transform_;
};
class Tf2StampStampInterface : virtual public StampInterface
{
public:
tf2::TimePoint GetStamp() const final
{
return stamp_;
}
void SetStamp(const tf2::TimePoint& time) final
{
stamp_ = time;
};
protected:
tf2::TimePoint stamp_;
};
class TransformImpl : virtual public StampInterface
{
public:
explicit TransformImpl(const rclcpp::Logger& logger = rclcpp::get_logger("swri_transform_util::TransformImpl")) :
logger_(logger)
{};
virtual ~TransformImpl() = default;
virtual void Transform(
const tf2::Vector3& v_in, tf2::Vector3& v_out) const = 0;
virtual tf2::Quaternion GetOrientation() const
{
tf2::Vector3 offset;
Transform(tf2::Vector3(1, 0, 0), offset);
tf2::Vector3 origin;
Transform(tf2::Vector3(0, 0, 0), origin);
tf2::Vector3 vector = offset - origin;
// Use the "half-way quaternion method" of summing and normalizing a
// quaternion with twice the rotation between the vector and the x-axis and
// the zero rotation.
tf2::Vector3 cross = tf2::Vector3(1, 0, 0).cross(vector);
double w = vector.length() + tf2::Vector3(1, 0, 0).dot(vector);
return tf2::Quaternion(cross.x(), cross.y(), cross.z(), w).normalized();
}
virtual std::shared_ptr<TransformImpl> Inverse() const = 0;
protected:
rclcpp::Logger logger_;
};
typedef std::shared_ptr<TransformImpl> TransformImplPtr;
class Transform
{
public:
Transform();
explicit Transform(const tf2::Transform& transform);
explicit Transform(const tf2::Stamped<tf2::Transform>& transform);
explicit Transform(std::shared_ptr<TransformImpl> transform);
Transform& operator=(const tf2::Transform transform);
Transform& operator=(std::shared_ptr<TransformImpl> transform);
tf2::Vector3 operator()(const tf2::Vector3& v) const;
tf2::Vector3 operator*(const tf2::Vector3& v) const;
tf2::Quaternion operator*(const tf2::Quaternion& q) const;
tf2::Transform GetTF() const;
Transform Inverse() const;
tf2::Vector3 GetOrigin() const;
tf2::Quaternion GetOrientation() const;
tf2::TimePoint GetStamp() { return transform_->GetStamp(); }
private:
std::shared_ptr<TransformImpl> transform_;
};
class IdentityTransform : public TransformImpl, public Tf2StampStampInterface
{
public:
IdentityTransform() { Tf2StampStampInterface::SetStamp(tf2::TimePointZero); }
void Transform(const tf2::Vector3& v_in, tf2::Vector3& v_out) const override;
TransformImplPtr Inverse() const override;
};
class TfTransform : public TransformImpl, public Tf2StampStampInterface
{
public:
explicit TfTransform(const tf2::Transform& transform);
explicit TfTransform(const tf2::Stamped<tf2::Transform>& transform);
void Transform(const tf2::Vector3& v_in, tf2::Vector3& v_out) const override;
tf2::Quaternion GetOrientation() const override;
TransformImplPtr Inverse() const override;
protected:
tf2::Transform transform_;
};
}
#endif // TRANSFORM_UTIL_TRANSFORM_H_