Welcome to the powerful world of {{ kdflex }}! As a new user, you're about
to embark on a journey with a state-of-the-art multibody dynamics
modeling and simulation toolkit. {{ kdflex }} is renowned for its speed and
fidelity, built on cutting-edge Spatial Operator Algebra (SOA) and
minimal coordinate techniques, enabling efficient O(N) computational
algorithms for both rigid and flexible bodies.

To help you hit the ground running, this section highlights the key
concepts you should grasp early on, the ones you will need on a regular
day-to-day basis, and highlights some important and less common advanced
topics. Understanding these foundational elements will make your
{{ kdflex }} experience smoother and more productive.

---


## Key concepts

The following figure shows a high-level overview of the major components of {{ kdflex }}.



```{eval-rst}
.. figure:: images/top_modules.png
    :width: 750px
    :alt: top_modules

    The key components of kdFlex 
```

The foundation layer at the top consist of the multibody dynamics
modules, modules to integrate in other component models along with basic
simulation service capabilities. The model manager integrates these
components for the system level model. The state propagator brings in
numerical integration to support the time domain simulation capability.


---

(dippingtoes_sec)=
### 1. Dipping toes

####  kdFlex: The Underlying Framework

Before diving deep into {{ kdflex }}, it's crucial to understand its
foundational framework which  provides infrastructure, core
functionalities and data types that you will use constantly. 

Key {{ kdflex }} modules you'll encounter:

*   **`Karana.Math`**: This module is your toolkit for all mathematical operations. You'll frequently use:
    *   `Vectors and matrices`: At the Python level, these are
        `numpy.array` proxies for the underlying C++
        `Karana::Math::Vec` and
        `Karana::Math::Mat` classes.
    *   blah {py:class}`SpatialVector <Karana.Math.SpatialVector>`: For
        representing spatial forces, velocities, and accelerations in 6D
        space.
    *   {py:class}`HomTran <Karana.Math.HomTran>` (Homogeneous
        Transformation): For representing position and orientation
        (pose) in 3D space.
    *   {py:class}`UnitQuaternion <Karana.Math.UnitQuaternion>`: For representing orientation.
    *   {py:class}`SpatialInertia <Karana.Math.SpatialInertia>`: For
        defining the mass and inertia properties of bodies.
*   **`Karana.Core`**: Contains fundamental utilities like:
    *   `MsgLogger`: Karana's powerful logging system for debugging and
        information output.
    *   `Ktime` (often represented by `numpy.timedelta64` in Python):
        Karana's internal time representation.
*   `Karana.Frame`: The cornerstone of spatial relationships, discussed next.

**Why it matters:** You'll be working with {{ kdflex }}'s specific data
types and methods for everything from defining geometry to applying
forces. Familiarize yourself with them! See {ref}`math_sec` section for
details.

####  Frames: The Foundation of Spatial Relationships

In {{ kdflex }} spatial poses, velocities and accelerations are defined
with respect to **Frames**. A `Frame` is simply a coordinate system that
defines a position and orientation in 3D space.

*  {py:class}`Frame <Karana.Frame.Frame>`: The frame instances associated with
       coordinate frames for locations of interest.
*  {py:class}`FrameToFrame <Karana.Frame.FrameToFrame>`: Defines relative 
       pose, velocity and acceleration relationships across arbitrary {{
       framecls }} pairs.
*   **`Newtonian` Frame:** This is your "world" or inertial reference
    frame. All absolute positions and orientations are ultimately
    referenced to the `Newtonian` frame.
*   **Frame Hierarchies:** Frames are organized in a hierarchy, with
    parent-child relationships. A {{ homtrancls }} (Homogeneous
    Transformation) describes the relationship between a child frame and
    its parent, and {{ spveccls }} the relative spatial velocity and
    acceleration quantities.
*   {py:class}`FrameContainer <Karana.Frame.FrameContainer>`: Manages all the frames in your system.

**Why it matters:** Understanding how to define, relate, and transform
between frames (`HomTran`) is fundamental. Whether you're placing a
sensor, defining a joint, or applying a force, you'll specify its
location and orientation relative to a particular frame. See
{ref}`framestop_sec` section for details.

####  Multibody Systems: Building Your Vehicle Platform

