Program Listing for File HingeBase.h

Program Listing for File HingeBase.h#

Return to documentation for file (include/Karana/SOADyn/HingeBase.h)

/*
 * Copyright (c) 2024-2026 Karana Dynamics Pty Ltd. All rights reserved.
 *
 * NOTICE TO USER:
 *
 * This source code and/or documentation (the "Licensed Materials") is
 * the confidential and proprietary information of Karana Dynamics Inc.
 * Use of these Licensed Materials is governed by the terms and conditions
 * of a separate software license agreement between Karana Dynamics and the
 * Licensee ("License Agreement"). Unless expressly permitted under that
 * agreement, any reproduction, modification, distribution, or disclosure
 * of the Licensed Materials, in whole or in part, to any third party
 * without the prior written consent of Karana Dynamics is strictly prohibited.
 *
 * THE LICENSED MATERIALS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
 * KARANA DYNAMICS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL KARANA DYNAMICS BE LIABLE FOR ANY DAMAGES WHATSOEVER,
 * INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR USE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, WHETHER IN CONTRACT, TORT,
 * OR OTHERWISE ARISING OUT OF OR IN CONNECTION WITH THE LICENSED MATERIALS.
 *
 * U.S. Government End Users: The Licensed Materials are a "commercial item"
 * as defined at 48 C.F.R. 2.101, and are provided to the U.S. Government
 * only as a commercial end item under the terms of this license.
 *
 * Any use of the Licensed Materials in individual or commercial software must
 * include, in the user documentation and internal source code comments,
 * this Notice, Disclaimer, and U.S. Government Use Provision.
 */

/**
 * @file
 * @brief Contains the declarations for the HingeBase class.
 */

#pragma once

#include "Karana/KCore/RegistryList.h"
#include "Karana/Math/UnitQuaternion.h"
#include "Karana/SOADyn/Defs.h"
#include "Karana/SOADyn/SubhingeBase.h"

namespace Karana::Dynamics {

    namespace kc = Karana::Core;
    namespace km = Karana::Math;

    class SubhingeBase;

    /**
     * @class HingeBase
     * @brief Represents the base class for articulation hinges
     *
     * This is the abstract base class for hinge containers for
     * PhysicalHinge and CompoundHinge classes that define articulation
     * for bodies. See \sref{body_hinge_sec} section for more discussion
     * on hinges.
     */
    class HingeBase {

        // for access to _subhinges_usage_map
        friend class HingeOnode;
        friend class SubTree;

        // for access to _subhinges_list
        friend class CompoundSubhinge;
        friend class CompoundBody;

      public:
        /**
         * @brief Return the list of SubhingeBase::SubhingeType subhinge types for a known hinge
         * type
         *
         * A hinge is a container for a list of subhinges. This method
         * returns the list of subhinge types for a known hinge type.
         *
         * @param htype the hinge type
         * @return list of subhinge types
         */
        static std::vector<SubhingeType> getSubhingeTypes(HingeType htype);

        /**
         * @brief Constructs a HingeBase.

         * @param htype the hinge type
         */
        HingeBase(HingeType htype)
            : _hinge_type(htype) {}

        /**
         * @brief Returns the type string of the HingeBase.
         *
         * @param brief if true, return the short form of the class type name, else the full type
         *        name
         * @return The type string.
         */
        virtual std::string_view typeString(bool brief) const noexcept = 0;

        /**
         * @brief HingeBase destructor.
         */
        virtual ~HingeBase(){};

        /**
         * @brief Return the name of the hinge instance
         *
         * @return the hinge name
         */
        virtual std::string_view name() const = 0;

        /**
         * @brief Return the SubhingeBase subhinge instance at the specified index
         *
         * @param index the subhinge index
         * @return the subhinge object
         */
        kc::ks_ptr<SubhingeBase> subhinge(size_t index) const;

        /**
         * @brief Return the number of subhinges in the hinge
         * @return the number of subhinges
         */
        size_t nSubhinges() const { return _subhinges_list.size(); }

        /**
         * @brief Return the total nU dofs from all the subhinges
         *
         * @returns the total number of U coordinates across the subhinges
         */
        size_t nU() const;

        /** @brief Return the HingeType hinge type for this hinge.
         *  @returns The hinge type used by this body.
         */
        HingeType hingeType() const { return _hinge_type; }

        /**
         * @brief Helper method to return the string name for a HingeType hinge type
         * @param htype the hinge type
         * @return the hinge type as a string
         */
        static std::string hingeTypeString(HingeType htype);

      public:
        /**
         * @brief Return the CoordData for the hinge's list of subhinges
         *
         * @return the CoordData for the subhinges
         */
        const kc::ks_ptr<CoordData> &coordData() const { return _hinge_coord_data; }

        /**
         * @brief Return the list of SubhingeBase subhinges
         * @return the list of subhinges
         */
        const kc::RegistryList<SubhingeBase> &subhinges() const { return _subhinges_list; }

