Program Listing for File ProfileGenerator.h

Program Listing for File ProfileGenerator.h#

Return to documentation for file (include/Karana/GeneralKModels/ProfileGenerator.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 ProfileGenerator declarations.
 */

#pragma once

#include "Karana/KCore/Allocator.h"
#include "Karana/KCore/Base.h"
#include "Karana/Math/Defs.h"
#include "Karana/Math/UnitQuaternion.h"

namespace Karana::Models {

    /**
     * @class ProfileGenerator
     * @brief ProfileGenerator base class.
     *
     * @tparam T The type that the ProfileGenerator produces, e.g., double, UnitQuaternion, etc.
     */
    template <typename T> class ProfileGenerator : public Karana::Core::Base {

      public:
        // Using the Base constructor
        using Karana::Core::Base::Base;

        /**
         * @brief Get the profile value for the provided time.
         *
         * @param t The current time
         * @return The profile value at the provided time.
         */
        virtual const T &getValue(const Karana::Math::Ktime &t) = 0;
    };

    /**
     * @brief A simple constant profile generator.
     *
     * @tparam T The type of object to generate a profile for.
     */
    template <typename T> class ConstantProfileGenerator : public ProfileGenerator<T> {
      public:
        /**
         * @brief ConstantProfileGenerator constructor. The constructor is not meant to be called
         * directly. Please use the create(...) method instead to create an instance.
         *
         * @param name The name of the ConstantProfileGenerator.
         * @param value The value of the ConstantProfileGenerator.
         */
        ConstantProfileGenerator(std::string_view name, const T &value)
            : ProfileGenerator<T>(name)
            , value(value) {}

        /**
         * @brief ConstantProfileGenerator constructor.
         *
         * @param name The name of the ConstantProfileGenerator.
         * @param value The value of the ConstantProfileGenerator.
         * @returns A pointer to the newly created instance of ConstantProfileGenerator.
         */
        static Karana::Core::ks_ptr<ConstantProfileGenerator> create(std::string_view name,
                                                                     const T &value) {
            return std::allocate_shared<ConstantProfileGenerator<T>>(
                Karana::Core::Allocator<ConstantProfileGenerator<T>>{}, name, value);
        }

        /**
         * @brief Get the constant profile value; ignores the time argument.
         * @param t The current time (not used).
         *
         * @return The constant profile value.
         */
        const T &getValue([[maybe_unused]] const Karana::Math::Ktime &t) override { return value; }

        /// The value for constant interpolation
        T value;
    };

    extern template class ConstantProfileGenerator<double>;
    extern template class ConstantProfileGenerator<Karana::Math::UnitQuaternion>;
    extern template class ConstantProfileGenerator<Karana::Math::Vec>;

    /**
     * @brief A simple linear profile generator.
     *
     * This does linear interpolation between (t_i,value_i) and (t_f,value_f).
     * Times provided outside the given range, less than t_i or greater
     * than t_f, will yield value_i and value_f, respectively.
     *
     * @tparam T The type of object to generate a profile for.
     */
    template <typename T> class LinearProfileGenerator : public ProfileGenerator<T> {
      public:
        /**
         * @brief LinearProfileGenerator constructor. The constructor is not meant to be called
         * directly. Please use the create(...) method instead to create an instance.
         *
         * @param t_i Time associated with value_i
         * @param value_i The starting value for linear interpolation
         * @param t_f Time associated with value_f
         * @param value_f The ending value for linear interpolation
         * @param name The name of the LinearProfileGenerator.
         */
        LinearProfileGenerator(std::string_view name,
                               const Karana::Math::Ktime &t_i,
                               const T &value_i,
                               const Karana::Math::Ktime &t_f,
                               const T &value_f)
            : ProfileGenerator<T>(name)
            , t_i(t_i)
            , value_i(value_i)
            , t_f(t_f)
            , value_f(value_f)
            , _v(value_i) {}

        /**
         * @brief LinearProfileGenerator constructor.
         *
         * @param name The name of the LinearProfileGenerator.
         * @param t_i Time associated with value_i
         * @param value_i The starting value for linear interpolation
         * @param t_f Time associated with value_f
         * @param value_f The ending value for linear interpolation
         * @returns A pointer to the newly created instance of LinearProfileGenerator.
         */
        static Karana::Core::ks_ptr<LinearProfileGenerator> create(std::string_view name,
                                                                   const Karana::Math::Ktime &t_i,
                                                                   const T &value_i,
                                                                   const Karana::Math::Ktime &t_f,
                                                                   const T &value_f) {
            return std::allocate_shared<LinearProfileGenerator<T>>(
                Karana::Core::Allocator<LinearProfileGenerator<T>>{},
                name,
                t_i,
                value_i,
                t_f,
                value_f);
        }

        /**
         * @brief Get the profile value for the provided time.
         *
         * @param t The current time
         * @return The profile value at the provided time.
         */
        const T &getValue(const Karana::Math::Ktime &t) override {
            if (t < t_i) {
                return value_i;
            } else if (t > t_f) {
                return value_f;
            } else {
                _v = value_i + (value_f - value_i) / Karana::Math::ktimeToSeconds(t_f - t_i) *
                                   Karana::Math::ktimeToSeconds(t);
                return _v;
            }
        }

        /**
         * @brief Indicate whether this LinearProfileGenerator is ready for simulation.
         *
         * @return true if it is ready, false otherwise.
         */
        bool isReady() const override {
            bool flag = true;

            if (not Karana::Math::isReady(t_i)) {
                flag = false;
                Karana::Core::warn("t_i of {} is not ready.", Karana::Core::Base::name());
            }
            if (not Karana::Math::isReady(t_f)) {
                flag = false;
                Karana::Core::warn("t_f of {} is not ready.", Karana::Core::Base::name());
            }

            return flag;
        }

        /// Time associated with value_i
        Karana::Math::Ktime t_i;

        /// The starting value for linear interpolation
        T value_i;

        /// Time associated with value_f
        Karana::Math::Ktime t_f;

        /// The ending value for linear interpolation
        T value_f;

      private:
        /// Represents the current value
        T _v;
    };

    extern template class LinearProfileGenerator<double>;
    extern template class LinearProfileGenerator<Karana::Math::Vec>;

} // namespace Karana::Models