The heart of your {{ kdflex }} model is the
`Karana.Dynamics.Multibody` object. This represents your entire
mechanical system—your robot, vehicle, or mechanism.

You typically define your multibody system using a data structure approach:

*   {py:class}`Multibody <Karana.Dynamics.Multibody>`: This top-level container class allows you to
    declaratively define your system's bodies, their connection topology
    and properties.
*   **Key Components of {{ mbodycls }}:**
    *   {py:class}`PhysicalBody <Karana.Dynamics.PhysicalBody>`: Defines a rigid body. You specify its name, parent
        frame, and `PhysicalBodyParams` (mass, `SpatialInertia`, and
        transformations defining its local frames).
    *   {py:class}`PhysicalHinge <Karana.Dynamics.PhysicalHinge>`: Connects two bodies (or a body to the Newtonian
        frame) and defines the degrees of freedom (DOF) between them. {{
        kdflex }} supports various `HINGE_TYPE`s:
        *   `FULL6DOF`: A free-floating body (6 DOFs).
        *   `REVOLUTE`: A single rotational DOF.
        *   `PRISMATIC`: A single translational DOF.
        *   And many others for specific joint types.
    *   **`Base Bodies`:** These are the bodies directly attached to the
        `Newtonian` frame, forming the "base" of your system's kinematic
        tree.
    *   {py:class}`Node <Karana.Dynamics.Node>`: A {{ framecls }} attached to a {{
        physbody }} for sensing and applying external forces.

**The `mb.ensureHealthy()` method:** After defining your {{ mbodycls }}
 `Karana.Dynamics.Multibody` instance, always call
 `mb.ensureHealthy()`. This crucial step finalizes the internal
 structure of the multibody system, making it ready for dynamics
 computations.

**Why it matters:** This is how you construct your model. A well-defined
{{ mbodycls }} is the prerequisite for any simulation. See {ref}`multibodytop_sec` section for
details. 

####  Dynamics and Simulation: Bringing Your System to Life

Once your {{ mbodycls }} system is defined, the
{py:class}`Karana.Dynamics.StatePropagator` instance takes center stage for time-domain
simulations.

*   **Role of {{ spcls }}:** It integrates the system's equations
    of motion over time, advancing its generalized positions (`Q`) and
    velocities (`U`).
*   **Integrator Types:**
    *   `"cvode_stiff"`: Often the recommended choice for general
        robustness, especially with stiff systems (common in robotics
        and complex mechanisms).
    *   `"rk4"`: A simpler, fixed-step Runge-Kutta 4th order integrator,
        useful for non-stiff systems or when precise fixed steps are
        required.
*   **Setting Initial Conditions:** You must provide the
    {{ spcls }}  with an `initial_time` and an
    `initial_state_vector` (containing `Q` and `U` for your system).
*   **Advancing the Simulation:** Use methods like
    `sp.advanceBy(duration)` or `sp.advanceTo(target_time)` to run your
    simulation.
*   **Applying Forces/Torques:** To interact with your system (e.g.,
    apply gravity, control forces), you'll use methods like
    `body.applySpatialForce(spatial_vector)`. These are typically
    applied within specialized callback functions registered with the
    {{ spcls }} (see `pre_deriv_fns` below).

**Why it matters:** The {{ spcls }} is how you observe your model's
behavior over time. Mastering its configuration and usage is key to
running meaningful simulations. See {ref}`time_domain_sim_sec` section for
details.

---

{{ kdflex }} is a powerful tool, and like any powerful tool, it has a
learning curve. By focusing on these core concepts—Karana's types,
Frames, Multibody definition, StatePropagator, DataCaches, and debugging
utilities—you'll build a strong foundation for creating robust and
efficient simulations.

