Program Listing for File pybind11ParamsCaster.h#
↰ Return to documentation for file (include/Karana/SOADyn/pybind11ParamsCaster.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 Casters for *Params types.
*/
#pragma once
#include "Karana/SOADyn/PhysicalBody.h"
#include "Karana/SOADyn/PhysicalHinge.h"
#include "Karana/SOADyn/PhysicalSubhinge.h"
#include "Karana/SOADyn/PinSubhinge.h"
#include "Karana/Scene/SceneFileObjectSpec.h"
#include "Karana/Scene/ScenePartSpec.h"
#include <pybind11/eigen.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
namespace kd = Karana::Dynamics;
namespace kc = Karana::Core;
namespace km = Karana::Math;
namespace ks = Karana::Scene;
namespace Karana::Dynamics {
/// The module to import Subhinge DataStructs from.
constexpr std::string_view subhingeDSModule = "Karana.Dynamics._params";
/**
* @brief Get the Python subhinge DataStruct class associated with the given name.
*
* @param name The name of the DataStruct to get.
* @return The Python class for the DataStruct.
*/
inline py::object subhingeDSClass(const char *name) {
return py::module_::import(subhingeDSModule.data()).attr(name);
}
/**
* @brief Convert a Python subhinge DataStruct to its associated C++ parameter object.
*
* @param src The Python subhinge DataStruct
* @return The associated C++ parameter object.
*/
inline kc::ks_ptr<kd::PhysicalSubhingeParams> subhingeParamsFromDS(const py::handle &src) {
if (py::isinstance(src, subhingeDSClass("PinSubhingeParams"))) {
return kd::PinSubhingeParams::create(py::cast<km::Vec3>(src.attr("unit_axis")),
py::cast<bool>(src.attr("prescribed")),
py::cast<km::Vec>(src.attr("joint_limits")));
}
if (py::isinstance(src, subhingeDSClass("LinearSubhingeParams"))) {
return kd::LinearSubhingeParams::create(py::cast<km::Vec3>(src.attr("unit_axis")),
py::cast<bool>(src.attr("prescribed")),
py::cast<km::Vec>(src.attr("joint_limits")));
}
if (py::isinstance(src, subhingeDSClass("ScrewSubhingeParams"))) {
return kd::ScrewSubhingeParams::create(py::cast<km::Vec3>(src.attr("unit_axis")),
py::cast<double>(src.attr("pitch")),
py::cast<bool>(src.attr("prescribed")));
}
if (py::isinstance(src, subhingeDSClass("Linear3SubhingeParams"))) {
return kd::Linear3SubhingeParams::create(py::cast<bool>(src.attr("prescribed")));
}
if (py::isinstance(src, subhingeDSClass("SphericalSubhingeParams"))) {
return kd::SphericalSubhingeParams::create(py::cast<bool>(src.attr("prescribed")));
}
if (py::isinstance(src, subhingeDSClass("SphericalQuatSubhingeParams"))) {
return kd::SphericalQuatSubhingeParams::create(py::cast<bool>(src.attr("prescribed")));
}
if (py::isinstance(src, subhingeDSClass("LockedPhysicalSubhingeParams"))) {
return kd::PhysicalSubhingeParams::create();
}
return {};
}
/**
* @brief Convert a C++ subhinge parameter to its associated Python DataStruct.
*
* @param src The C++ subhinge parameter
* @return The associated Python DataStruct
*/
inline py::object subhingeParamsToDS(const kc::ks_ptr<kd::PhysicalSubhingeParams> &src) {
if (auto params = kc::dynamic_pointer_cast<kd::PinSubhingeParams>(src)) {
return subhingeDSClass("PinSubhingeParams")(py::arg("unit_axis") = params->unit_axis,
py::arg("joint_limits") =
params->joint_limits,
py::arg("prescribed") = params->prescribed);
}
if (auto params = kc::dynamic_pointer_cast<kd::LinearSubhingeParams>(src)) {
return subhingeDSClass("LinearSubhingeParams")(
py::arg("unit_axis") = params->unit_axis,
py::arg("joint_limits") = params->joint_limits,
py::arg("prescribed") = params->prescribed);
}
if (auto params = kc::dynamic_pointer_cast<kd::ScrewSubhingeParams>(src)) {
return subhingeDSClass("ScrewSubhingeParams")(py::arg("unit_axis") = params->unit_axis,
py::arg("pitch") = params->pitch,
py::arg("prescribed") =
params->prescribed);
}
if (auto params = kc::dynamic_pointer_cast<kd::Linear3SubhingeParams>(src)) {
return subhingeDSClass("Linear3SubhingeParams")(py::arg("prescribed") =
params->prescribed);
}
if (auto params = kc::dynamic_pointer_cast<kd::SphericalSubhingeParams>(src)) {
return subhingeDSClass("SphericalSubhingeParams")(py::arg("prescribed") =
params->prescribed);
}
if (auto params = kc::dynamic_pointer_cast<kd::SphericalQuatSubhingeParams>(src)) {
return subhingeDSClass("SphericalQuatSubhingeParams")(py::arg("prescribed") =
params->prescribed);
}
return subhingeDSClass("LockedPhysicalSubhingeParams")();
}
/**
* @brief Get the PhysicalBodyParams DataStruct class.
*
* @return The PhysicalBodyParams DataStruct class.
*/
inline py::object physicalBodyParamsDSClass() {
return py::module_::import("Karana.Dynamics._params").attr("PhysicalBodyParams");
}
} // namespace Karana::Dynamics
namespace pybind11::detail {
/** Python DataStruct name associated with a concrete subhinge parameter type. */
template <typename Params> struct SubhingeParamsDSName;
/** DataStruct associated with PinSubhingeParams. */
template <> struct SubhingeParamsDSName<kd::PinSubhingeParams> {
/**
* @brief Python class for PinSubhingeParams
*/
static constexpr auto value = const_name("Karana.Dynamics.SOADyn_types.PinSubhingeParams");
};
/** DataStruct associated with LinearSubhingeParams. */
template <> struct SubhingeParamsDSName<kd::LinearSubhingeParams> {
/**
* @brief Python class for LinearSubhingeParams
*/
static constexpr auto value =
const_name("Karana.Dynamics.SOADyn_types.LinearSubhingeParams");
};
/** DataStruct associated with ScrewSubhingeParams. */
template <> struct SubhingeParamsDSName<kd::ScrewSubhingeParams> {
/**
* @brief Python class for ScrewSubhingeParams
*/
static constexpr auto value =
const_name("Karana.Dynamics.SOADyn_types.ScrewSubhingeParams");
};
/** DataStruct associated with Linear3SubhingeParams. */
template <> struct SubhingeParamsDSName<kd::Linear3SubhingeParams> {
/**
* @brief Python class for Linear3SubhingeParams
*/
static constexpr auto value =
const_name("Karana.Dynamics.SOADyn_types.Linear3SubhingeParams");
};
/** DataStruct associated with SphericalSubhingeParams. */
template <> struct SubhingeParamsDSName<kd::SphericalSubhingeParams> {
/**
* @brief Python class for SphericalSubhingeParams
*/
static constexpr auto value =
const_name("Karana.Dynamics.SOADyn_types.SphericalSubhingeParams");
};
/** DataStruct associated with SphericalQuatSubhingeParams. */
template <> struct SubhingeParamsDSName<kd::SphericalQuatSubhingeParams> {
/**
* @brief Python class for SphericalQuatSubhingeParams
*/
static constexpr auto value =
const_name("Karana.Dynamics.SOADyn_types.SphericalQuatSubhingeParams");
};
/**
* @brief General type caster that can be used on all concerte PhysicalSubhingeParams subtypes.
*/
template <typename Params> struct ConcreteSubhingeParamsCaster {
/// The type this pybind11 caster uses
using T = kc::ks_ptr<Params>;
/// A pybind11 caster for PhysicalSubhingeParams subtypes
PYBIND11_TYPE_CASTER(T, SubhingeParamsDSName<Params>::value);
/**
* @brief Load a C++ PhysicalSubhingeParams subtype from its Python DataStruct
*
* @param src The associated Python DataStruct
* @return The C++ PhysicalSubhingeParams subtype associated with the DataStruct
*/
bool load(handle src, bool) {
value = kc::dynamic_pointer_cast<Params>(Karana::Dynamics::subhingeParamsFromDS(src));
return static_cast<bool>(value);
}
/**
* @brief Convert a C++ PhysicalSubhingeParams subtype to its Python DataStruct
*
* @param src A C++ PhysicalSubhingeParams subtype
* @return The associated Python DataStruct
*/
static handle cast(const T &src, return_value_policy, handle) {
if (!src) {
return py::none().release();
}
return Karana::Dynamics::subhingeParamsToDS(src).release();
}
};
/**
* @brief Convert PhysicalSubhingeParams C++ objects to/from Python PhysicalSubhingeParams
* DataStruct objects.
*/
template <> struct type_caster<kc::ks_ptr<kd::PhysicalSubhingeParams>> {
/// Typedef for the type used by this type caster
using T = kc::ks_ptr<kd::PhysicalSubhingeParams>;
/// pybind11 type caster for PhysicalSubhingeParams
PYBIND11_TYPE_CASTER(T, const_name("Karana.Dynamics.SOADyn_types.PhysicalSubhingeParams"));
/** Load a C++ parameter pointer from a Python PhysicalSubhingeParams. */
/**
* @brief Load a C++ PhysicalSubhingeParams from a Python PhysicalSubhingeParams DataStruct.
*
* @param src The Python PhysicalSubhingeParams DataStruct
* @return A C++ PhysicalSubhingeParams
*/
bool load(handle src, bool) {
value = Karana::Dynamics::subhingeParamsFromDS(src);
return static_cast<bool>(value);
}
/** Cast a C++ parameter pointer to its concrete Python PhysicalSubhingeParams. */
/**
* @brief Cast a C++ PhysicalSubhingeParams to the Python PhysicalSubhingeParams DataStruct.
*
* @param src The C++ PhysicalSubhingeParams
* @return The Python PhysicalSubhingeParams DataStruct
*/
static handle cast(const T &src, return_value_policy, handle) {
if (!src) {
return py::none().release();
}
return subhingeParamsToDS(src).release();
}
};
/** Convert PinSubhingeParams shared pointers to and from PinSubhingeParams objects. */
template <>
struct type_caster<kc::ks_ptr<kd::PinSubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::PinSubhingeParams> {};
/** Convert LinearSubhingeParams shared pointers to and from LinearSubhingeParams objects. */
template <>
struct type_caster<kc::ks_ptr<kd::LinearSubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::LinearSubhingeParams> {};
/** Convert ScrewSubhingeParams shared pointers to and from ScrewSubhingeParams objects. */
template <>
struct type_caster<kc::ks_ptr<kd::ScrewSubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::ScrewSubhingeParams> {};
/** Convert Linear3SubhingeParams shared pointers to and from Linear3SubhingeParams objects. */
template <>
struct type_caster<kc::ks_ptr<kd::Linear3SubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::Linear3SubhingeParams> {};
/** Convert SphericalSubhingeParams pointers to and from SphericalSubhingeParams objects. */
template <>
struct type_caster<kc::ks_ptr<kd::SphericalSubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::SphericalSubhingeParams> {};
/** Convert quaternion spherical parameter pointers to and from their DataStructs. */
template <>
struct type_caster<kc::ks_ptr<kd::SphericalQuatSubhingeParams>>
: ConcreteSubhingeParamsCaster<kd::SphericalQuatSubhingeParams> {};
/**
* @brief Caster to convert C++ PhysicalHingeParams to and from Python PhysicalHingeParams
* DataStruct objects.
*/
template <> struct type_caster<kd::PhysicalHingeParams> {
/// Pybind11 caster for PhysicalHingeParams
PYBIND11_TYPE_CASTER(kd::PhysicalHingeParams,
const_name("Karana.Dynamics.SOADyn_types.PhysicalHingeParams"));
/**
* @brief Load a C++ PhysicalHingeParams from a Python PhysicalHingeParams DataStruct.
*
* @param src The Python PhysicalHingeParams DataStruct
* @return The C++ PhysicalHingeParams
*/
bool load(handle src, bool) {
if (src.is_none()) {
value = {};
return true;
}
py::object hinge_ds =
py::module_::import("Karana.Dynamics.SOADyn_types").attr("PhysicalHingeParams");
if (!py::isinstance(src, hinge_ds)) {
return false;
}
value = kd::PhysicalHingeParams{
py::cast<kd::HingeType>(src.attr("hinge_type")),
py::cast<std::vector<kc::ks_ptr<kd::PhysicalSubhingeParams>>>(
src.attr("subhinge_params"))};
return true;
}
/** Cast PhysicalHingeParams to a Python PhysicalHingeParams. */
/**
* @brief Cast PhysicalHingeParams to a Python PhysicalHingeParams DataStruct.
*
* @param src The C++ PhysicalHingeParams
* @return The Python PhysicalHingeParams DataStruct
*/
static handle cast(const kd::PhysicalHingeParams &src, return_value_policy, handle) {
py::object hinge_ds =
py::module_::import("Karana.Dynamics.SOADyn_types").attr("PhysicalHingeParams");
py::object result = hinge_ds(py::arg("hinge_type") = src.hinge_type,
py::arg("subhinge_params") = src.subhinge_params);
return result.release();
}
};
/** Convert PhysicalBodyParams values to and from Python PhysicalBodyParams DataStructs. */
template <> struct type_caster<kd::PhysicalBodyParams> {
// We use an std::optional in this type caster because PhysicalBodyParms is not default
// constructable
/// Type caster to use to convert PhysicalBodyParams
PYBIND11_TYPE_CASTER(std::optional<kd::PhysicalBodyParams>,
const_name("Karana.Dynamics._params.PhysicalBodyParams"));
// Add conversions to PhysicalBodyParams types from value
/**
* @brief Get a PhysicalBodyParams reference from this caster.
*
* @return A PhysicalBodyParams reference.
*/
operator const kd::PhysicalBodyParams &() const { return *value; }
/**
* @brief Get a PhysicalBodyParams reference from this caster.
*
* @return A PhysicalBodyParams reference.
*/
operator kd::PhysicalBodyParams &() { return *value; }
/**
* @brief Load PhysicalBodyParams from its Python DataStruct.
*
* @param src The Python DataStruct to turn into PhysicalBodyParams.
* @return The PhysicalBodyParams created from the DataStruct.
*/
bool load(handle src, bool) {
py::object cls = kd::physicalBodyParamsDSClass();
if (!py::isinstance(src, cls)) {
return false;
}
value.emplace(py::cast<km::SpatialInertia>(src.attr("spatial_inertia")),
py::cast<km::HomTran>(src.attr("body_to_joint_transform")),
py::cast<kd::PhysicalHingeParams>(src.attr("hinge_params")),
py::cast<kc::ks_ptr<kd::ParentBodyAttachmentParams>>(
src.attr("parent_body_attachment_params")),
py::cast<std::vector<ks::ScenePartSpec>>(src.attr("scene_part_specs")),
py::cast<std::vector<ks::SceneFileObjectSpec>>(
src.attr("scene_file_object_specs")));
return true;
}
/**
* @brief Cast PhysicalBodyParams to its Python DataStruct.
*
* @param src The C++ PhysicalBodyParams to turn into the Python DataStruct.
* @return The Python DataStruct associated with the C++ object.
*/
static handle cast(const kd::PhysicalBodyParams &src, return_value_policy, handle) {
py::object result = kd::physicalBodyParamsDSClass()(
py::arg("spatial_inertia") = src.spatial_inertia,
py::arg("body_to_joint_transform") = src.body_to_joint_transform,
py::arg("hinge_params") = src.hinge_params,
py::arg("parent_body_attachment_params") = src.parent_body_attachment_params,
py::arg("scene_part_specs") = src.scene_part_specs,
py::arg("scene_file_object_specs") = src.scene_file_object_specs);
return result.release();
}
};
} // namespace pybind11::detail