Karana.KUtils.BasicPrefab
=========================

.. py:module:: Karana.KUtils.BasicPrefab

.. autoapi-nested-parse::

   BasicPrefab and associated classes.

   This Prefab is used to generically represent multibody objects and a list of KModels.



Attributes
----------

.. autoapisummary::

   Karana.KUtils.BasicPrefab.LinkJointTree
   Karana.KUtils.BasicPrefab.ExtraInfoType


Classes
-------

.. autoapisummary::

   Karana.KUtils.BasicPrefab.BasicParams
   Karana.KUtils.BasicPrefab.BasicContext
   Karana.KUtils.BasicPrefab.BasicPrefab
   Karana.KUtils.BasicPrefab.BasicPrefabDS


Functions
---------

.. autoapisummary::

   Karana.KUtils.BasicPrefab.getUid
   Karana.KUtils.BasicPrefab.urdfToBodyDS
   Karana.KUtils.BasicPrefab.urdfToBodyWithContextDS
   Karana.KUtils.BasicPrefab.readUrdf
   Karana.KUtils.BasicPrefab.bodyDSToUrdf
   Karana.KUtils.BasicPrefab.bodyWithContextDSToUrdf
   Karana.KUtils.BasicPrefab.writeUrdf


Module Contents
---------------

.. py:type:: LinkJointTree
   :canonical: list[tuple[Link, Joint, 'LinkJointTree']]


.. py:data:: ExtraInfoType

.. py:function:: getUid() -> int

   Get a unique ID.

   This is used by the URDF writer to get unique IDs that
   can be used to associate subhinges with
   SubhingeSpringDamper KModels.

   :returns: A unique ID.
   :rtype: int


.. py:function:: urdfToBodyDS(link: urchin.Link, joint: urchin.Joint) -> tuple[Karana.Dynamics.SOADyn_types.BodyDS, Karana.Models.GeneralKModels_types.SubhingeSpringDamperDS | None]

   Convert from a urchin Link and Joint to a BodyDS.

   :param link: The URDF Link.
   :type link: Link
   :param joint: The URDF parent joint.
   :type joint: Joint

   :returns: The BodyDS representation of the provided Link/Joint pair and
             any SubhingeSpringDamperDS representations of joint damping.
   :rtype: tuple[BodyDS, list[SubhingeSpringDamperDS]]


.. py:function:: urdfToBodyWithContextDS(link: urchin.Link, joint: urchin.Joint, children_urdf: LinkJointTree) -> tuple[Karana.Dynamics.SOADyn_types.BodyWithContextDS, list[Karana.Models.GeneralKModels_types.SubhingeSpringDamperDS]]

   Convert from links and joints to BodyWithContextDS.

   :param link: The link to use for creating the body.
   :type link: Link
   :param joint: The joint to use for creating the body.
   :type joint: Joint
   :param children_urdf: A LinkJointTree that defines the links and joints to use for the
                         children. This is an arbitrarily nested list of tuples of links
                         and joints, each of which can be used to define a body.
   :type children_urdf: LinkJointTree

   :returns: The BodyWithContextDS representation of the provided Links/Joints and
             any SubhingeSpringDamperDS representations of joint damping for the
             provided Joints.
   :rtype: tuple[BodyWithContextDS, list[SubhingeSpringDamperDS]]


.. py:function:: readUrdf(file: pathlib.Path | str) -> BasicPrefabDS[ExtraInfoType]

   Read a URDF file and convert it to a name and list of BodyWithContextDS.

   :param file: The file to read the URDF from.
   :type file: Path | str

   :returns: A SubTreeDS representing the URDF file.
   :rtype: SubTreeDS


.. py:function:: bodyDSToUrdf(body_ds: Karana.Dynamics.SOADyn_types.BodyDS, parent_link: str, models: list[Karana.Models.GeneralKModels_types.SubhingeSpringDamperDS]) -> tuple[urchin.Link, urchin.Joint]

   Convert the BodyDS to a urchin Link and Joint. These can be used to create a URDF file.

   :param parent_link: The name of the parent link for the Joint.
   :type parent_link: str

   :returns: The Link and Joint associated with this body.
   :rtype: tuple[Link, Joint]