Don't hesitate to explore the rest of the {{ kdflex }} documentation,
notebook examples and the  [kdFlex
Chatbot](https://portal.karanadyn.com/chatbot/). Happy simulating!

---

(freeswim_sec)=
### 2. Free swim




As you start to use {{ kdflex }}, you will want to go beyond the
essentials described in the previous section. Here is an introductory
overview of some key topics that you will find useful for day-to-day
use.






#### Computational Algorithms

{{ kdflex }} provides a comprehensive and fast collection of computational
algorithms designed for multibody, subgraph, and subtree
instances. These algorithms are built upon advanced techniques, notably
the **Spatial Operator Algebra (SOA)**, which is recognized for its
high-performance and robust computational dynamics
capabilities. {{ kdflex }} specifically leverages SOA-based low-cost, minimal
coordinate recursive techniques, which are considered among the lowest
cost and most robust methods available for multibody dynamics. The
algorithms are available for systems that include rigid as well as
flexible bodies.

Here's an introductory summary of the types of computational algorithms supported:

*   **Kinematics Algorithms**: {{ kdflex }} includes algorithms for both
    **inverse kinematics**, which determines the joint configurations
    needed to achieve a desired end-effector pose, and **forward
    kinematics**, which calculates the end-effector pose given the joint
    configurations.
*   **Dynamics Algorithms**:
    *   **Forward Dynamics**: Computes the accelerations of the system
        given the applied forces and torques. This is a standard
        capability, and {{ kdflex }} offers various methods, including
        **O(N) ABI** (Articulated Body Inertia) and **Tree-Augmented
        (TA) methods** for tree and graph systems. The TA method is
        particularly used for closed-chain topology systems, where it
        creates a spanning tree by introducing loop-cuts, applies O(N)
        methods, and then corrects the solution for the loop-cuts. For
        closed-chain systems, {{ kdflex }} also includes the advanced
        **Constraint-Embedding (CE) methods** that transforms the system
        into a tree-topology system for the direct use of the fast
        **O(N) ABI** methods and avoiding the need for constraint error
        management and complex DAE solvers.
    *   **Inverse Dynamics**: Calculates the forces and torques required to achieve a desired motion or acceleration for tree and graph systems.
*   **System Property Computations**: Algorithms are available for calculating essential system properties, such as:
    *   **System spatial momentum**
    *   **Mass properties**
    *   **Kinetic energy**
*   **Contact/Collision Dynamics Algorithms**: {{ kdflex }} supports
    collision detection and non-smooth dynamics related to contact and
    collision using penalty-based methods.

*   **Efficient Inter-Body Force Computation**: {{ kdflex }} provides an
    inexpensive way for computing inter-body forces using the SOA
    algorithm. While not strictly required for primary forward dynamics,
    this efficient computation can be an optional step when detailed
    force information is needed.
*   **Recursive OSCM Algorithms**: For certain computationally expensive
    tasks, such as evaluating expressions involving the Operational
    Space Mass Matrix (OSCM), {{ kdflex }} uses recursive SOA
    algorithms. These algorithms exploit the structure of the OSCM to
    develop decompositions that avoid the direct computation and
    inversion of the mass matrix, offering significant computational
    benefits.
*   **Dynamics Solvers and Integrators**: {{ kdflex }} incorporates C++
    solver classes to ensure proper compatibility between chosen
    solution methods (e.g., O(N) ABI, TA) and appropriate numerical
    integrators, such as ODE integrators for minimal coordinate
    formulations.

Overall, {{ kdflex }} is designed with a broad family of computational
algorithms to provide fast performance and accurate flexible multibody
dynamics modeling, addressing diverse engineering needs. See {ref}`computational_algorithms_sec` section for
details.




#### KModels

**KModels** are a core component of {{ kdflex }}'s simulation layer,
providing a structured way to interact with objects in a
simulation. They act as component models that can be used to perform
various tasks, such as:

*   Sensing the position and velocity of a joint or sensor node, as well
    as using complex models for body mounted sensors such as IMUs, cameras etc.
*   Applying direct forces via a joint or actuator node, as well as
    models such as terramechanics, aerodynamics for environmental
    interactions.
*   Supporting actions to support simulation services such as data
    logging, plotting, visualization updates etc..

The `Karana.Dynamics.ModelManager` class is responsible for registering
these component models, allowing their methods and functionality to be
integrated into the overall system dynamics.

In C++, KModels are created by deriving from a `Karana::Models::KModel`
base class, with the introspection capacity to determine which methods a
derived class has defined. Python models derive from a different class,
`Karana.Models.PyKModelBase`, and use object attributes. KModels support
custom parameter classes (e.g., derived from
`Karana::Models::KModelParams`) and can be configured for multi-rate
operations. Parameters for a KModel are typically initialized via member
variables on its `params` member or through setter methods. See {ref}`kmodels_sec` section for
details.

Examples of KModels include `ComputedTorque`, `DataLogger`,
`GraphicalSceneMovie`, `PID`, `PenaltyContact`, and `UniformGravity`. 

#### Scene for Geometry

The **Scene layer** in {{ kdflex }} defines an abstract interface for
managing 3D geometries attached to physical bodies within a multibody
system. This layer is implemented through classes like
`Karana.Scene.Scene`, `Karana.Scene.SceneNode`, and
`Karana.Scene.ScenePart`.

*   **`Karana.Scene.Scene`**: A base container for a hierarchy of
    geometries.
*   **`Karana.Scene.SceneNode`**: Represents an object with a transform
    (position, rotation, and uniform scale factor) relative to a
    parent. Scene nodes can be attached to one another, forming a tree
    structure for the overall scene. They also have a visibility flag.
*   **`Karana.Scene.ScenePart`**: A type of scene node that additionally
    possesses a 3D geometry and a material.

{{ kdflex }} supports various geometry types for scene parts, including
analytical primitive shapes like `BoxGeometry`, `CapsuleGeometry`,
`ConeGeometry`, `CylinderGeometry`, `RoundFrustumGeometry`, and
`SphereGeometry`, as well as triangular meshes
(`StaticMeshGeometry`). User-defined geometry types can also be
incorporated. Materials, such as Phong and PBR, describe the surface
properties and appearance of scene parts. The `Karana.Scene.ProxyScene`
acts as a manager for multiple client scenes, allowing for filtering of
scene parts. See {ref}`scenetop_sec` section for
details.

#### Visualization

{{ kdflex }} includes robust **3D graphics visualization** capabilities to
inspect and debug models. The primary implementation for visualization
is `Karana.Scene.WebScene`,  and uses `WebGL`
for hardware-accelerated 3D rendering in a web browser. This allows for
live, interactive visualization of a simulation by simply opening a
URL. A standalone `Electron` application is also available for local 3D
visualization.

Setting up visualization is streamlined using the `setupGraphics` helper
method, typically called on a multibody object. This method returns a
cleanup function and a `Karana.Scene.WebScene` instance, which can then
be used to programmatically set the camera position and orientation
(e.g., `web_scene.defaultCamera().pointCameraAt(...)`). Visualization
can display a built-in stick figure model for debugging or attach
primitive geometries or CAD parts for richer representations. See {ref}`visualization_sec` section for
details.

#### Data Plotting

{{ kdflex }} provides tools for **dynamic data plotting**, allowing plots to
be updated in real-time as a simulation progresses. Key classes for this
functionality are `Karana.KUtils.DataPlotter.DashApp` and
`Karana.KUtils.DataPlotter.SinglePlotData`.

*   **`Karana.KUtils.DataPlotter.DashApp`**: Used to create a live
    plotting instance. It can take a list of `PlotDataDS` instances to
    display multiple plots on the same web frontend. It automatically
    starts a websocket and HTTP server, printing a URL for users to view
    the plots in a web browser.
*   **`Karana.KUtils.DataPlotter.SinglePlotData`**: Defines the data to
    be plotted. This includes the title of the graph, the name and
    callable function for the x-axis data (independent variable), and a
    dictionary of names and callable functions for the y-axis data
    (dependent variables), which can be scalar or vector values.

Plots can be updated manually by calling the `update` method on the
`DashApp` instance, or automatically during a simulation step using the
`Karana.Models.DataPlotter` KModel. See {ref}`recipe_plotting_sec` section for
details.

#### Data Logging

**Data logging** in {{ kdflex }} allows for recording simulation data into
HDF5 files. This is primarily managed by the `Karana.KUtils.H5Writer`
class, which leverages `Karana.KUtils.PacketTableConfig` to define
tables and functions that populate their columns.

The general process for data logging involves:

1.  **Defining Data Structure:** Using `PacketTableConfig` instances to
    define each table you wish to create in the HDF5 file. These
    configurations include callable functions (defined in C++ or Python)
    that calculate new row data each time `H5Writer.log` is called.
2.  **Initializing the Logger:** Creating an instance of `H5Writer`.
3.  **Registering Data Configurations:** Calling `createTable` on the
    `H5Writer` for each `PacketTableConfig`.
4.  **Logging Data:** Invoking the `log` method on the `H5Writer` to
    write data for all active tables, or `logTable` to log a specific
    table regardless of its active status.

For automatically logging simulation data at regular intervals, the
`Karana.Models.DataLogger` KModel is used. This model can be registered
with the `StatePropagator`, and its `log_first_step` parameter can
ensure an initial data entry at time 0. Data logging can also be
performed independently of a running simulation. See {ref}`data_logging_sec` section for
details.


#### Cut-Joint Loop Constraints

In {{ kdflex }}, a multibody system with a closed-chain topology is
represented as a physical body tree combined with an additional set of
**cut-joint constraints**, defined as
`Karana.Dynamics.LoopConstraintHinge` instances. For systems with a
regular serial or tree topology, there are no loops, and thus no
cut-joints. Cut-joint constraints have hinges that define the
unconstrained motion across the cut-joint. The number of loops in a
multibody's topology establishes the lower bound on the number of
required cut-joint constraints, and the preferred option is to minimize
the number cut-joint constraints. However a larger number of cut-joint
constraints is permissible, and in the extreme case, all the tree hinges
can be replaced by cut-joint constraints to yield what is referred to as
the **fully-augmented (FA)** model. In the FA model, the multibody
topology consists of independent bodies, held together by cut-joint
constraints. The FA model is by far the predominant modeling approach by
most dynamics modeling tools.

{{ kdflex }} offers a numerical inverse kinematics solver through the
`Karana.Dynamics.ConstraintKinematicsSolver` class that can be used to
iteratively solve `Q` and `U` coordinates that satisfy the
constraints. See {ref}`cutjoint_constraints_sec` section for details.





#### Contact Dynamics
{{ kdflex }} supports **contact and collision dynamics**, which are
considered non-smooth dynamics. Contact dynamics is based on
penalty-based methods that simulate contact forces based on penetration
depth and Coulomb friction.

1.  **Collision Detection:** Handled by collision engines, which detect
    object collisions and provide information such as penetration depth
    and collision normals. The `Karana.Collision.FrameCollider` class is
    used to capture this information.
2.  **Contact Force Calculation:** Once collision information is
    gathered, contact forces are calculated and applied. This often
    involves creating a `PenaltyContact` instance with `FrameCollider`
    and `ContactForceBase` as arguments.

An example notebook, "2 link pendulum (collisions)," illustrates how to
use collision dynamics within {{ kdflex }}. See {ref}`collision_dynamics_sec` section for
details.


#### Model Parameters 

{{ kdflex }} supports the assignment of **quantities** and **units** for
numerical parameters and includes helper functions for unit conversion. See {ref}`units_quantities_sec` section for
details.

Proper **initialization** of parameter and state data is essential for
correct simulation results. {{ kdflex }} includes mechanisms to detect
initialization gaps and raise errors early so they can be fixed.  When
undetected, such gaps otherwise be notoriously difficult to detect and
fix. See {ref}`math_sec` section for
details.





#### Model and State Import/Export

{{ kdflex }} includes support for exporting the simulation model information
to the file system in standard formats such as `yaml`, `json`, `hdf5`
and more. The model data from these files can be imported in simulations
to recreate the model. In a similar way, state data and be exported to
the file system, and later imported to initialize system state in other
simulations. See {ref}`datastruct_sec` section for
details.


#### Environment variables

There are a number of environment variables in {{ kdflex }} that can be used to
configure its behavior based on your environment:

* `KARANA_LICENSE_FILE`: This must be set to the filepath of your license file.
* `KARANA_LOG_LEVEL`: Sets the logging verbosity level. This should be one of the options in {py:class}`LogLevel <Karana.Core.LogLevel>` such as `"WARN"` or `"DEBUG"`.
* `KARANA_SHARE_DIR`: If `kdflex` is installed to a nonstandard location, this should be set to the absolute path of the `share/Karana` directory.



<!--
#### Subhinges

#### CoordData for managing coordinate data

#### Pre-fabs

-->


---


(deepdive_sec)=
### 3. Deep dive


While the sections above focused on the important main stream {{ kdflex }}
capabilities, there are several additional advanced {{ kdflex }}
capabilities - some of which are described below.


#### SubTrees and SubGraphs


While most computations are carried out on the full multibody system, {{
kdflex }} supports the ability to limit the computations to just a part
of the multibody system by defining sub-tree and sub-graph
instances. Sub-trees are a connected subset of bodies in the multibody
system. Sub-graphs are sub-trees with additional constraints.  The
multibody class itself is a specialization of the sub-graph class.  Most
of the {{ kdflex }} algorithms take a sub-tree or sub-graph argument and
will limit their computations to just the bodies defined for them. 

There is no restriction on the number of sub-trees and sub-graphs that
can be defined. However, computations can only be carried out on
sub-graphs that have been explicitly enabled for algorithmic
computations. While multiple subgraphs may be simultaneously enabled
for algorithmic computation, there is a requirement that all enabled
ones be disjoint, i.e. there can be no overlap in the bodies they
contain. See {ref}`subtrees_sec` section for
details.


#### Non cut-joint constraints

{{kdflex }} supports additional constraint types beyond cut-joint
constraints. **Coordinate constraints** are an important constraint type
which can be used to define geared constraints that directly constrain
the coordinate rates of a pair of joints to a specific gear ration scale
factor.  The coupling can be either pairing of rotational/rotational
coordinates or rotational/translational ones.  See {ref}`coordinate_constraints_sec` section for
details.




#### Flexible Body Dynamics

**Flexible body dynamics** in {{ kdflex }} extends the simulation
capabilities beyond purely rigid bodies to include components that
deform under load. {{ kdflex }} supports flexible body dynamics 
using the modal analysis approach.

Key aspects include:

*   **Modal Representation**: Flexible bodies are typically represented
    using a set of assumed modes (e.g., normal modes from  FEM
    analysis) that describe their deformation. The motion of the
    flexible body is then described by the rigid body motion of a
    reference frame and the time-varying amplitudes of these modes.
*   **Coupling with Rigid Bodies**: {{ kdflex }} seamlessly couples the
    dynamics of these flexible bodies with the rigid bodies in the
    system, ensuring accurate interaction and force transmission.
*   **Computational Efficiency**: {{kdflex }} extends the **O(N) ABI**
    recursive methods to such deformable bodies as well to support fast
    dynamics computations.  multibody simulation.

This capability is vital for applications where component flexibility
significantly influences the overall system behavior, such as in
aerospace, automotive, and advanced robotics. See {ref}`modal_flex_body_sec` section for
details.

#### System Kinematics Analysis

**Kinematic analysis** in {{ kdflex }} focuses on analyzing closed-chain
topology systems. The kinematics analysis methods allow for the
computation, of system level constraint matrices, evaluating the
independence of the constraints on the system, and assessing the best
subset of coordinates to choose for independent coordinates - should
such a choice be needed. See {ref}`constraints_kin_algorithms_sec` section for
details.



#### Variable topology

{{ kdflex }} supports mid-stream structural changes to the multibody system
from body deletion, body addition, and body reattachment. Also support
are changes from the enabling and disabling of constraints at
run-time. The recursive nature of the SOA based computational dynamics
algorithms allows them to adapt to such changes with very little
overhead. Such powerful versatility allows {{ kdflex }} to support a rich
set of behaviors and broad range of realistic simulation scenarios. See {ref}`mbody_config_changes_sec` section for
details.





#### Compound Bodies

**Compound bodies** in {{ kdflex }} allow for the creation of complex rigid
bodies by combining multiple simpler rigid bodies into a single
entity. This is particularly useful when dealing with assemblies of
parts that move together as a single rigid unit. Instead of modeling
each sub-component individually and linking them with rigid joints
(which can increase computational cost), {{ kdflex }} allows you to compute
the combined mass, center of mass, and inertia tensor for the entire
compound body. This simplifies the model, improves computational
efficiency, and makes the system easier to manage. Compound bodies are
often used to represent structures like a robot's end-effector, a
vehicle chassis, or other rigid assemblies.

#### Constraint Embedding

**Constraint embedding** is a technique used in {{ kdflex }} to incorporate
kinematic constraints directly into the system's equations of
motion. Instead of using Lagrange multipliers or penalty methods to
enforce constraints, embedding modifies the system's dynamics equations
such that the constraints are inherently satisfied. This approach can
lead to more stable and efficient simulations, especially for systems
with complex closed-loop constraints.

{{ kdflex }} uses minimal coordinate techniques, which inherently embed
certain types of constraints (like those imposed by joints) by
describing the system's configuration with the smallest possible number
of independent variables. For more general constraints (e.g., loop
closures or specific contact conditions), {{ kdflex }} might use methods
that reformulate the dynamics to eliminate dependent coordinates,
effectively "embedding" the constraint into the system's reduced set of
equations. This contrasts with approaches that add constraint forces as
external terms.


#### Timed Events

The {{ kdflex }} state propagator allows the registering of user defined
**timed events**. The time event executions can be one time, irregular,
or periodic. The state propagator that state propagation supports the
execution of the registered time events at the correct time with valid
states. See {ref}`timed_events_sec` section for
details.

#### Multi-rate State Propagation

 {{ kdflex }} supports multi-rate simulations. Models can register specific
 rates at which they need to run. The {{ kdflex }} scheduler will take into
 account the different rate requirements to automatically determine the
 propagation hops required to meet the overall rates for all of the
 models. In addition, the propagator allows the specification of
 **zero-crossing** conditions. When such conditions are registered, the
 state propagation will detect the exact time when the condition is
 successfully and ensure that the associated callback is invoked at that
 time. See {ref}`kmodel_methods_sec` and {ref}`zero_crossings_sec` sections for
details.



#### Equilibration

**Equilibration** in {{ kdflex }} refers to the process of finding a static
equilibrium configuration for a multibody system. This involves
determining the set of generalized coordinates (e.g., joint angles) and
potentially external forces (e.g., actuator torques) where the net
forces and torques on all bodies in the system are zero, and the system
remains motionless.  This is a crucial capability for finding a
equilibrium starting configuration for a simulation to avoid large
transients and instabilities in the simulation runs.  The equilibration
solver typically employs iterative numerical methods to converge to a
state where all forces and moments are balanced.

#### FEMBridge

**FEMBridge** in {{ kdflex }} is a capability that facilitates the
integration of **Finite Element Method (FEM)** models with the multibody
dynamics environment. It acts as a bridge, allowing users to incorporate
flexible bodies whose properties and behavior are derived from FEM
analyses.

This means you can: take deformation modes, mass, and stiffness matrices
    from a pre-computed FEM analysis (e.g., from Nastran, Abaqus, or
    other FEA software) and use them to represent a flexible body within
    {{ kdflex }}.


FEMBridge is essential for accurately simulating systems where
structural flexibility plays a significant role, such as lightweight
robotic arms, aircraft components, or compliant mechanisms, without
having to perform the full, computationally expensive FEM analysis at
each time step of the multibody simulation.

#### State Space Model Generation

**State space model generation** in {{ kdflex }} involves deriving a set of
first-order ordinary differential equations (ODEs) that describe the
system's dynamics. A state-space model represents the system's behavior
using a minimal set of state variables (e.g., positions and velocities)
and inputs, and provides outputs that are functions of these states and
inputs.

{{ kdflex }} can:

*   **Linearize Dynamics**: Linearize the non-linear multibody dynamics
    equations around an operating point (e.g., an equilibrium
    configuration).
*   **Generate A, B, C, D Matrices**: Output the `A`, `B`, `C`, and `D`
    matrices that define the linear time-invariant (LTI) state-space
    model:
    *   `dx/dt = Ax + Bu`
    *   `y = Cx + Du` where `x` is the state vector, `u` is the input
    vector, and `y` is the output vector.

This capability is extremely valuable for:

*   **Control System Design**: Designing controllers using linear
    control theory (e.g., LQR, H-infinity).
*   **System Analysis**: Analyzing stability, controllability, and
    observability of the multibody system.
*   **Model Reduction**: Creating simplified models for higher-level
    simulations or embedded applications.

See {ref}`state_space_sec` section for
details.

#### Modal Analysis

**Modal analysis** in {{ kdflex }} is a technique used to understand the
inherent dynamic characteristics of a flexible structure. It involves
calculating the natural frequencies and corresponding mode shapes
(eigenvectors) of a system. These modes represent the patterns of
vibration that a structure would exhibit if disturbed from its
equilibrium position.

In {{ kdflex }}:

*   **Basis for Flexible Bodies**: The results of modal analysis (often
    derived from FEM software) are used as the basis for representing
    flexible bodies within the multibody dynamics simulation. Instead of
    modeling every finite element, the flexible body's deformation is
    approximated by a superposition of its dominant mode shapes.
*   **Understanding Vibrations**: Modal analysis helps engineers
    identify potential resonance issues, predict how a structure will
    vibrate under dynamic loads, and design structures to avoid
    undesirable vibrational characteristics.

Using modal analysis, {{ kdflex }} can support the development of reduced
order models for the system that are important for control system design
and analysis. See {ref}`gnc_algorithms_sec` section for
details.

<!--
#### Data Caching and Stale Tracking

{{ kdflex }} is highly optimized for performance, and a core part of
this is its intelligent **`DataCache`** system.

*   **`DataCache`**: This class transparently stores computed values
    (e.g., mass matrices, transformations, kinematics) and automatically
    marks them as "stale" when their underlying inputs change.
*   **Stale Flag Mechanism:** When a `DataCache` is accessed and found
    to be stale, it automatically triggers a registered callback
    function to recompute and update its value.
*   **Dependencies:** `DataCache`s form a dependency graph. If a
    "parent" cache becomes stale, all its "child" caches that depend on
    its value are also automatically marked stale.

**Why it matters:** This system ensures that computations are only
performed when necessary, significantly boosting performance. While
largely automatic, understanding the concept helps you appreciate {{
kdflex }}'s efficiency and debug potential issues related to data
freshness.


#### Usage Tracking

**Usage tracking** in {{ kdflex }} refers to the internal mechanisms that
monitor and log how the {{ kdflex }} software is being used. This typically
involves collecting anonymous data on:

*   **Feature Usage**: Which specific functionalities, algorithms, or
    classes are being invoked.
*   **Performance Metrics**: Data related to simulation run times, model
    complexity, and computational resource utilization.
*   **Error Reporting**: Information about crashes or unexpected
    behavior.

The primary purpose of usage tracking is to help the {{ kdflex }}
development team understand how users interact with the software,
identify popular features, pinpoint areas for improvement, and debug
issues. This data is usually collected in an aggregated and anonymized
fashion to protect user privacy.




#### Debugging and Troubleshooting: Your Best Friends

Simulations can be complex, and `NaN`s (Not a Number) or unexpected
behavior are part of the journey. {{ kdflex }} provides powerful
debugging tools:

*   **`Karana.Core.MsgLogger`:** This is your primary logging system.
    *   Use `kc.MsgLogger.info()`, `kc.MsgLogger.debug()`,
        `kc.MsgLogger.warn()`, `kc.MsgLogger.error()`, and
        `kc.MsgLogger.trace()` to output messages at different verbosity
        levels.
    *   **Runtime Control:** You can dynamically change the verbosity
        level of loggers (e.g., `kc.MsgLogger.changeVerbosity("stdout",
        kc.LogLevel.DEBUG)`) without modifying code.
    *   **Lazy Message Generation:** For performance, use `lambda`
        functions for `debug` and `trace` messages
        (`kc.MsgLogger.debug(lambda: f"My detailed message:
        {expensive_calc()}")`). The lambda only executes if the message
        level is enabled.
*   **`Karana.Math.floatingPointExceptions(True)`:** This is a
    game-changer for tracking `NaN`s. Enabling this will cause a Python
    exception (and a debugger break if attached) at the *exact point*
    where a floating-point error (like division by zero or `sqrt(-1)`)
    occurs. This helps you pinpoint the source of `NaN`s immediately,
    rather than waiting for them to propagate.
*   **`StatePropagator` Callbacks (`pre_deriv_fns`,
    `post_deriv_fns`):** * Register functions with
    `sp.fns.pre_deriv_fns` to execute code *before* derivatives are
    computed. This is ideal for applying forces or checking the state
    (`Q`, `U`) for `NaN`s.
    *   Register functions with `sp.fns.post_deriv_fns` to execute code
        *after* derivatives are computed. This is useful for checking
        the computed derivatives (`QD`, `UD`) for `NaN`s or for logging.

**Why it matters:** Effective debugging tools save you countless
hours. Learn to use the `MsgLogger` and `floatingPointExceptions` early!

-->