        /**
         * @brief The overall pframe coordinate map matrix for the hinge
         *
         * Return the overall 6xnU() coord map matrix for the hinge in the
         * pframe frame from all of its subhinges. Note that the matrix will
         * be configuration dependent when there are multiple subhinges. This
         * method is specialized by PhysicalHinge and CompoundHinge hinges.
         *
         * @return the coordinate map matrix
         */
        virtual km::Mat pframeCoordMapMatrix() const = 0;

        /**
         * @brief Return the orthogonal complement for the pframeCoordMapMatrix() matrix
         *
         * Compute the orthogonal complement (OC) of the pframe coord
         * map matrix computed by pframeCoordMapMatrix(). The product of
         * this OC with the pframe coord map matrix is zero.
         *
         * @return the orthogonal complement matrix
         */
        km::Mat pframeCoordMapMatrixOrthoComplement() const;

        /**
         * @brief Return the orthogonal complement for the oframe coordinate map matrix
         *
         * Compute the orthogonal complement (OC) of the pframe coord map
         * matrix. The product of the OC with the oframe coord map matrix
         * is zero.
         *
         * @return the orthogonal complement matrix
         */
        km::Mat oframeCoordMapMatrixOrthoComplement() const;

        /**
         * @brief Return list of singular values for the hinge's pframe coord map matrix
         *
         * This method is handy for monitoring potential loss in rank for
         * hinges such as ujoint and gimbal hinges. For full rank, there
         * should be nu() singular values.
         *
         * @return Array of singular values.
         */
        km::Vec pframeCoordMapSingularValues() const;

        /** @brief Struct with hinge parameters for the HingeType::HOOKE,
                HingeType::INLINE etc hinge types defined by motion
                constraints between a pair of frames on the inboard and
                outboard bodies
             */
        struct HingeParams {
            km::UnitQuaternion i_to_onode_q = km::UnitQuaternion(
                0, 0, 0, 1); //!< onode orientation with respect to the inboard frame
            km::UnitQuaternion j_to_pnode_q = km::UnitQuaternion(
                0, 0, 0, 1); //!< onode orientation with respect to the outboard frame
            km::Mat axes;    //!< 3xm matrix with columns defining the 1-dof subhinge axes
        };

        /**
         * @brief Helper method to compute the onode, pnode transform and axis params for a
         * HingeType::HOOKE hinge
         *
         * For a HingeType::HOOKE joint, an outboard body's frame's
         * Y-axis is constrained to remain perpendicular to an inboard
         * body frame's X-axis, and the pair of frames to remain
         * co-located.
         *
         * @param ij_q the inboard to outboard frames relative orientation unit quaternion
         * @return struct with the hinge onode, pnode and axis parameter values
         */
        static HingeParams getHookeHingeParams(const km::UnitQuaternion &ij_q);

        /**
         * @brief Helper method to compute  the onode, pnode transform and axis params for an
         * HingeType::INLINE hinge
         *
         * For an HingeType::INLINE joint, an outboard body frame is
         * constrained to translate only along an inboard body frame's
         * Z-axis
         *
         * @return struct with the hinge onode, pnode and axis parameter values
         */
        static HingeParams getInlineHingeParams();

        /**
         * @brief Helper method to compute  the onode, pnode transform and axis params for an
         * HingeType::INPLANE hinge
         *
         * For an HingeType::INPLANE joint, an outboard body frame is constrained to
         * translate only within the inboard frame's XY-plane
         *
         * @return struct with the hinge onode, pnode and axis parameter values
         */
        static HingeParams getInplaneHingeParams();

        /**
         * @brief Helper method to compute  the onode, pnode transform and axis params for a
         * HingeType::PERPENDICULAR hinge
         *
         * For a HingeType::PERPENDICULAR joint, an outboard body
         * frame's Z-axis is constrained to remain perpendicular to an
         * inboard body frame's Z-axis
         *
         * @param ij_q the inboard to outboard frames relative orientation unit quaternion
         * @return struct with the hinge onode, pnode and axis parameter values
         */
        static HingeParams getPerpendicularHingeParams(const km::UnitQuaternion &ij_q);

        /**
         * @brief Helper method to compute  the onode, pnode transform and axis params for a
         * HingeType::PARALLEL hinge
         *
         * For a HingeType::PARALLEL joint, an outboard body frame's
         * Z-axis is constrained to remain parallel to an inboard body
         * frame's Z-axis. It is assumed that the outboard frame's
         * Z-axis is parallel to the inboard frame's Z-axis to begin
         * with.
         *
         * @return struct with the hinge onode, pnode and axis parameter values
         */
        static HingeParams getParallelHingeParams();

      protected:
        /** @brief The coordinate map matrix across all subhinges in the onode frame
            @return the coordinate map matrix
        */
        virtual km::Mat oframeCoordMapMatrix() const // NOLINT(readability-identifier-naming)
        {
            return km::Mat(0, 0);
        }

        /// ordered list of subhinges
        kc::RegistryList<SubhingeBase> _subhinges_list;

        /** the hinge type */
        HingeType _hinge_type;

        /** the list of subhinge types for the hinge */
        std::vector<SubhingeType> _subhinge_types;

        /** the CoordData for the hinge's subhinge coordinates */
        kc::ks_ptr<CoordData> _hinge_coord_data = nullptr;
    };

} // namespace Karana::Dynamics