.. py:function:: bodyWithContextDSToUrdf(body_with_context_ds: Karana.Dynamics.SOADyn_types.BodyWithContextDS, parent_link: str, models: list[Karana.Models.GeneralKModels_types.SubhingeSpringDamperDS]) -> tuple[list[urchin.Link], list[urchin.Joint]]

   Convert a BodyWithContextDS to a list of Links and Joints. These can be used to create a URDF file.

   :param body_with_context_ds: The BodyWithContextDS to convert to a list of URDF links and joints.
   :type body_with_context_ds: BodyWithContextDS
   :param parent_link: The name of the parent link for the body of this BodyWithContextDS.
   :type parent_link: str

   :returns: The Links and Joints associated with the body and children of this BodyWithContextDS.
   :rtype: tuple[list[Link], list[Joint]]


.. py:function:: writeUrdf(basic_prefab_ds: BasicPrefabDS[ExtraInfoType], file: pathlib.Path | str)

   Convert this DataStruct to a URDF file.

   :param basic_prefab_ds: The BasicPrefab DataStruct to convert to a URDF file.
   :type basic_prefab_ds: BasicPrefabDS[ExtraInfoType]
   :param file: The file to write the URDF to.
   :type file: Path | str


.. py:class:: BasicParams(/, **data: Any)

   Bases: :py:obj:`Karana.KUtils.Prefab.Params`, :py:obj:`Generic`\ [\ :py:obj:`ExtraInfoType`\ ]


   Params for the BasicPrefab.

   :param subtree: The SubTree of bodies/nodes to add.
   :type subtree: SubTreeDS[SubTreeDSType]
   :param models: The list of models to add. Each value in the list is a KModelDS and optional state data for the associated KModel.
   :type models: list[tuple[KModelDS[BaseKModelType], KModelStateDS[BaseKModelType] | None]] = []
   :param subtree_state_info: State information for the SubTree.
   :type subtree_state_info: SubTreeStateDS | None = None
   :param extra_info: Any extra information to store. This information is primarily used for validation of the SubTree and/or models.
                      It is Python Generic, and can set by the user.
   :type extra_info: SerializeAsAny[ExtraInfoType] | None = None


   .. py:attribute:: subtree
      :type:  pydantic.SerializeAsAny[Karana.Dynamics.SOADyn_types.SubTreeDS[Karana.Dynamics.SOADyn_types.SubTreeDSType]]


   .. py:attribute:: models
      :type:  list[tuple[pydantic.SerializeAsAny[Karana.Dynamics.SOADyn_types.KModelDS[Karana.Dynamics.SOADyn_types.BaseKModelType]], pydantic.SerializeAsAny[Karana.Dynamics.SOADyn_types.KModelStateDS[Karana.Dynamics.SOADyn_types.BaseKModelType]] | None]]
      :value: []



   .. py:attribute:: subtree_state_info
      :type:  Karana.Dynamics.SOADyn_types.SubTreeStateDS | None
      :value: None



   .. py:attribute:: extra_info
      :type:  pydantic.SerializeAsAny[ExtraInfoType] | None
      :value: None



