NVIDIA Holoscan SDK v3.4.0

Program Listing for File pose2.hpp

Return to documentation for file (include/holoscan/pose_tree/math/pose2.hpp)

Copy
Copied!
            

/* * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef HOLOSCAN_POSE_TREE_MATH_POSE2_HPP #define HOLOSCAN_POSE_TREE_MATH_POSE2_HPP #include <cmath> #include "holoscan/pose_tree/math/so2.hpp" #include "holoscan/pose_tree/math/types.hpp" namespace holoscan { template <typename K> struct Pose2 { using Scalar = K; static constexpr int kDimension = 2; SO2<K> rotation; Vector2<K> translation; static Pose2 identity() { return Pose2{SO2<K>::identity(), Vector2<K>::Zero()}; } static Pose2 from_translation(const Vector2<K>& translation) { return Pose2{SO2<K>::identity(), translation}; } static Pose2 from_translation(K x, K y) { return Pose2{SO2<K>::identity(), Vector2<K>{x, y}}; } static Pose2 from_rotation(const K angle) { return Pose2{SO2<K>::from_angle(angle), Vector2<K>::Zero()}; } static Pose2 from_xy_a(K px, K py, K angle) { return Pose2{SO2<K>::from_angle(angle), Vector2<K>{px, py}}; } static Pose2 from_matrix(const Matrix3<K>& matrix) { return Pose2{SO2<K>::from_normalized(matrix(0, 0), matrix(1, 0)), Vector2<K>(matrix(0, 2), matrix(1, 2))}; } Pose2 inverse() const { const SO2<K> inv = rotation.inverse(); return Pose2{inv, -(inv * translation)}; } Matrix3<K> matrix() const { Matrix3<K> ret; ret << rotation.cos(), -rotation.sin(), translation.x(), rotation.sin(), rotation.cos(), translation.y(), K(0), K(0), K(1); return ret; } template <typename S, typename std::enable_if_t<!std::is_same<S, K>::value, int> = 0> Pose2<S> cast() const { return Pose2<S>{rotation.template cast<S>(), translation.template cast<S>()}; } template <typename S, typename std::enable_if_t<std::is_same<S, K>::value, int> = 0> const Pose2& cast() const { // Nothing to do as the type does not change return *this; } friend Pose2 operator*(const Pose2& lhs, const Pose2& rhs) { return Pose2{lhs.rotation * rhs.rotation, lhs.rotation * rhs.translation + lhs.translation}; } friend Vector2<K> operator*(const Pose2& pose, const Vector2<K>& vec) { return pose.rotation * vec + pose.translation; } Pose2 pow(K exponent) const { const K angle = rotation.angle(); const K half_angle = angle / K(2); const K csc_sin = is_almost_zero(angle) ? exponent * (K(1) + (K(1) - exponent * exponent) * half_angle * half_angle / K(6)) : std::sin(half_angle * exponent) / std::sin(half_angle); const SO2<K> rot = SO2<K>::from_angle(half_angle * (exponent - K(1))); return Pose2{SO2<K>::from_angle(angle * exponent), csc_sin * (rot * translation)}; } }; using Pose2d = Pose2<double>; using Pose2f = Pose2<float>; template <typename K> Pose2<K> pose2_exp(const Vector3<K>& tangent) { return Pose2<K>{SO2<K>::from_angle(tangent[2]), tangent.template head<2>()}; } template <typename K> Vector3<K> pose2_log(const Pose2<K>& pose) { return Vector3<K>{pose.translation.x(), pose.translation.y(), pose.rotation.angle()}; } template <typename K> bool is_pose_almost_identity(const Pose2<K>& pose) { return is_almost_zero(pose.translation.x()) && is_almost_zero(pose.translation.y()) && is_almost_one(pose.rotation.cos()); } template <typename K> Vector2<K> pose2_magnitude(const Pose2<K>& pose) { return {pose.translation.norm(), std::abs(pose.rotation.angle())}; } } // namespace holoscan #endif/* HOLOSCAN_POSE_TREE_MATH_POSE2_HPP */

© Copyright 2022-2025, NVIDIA. Last updated on Jul 1, 2025.