.. py:class:: BasicContext(/, **data: Any)

   Bases: :py:obj:`Karana.KUtils.Prefab.Context`


   Context for the BasicPrefab.

   .. attribute:: parent_body

      The parent_body to attach bodies to from the subtree on params. If None, then a FrameContainer can be
      used if the subtree is a SubGraphDS. See frame_container above for details.

      :type: PhysicalBody | None = None

   .. attribute:: model_manager

      The model_manager to register models with. If None and allow_create_model_manager is True in BasicConfig,
      then the BasicPrefab will attempt to create one.

      :type: ModelManager | None = None

   .. attribute:: frame_colliders

      An optional list of FrameColliders. If provided, these will be used for any PenaltyContact models in-place
      of the FrameColliders that they have listed as part of their DataStruct.

      :type: list[FrameCollider] = []


   .. py:attribute:: parent_body_raw
      :type:  Annotated[Karana.Dynamics.PhysicalBody | int | None, *SerializeAsId(allow_int=True, allow_None=True)]
      :value: None



   .. py:attribute:: model_manager_raw
      :type:  Annotated[Karana.Dynamics.ModelManager | int | None, *SerializeAsId(allow_int=True, allow_None=True)]
      :value: None



   .. py:attribute:: frame_colliders_raw
      :type:  list[Karana.Collision.FrameCollider | Karana.Collision.Collision_types.FrameColliderDS]
      :value: None



   .. py:property:: frame_colliders
      :type: list[Karana.Collision.FrameCollider]


      Get the FrameColliders for the associated PenaltyContact model.

      :returns: The FrameColliders for the associated PenaltyContact model.
      :rtype: list[FrameCollider]


   .. py:property:: model_manager
      :type: Karana.Dynamics.ModelManager | None


      Return the ModelManager.

      :returns: The ModelManager if set. Otherwise, returns None.
      :rtype: ModelManager | None


   .. py:property:: parent_body
      :type: Karana.Dynamics.PhysicalBody | None


      Get the parent_body.

      :returns: The parent_body if it is set. Otherwise, None is returned.
      :rtype: PhysicalBody | None


.. py:class:: BasicPrefab(name: str, config: ConfigType, context: ContextType, params: ParamsType, parent_prefab: Prefab[Any, Any, Any] | None = None)

   Bases: :py:obj:`Karana.KUtils.Prefab.Prefab`\ [\ :py:obj:`Karana.KUtils.Prefab.Config`\ , :py:obj:`BasicContext`\ , :py:obj:`BasicParams`\ [\ :py:obj:`ExtraInfoType`\ ]\ ], :py:obj:`Generic`\ [\ :py:obj:`ExtraInfoType`\ ]


   BasicPrefab for holding multibody objects and KModels.

   This BasicPrefab contains contains a SubTreeDS and a list of KModelDSs in its BasicParams.
   These are used to create multibody objects and KModels. See the associated BasicConfig,
   BasicContext, and BasicParams for how these can be used.


   .. py:method:: addMultibodyObjects()

      Add multibody objects from params.

      This adds the multibody objects stored in params.subtree.

      If the context.parent_body is None, then no multibody objects will be added and
      a warning will be triggered.



   .. py:method:: addKModels()

      Add KModels from params.

      This method attempts to create KModels. To do so requires a ModelManager. This can
      be provided via context.model_manager.

      If this value is None and there are models, a warning will be triggered.



   .. py:method:: toDS() -> BasicPrefabDS[ExtraInfoType]

      Create a BasicPrefabDS from this Prefab.

      :returns: The DataStruct that represents this Prefab.
      :rtype: BasicPrefabDS[ExtraInfoType]



   .. py:method:: fromDS(data_struct: BasicPrefabDS[ExtraInfoType], parent_or_top: Prefab[Any, Any, Any] | None, *_, **kwargs) -> Self
      :classmethod:


      Convert the BasicPrefabDS to an instance of BasicPrefab.

      This will also create instances of the associated children if applicable.

      :param data_struct: The BasicPrefabDS[ExtraInfoType] to create an instance of this Prefab from.
      :type data_struct: BasicPrefabDS[ExtraInfoType]
      :param parent_or_top: The parent prefab or top_prefab. First, we will try to find the parent string
                            from the PrefabDS on this value. If it exists, we will use that as the parent.
                            Otherwise, we will use this as the parent directly. If None, then we will assume
                            the Prefab being created is the top-level Prefab.
      :type parent_or_top: Prefab[Any, Any, Any] | None

      :returns: An instance of this BasicPrefab.
      :rtype: Self



   .. py:method:: createDS(name: str, config: Karana.KUtils.Prefab.Config, context: BasicContext, params: BasicParams[ExtraInfoType]) -> BasicPrefabDS[ExtraInfoType]
      :classmethod:


      Create a DataStruct representing a BasicPrefab.

      This is a helper method to create the DataStruct version of Basic, without having
      to create an instance of Basic.

      :param name: The name for the BasicPrefab.
      :type name: str
      :param config: The Config for the BasicPrefab.
      :type config: Config
      :param context: The BasicContext for the BasicPrefab.
      :type context: BasicContext
      :param params: The BasicParams for the BasicPrefab.
      :type params: BasicParams[ExtraInfoType]

      :returns: The DataStruct representation of the BasicPrefab with the provided
                config, context, and params.
      :rtype: PrefabDS[BasicConfig, BasicContext, BasicParams[ExtraInfoType]]



   .. py:method:: createStandalone(basic_prefab_ds: Karana.KUtils.Prefab.PrefabDS[Karana.KUtils.Prefab.Config, BasicContext, BasicParams[ExtraInfoType]], fc: Karana.Frame.FrameContainer) -> tuple[Self, Karana.Dynamics.StatePropagator]
      :classmethod:


      Create a simulation from a BasicPrefab DataStruct.

      This creates an empty Multibody from the FrameContainer and an empty StatePropagator
      with the cvode integrator from the Multibody. Then, these are added to the
      BasicPrefab DataStruct's context, and a BasicPrefab is created from it.

      :param basic_prefab_ds: The BasicPrefab DataStruct to use to construct the simulation.
      :type basic_prefab_ds: PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType]]
      :param fc: The FrameContainer used to create the Multibody.
      :type fc: FrameContainer

      :returns: An instance of the BasicPrefab and the StatePropagator created by this method.
      :rtype: tuple[Self, StatePropagator]



.. py:class:: BasicPrefabDS

   Bases: :py:obj:`Karana.KUtils.Prefab.PrefabDS`\ [\ :py:obj:`Karana.KUtils.Prefab.Config`\ , :py:obj:`BasicContext`\ , :py:obj:`BasicParams`\ [\ :py:obj:`ExtraInfoType`\ ]\ ], :py:obj:`Generic`\ [\ :py:obj:`ExtraInfoType`\ ]


   A DataStruct representation of a BasicPrefab.

   This is a thin wrapper around PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType]]
   that provides a more  ergonomic syntax and also allows overriding certain methods, e.g.,
   to/fromFile.


   .. py:method:: fromPrefabDS(ds: Karana.KUtils.Prefab.PrefabDS[Karana.KUtils.Prefab.Config, BasicContext, BasicParams[ExtraInfoType]]) -> Self
      :classmethod:


      Convert a PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType]] to a BasicPrefabDS.

      :param ds: The PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType]] to convert.
      :type ds: PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType]]

      :returns: The new instance of BasicPrefabDS created from the provided
                PrefabDS[Config, BasicContext, BasicParams[ExtraInfoType].
      :rtype: Self



   .. py:method:: fromFile(file: pathlib.Path | str | IO[bytes], *, file_type: Optional[Literal['json', 'yaml', 'yml', 'h5', 'hdf5', 'pickle', 'pck', 'pcl']] = None, get_meta: Literal[False] = False) -> Self
                  fromFile(file: pathlib.Path | str | IO[bytes], *, file_type: Optional[Literal['json', 'yaml', 'yml', 'h5', 'hdf5', 'pickle', 'pck', 'pcl']] = None, get_meta: Literal[True]) -> tuple[Self, Karana.KUtils.DataStruct.Meta]
                  fromFile(file: pathlib.Path | str, *, file_type: Optional[Literal['urdf']] = None) -> Self
                  fromFile(file: pathlib.Path | str, *, file_type: Optional[Literal['freecad']] = None) -> Self
                  fromFile(g: h5py.Group, *, get_meta: Literal[False] = False) -> Self
                  fromFile(g: h5py.Group, *, get_meta: Literal[True]) -> tuple[Self, Karana.KUtils.DataStruct.Meta]
      :classmethod:


      Create an instance of this DataStruct a file.

      See overloads for details.



   .. py:method:: toFile(file: pathlib.Path | str | IO[bytes], file_type: Optional[Literal['json', 'yaml', 'yml', 'h5', 'hdf5', 'pickle', 'pck', 'pcl']] = None, meta: Karana.KUtils.DataStruct.Meta | None = None) -> None
                  toFile(file: pathlib.Path | str, file_type: Optional[Literal['urdf']] = None) -> None
                  toFile(g: h5py.Group, meta: Karana.KUtils.DataStruct.Meta | None = None) -> None

      Write the SubTreeDS to a file.

      See overloads for details.



