Karana.Dynamics

Contents

Karana.Dynamics#

Classes and modules related to dynamics computation.

Submodules#

Classes#

Algorithms

@class Algorithms Class with static methods for various system level

BilateralConstraintBase

@class BilateralConstraintBase Base class for bilateral constraints

BilateralConstraintType

Members:

BodyBase

CECompoundBody

@class CECompoundBody Represents a compound body

CECompoundSubhinge

@class CECompoundSubhinge Represents the articulation subhinge class

CompoundBody

CompoundBodyInvDynVectors

CompoundHinge

CompoundSubhinge

ConstraintKinematicsSolver

ConstraintNode

CoordBase

@class CoordBase Represents the base class for Q, U etc coordinate

CoordData

CoordDataCoordOffset

CoordinateConstraint

@class CoordinateConstraint Class for coordinate constraints

FramePairHinge

@class FramePairHinge Represents the articulation class used by

FrameToFrameJacobianGenerator

GearedCompoundBody

@class GearedCompoundBody Constraint embedding class for a body pair

HingeBase

HingeNode

@class HingeNode Represents the base class for physical HingePnode and

HingeOnode

HingeOnodeATBIFilterVectors

HingeOnodeATBIMatrices

HingeOnodeATBISmootherVectors

HingeOnodeInvDynVectors

HingeOnodeUpsilonMatrices

HingeParams

Struct with hinge parameters for the HingeType::HOOKE,

HingePnode

HingePnodeATBIFilterVectors

HingePnodeATBIMatrices

HingePnodeATBISmootherVectors

HingePnodeInvDynVectors

HingePnodeUpsilonMatrices

HingeType

Members:

Linear3Subhinge

@class Linear3Subhinge Represents a 3 dof translational subhinge

LinearSubhinge

@class LinearSubhinge Represents a 1 dof translational subhinge

LockedSubhinge

@class LockedSubhinge Represents a locked subhinge

LoopConstraintBase

@class LoopConstraintBase Base class for loop constraints See the

LoopConstraintConVel

@class LoopConstraintConVel Class for constant velocity loop

LoopConstraintHinge

@class LoopConstraintHinge Class for loop constraints that are based

LoopConstraintQMats

LoopsCompoundBody

@class LoopsCompoundBody Constraint embedding class for a bodies with

ModalAnalysis

MultiJacobianGenerator

Multibody

Node

@class Node Represents the body node base class

NodeDeformationProvider

@class NodeDeformationProvider Base abstract class node deformation

Physical1DofSubhinge

@class Physical1DofSubhinge Base class for 1 degree of freedom

PhysicalBody

PhysicalBodyParams

Struct with parameters for a PhysicalBody rigid physical body */

PhysicalHinge

PhysicalSubhinge

@class PhysicalSubhinge Represents the abstract base class for

PhysicalSubhinge_T_0_0

@class PhysicalSubhinge Represents the abstract base class for

PhysicalSubhinge_T_1_1

@class PhysicalSubhinge Represents the abstract base class for

PhysicalSubhinge_T_3_3

@class PhysicalSubhinge Represents the abstract base class for

PhysicalSubhinge_T_4_3

@class PhysicalSubhinge Represents the abstract base class for

PinSubhinge

PrePostCallbackRegistry

Scheduler

@class Scheduler The schedule class for the state propagator

ScrewSubhinge

@class ScrewSubhinge Represents a 1 dof helical subhinge with coupled

SpFunctions

Struct with optional user-defined functions to be used by the state

SpOptions

Options for the state propagator */

SpSolverType

Members:

SpStatusEnum

Enum with values to classify the reason for the termination of a step

SphericalQuatSubhinge

@class SphericalQuatSubhinge Represents a 3 dof rotational subhinge

SphericalSubhinge

@class SphericalSubhinge Represents a 1 dof rotational subhinge using

StatePropagator

StatePropagatorCounters

StickPartsConfig

SubGraph

@class SubGraph Represents a subtree of bodies with motion constraints

SubTree

@class SubTree Represents a SubTree with connected bodies

SubTreeDumpTreeOptions

SubhingeBase

SubhingeType

Members:

TerminateCrossingCallbackRegistry

TimeKeeper

Keeps track of time.

TimedEvent

This class is used to execute events at a given time. The initial time

ZeroCrossingCallbackRegistry

ModalNodeDeformationProvider

@class ModalNodeDeformationProvider Node deformation provider class

PhysicalModalBody

@class PhysicalModalBody Flexible body class supporting assumed modes

PhysicalModalBodyParams

Package Contents#

class Karana.Dynamics.Algorithms#

@class Algorithms Class with static methods for various system level algorithms.

This is a container class for static methods to compute various multibody algorithms. See Dynamics Computations section for more information.

static constraintKinematicsSolver(arg0: SubGraph) ConstraintKinematicsSolver#

Return a constraint/inverse kinematics solver instance

Creates a constraint kinematics (CK) solver for the specified SubGraph and its coordinates and loop constraints. The CK solver uses the CoordData for the SubGraph for the coordinates to solver for. Coordinates can be frozen during the solution process. Only the subhinge coordinates are solved for, and deformation coordinates - if any - are not used.

See the Kinematics Algorithms section for more information.

Parameter sg:

SubGraph instance

Returns:

The constraint kinematics solver instance

static evalCentroidalMomentum(arg0: SubTree) Karana.Math.SpatialVector#

Calculate the centroidal spatial momentum for the SubTree

This is the same as the sub-tree’s spatial momentum (computed by evalSpatialMomentum()), except that this value is referenced about the sub-tree’s center of mass location, though still represented in the virtual root frame. Note that this quantity is conserved in the absence of external forces on the system.

This method does not support deformable bodies.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

Spatial momentum.

static evalCentroidalMomentumMatrix(arg0: SubTree) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the centroidal momentum matrix for the SubTree

This returns the centroidal momentum matrix (CMM) that defines the mapping between the system generalized velocities and the system’s centroidal momentum. Note that this matrix is configuration dependent. This matrix is used in the context the control of legged robots and managing the motion of their CM for stable walking.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

The 6xnU centroidal momentum matrix (CMM).

static evalCmLocation(arg0: SubTree) Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]#

Return the location of the sub-tree CM from the virtual root.

Return the current location of the center-of-mass frame for the whole sub-tree with respect to the virtual root.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

The position of the CM with respect to the virtual root.

static evalComputedTorque(arg0: SubTree) Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Calculate the computed torque using NE algorithm

Method to compute the “computed torque”, i.e. the generalized forces needed - usually for a specific generalized acceleration inputs. This assumes that the state (generalized coordinates (Q) and velocities (U) have been set to the desired values in the multibody system, as have the generalized accelerations (Udot).

This method should not to be used for systems with deformable bodies. Systems with deformable bodies are under-actuated, while computed torque only applies to fully actuated systems. Prescribed subhinges and constraints are ignored in this computation.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

The computed T generalized forces

static evalDependentVelCoordinatesMatrix(arg0: SubGraph, arg1: collections.abc.Sequence[SupportsInt], arg2: bool) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the dependent velocity coordinates matrix map for the specified set of independent coordinates

For a SubGraph with constraints, only a subset of the velocity coordinates are independent. This method computes the matrix X that can be used to compute the dependent velocity coordinates, U_d, for the specified set of independent velocity coordinates, U_i, via U_d = X * U_i,

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter indep_indices:

the list of independent U indices

Parameter full:

if true, the matrix also includes columns for the independent coordinates, else only for the dependent coordinates

Returns:

the dependent coordinates mapping matrix

static evalExternalSpatialForce(arg0: SubTree) Karana.Math.SpatialVector#

Calculate the overall external spatial force for for the SubTree about its CM

The computed value includes external force contributions from all of the force nodes on all the bodies (including active contact nodes) as well as any constraint forces from constraint nodes. The returned value is referenced about, and represented in the sub-tree’s center of mass frame.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

The overall external spatial force.

static evalForwardDynamics(st: SubTree) None#

Compute the forward dynamics for a system.

This uses tree-augmented forward dynamics if there are with loop constraints, and tree forward dynamics if there are no loop constraints.

The tree-augmented algorithm solves the graph system forward dynamics using recursive {{ SOA }} recursive algorithms with exact enforcement of the loop constraints. This algorithm does not require the computation of inversion of the mass matrix.

The tree forward dynamics uses Articulated Body Inertia (ATBI) based forward dynamics.

See the Forward Dynamics Algorithms section for more information.

Parameter st:

SubTree instance

static evalFramesOSCM(st: SubTree, body_frames: collections.abc.Sequence[Karana.Frame.Frame], subhinges: collections.abc.Sequence[PhysicalSubhinge] = []) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the tree system operational space compliance matrix (OSCM)

The OSCM is defined at J*M^{-1}*J^*, where J is the Jacobian matrix, and M is the mass matrix of the system. This method does not use this brute force expression. Instead it uses the {{ SOA }} recursive methods to do this computation without ever computing the mass matrix or its inverse, or even the Jacobian matrix itself.

In addition, one or more subhinges can also be provided. The returned matrix will include additional mass matrix inverse rows and columns for these subhinges. This is equivalent to computing the OSCM for the “extended Jacobian” defined as [J \ E], where E is a selector matrix that picks out a subset of the subhinges in the system. While the rows and columns associated with the frames define a mapping between spatial forces and spatial accelerations, the subhinge rows and columns define the mapping between generalized forces and generalized accelerations. The off-diagonal sub-blocks define cross-term mappings.

If no subhinges are specified, the returned matrix is the regular OSCM, and if no frames are specified, the returned matrix is the sub- block of the mass matrix inverse with rows and columns for the specified subhinges. This more general form of the OSCM allows users to properly handle a mix of constraints from the task and joint spaces.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter body_frames:

list of Frame instances to compute the OSCM for

Parameter subhinges:

list of physical subhinge mass matrix inverse contributions to include

Returns:

The tree OSCM matrix

static evalGravityCompensation(arg0: SubTree) Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Compute the gravity compensation torque for the system

Compute the generalized forces needed to support the gravitational load on the system. This method automatically takes into account additional bodies that are attached or detached from the system.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

The vector of generalized forces.

static evalIndepPoseConstraintIndices(arg0: SubGraph) list[int]#

Compute the indices for best independent bilateral constraints on the system based on the pose gradients matrix map.

For a SubGraph with constraints, only a subset of the Q pose-level constraints may be independent. This method computes the indices of the independent constraints.

Since the pose and velocity level constraints may not be the same, the results from this method may not match the constraint and coordinate indices returned by the evalIndepVelConstraintCoordIndices() method.

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Returns:

a pair consisting of a list of independent constraint indices, and a list of independent coordinate indices based on the pose-level constraints

static evalIndepPoseCoordIndices(sg: SubGraph, available_indices: collections.abc.Sequence[SupportsInt] = []) list[int]#

Compute the best indices for independent Q coordinates for the bilateral constraints on the system

For a SubGraph with constraints, only a subset of the Q pose-level coordinates are independent. This method computes the indices of the coordinates in the Q vector that are best choice for independent coordinates (at the current configuration). A non-empty available_indices list can be used to restrict the pool of indices to pick the independent coordinates from.

Since the pose and velocity level constraints may not be the same, the results from this method may not match the constraint and coordinate indices returned by the evalIndepVelConstraintCoordIndices() method.

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter available_indices:

If non-empty, the indices to pick the independent coordinates from

Returns:

a pair consisting of a list of independent constraint indices, and a list of independent coordinate indices based on the pose-level constraints

static evalIndepVelConstraintCoordIndices(sg: SubGraph, available_indices: collections.abc.Sequence[SupportsInt] = []) tuple[list[int], list[int]]#

Compute the best indices for independent constraints and velocity coordinates using the velocity constraint matrix

For a SubGraph with constraints, only a subset of the U velocity coordinates are independent (and not all constraints may be independent). This method computes the indices of the independent constraints, and the indices of the coordinates in the U vector that are best choice for independent velocity coordinates (at the current configuration).

Since the pose and velocity level constraints may not be the same, the results from this method may not match the constraint and coordinate indices returned by the evalIndepPoseCoordIndices() and evalIndepPoseConstraintIndices() methods.

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter available_indices:

the list of indices to pick the independent ones from

Returns:

a pair consisting of a list of independent constraint indices, and a list of independent coordinate indices based on the velocity- level constraints

static evalInverseDynamics(arg0: SubTree) None#

Evaluate Newton-Euler inverse dynamics

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

static evalKineticEnergy(arg0: SubTree) float#

Calculate the overall kinetic energy of the component bodies in the SubTree

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

Kinetic energy.

static evalSerialChainMassMatrixInverse(subtree: SubTree, coord_data: CoordData = None) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate serial-chain system mass matrix inverse using {{ SOA }} operator-based decomposition expressions

This method does not require the mass matrix or matrix inversions to compute the mass matrix inverse! The algorithm instead takes advantage of an analytical operator based decomposition of the mass matrix inverse to carry out the computation much lower cost.

A CoordData argument can be specified to set the specific order for the rows and columns in the computed mass matrix inverse. This method cannot be used for systems containing deformable bodies. This mass matrix inverse computation can also be done via the more general evalTreeMassMatrixInverse() which also works for deformable bodies. We however also have this method since it is considerably simpler for the simpler serial-chain topology.

This method does not allow internal 6 dof hinges to avoid ambiguities about whether mass properties should be coupled across such hinges. Also the prescribed motion flag for any subhinge that has been enabled is reset. This is to ensure that the mass matrix computed from this method are consistent with the results from the alternative dynamics based computation methods.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter coord_data:

CoordData to specify the order of the mass matrix inverse’s rows and columns

Returns:

The serial-chain mass matrix inverse

static evalSpatialInertia(arg0: SubTree, arg1: Karana.Frame.Frame) Karana.Math.SpatialInertia#

Calculate the overall spatial inertia for a sub-tree

Return the overall spatial inertia of all the bodies in the sub-tree about the reference frame. The multibody virtual root serves as the default reference frame.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter ref_frame:

reference frame for the spatial inertia (default: the virtual root)

Returns:

The overall tree spatial inertia

static evalSpatialMomentum(arg0: SubTree) Karana.Math.SpatialVector#

Calculate the overall spatial momentum for the SubTree

The returned value is by default is referenced about, and represented in the virtual root frame. Note that this quantity is conserved in the absence of external forces on the system.

See the Embedded Control Algorithms section for more information.

Parameter st:

SubTree instance

Returns:

Spatial momentum.

static evalSqueezeMatrix(arg0: SubGraph) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return a matrix for computing squeeze generalized forces

Compute the squeeze matrix, S, whose column space consists of “squeeze” generalized forces, i.e. generalized forces that only effect internal forces within the constrained multibody and do not induce any motion. Thus, the generalized force, S*x, for any vector x will not induce any motion. The row dimension is nU(), while the column dimension is the size of the constraints on the system.

Note that the returned matrix may not have full column rank when the constraints are not all independent. The evalIndepVelConstraintCoordIndices() method can be used to check for the columns that are independent.

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Returns:

The squeeze matrix.

static evalTreeMassMatrixCRB(subtree: SubTree, coord_data: CoordData = None) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the tree system mass matrix using CRB approach

This method uses the composite rigid body inertias (CRB) recursive method for computing the mass matrix

See the System Properties Algorithms section for more information.

This method does not allow internal 6 dof hinges to avoid ambiguities about whether mass properties should be coupled across such hinges. Also the prescribed motion flag for any subhinge that has been enabled is reset. This is to ensure that the mass matrix computed from this method are consistent with the results from the alternative dynamics based computation methods.

Parameter st:

SubTree instance

Parameter coord_data:

CoordData to specify the order of the mass matrix rows and columns

Returns:

The tree mass matrix

static evalTreeMassMatrixInvDyn(subtree: SubTree, coord_data: CoordData = None) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the tree system mass matrix using Newton-Euler inverse dynamics

Calculate the tree system mass matrix using NE inverse dynamics. A CoordData argument can be specified to set the specific order for the rows and columns in the computed mass matrix.

This method does not currently support deformable bodies.

This method does not allow internal 6 dof hinges to avoid ambiguities about whether mass properties should be coupled across such hinges. Also the prescribed motion flag for any subhinge that has been enabled is reset. This is to ensure that the mass matrix computed from this method are consistent with the results from the alternative dynamics based computation methods.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter coord_data:

CoordData to specify the order of the mass matrix rows and columns

Returns:

The tree mass matrix

static evalTreeMassMatrixInvFwdDyn(subtree: SubTree, coord_data: CoordData = None) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the tree system mass matrix inverse using forward dynamics

Calculate the tree system mass matrix inverse using ATBI forward dynamics. A CoordData argument can be specified to set the specific order for the rows and columns in the computed mass matrix inverse. This method currently supports physical rigid and flexible bodies, but not compound bodies.

This method does not allow internal 6 dof hinges to avoid ambiguities about whether mass properties should be coupled across such hinges. Also the prescribed motion flag for any subhinge that has been enabled is reset. This is to ensure that the mass matrix computed from this method are consistent with the results from the alternative dynamics based computation methods.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter coord_data:

CoordData to specify the order of the mass matrix inverse’s rows and columns

Returns:

The tree mass matrix inverse

static evalTreeMassMatrixInverse(subtree: SubTree, coord_data: CoordData = None) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Calculate the tree system mass matrix inverse using {{ SOA }} decomposition expressions

This method does not require the mass matrix or matrix inversions to compute the mass matrix inverse! The algorithm instead takes advantage of an analytical operator based decomposition of the mass matrix inverse to carry out the computation much lower cost. For serial-chain system, the mass matrix inverse can also be computed using the evalSerialChainMassMatrixInverse() specifically for such systems.

A CoordData argument can be specified to set the specific order for the rows and columns in the computed mass matrix inverse. This method is currently limited to physical and rigid bodies.

This method supports both rigid and deformable bodies.

This method does not allow internal 6 dof hinges to avoid ambiguities about whether mass properties should be coupled across such hinges. Also the prescribed motion flag for any subhinge that has been enabled is reset. This is to ensure that the mass matrix computed from this method are consistent with the results from the alternative dynamics based computation methods.

See the System Properties Algorithms section for more information.

Parameter st:

SubTree instance

Parameter coord_data:

CoordData to specify the order of the mass matrix inverse’s rows and columns

Returns:

The tree mass matrix inverse

static evalVelCoordinatePartitioning(sg: SubGraph, available_indices: collections.abc.Sequence[SupportsInt] = []) tuple[list[int], Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]]#

Compute the best indices for independent and dependent velocity coordinates matrix map

For a SubGraph with constraints, only a subset of the velocity coordinates are independent. This method computes the indices of the coordinates in the U vector that are best choice for independent velocity coordinates (at the current configuration). It also returns a matrix X that can be used to compute the dependent velocity coordinates, U_d, for a set of independent velocity coordinates, U_i, via U_d = X * U_i,

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter available_indices:

the list of indices to pick the independent ones from

Returns:

The list of independent coordinate indices and the dependent coordinate mapping matrix

static evalVelocityConstraintMatrix(arg0: SubGraph, arg1: bool) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the velocity constraint matrix.

Compute the velocity constraint matrix, Gc, such that Gc * U = 0, i.e. the matrix whose null space contains the generalized velocity U values that satisfy the loop and coordinate constraints on the SubGraph.

If “with_constraints” is true, then Gc’s columns include ones for the loop hinge constraint coordinates, and the block row for each constraint contain the mapping to their constraint errors.

On the other hand, if “with_constraints” is false, Gc’s columns exclude ones for the constraint coordinates, and the block row for each loop hinge constraint maps to the residual vector for each constraint. In the latter case, the number of columns and rows shrink equally by the number of constraint coordinates.

Note that the returned matrix may not have full row rank when the constraints are not all independent. The evalIndepVelConstraintCoordIndices() method can be used to check for the rows that are independent.

The SubGraph::constraintErrorAt() and the SubGraph::constraintResidualAt() methods and can be used to look up the constraint instance associated with any specific row index in the returned matrix (based on whether with_constraint is ‘true’ or ‘false’ respectively). Similarly, the SubGraph::coordAt() method can be used to look up the coordinate instance for a specific column index in the returned matrix.

See the Constraints Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter with_constraints:

If true, columns for the hinge loop constraint coords are included

Returns:

The velocity constraint matrix.

static jacobianGenerator(arg0: collections.abc.Sequence[Karana.Frame.FrameToFrame], arg1: CoordData) MultiJacobianGenerator#

Return a Jacobian generator for the subtree

Create a Jacobian generator object for the specified SubGraph and its coordinates and the list source/target frame pairs in the list of frame2frames. Note that the resulting jacobian and pose gradient matrices will exclude columns for any coordinates frozen in the coord data of the subtree.

See the Kinematics Algorithms section for more information.

Parameter f2fs:

list of FrameToFrames to compute the Jacobian for

Parameter cd:

the CoordData that specify the columns in the computed Jacobian

Returns:

The Jacobian generator instance

static modalAnalysis(st: SubTree, deriv_fn: collections.abc.Callable[[], None], tol: SupportsFloat = 0.001) ModalAnalysis#

Perform a modal analysis for the sub-tree.

This creates a state space model of the system about the current configuration, and then solves an eigenproblem to get the frequencies and mode shapes.

See the Guidance and Control Related Algorithms section for more information.

Parameter st:

The subtree whose bodies should be used for the modal analysis.

Parameter deriv_fn:

The derivative function to use when computing the StateSpace model used to compute the eigenproblem.

Parameter tol:

The tolerance used to eliminate rigid-body modes.

Returns:

the eigen problem solution for the state space modal

static stateSpaceGenerator(arg0: SubGraph, arg1: SupportsInt, arg2: SupportsInt, arg3: collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], None], arg4: collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], Annotated[numpy.typing.NDArray[numpy.float64], [m, 1], flags.writeable]], None]) Karana.Math.StateSpace#

Create generator for linearized state space representation of the system

Method to create a StateSpace object for creating (A,B,C,D) state space linear system matrices for sub-tree multibody system. The returned state space generation object’s generate(x,u) can be called to compute the state space matrices at the state and input vector set point values about which the linearization should be carried out.

The first two inputs are the size of the inputs and outputs for the state space system. The u_fn argument is a user-defined function that takes (x,u) arguments and sets the appropriate forces, gravity etc values for the in the multibody system for dynamics computations. The y_fn argument takes (x, u, y) arguments and computes the outputs y for the (x, u) and state and input values.

See the Guidance and Control Related Algorithms section for more information.

Parameter sg:

SubGraph instance

Parameter n_inputs:

number of inputs

Parameter n_outputs:

number of outputs

Parameter u_fn:

function to evaluate the state derivative value for an input value

Parameter y_fn:

function to evaluate the output value for a given state

Returns:

State space generator instance

class Karana.Dynamics.BilateralConstraintBase#

Bases: Karana.Core.LockingBase

@class BilateralConstraintBase Base class for bilateral constraints

See the Coordinate constraints section for more discussion on bilateral constraints.

accelError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the current constraint spatial acceleration error

Returns:

the acceleration error

nResiduals() int#

Return the size of residuals for the constraint

Returns:

the residuals size for the constraint

poseError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the 6 size pose residual term for the constraint

Used for computing the pose configuration kinematics

Returns:

The pose error

type() BilateralConstraintType#

Return the bilateral constraint type

Returns:

the bilateral constraint type

velError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the current constraint spatial velocity error

Returns:

the spatial velocity error as a 6-vector

class Karana.Dynamics.BilateralConstraintType(value: SupportsInt)#

Members:

HINGE_LOOP : //!< hinge loop constraint

CONVEL_LOOP : //!< convel loop constraint

COORDINATE : //!< coordinate constraint

CONVEL_LOOP: ClassVar[BilateralConstraintType]#
COORDINATE: ClassVar[BilateralConstraintType]#
HINGE_LOOP: ClassVar[BilateralConstraintType]#
__members__: ClassVar[dict[str, BilateralConstraintType]]#
__eq__(other: Any) bool#
__getstate__() int#
__hash__() int#
__index__() int#
__int__() int#
__ne__(other: Any) bool#
__repr__() str#
__setstate__(state: SupportsInt) None#
__str__() str#
property name: str#
property value: int#
class Karana.Dynamics.BodyBase#

Bases: CoordBase

isCompoundBody() bool#

Return flag indicating whether this is a CompoundBody

Returns:

true is the body is a CompoundBody

isRootBody() bool#

Return true is this body is the Multibody’s virtual root body

The default return value if false, since only physical bodies can possibly be the virtual root body.

Returns:

true if this is the virtual root body

multibody() Multibody#

Return the Multibody system that the body belongs to

Returns:

the parent Multibody instance

parentHinge() HingeBase#

Return the parent hinge for the body.

For a PhysicalBody, parent hinge is a PhysicalHinge, while for a CompoundBody the parent hinge is a CompoundHinge

Returns:

The parent HingeBase instance

class Karana.Dynamics.CECompoundBody#

Bases: CompoundBody

@class CECompoundBody Represents a compound body

This class is for compound bodies representing a subtree of bodies.

independentIndicesQ() list[int]#
independentIndicesU() list[int]#
class Karana.Dynamics.CECompoundSubhinge#

Bases: CompoundSubhinge

@class CECompoundSubhinge Represents the articulation subhinge class for compound body subhinge with embedded constraints

class Karana.Dynamics.CompoundBody(name: str, parent_subtree: SubTree, subtree: SubTree)#

Bases: BodyBase, Karana.Core.LockingBase

static create(name: str, parent_subtree: SubTree, subtree: SubTree) CompoundBody#

Factory create method for a CompoundBody

Parameter parent_subtree:

the parent SubTree for the compound body

Parameter name:

body name

Parameter component_bodies:

SubTree with the bodies behind aggregated

Returns:

the CompoundBody instance

bodiesTree() SubTree#

Return the SubTree for the aggregated bodies

Returns:

the aggregated bodies SubTree

containsBody(arg0: BodyBase) bool#

Return true if the specified BodyBase body is embedded at some level within this compound body

Parameter bd:

the input body

Returns:

true if the body belongs to the subtree

getInterBodyForceTreeFwdDyn() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#
inverseDynamicsVectors() Ellipsis#

Return the updated inverse dynamics vectors

Returns:

the inverse dynamics vectors

physicalBodiesTree() SubTree#

Return the SubTree with aggregated physical bodies

The returned tree only has physical bodies, and is obtained by recursively expanding out any compound bodies within the aggregated bodies in this compound body

Returns:

the SubTree with all aggregated physical bodies

class Karana.Dynamics.CompoundBodyInvDynVectors#
property f: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#
property f_prime: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#
class Karana.Dynamics.CompoundHinge#

Bases: HingeBase, Karana.Core.LockingBase

compoundBody() CompoundBody#

Returns the CompoundBody for the hinge

Returns:

the outboard CompoundBody instance

class Karana.Dynamics.CompoundSubhinge#

Bases: Karana.Core.LockingBase, SubhingeBase

atbiCoordMapMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
class Karana.Dynamics.ConstraintKinematicsSolver(name: str, subgraph: SubGraph)#

Bases: Karana.Core.LockingBase

static create(name: str, subgraph: SubGraph) ConstraintKinematicsSolver#

Factory method to create a ConstraintKinematicsSolver instance

Creates constraint kinematics solver for the specified SubGraph’s coordinates and constraints. Frozen_coordinates can be set in the SubGraph’s CoordData to specify ones that should be frozen and not changed by the kinematics solver.

Parameter name:

instance name

Parameter sg:

the SubGraph to use for coordinates and constraints

Returns:

new ConstraintKinematicsSolver instance.

checkVelJacobian(tolerance: SupportsFloat = 1e-06) bool#

Verify that the velocity Jacobian values from the analytical and numerical differencing approaches agree.

Parameter tolerance:

the comparison tolerance to use

Returns:

return true if the Jacobians agree

clearFrozenCoords() None#

Method to empty out list of frozen coordinates

dump(flag: str = '') None#

Print out information about the CK solver.

Parameter prefix:

the prefix to use for each line of output

freezeCoord(arg0: CoordBase, arg1: SupportsInt) None#

Method to freeze a coordinate component

The frozen coordinate element values are not changed by the solveQ(), solveU() and solveUdot() methods used for solving the constraint kinematics.

Parameter coord:

The coordinate whose element is being frozen

Parameter index:

The index for the coordinate element being frozen

frozenCoords() list[int]#

Return the list of frozen coordinate indices.

Returns:

the list of frozen coordinate indices.

getNonfrozenQ() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Q coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

getNonfrozenU() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the U velocity coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

getNonfrozenUdot() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Udot acceleration coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

nonfrozenNU() int#

The number of U velocity coords for the CoordBase.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

the number of velocity coordinates

setNonfrozenQ(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#

Set the Q coordinates.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter Q:

Array of values.

setNonfrozenU(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#

Set the U velocity coordinates.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter U:

Array of values.

setNonfrozenUdot(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#

Set the Udot acceleration coordinates.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter u_dot:

Array of values.

solveQ() float#

Solve for the Q generalized coordinates to satisfy constraints

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

The final error.

solveU() float#

Solve for the U velocity coordinates to satisfy velocity level constraints

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

The final error.

solveUdot() float#

Solve for the Udot accel coordinates to satisfy accel level constraints

Solve for the Udot gen accel coordinates to zero out constraints acceleration error. Unlike, solveQ() and solveU(), this method does change the frozen gen accel values.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

The final error.

unfreezeCoord(arg0: CoordBase, arg1: SupportsInt) None#

Method to unfreeze a coordinate component

Parameter coord:

The coordinate whose element is being unfrozen

Parameter index:

The index for the coordinate element being unfrozen

class Karana.Dynamics.ConstraintNode#

Bases: Node

static lookupOrCreate(arg0: PhysicalBody, arg1: str) ConstraintNode#

Factory method to create a ConstraintNode instance.

This method first checks if a detached constraint node is available for use. If not, the method creates a new ConstraintNode for the body.

Parameter bd:

the physical parent body

Parameter name:

the name for the node

Returns:

a ConstraintNode instance

loopConstraint() Ellipsis#

Return the loop constraint using this constraint node

Returns:

the loop constraint using this node.

class Karana.Dynamics.CoordBase#

@class CoordBase Represents the base class for Q, U etc coordinate data providers.

This class is the base class for subhinges, compound subhinges, and bodies that can contribute motion degrees of freedom to the system. These degrees of freedom are associated with coordinates designated Q, U etc.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

getATBID() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Get the ATBI D matrix value.

Returns:

The ATBI D matrix value for this subhinge.

getQ() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the global (chart) Q coordinates

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values.

getQdot() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Qdot rate coordinates

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values.

getT() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the T generalized forces

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values.

getU() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the U velocity coordinates

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values.

getUdot() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Udot acceleration coordinates

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values.

jacobian(target: Karana.Frame.Frame, oriented: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the Jacobian matrix for the target Karana::Frame::Frame

For this coordinates provider, return the 6xnU Jacobian matrix for the target frame that maps generalized velocities U to the target Karana::Frame::Frame’s spatial velocity (and represented in the target Karana::Frame::Frame). The Jacobian is useful for velocity space kinematics, computing force reflection and for mass matrix and operational space inertia related computations. If oriented is false, the return value is negated.

See Coordinate Frames section for more information on frames, and Jacobians section for more on Jacobians.

Parameter target:

Frame the target frame

Parameter oriented:

the orientation of the coordinates provider

Returns:

the Jacobian matrix

jacobianDot(target: Karana.Frame.Frame, oriented: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the time derivative of the Jacobian matrix for the target Karana::Frame::Frame

For this coordinates provider, return the 6xnU Jacobian matrix time derivative for the target Karana::Frame::Frame. If oriented is false, the return value is negated.

See Coordinate Frames section for more information on frames, and Jacobians section for more on Jacobians.

Parameter target:

Frame the target frame

Parameter oriented:

the orientation of the coordinates provider

Returns:

the Jacobian matrix time derivative

See also

jacobian()

jacobianNumDiff(arg0: Karana.Frame.FrameToFrame) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the relative Jacobian matrix for a Karana::Frame::FrameToFrame using numerical differencing

This method uses numerical differencing to compute the 6xnU Jacobian for a Karana::Frame::FrameToFrame’s pframe with respect to its oframe. The primary purpose of this method is to cross-validate the analytical jacobian computation, where the f2f pframe is the target frame.

See Coordinate Frames section for more information on frames, and Jacobians section for more on Jacobians.

Parameter f2f:

the Karana::Frame::FrameToFrame defining the relative Jacobian from/to frames

Returns:

the Jacobian matrix

nQ() int#

The number of generalized coords for the CoordBase.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

the number of generalized coordinates

nU() int#

The number of velocity coords for the CoordBase_T.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

the number of velocity coordinates

poseGradient(f_to_f: Karana.Frame.FrameToFrame, oriented: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the pose gradient matrix for a Karana::Frame::FrameToFrame

Return the 6xnU gradient matrix for the pose of a Karana::Frame::FrameToFrame’s pframe with respect to its oframe with respect to the generalized coordinates Q using analytical methods. The relative orientation is expressed using RotationVectors for a minimal coordinates representation. Though closely related to the Jacobian, the gradient matrix is a coordinate space mapping, while the Jacobian is a velocity space mapping. The gradient matrix is handy for inverse kinematics computations. If oriented is false, the returned value is negated first.

See Coordinate Frames section for more information on frames, and Jacobians section for more on Jacobians.

Parameter f_to_f:

the FrameToFrame defining the relative from/to frames

Parameter oriented:

the orientation of the coordinates provider

Returns:

the gradient matrix

poseGradientNumDiff(arg0: Karana.Frame.FrameToFrame) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the pose gradient matrix for a Karana::Frame::FrameToFrame using numerical differencing

This method uses numerical differencing to compute the 6xnU pose gradient of a Karana::Frame::FrameToFrame’s pframe with respect to its oframe using numerical differencing. The primary purpose of this method is to cross-validate the analytical pose gradient computation.

See Coordinate Frames section for more information on frames, and Jacobians section for more on Jacobians.

Parameter f2f:

the FrameToFrame defining the relative Jacobian from/to frames

Returns:

the pose gradient matrix

setQ(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setQ(arg0: SupportsFloat) None

Set the global (chart) Q coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setT(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setT(arg0: SupportsFloat) None

Set the T generalized forces to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setU(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setU(arg0: SupportsFloat) None

Set the U velocity coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setUdot(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setUdot(arg0: SupportsFloat) None

Set the Udot acceleration coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

class Karana.Dynamics.CoordData(arg0: str, arg1: collections.abc.Sequence[CoordBase])#

Bases: Karana.Core.LockingBase

coordAt(arg0: SupportsInt) tuple[CoordBase, int]#

Returns coord obj and its coord offset corresponding to overall U offset

The CoordData has get/set methods to pack and unpack the coordinate values for its set of CoordBase instances. This method returns the CoordBase and its local coordinate offset corresponding to the specified overall U offset value.

Parameter u_offset:

the input overall U offset value

Returns:

The CoordBase instance and its local U coord offset

coordBases() list[CoordBase]#

Get a vector of the CoordBase instances for this CoordData

Returns:

A vector of CoordBase instances.

coordOffsets(arg0: CoordBase) CoordDataCoordOffset#

Returns the packing offset for the specified CoordBase

The CoordData has get/set methods to pack and unpack the coordinate values for its set of CoordBase instances. This method returns the offsets for the Q and U values for the specified CoordBase in these arrays.

Parameter c:

The CoordBase to check for

Returns:

A CoordOffset struct with the Q and U offsets

dumpState(prefix: str = '', filter: collections.abc.Sequence[str] = ['ALL']) None#

Print out the coordinate values for all the coordinates

The filter values for controlling output are any combination of: ‘Q’, ‘U’, ‘Udot’, ‘T’, ‘ALL’

Parameter prefix:

The prefix to add to each output line

Parameter filter:

Filter output to the specified coordinate types.

getQ() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Q coordinates as an array

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values

getT() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the T generalized forces as an array

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values

getU() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the U velocity coordinates as an array

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values

getUdot() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Udot acceleration coordinates as an array

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

Array of values

nQ() int#

The number of Q generalized coords for the CoordBase.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

the number of coordinates

nU() int#

The number of U velocity coords for the CoordBase.

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Returns:

the number of velocity coordinates

parent(arg0: CoordBase) CoordBase#

Return the CoordBase that is the closed parent to the specified one

Parameter cb:

the CoordBase to check for

Returns:

the CoordBase parent if it exists

setQ(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setQ(val: SupportsFloat) None

Set the Q coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setT(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setT(arg0: SupportsFloat) None

Set the T generalized forces to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setU(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setU(val: SupportsFloat) None

Set the U velocity coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

setUdot(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setUdot(val: SupportsFloat) None

Set the Udot acceleration coordinates to a constant value

See Generalized Q, U etc coordinates section for discussion on Q, U etc coordinates.

Parameter fill_value:

Fill value.

toDS() CoordDataDS#

Convert this CoordData to a DataStruct.

CoordDataDS

DataStruct that represents this CoordData.

toMap() dict[str, list[Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]]]#

Dump the CoordData to a map. They keys are named after the CoordBase objects, and the values are a vector of the Coord Base data.

Returns:

A map representation of the CoordData object.

class Karana.Dynamics.CoordDataCoordOffset#
property Q: int#
property U: int#
class Karana.Dynamics.CoordinateConstraint(mb: Multibody, oshg: PhysicalSubhinge, pshg: PhysicalSubhinge, name: str)#

Bases: BilateralConstraintBase, Karana.Core.LockingBase

@class CoordinateConstraint Class for coordinate constraints

This constraint requires that the ratio of the Q coordinates for a pair of subhinges be related via a specific scale ratio.

See the Coordinate constraints section for more discussion on coordinate constraints.

static create(mb: Multibody, oshg: PhysicalSubhinge, pshg: PhysicalSubhinge, name: str) CoordinateConstraint#

Factory method for creating a CoordinateConstraint instance

Parameter mb:

The Multibody instance

Parameter osh:

the first Karana::Dynamics::PhysicalSubhinge instance

Parameter psh:

the second Karana::Dynamics::PhysicalSubhinge instance

Parameter name:

the name for the loop constraint instance

Returns:

a CoordinateConstraint instance

getScaleRatio() float#

Return the Q(pshg)/Q(oshg) coordinate scale ratio

Returns:

The scale ratio

osubhinge() PhysicalSubhinge#

Return the first subhinge for this coordinate constraint

Returns:

The first subhinge.

psubhinge() PhysicalSubhinge#

Return the second subhinge for this coordinate constraint

Returns:

The second subhinge.

setScaleRatio(arg0: SupportsFloat) None#

Set the Q(pshg)/Q(oshg) coordinate scale ratio

Parameter scale_ratio:

The scale ratio

class Karana.Dynamics.FramePairHinge#

Bases: HingeBase, Karana.Frame.OrientedChainedFrameToFrame

@class FramePairHinge Represents the articulation class used by PhysicalHinge and LoopConstraintHinge physical articulation classes

See Connecting bodies via hinges section for more discussion on hinges.

fitQ(T: Karana.Math.HomTran, f_to_f: Karana.Frame.FrameToFrame = None) Karana.Math.HomTran#

Method to find best fit Q coordinates for the hinge for the input transform

This method can be used to initialize the hinge’s Q coordinates to values that best fit the input transform T. If f_to_f is non-null, then T is assumed to be the desired relative transform for the f_to_f, and if null then this hinge is used as the f_to_f.

Parameter T:

Input transform

Parameter f_to_f:

The frame to frame instance the T transform is for

Returns:

The residual error transform

fitU(V: Karana.Math.SpatialVector, f_to_f: Karana.Frame.FrameToFrame = None) Karana.Math.SpatialVector#

Method to find best fit U velocity coordinates for the input spatial velocity vector

This method can be used to initialize the hinge U velocity coordinates to values that best fit the input spatial velocity for the hinge. If f_to_f is non-null, then V is assumed to be the desired spatial velocity for this f_to_f , and if null then this hinge is used as the f_to_f .

Parameter V:

Input spatial velocity vector

Parameter f_to_f:

The frame to frame instance the V spatial velocity is for

Returns:

The residual spatial velocity error

fitUdot(A: Karana.Math.SpatialVector, f_to_f: Karana.Frame.FrameToFrame = None) Karana.Math.SpatialVector#

Method to find best fit Udot accel coordinates for the input spatial acceleration vector

This method can be used to initialize the hinge Udot acceleration coordinates to values that best fit the input spatial acceleration for the hinge. If f_to_f is non-null, then A is assumed to be the desired spatial accel for this f_to_f , and if null then this hinge is used as the f_to_f .

Parameter alpha:

Input spatial acceleration vector

Parameter f_to_f:

The frame to frame instance the A spatial acceleration is for

Returns:

The residual spatial acceleration error

class Karana.Dynamics.FrameToFrameJacobianGenerator(name: str, f_to_f: Karana.Frame.FrameToFrame, coord_data: CoordData)#

Bases: Karana.Core.LockingBase

static create(name: str, f_to_f: Karana.Frame.FrameToFrame, coord_data: CoordData) FrameToFrameJacobianGenerator#

Factory method for creating a FrameToFrameJacobianGenerator

Parameter name:

name for the new object

Parameter f_to_f:

the Karana::Frame::FrameToFrame instance to compute the relative Jacobian for

Parameter coord_data:

the list of CoordData with the coordinates

Returns:

the new FrameToFrameJacobianGenerator instance

jacobian(analytical: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Method to compute the Jacobian matrix

Return the overall assembled 6xnU Jacobian to the target frame spatial velocity (represented in the target frame) with respect to the path map’s source frame from the U generalized velocities of all the component coordinate providers. Use the component analytical Jacobians if analytical is true, or the numerical differencing approach otherwise. If not provided, the source frame is assumed to be the newtonian frame. This Jacobian is such that the following will be true:

f2f.relSpVel() == f2f.relTransform().getUnitQuaternion() (jac * getU())

The input polarity map must be compatible with the same source/target frame values used when calling this method. It will be created if it is not provided. Coordinate providers not in the polarity map are assumed to not have an effect on the target frame, and zero sub-matrix entries are assigned for them.

For normal inverse kinematics (e.g., with respect to inertial frame), we normally exclude coordinate providers that are outboard of (or on a separate branch from) the target frame of interest.

Otherwise, the polarity map value for each coordinate provider is used to negate the sub-matrix entries for the ones with opposed polarity. We include such opposed polarity coordinate provider elements for cases where the source frame is not the inertial frame, and the coordinate provider is on the path from the source to the target frame, but may be on a different branch and o the path from the source frame to the common ancestor frame. In this case, the coordinate provider’s effect is the negative of the normal effect on the target frame.

Parameter analytical:

If true, use the analytical process, else numerical differencing

Returns:

the Jacobian matrix

jacobianDot() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Method to compute the time derivative of the Jacobian matrix

Returns:

the time derivative of the Jacobian matrix

poseGradient(analytical: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Method to compute the pose gradient matrix

Return the overall assembled 6xnU gradient for the target frame pose with respect to the Q generalized coordinates of all the component coordinate providers. Use the component analytical gradient contributions if analytical is true, or the numerical differencing approach otherwise.

The input polarity map must be compatible with the same source/target frame values used when calling this method. It will be created if it is not provided. Coordinate providers not in the polarity map are assumed to not have an effect on the target frame, and zero sub-matrix entries are assigned for them. For normal inverse kinematics (e.g., with respect to inertial frame), we exclude coordinate providers that are outboard of (or on a separate branch from) the target frame of interest.

Otherwise, the polarity map value for each coordinate provider is used to negate the sub-matrix entries for the ones with opposed polarity. We include such opposed polarity coordinate provider elements for cases where the source frame is not the inertial frame, and the coordinate provider is on the path from the source to the target frame, but may be on a different branch and o the path from the source frame to the common ancestor frame. In this case, the coordinate provider’s effect is the negative of the normal effect on the target frame.

We can choose to eliminate some columns from the computed matrix by specifying the corresponding coordinate providers in the skip_coords list. An alternative option is to set the columns to zero values, but this is non-optimal since the column values would need to be computed (only to be discarded), and the returned matrix would be larger.

Parameter analytical:

If true, use the analytical process, else numerical differencing

Returns:

the pose gradient matrix

class Karana.Dynamics.GearedCompoundBody(name: str, parent_subtree: SubGraph, subtree: SubGraph)#

Bases: CECompoundBody

@class GearedCompoundBody Constraint embedding class for a body pair connected by a gear

This class is for a parent/child body pair with 1 dof hinge with a gear ratio relating the outboard body hinge coordinates to those of the inboard body. The inboard body coordinates are treated as the independent coordinates.

static create(name: str, parent_subtree: SubGraph, subtree: SubGraph) GearedCompoundBody#
setGearRatio(arg0: SupportsFloat) None#

Set the gear ratio.

Parameter the:

gear ratio

class Karana.Dynamics.HingeBase#
static getHookeHingeParams(arg0: Karana.Math.UnitQuaternion) HingeParams#

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.

Parameter ij_q:

the inboard to outboard frames relative orientation unit quaternion

Returns:

struct with the hinge onode, pnode and axis parameter values

static getInlineHingeParams() HingeParams#

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

Returns:

struct with the hinge onode, pnode and axis parameter values

static getInplaneHingeParams() HingeParams#

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

Returns:

struct with the hinge onode, pnode and axis parameter values

static getParallelHingeParams() HingeParams#

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.

Returns:

struct with the hinge onode, pnode and axis parameter values

static getPerpendicularHingeParams(arg0: Karana.Math.UnitQuaternion) HingeParams#

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

Parameter ij_q:

the inboard to outboard frames relative orientation unit quaternion

Returns:

struct with the hinge onode, pnode and axis parameter values

coordData() CoordData#

Return the CoordData for the hinge’s list of subhinges

Returns:

the CoordData for the subhinges

hingeType() HingeType#

Return the HingeType hinge type for this hinge.

Returns:

The hinge type used by this body.

hingeTypeString() str#

Helper method to return the string name for a HingeType hinge type

Returns:

the hinge type as a string

nSubhinges() int#

Return the number of subhinges in the hinge

Returns:

the number of subhinges

nU() int#

Return the total nU dofs from all the subhinges

Returns:

the total number of U coordinates across the subhinges

pframeCoordMapMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

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.

Returns:

the coordinate map matrix

pframeCoordMapSingularValues() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

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.

Returns:

Array of singular values.

subhinge(index: SupportsInt) SubhingeBase#

Return the SubhingeBase subhinge instance at the specified index

Parameter index:

the subhinge index

Returns:

the subhinge object

class Karana.Dynamics.HingeNode#

Bases: Node

@class HingeNode Represents the base class for physical HingePnode and HingeOnode classes

hinge() PhysicalHinge#

Return the PhysicalHinge hinge the node is attached to

Returns:

The attached PhysicalHinge instance

class Karana.Dynamics.HingeOnode#

Bases: HingeNode

atbiFilterVectors() HingeOnodeATBIFilterVectors#

Update and return the ATBI filter vectors

Returns:

the ATBI filter vectors

atbiMatrices() HingeOnodeATBIMatrices#

Update and return the ATBI matrices

Returns:

the ATBI matrices

atbiSmootherVectors() HingeOnodeATBISmootherVectors#

Update and return the ATBI smoother vectors

Returns:

the ATBI smoother vectors

getInterBodyForceTAFwdDyn() Karana.Math.SpatialVector#

Return the interbody force at the onode for Tree Augmented (TA) dynamics with constraints

This method returns the interbody force at the onode when doing TA dynamics for the system in the presence of loop constraints. This is only meant to be used for regular hinges (not cut-joint hinges)

Returns:

the inter-body spatial force

getInterBodyForceTreeFwdDyn() Karana.Math.SpatialVector#

Return the inter-body spatial force at the hinge

While the spatial force is at the onode, and in the onode frame, its sign is that for the version applying on the outboard (the pnode) body. This values should be negated to get the equal and opposite spatial force on the onode’s body.

Returns:

the inter-body spatial force

inverseDynamicsVectors() HingeOnodeInvDynVectors#

Update and return the inverse dynamics vectors

Returns:

the inverse dynamics vectors

upsilonMatrices() HingeOnodeUpsilonMatrices#

Update and return the OSCM Upsilon matrices

Returns:

the OSCM Upsilon matrices

class Karana.Dynamics.HingeOnodeATBIFilterVectors#
zplus: Karana.Math.SpatialVector#
zplus_extra: Karana.Math.SpatialVector#
class Karana.Dynamics.HingeOnodeATBIMatrices#
property Pplus: Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#
class Karana.Dynamics.HingeOnodeATBISmootherVectors#
alpha_plus: Karana.Math.SpatialVector#
alpha_plus_extra: Karana.Math.SpatialVector#
class Karana.Dynamics.HingeOnodeInvDynVectors#
f: Karana.Math.SpatialVector#
class Karana.Dynamics.HingeOnodeUpsilonMatrices#
property UpsilonPlus: Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#
class Karana.Dynamics.HingeParams#

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

i_to_onode_q: Karana.Math.UnitQuaternion#
j_to_pnode_q: Karana.Math.UnitQuaternion#
property axes: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

//!< 3xm matrix with columns defining the 1-dof subhinge axes

class Karana.Dynamics.HingePnode#

Bases: HingeNode

atbiFilterVectors() HingePnodeATBIFilterVectors#

Update and return the ATBI filter vectors

Returns:

the ATBI filter vectors

atbiMatrices() HingePnodeATBIMatrices#

Update and return the ATBI matrices

Returns:

the ATBI matrices

atbiSmootherVectors() HingePnodeATBISmootherVectors#

Update and return the ATBI smoother vectors

Returns:

the ATBI smoother vectors

crbInertiaMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Update and return the CRB spatial inertia for the body referenced to the pnode.

This is a (nmodes+6) size square, symmetric, positive semi-definite matrix

Returns:

the CRB inertia matrix.

inverseDynamicsVectors() HingePnodeInvDynVectors#

Update and return the inverse dynamics vectors

Returns:

the inverse dynamics vectors

upsilonMatrices() HingePnodeUpsilonMatrices#

Update and return the OSCM Upsilon matrices

Returns:

the OSCM Upsilon matrices

class Karana.Dynamics.HingePnodeATBIFilterVectors#
z: Karana.Math.SpatialVector#
class Karana.Dynamics.HingePnodeATBIMatrices#
property P: Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#
class Karana.Dynamics.HingePnodeATBISmootherVectors#
class Karana.Dynamics.HingePnodeInvDynVectors#
f: Karana.Math.SpatialVector#
class Karana.Dynamics.HingePnodeUpsilonMatrices#
property Upsilon: Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#
class Karana.Dynamics.HingeType(value: SupportsInt)#

Members:

LOCKED : //!< locked subhinge, no relative motion permitted

PIN : //!< 1 dof hinge with a single SubhingeBase::SubhingeType::PIN //!<

subhinge

UJOINT : //!< 2 dof hinge with 2 successive //!<

SubhingeBase::SubhingeType::PIN subhinges

GIMBAL : //!< 3 dof hinge with 2 successive //!<

SubhingeBase::SubhingeType::PIN subhinges

BALL : //!< 3 dof hinge with 1 SubhingeBase::SubhingeType::SPHERICAL //!<

subhinge

BALL_QUAT : //!< 3 dof hinge with 1 //!<

SubhingeBase::SubhingeType::SPHERICAL_QUAT subhinge

SLIDER : //!< 1 dof hinge with 1 SubhingeBase::SubhingeType::LINEAR //!<

subhinge

PLANAR : //!< 2 dof hinge with 2 successive //!<

SubhingeBase::SubhingeType::LINEAR subhinges

TRANSLATIONAL : //!< 3 dof hinge with 3 successive //!<

SubhingeBase::SubhingeType::LINEAR subhinges

FULL6DOF : //!< 6 dof hinge with a SubhingeBase::SubhingeType::LINEAR3 //!<

subhinge followed by a

CYLINDRICAL : //!< 2 dof hinge with a //!< SubhingeBase::SubhingeType::LINEAR

subhinge //!< followed by a //!< SubhingeBase::SubhingeType::PIN subhinge

HELICAL : //!< 1 dof hinge with a single //!< SubhingeBase::SubhingeType::SCREW

subhinge

HOOKE : //!< 2 dof hinge that keeps an outboard body frame’s //!< Y-axis

perpendicular to an inboard body frame’s //!< X-axis. The subhinge sequence consists of a pair of //!< SubhingeBase::SubhingeType::PIN //!< subhinges. The hinge parameters can be computed using the //!< HingeBase::getHookeHingeParams() method.

INLINE : //!< 4 dof hinge that keeps an outboard body frame’s //!< Z-axis

constrained to translate along an inboard //!< body frame’s Z-axis. The subhinge sequence //!< consists of a SubhingeBase::SubhingeType::LINEAR //!< subhinge followed by a //!< SubhingeBase::SubhingeType::SPHERICAL subhinge //!< The hinge parameters can be computed using //!< the HingeBase::getInlineHingeParams() method.

INPLANE : //!< 5 dof hinge that keeps an outboard body frame //!< constrained to

translate in an inboard body //!< frame’s XY plane. The subhinge sequence //!< consists of a pair of //!< SubhingeBase::SubhingeType::LINEAR subhinges //!< followed by a !< //!< SubhingeBase::SubhingeType::SPHERICAL subhinge. //!< The hinge parameters can be computed using //!< the HingeBase::getInplaneHingeParams() method.

PERPENDICULAR : //!< 5 dof hinge that keeps an outboard body //!< frame’s Z-axis to

remain perpendicular to an //!< inboard body frame’s Z-axis. The subhinge //!< sequence consists of a //!< SubhingeBase::SubhingeType::LINEAR3 subhinge //!< followed by a pair of //!< SubhingeBase::SubhingeType::PIN subhinges. The //!< hinge parameters can be computed using the //!< HingeBase::getPerpendicularHingeParams() method.

PARALLEL : //!< 4 dof hinge that keeps an outboard frame’s //!< Z-axis to remain

parallel to an inboard body //!< frame’s Z-axis. The subhinge sequence //!< consists of a //!< SubhingeBase::SubhingeType::LINEAR3 subhinge //!< followed by a SubhingeBase::SubhingeType::PIN //!< subhinge. The hinge parameters can be computed //!< using the HingeBase::getParallelHingeParams() //!< method.

CUSTOM : //!< hinge with user specified sequence of subhinge types

COMPOUND : //!< hinge with a single //!< SubhingeBase::SubhingeType::COMPOUND

subhinge

BALL: ClassVar[HingeType]#
BALL_QUAT: ClassVar[HingeType]#
COMPOUND: ClassVar[HingeType]#
CUSTOM: ClassVar[HingeType]#
CYLINDRICAL: ClassVar[HingeType]#
FULL6DOF: ClassVar[HingeType]#
GIMBAL: ClassVar[HingeType]#
HELICAL: ClassVar[HingeType]#
HOOKE: ClassVar[HingeType]#
INLINE: ClassVar[HingeType]#
INPLANE: ClassVar[HingeType]#
LOCKED: ClassVar[HingeType]#
PARALLEL: ClassVar[HingeType]#
PERPENDICULAR: ClassVar[HingeType]#
PIN: ClassVar[HingeType]#
PLANAR: ClassVar[HingeType]#
SLIDER: ClassVar[HingeType]#
TRANSLATIONAL: ClassVar[HingeType]#
UJOINT: ClassVar[HingeType]#
__members__: ClassVar[dict[str, HingeType]]#
static to_json(o: HingeType) dict[str, Any]#

Class method used to represent HingeType in a json file.

classmethod from_json(d: dict[str, Any]) Self#

Construct a HingeType from json file data.

classmethod from_yaml(_, node) Self#

Construct a HingeType from yaml file data.

classmethod to_yaml(representer, node)#

Class method used to represent HingeType in a yaml file.

__eq__(other: Any) bool#
__getstate__() int#
__getstate__() str
__hash__() int#
__index__() int#
__int__() int#
__ne__(other: Any) bool#
__repr__()#
__setstate__(state: SupportsInt) None#
__setstate__(arg0: str) None
__str__() str#
property name: str#
property value: int#
class Karana.Dynamics.Linear3Subhinge#

Bases: PhysicalSubhinge_T_3_3

@class Linear3Subhinge Represents a 3 dof translational subhinge

See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.LinearSubhinge#

Bases: Physical1DofSubhinge

@class LinearSubhinge Represents a 1 dof translational subhinge

See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.LockedSubhinge#

Bases: PhysicalSubhinge_T_0_0

@class LockedSubhinge Represents a locked subhinge

See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.LoopConstraintBase#

Bases: BilateralConstraintBase, Karana.Core.LockingBase

@class LoopConstraintBase Base class for loop constraints See the Bilateral closure constraints section for more discussion on loop constraints.

constrainsQ() bool#

Return true if the loop constraint constrains Q configuration coordinates

Returns:

true if the loop constraint constrains the Q coordinates

constraintFrameToFrame() Karana.Frame.FrameToFrame#

Return the Karana::Frame::FrameToFrame whose oframe/pframe define the constraint

When the constraint is satisfied, the relative configuration, velocity and accel values across the Karana::Frame::FrameToFrame f2f are constrained to those satisfied by the associated constraint hinge

Returns:

the constraint FrameToFrame instance

getQMats() LoopConstraintQMats#

Return the constraint QMat matrices for this constraint

Returns:

the QMats struct for this constraint

hasHinge() bool#

Return true if the loop constraint is based on a hinge

Returns:

true if the loop constraint is based on a hinge

sourceNode() ConstraintNode#

Return the source (oframe) node for the constraint

Return the source frame as a constraint node, if the source frame is attached to a non-virtual root body. Return a null pointer if the source frame is not attached to a multibody body.

Returns:

the source constraint node.

targetNode() ConstraintNode#

Return the target (pframe) node for the constraint

Return the target frame as a constraint node, if the target frame is attached to a non-virtual root body. Return a null pointer if the target frame is not attached to a multibody body.

Returns:

the source constraint node.

class Karana.Dynamics.LoopConstraintConVel(mb: Multibody, constraint_f_to_f: Karana.Frame.FrameToFrame, name: str)#

Bases: LoopConstraintBase, BilateralConstraintBase, Karana.Core.LockingBase

@class LoopConstraintConVel Class for constant velocity loop constraints

This constraint requires that a component of the relative angular/linear velocity of a pair of body constraint nodes projected onto a unit axis be equal. This constraint only applies at the velocity and acceleration levels, and not the positional level.

See the Convel loop-constraints section for more discussion on convel loop constraints.

static create(mb: Multibody, constraint_f_to_f: Karana.Frame.FrameToFrame, name: str) LoopConstraintConVel#

Factory method for creating a LoopConstraintConVel instance

Parameter mb:

The Multibody instance

Parameter constraint_f_to_f:

the Karana::Frame::FrameToFrame defining the constrained Frame pair

Parameter name:

the name for the loop constraint instance

Returns:

a LoopConstraintHinge instance

getUnitAxis() Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]#

Get the unit axis to which the convel constraint applies.

Returns:

The unit axis vector in the source node frame

isRotational() bool#

Get whether the constraint is on relative angular velocity

Returns:

If the constraint is angular, else linear

setInput(arg0: SupportsFloat, arg1: SupportsFloat) None#

Set the velocity and acceleration inputs for the convel constraint.

The input is used to set the difference between the source and target component velocity and acceleration component values.

Parameter vel:

The input velocity

Parameter accel:

The input accel

setUnitAxis(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], arg1: bool) None#

Set the unit axis long which the convel constraint applies.

Parameter axis:

The unit axis vector in the source node frame

Parameter is_rotational:

If true, the constraint is assumed to on relative angular velocity, else translational

class Karana.Dynamics.LoopConstraintHinge(mb: Multibody, constraint_f_to_f: Karana.Frame.FrameToFrame, name: str, htype: HingeType, subhinge_types: collections.abc.Sequence[SubhingeType] = [])#

Bases: LoopConstraintBase, BilateralConstraintBase, Karana.Core.LockingBase

@class LoopConstraintHinge Class for loop constraints that are based on a hinge to define the constraint See the Hinge loop-constraints section for more discussion on hinge loop constraints.

static create(mb: Multibody, constraint_f_to_f: Karana.Frame.FrameToFrame, name: str, htype: HingeType, subhinge_types: collections.abc.Sequence[SubhingeType] = []) LoopConstraintHinge#

Factory method for creating a LoopConstraintHinge instance

Parameter mb:

The Multibody instance

Parameter constraint_f_to_f:

the Karana::Frame::FrameToFrame defining the constrained Frame pair

Parameter name:

the name for the loop constraint instance

Parameter htype:

the HingeBase::HingeType defining the constraint type

Parameter subhinge_types:

the list of SubhingeBase::SubhingeType subhinge types for a custom hinge type

Returns:

a LoopConstraintHinge instance

static toPhysicalHinge(arg0: LoopConstraintHinge, arg1: bool) PhysicalHinge#

Convert this loop constraint into an inter-body PhysicalHinge

Replaces the loop constraint with a hinge between the constraint nodes to make one body the child of the other. This method can only be called when the new child body (either of source or target) is a base body with a 6 dof hinge. This requirement allows us to preserve the system’s tree topology. If reverse false, the target node’s body is made the child of the source node’s body, and the converse if reverse is true. The original loop constraint is discarded by this method.

Parameter lc:

The loop constraint to replace with a hinge

Parameter reverse:

If true, reverse the polarity of the hinge

Returns:

the new hinge

errorFrameToFrame() Karana.Frame.FrameToFrame#

the Karana::Frame::FrameToFrame that measures the constraint residual error

The constraint is fully satisfied only when this f2f relative transform, spatial velocity and acceleration values are zero, i.e. its oframe and pframe are coincident

Returns:

the error FrameToFrame instance

getInterBodyForceTAFwdDyn() Karana.Math.SpatialVector#

Return the interbody spatial force at the source node for TA dynamics

This method returns the interbody force at the source when doing TA dynamics for the loop constraint. The force has the sign as if acting on the target node (this is consistent with our general convention to book keep the pnode’s inter-body force at the onode). The term also includes contributions from any generalized forces at the cut-joint.

The method should only be called after TA forward dynamics has been called, since it expects the constraint forces to be set in the constraint nodes. Also this method assumes that the T value in the CoordData member is the cutjoint generalized force value.

Returns:

the inter-body spatial force

hinge() FramePairHinge#

Return the FramePairHinge hinge associated with this loop constraint

When the constraint is satisfied, the relative configuration, velocity and accel values across the f2f are constrained to those satisfied by the associated constraint hinge

Returns:

the FramePairHinge instance

spExternalForceFromT(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], arg1: bool) None#

Apply the input T generalized force at the constraint hinge as an external force.

This method is used to handle any generalized forces at cut-joints. Once the joint is cut, its generalized forces are no longer included in the normal dynamics. The workaround is to convert the cut-joint generalized forces into equivalent equal and opposite external forces at the constraint nodes for the cut-joint.

Parameter T:

the input generalized forces

Parameter no_accumulate:

if true, then accumulate the input forces at the constraint nodes

class Karana.Dynamics.LoopConstraintQMats#
property source_Q: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
property target_Q: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
class Karana.Dynamics.LoopsCompoundBody(name: str, parent_subtree: SubGraph, aggregated_bodies_tree: SubGraph, indep_bodies: collections.abc.Sequence[PhysicalBody])#
class Karana.Dynamics.LoopsCompoundBody(name: str, parent_subtree: SubGraph, subtree: SubGraph, indep_indices_U: collections.abc.Sequence[SupportsInt], indep_indices_Q: collections.abc.Sequence[SupportsInt] = [])

Bases: CECompoundBody

@class LoopsCompoundBody Constraint embedding class for a bodies with loop constraints

This class is embedding loop constraint for a SubGraph of bodies.

static create(name: str, parent_subtree: SubGraph, aggregated_bodies_tree: SubGraph, indep_bodies: collections.abc.Sequence[PhysicalBody]) LoopsCompoundBody#

Constructs a LoopsCompoundBody with list of independent bodies

Parameter name:

instance name

Parameter parent_subtree:

the parent SubGraph this the body will belong to

Parameter component_bodies:

SubGraph with bodies being embedded

Parameter indep_bodies:

the bodies whose coordinates should be independent

Returns:

a LoopsCompoundBody instance

static createFromIndices(name: str, parent_subtree: SubGraph, subtree: SubGraph, indep_indices_U: collections.abc.Sequence[SupportsInt], indep_indices_Q: collections.abc.Sequence[SupportsInt] = []) LoopsCompoundBody#

Constructs a LoopsCompoundBody with list of independent coord indices

The option of specifying independent coordinates at the indices level gives finer-grain control than the other create() method. Also, this method allows specifying different values for the independent Q and U coordinates. The U coordinates are used if the Q list is empty.

Parameter name:

instance name

Parameter parent_subtree:

the parent SubGraph this the body will belong to

Parameter component_bodies:

SubGraph with bodies being embedded

Parameter indep_indices_U:

the list of independent U coordinate indices

Parameter indep_indices_Q:

the list of independent Q coordinate indices

Returns:

a LoopsCompoundBody instance

class Karana.Dynamics.ModalAnalysis#
property phi: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
property w: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#
class Karana.Dynamics.MultiJacobianGenerator(arg0: str, arg1: collections.abc.Sequence[Karana.Frame.FrameToFrame], arg2: CoordData)#

Bases: Karana.Core.LockingBase

static create(arg0: str, arg1: collections.abc.Sequence[Karana.Frame.FrameToFrame], arg2: CoordData) MultiJacobianGenerator#

Factory method for creating a new MultiJacobianGenerator instance

Parameter name:

the name for the new object.

Parameter f2fs:

the list of FrameToFrame’s for the Jacobian generator

Parameter coord_data:

the CoordDatas to use for the Jacobian columns

Returns:

a new MultiJacobianGenerator instance

jacobian(analytical: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the Jacobian matrix

Return the Jacobian matrix map from the free U velocity coordinate to the f2fs relative velocity.

Parameter analytical:

If true, use the analytical method, else numerical differencing

Returns:

the Jacobian matrix

jacobianDot() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Method to compute the time derivative of the Jacobian matrix

Returns:

the time derivative of the Jacobian matrix

poseGradient(analytical: bool = True) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the pose gradient matrix

Return the gradient matrix map from the free Q configuration coordinates to the f2fs relative pose

Parameter analytical:

If true, use the analytical method, else numerical differencing

Returns:

the pose gradient matrix

class Karana.Dynamics.Multibody(name: str, fc: Karana.Frame.FrameContainer, mbroot_frame: Karana.Frame.Frame | None = None, newtonian_frame: Karana.Frame.Frame | None = None)#

Bases: SubGraph

static create(name: str, fc: Karana.Frame.FrameContainer, mbroot_frame: Karana.Frame.Frame | None = None, newtonian_frame: Karana.Frame.Frame | None = None) Multibody#

Factory method to create a new Multibody instance.

The virtual root body is attached to the multibody root frame. If the multibody root frame is not specified, then the method uses the newtonian frame, and if that is unspecified as well, then the method uses the frame container’s root frame as the root frame.

Parameter name:

The name for the new Multibody instance

Parameter fc:

The Karana::Frame::FrameContainer to use

Parameter mbroot_frame:

The parent Karana::Frame::Frame for the virtual root body

Parameter newtonian_frame:

The inertial Karana::Frame::FrameToFrame frame

Returns:

a new Multibody instance

classmethod fromDS(mbody_ds: MultibodyDS, fc: FrameContainer, newtonian_frame: ForwardRef('Frame') | None = None, scene: ForwardRef('ProxyScene') | None = None) Multibody#

Convert the MultibodyDS to a Multibody.

mbody_dsMultibodyDS

The Multibody DataStruct to convert to a multibody.

fcFrameContainer

The FrameContainer to use for the Multibody.

Multibody

The Multibody created from the MultibodyDS.

constraints() list[BilateralConstraintBase]#

Return the list of existing constraint instances (enabled and disabled)

Returns:

constraints list

createStickParts(stick_parts_config: StickPartsConfig = ...) None#

Create stick parts for the multibody.

A Karana::Scene::ProxyScene scene must be registered with the Multibody first.

Parameter c:

Config that controls the look of the stick parts visualization.

frameContainer() Karana.Frame.FrameContainer#

Return the Karana::Frame::FrameContainer frame container for the multibody system

See the Manual creation section for more information.

Returns:

the Karana::Frame::FrameContainer instance

getConstraint(arg0: str) BilateralConstraintBase#

Look up a existing constraint by name (enabled or disabled) See Bilateral closure constraints section for more info on constraints.

Parameter name:

the constraint’s name

Returns:

the CoordinateConstraint instance

getNewtonianFrame() Karana.Frame.Frame#

Return the Newtonian Karana::Frame::Frame

See the Manual creation section for more information.

Returns:

the Newtonian Frame instance

getNodeAncestor(frame: Karana.Frame.Frame) Node#

Look up and return the closest Node ancestor for a Karana::Frame::Frame.

Return null if the Karana::Frame::Frame is not the descendant of a body Node. See Body nodes section for information on body nodes.

Parameter frame:

the input Karana::Frame::Frame

Returns:

the ancestor Node for the Frame.

getScene() Karana.Scene.ProxyScene | None#

Get the Karana::Scene::ProxyScene scene member for the multibody system See ProxyScene section for more information on Karana::Scene::ProxyScene.

Returns:

The scene member

setScene(arg0: Karana.Scene.ProxyScene) None#

Set the Karana::Scene::ProxyScene instance for the multibody system

See ProxyScene section for more information on Karana::Scene::ProxyScene.

Parameter scene:

The scene instance

setupGraphics(*, port: int = 29523, axes: float = 1.0, client_type: Literal['auto', 'electron', 'notebook', 'webbrowser', 'selenium'] | None = 'auto', origin_frame: ForwardRef('Frame') | None = None, wait_for_clients: int = 0, wait_for_clients_timeout: float = 0.0) tuple[Callable[[], NoneType], WebScene]#

Easily set up graphics.

portint

Port to bind the WebUI server to. Use 0 to request an arbitrary unused port. Defaults to 29523.

axesfloat

Length of axes visualization on root frame. Defaults to 1.0.

client_typeLiteral[“auto”, “electron”, “notebook”, “webbrowser”, “selenium”] | None
Policy for launching a client.

“auto”: pick the best option for the environment and OS “electron”: always launch the electron client “notebook”: always open an IFrame in IPython “webbrowser”: always open a browser tab “selenium”: always open a chrome driver using selenium None: don’t automatically open a client

Defaults to “auto”.

origin_frame: Optional[Frame]

Frame to use as the world origin for the graphics scene. If None, use the Multibody’s virtualRoot.

wait_for_clients: int

Number of client connections to wait for before continuing. Defaults to 0.

wait_for_clients_timeoutfloat

Number of seconds to wait before raising an error if wait_for_clients is positive. Defaults to 0.

tuple[Callable[[],None], WebScene]

A tuple containing the a cleanup callable and the graphics scene.

toDS() MultibodyDS#

Convert this Multibody to a MultibodyDS.

toFullyAugmentedModel() None#

Convert all PhysicalHinges into LoopConstraintHinges to create a fully augmented (FA) model

The FA model consists of independent physical bodies, where the couple hinges are replaced with equivalent loop constraints. The FA model is also referred to as the absolute coordinates model. The main purpose of this method is to create FA models to compare and benchmark performance of absolute coordinate dynamics with the minimal coordinate methods. This method introduces constraints, and hence the TA algorithm must be used for dynamics computations for the FA model. See Multibody representations section for discussion of FA models.

tui() MultibodyTUI#

Create the TUI for this multibody system.

selfMultibody

The multibody instance

class Karana.Dynamics.Node#

Bases: Karana.Frame.Frame

@class Node Represents the body node base class

This class is for nodes attached to PhysicalBody instances. See Body nodes section for more information on the Node class.

static lookupOrCreate(bd: PhysicalBody, name: str, force_node: bool = False) Node#

Factory method to create a Node instance.

This method first checks if a detached node is available for use. If not, the method creates a new Node for the body.

Parameter bd:

the physical parent body

Parameter name:

the name for the node

Parameter force_node:

if true, the node is marked as one that can apply forces

Returns:

a Node instance

static lookupOrCreateContact(bd: PhysicalBody, T: Karana.Math.HomTran, name: str = '') Node#

Factory method to create a Node instance that is used for contact forces.

A contact force node is one whose forces will only apply for for one dynamics calculation. Whenever the externals are cleared, these nodes will become inactive. These nodes are always force nodes. If no name is provided, one will be given to them automatically.

This method first checks if a detached node is available for use. If not, the method creates a new Node for the body.

Parameter bd:

The physical parent body

Parameter T:

The transform of the node relative to the body.

Parameter name:

instance name

Returns:

a Node instance

deformationProvider() NodeDeformationProvider#

Return the <NodeDeformationProvider deformation provider for the node

Returns:

the NodeDeformationProvider instance

detach() None#

Method to detach the node from the current parent body

Once detached, the node is put in the pool of detached nodes for possible reuse when new nodes are needed.

getBodyToNodeTransform() Karana.Math.HomTran#

Return the node’s transform with respect to the parent PhysicalBody’s body frame

This transform defines the Node’s location for an undeformed PhysicalBody parent body. Use Karana::Frame::FrameToFrame queries to find the actual location of a Node after body deformation.

Returns:

the node’s offset transform

getSpForce() Karana.Math.SpatialVector#

Get the external spatial force at the node represented in the node frame.

Returns:

the spatial force vector

isExternalForceNode() bool#

Check whether the Node is a force node

A force node is one that has been designated as one that can apply forces on the body. See Body nodes section for more on force nodes.

Returns:

true if the node is a force node

newtonianToNodeFrameToFrame() Karana.Frame.OrientedChainedFrameToFrame#

Return the Karana::Frame::FrameToFrame from the Newtonian frame to the body frame

Returns:

the Karana::Frame::FrameToFrame instance

nodeObservedSpatialAccel() Karana.Math.SpatialVector#

Return the node frame observed spatial acceleration of the node with respect to the Newtonian frame.

This is the spatial acceleration of the node with respect to the Newtonian Karana::Frame::Frame, as observed from and represented in the node frame. Note that this is not and should not be confused with newtoninan_frame.frameToFrame(node).relSpAccel() which returns the Newtonian frame observed acceleration of the node with respect to the Newtonian frame!

Returns:

the spatial acceleration vector

parentBody() PhysicalBody#

Return the PhysicalBody parent body for the node.

Returns:

the parent PhysicalBody instance

setBodyToNodeTransform(t: Karana.Math.HomTran) None#

Set the node’s transform with respect to the parent PhysicalBody’s body frame

This transform defines the Node’s location for an undeformed PhysicalBody parent body. Use Karana::Frame::FrameToFrame queries to find the actual location of a Node after body deformation.

Parameter t:

the offset transform

setExternalSpForce(spforce: Karana.Math.SpatialVector, ref_frame: Karana.Frame.Frame = None) None#

Set the external spatial force at the node represented in the specified Karana::Frame::Frame frame.

This method resets the specified spatial force to the currently set spatial force in the node. If no frame is specified, then the spatial force is assumed to be represented in the local node frame. Note that most algorithms will check this node for a spatial force only it has been registered as a force node - so make sure that this has been done.

Parameter spforce:

The spatial force value

Parameter ref_frame:

The reference Karana::Frame::Frame frame for the spatial force values

class Karana.Dynamics.NodeDeformationProvider#

Bases: Karana.Core.Base

@class NodeDeformationProvider Base abstract class node deformation

See Flexible body systems section for more information of deformation provider classes.

Base abstract class that provides data and methods for modeling node deformation

class Karana.Dynamics.Physical1DofSubhinge#

Bases: PhysicalSubhinge_T_1_1

@class Physical1DofSubhinge Base class for 1 degree of freedom physical subhinges

See Subhinges section for more information on physical subhinges.

getGearRatio() float#

Return the gear ratio for the 1 dof subhinge

Returns:

the gear ratio value

getJointLimits() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the lower/upper pair of joint limit values for the 1 dof subhinge

Returns:

array with the lower and upper joint limit values

getUnitAxis() Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]#

Get the unit axis for the pin hinge.

Returns:

The unit axis for the pin hinge.

setGearRatio(arg0: SupportsFloat) None#

Set the gear ratio for the 1 dof subhinge

Parameter gear_ratio:

the gear ratio

setJointLimits(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Set the lower/upper pair of joint limit values for the 1 dof subhinge

Parameter limits:

the lower and upper limit values

setUnitAxis(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]]) None#

Set the unit axis for the pin hinge.

Parameter axis:

The unit axis for the pin hinge.

class Karana.Dynamics.PhysicalBody(name: str, mb: Multibody)#

Bases: BodyBase, Karana.Frame.Frame

static addSerialChain(name: str, nbodies: SupportsInt, root: PhysicalBody, htype: HingeType = HingeType.PIN, params: PhysicalBodyParams = None) list[PhysicalBody]#

Add a serial chain of rigid PhysicalBody instances to the multibody system

Add a serial chain of rigid bodies to the multibody system to the specified root body with the specified mass properties, hinge type and hinge connection properties. This method is mainly used for procedurally generating large test systems. See Procedural creation section for more discussion on this topic.

Parameter name:

prefix string to use for the new body names

Parameter nbodies:

number of bodies

Parameter root:

the parent body to attach the chain to

Parameter htype:

the hinge type

Parameter params:

the body params for each body

Returns:

the list of new rigid bodies

static addTree(name: str, branch_length: SupportsInt, nbranches: SupportsInt, depth: SupportsInt, root: PhysicalBody, htype: HingeType = HingeType.PIN, params: PhysicalBodyParams = None) list[PhysicalBody]#

Add a sub-tree of rigid PhysicalBody instances to the multibody system

Add a sub-tree of rigid bodies to the multibody system to the specified root body with the specified mass properties, hinge type and hinge connection properties. This method is mainly used for procedurally generating large test systems. See the Procedural creation section for more discussion on this topic.

Parameter name:

prefix string to use for the new body names

Parameter branch_length:

the number of bodies in a branch

Parameter nbranches:

the number of children branches

Parameter depth:

the number of branching levels to create

Parameter root:

the parent body to attach the chain to

Parameter htype:

the hinge type

Parameter params:

the body params for each body

Returns:

the list of new rigid bodies

static create(name: str, mb: Multibody) PhysicalBody#

Creates a new PhysicalBody with the given name.

Parameter name:

The name of the frame to create.

Parameter mb:

The Multibody instance.

Returns:

The created body.

accumGravAccel(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Accumulate the gravitational linear acceleration for the body represented in the specified frame.

If no frame is specified, then the linear acceleration is assumed to be represented in the body frame

Parameter g:

the gravitational linear acceleration vector

Parameter ref_frame:

the representation frame for the input gravity accel vector

accumGravityGradient(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Accumulate the gravity gradient moment vector for the body represented in the specified frame.

If no frame is specified, then the moment is assumed to be represented in the body frame

Parameter grav_gradient:

the gravity gradient vector

Parameter ref_frame:

the representation frame for the input gravity accel vector

addScenePartSpec(arg0: Karana.Scene.ScenePartSpec) None#

Add a ScenePart description to the body to be realized whenever a ProxyScene is available.

The new scene part spec’s name must not conflict with the name of an existing scene part spec of scene part for the body.

Parameter scene_part:

The ScenePart description

bodyObservedSpatialAccel() Karana.Math.SpatialVector#

Return the body frame observed spatial acceleration for the body with respect to the Newtonian frame

Return the body frame observed spatial acceleration for the body with respect to inertial frame about and in the body frame. The returned value is in the body frame. Note that this is NOT the newtonian_frame.frameToFrame(body).relSpaAccel() which is the Newtonian frame observed spatial acceleration!

Returns:

the spatial acceleration

constraintNodeList() list[ConstraintNode]#

Get a list of the constraint nodes on this body.

Returns:

A list of constraint nodes on the body

detach() None#

Reattach the body to the virtual root via a 6 dof hinge.

Reattach the body to the virtual root via a 6 dof hinge (while preserving the inertial pose, spatial velocity and spatial acceleration. See Multibody configuration changes section for information.

discardAllNodes() None#

Discard all nodes in the _nodes_usage_map

externalSpatialForce(arg0: bool) Karana.Math.SpatialVector#

Return the overall spatial force on the body at its reference frame and in the body frame

This method will accumulate the external spatial forces from all the force nodes (including active contact nodes) on the body. If with_constraints is true, then constraint spatial forces from the constraint nodes will also be accumulated in the returned value.

Parameter with_constraints:

set to true to include constraint node contributions

Returns:

the overall spatial force on the body, at the body reference frame in the body frame

getBodyToJointTransform() Karana.Math.HomTran#

Return the body frame to body HingePnode pnode transform.

For a deformable body, this is the transform value in the undeformed configuration.

Returns:

the transform

getConstraintNode(arg0: str) ConstraintNode#

Retrieve the constraint node with the specified name.

Return nullptr if there is no constraint node with the specified name.

Parameter name:

the node’s name

Returns:

The constraint node on the body with the specified name.

getGravAccel() Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]#

Return the gravity linear acceleration at the body in the body frame

Returns:

the gravity acceleration vector

getNode(arg0: str) Node#
getNode(node_name: str) Node

Retrieve the node with the specified name.

Return nullptr if there is no node with the specified name.

Parameter name:

the node’s name

Returns:

The node on the body with the specified name.

getNodeUpsilonFromBody(arg0: Node) Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#

Return the 6x6 OSCM Upsilon matrix for a body node using the body’s Upsilon.

Their method is used to compute the child onode UpsilonPlus value after crossing the modal dofs.

Parameter node:

the body node

Returns:

the OSCM Upsilon matrix

getNodeUpsilonFromPnode(arg0: Node) Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#

Return the 6x6 OSCM Upsilon matrix for a body node using the pnode Upsilon.

This method is used for the scatter step for onode Upsilon computation.

Parameter nd:

the body node

Returns:

the OSCM Upsilon matrix

getScenePart(arg0: str) Karana.Scene.ProxyScenePart#

Return the ScenePart with the specified name

See ProxyScene section for proxy scene related discussion.

Returns:

The scene part with machine name, or nullptr if none found

getScenePartSpecs() list[Karana.Scene.ScenePartSpec]#

Return the list of ScenePartSpecs

See ProxyScene section for proxy scene related discussion.

Returns:

The list of scene part specs

getSceneParts() list[Karana.Scene.ProxyScenePart]#

Return the list of SceneParts created from Karana::Scene::ScenePartSpec values

See ProxyScene section for proxy scene related discussion.

Returns:

The list of scene parts

getSpatialInertia() Karana.Math.SpatialInertia#

Return the body’s Karana::Math::SpatialInertia spatial inertia about the body frame

Returns:

the spatial inertia

getUpsilonMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the body frame referenced OSCM Upsilon matrix for the body.

This method is specialized by flex bodies as well. For a rigid body the value is a 6x6 matrix, but is larger by the number of modes for a deformable body.

Returns:

the OSCM Upsilon matrix

insertDummyParentBody() None#

Add a mass less and locked parent body between the current parent

The resulting system will have equivalent dynamics to the current system.

This method is a no-op if the parent hinge has a single subhinge.

kineticEnergy() float#

Return the kinetic energy contribution for the body

Returns:

the kinetic energy value

nodeList() list[Node]#

Get a list of the nodes on this body. This does not include pnodes or onodes.

Returns:

A list of nodes on the body, not including pnodes or onodes.

onode() HingeOnode#

Return the onode for the parent hinge

See Connecting bodies via hinges section for more on body pnodes and onodes.

Returns:

the HingeOnode instance

physicalParentBody() PhysicalBody#
pnode() HingePnode#

Return the pnode for the parent hinge

See Connecting bodies via hinges section for more on body pnodes and onodes.

Returns:

the HingePnode instance

reattach(new_parent: PhysicalBody, hinge_type: HingeType = HingeType.FULL6DOF) None#

Reattach the body to the specified parent PhysicalBody

Reattach this PhysicalBody to the new parent PhysicalBody body via a hinge of the specified type. If the new hinge type is a 6-dof hinge, then the inertial pose, spatial velocity and spatial acceleration of the body are preserved after reattachment. For a non 6-dof hinge, no such pose preservation is done, and follow up steps to set the hinge parameters (e.g., axes) and initial state will be required.

See Multibody configuration changes section for information.

Parameter new_parent:

The new parent body

Parameter hinge_type:

The new hinge type

setBodyToJointTransform(T: Karana.Math.HomTran) None#

Set the the body frame to body HingePnode pnode transform.

For a deformable body, this is the transform value in the undeformed configuration. This method should only be used for body pnodes. The Node::setBodyToNodeTransform() method should be used for all other nodes.

Parameter T:

The input transform

setGravAccel(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Set the gravitational linear acceleration for the body represented in the specified frame.

If no frame is specified, then the linear acceleration is assumed to be represented in the body frame

Parameter g:

the gravitational linear acceleration vector

Parameter ref_frame:

the representation frame for the input gravity accel vector

setGravityGradient(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Set the gravity gradient moment vector for the body represented in the specified frame.

If no frame is specified, then the moment is assumed to be represented in the body frame

Parameter grav_gradient:

the gravity gradient vector

Parameter ref_frame:

the representation frame for the input gravity accel vector

setParams(arg0: PhysicalBodyParams) None#

Set the PhysicalBody parameters

Parameter params:

the parameters to set

setSpatialInertia(spI: Karana.Math.SpatialInertia, ref_frame: Karana.Frame.Frame = None) None#

Set the Karana::Math::SpatialInertia spatial inertia for the body in the specified reference Karana::Frame::Frame frame

If no frame is specified, then the spatial inertia is assumed to be represented in and about the body frame

Parameter sp_i:

the input spatial inertia

Parameter ref_frame:

the reference frame for the input spatial inertia

shiftBaseBody() None#

Convert this body into a floating base body.

Given a body with parent PhysicalBody body that is a 6-dof floating base body, reverse the connecting parent hinge to make this body into a 6-dof floating base body. This operation maintains the required tree structure for the multibody system. The new hinge has the same subhinges as the original hinge - but in reversed order. The subhinge parameters preserve the original params while taking into account the orientation reversals. The end result is that the poses of the bodies remains unaffected. See the Multibody configuration changes for more on Multibody configuration changes.

spatialMomentum() Karana.Math.SpatialVector#

Return the spatial momentum contribution for the body

Returns:

the spatial momentum vector

splitSubhinges() None#

Split up the parent hinge’s subhinges into sequence of hinges with single subhinges

The resulting system will have equivalent dynamics to the current system.

This method is a no-op if the parent hinge has a single subhinge.

toLoopConstraint() LoopConstraintHinge#

Replace the parent hinge with an equivalent loop constraint

The method removes the hinge between a parent/child body pair, and replaces it with an equivalent cut-joint LoopConstraintHinge between the bodies. The child body is attached to the virtual root via a 6 dof hinge. The parameters are set so that there is no change in the pose, velocities etc, and the new system is kinematically and dynamically equivalent - albeit one with redundant coordinates and constraints. See Multibody representations sec for discussion about the duality between PhysicalHinge and LoopConstraintHinge classes in Multibody representations.

Returns:

the new LoopConstraint instance

class Karana.Dynamics.PhysicalBodyParams(spI: Karana.Math.SpatialInertia = ..., axes: collections.abc.Sequence[Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]]] = ..., body_to_joint_transform: Karana.Math.HomTran = ..., inb_to_joint_transform: Karana.Math.HomTran = ..., scene_part_specs: collections.abc.Sequence[Karana.Scene.ScenePartSpec] = [])#

Struct with parameters for a PhysicalBody rigid physical body */

body_to_joint_transform: Karana.Math.HomTran#
inb_to_joint_transform: Karana.Math.HomTran#
sp_i: Karana.Math.SpatialInertia#
property axes: list[Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]]#
property scene_part_specs: list[Karana.Scene.ScenePartSpec]#
class Karana.Dynamics.PhysicalHinge(parent: PhysicalBody, child: PhysicalBody, htype: HingeType, subhinge_types: collections.abc.Sequence[SubhingeType] = [])#

Bases: FramePairHinge

static create(parent: PhysicalBody, child: PhysicalBody, htype: HingeType, subhinge_types: collections.abc.Sequence[SubhingeType] = []) PhysicalHinge#

Factory method to create a PhysicalHinge instance.

Parameter parent:

The parent body

Parameter child:

The child body

Parameter htype:

The hinge type

Parameter subhinge_types:

The list of subhinge types for a custom hinge type

Returns:

A new PhysicalHinge instance

onode() HingeOnode#

Return the onode for the hinge See Connecting bodies via hinges section for more information on onodes and pnodes.

Returns:

the HingeOnode instance

pnode() HingePnode#

Return the pnode for the hinge See Connecting bodies via hinges section for more information on onodes and pnodes.

Returns:

the HingePnode instance

class Karana.Dynamics.PhysicalSubhinge#

Bases: SubhingeBase, Karana.Frame.EdgeFrameToFrame

@class PhysicalSubhinge Represents the abstract base class for physical articulation subhinges

This class is the base class for subhinges from which physical subhinge classes are derived. See Subhinges section for more information on physical subhinges.

getIndex() int#

Return the slot index for the subhinge in the parent hinge’s list of subhinges

Returns:

the subhinge index

oframeCoordMapMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return matrix to map coord velocities to physical velocities

The product of this matrix with the generalized velocities vector (U) evaluates to the full relative spatial velocities contribution from this object.

For a PhysicalSubhinge, this is a 6xNU size matrix where NU is number of generalized velocity coordinates for the subhinge. For a physical subhinge, this matrix is uses oframe representation. The product with U returns the relative spatial velocity across the subhinge referenced in the oframe.

For a CompoundSubhinge, this matrix is (6*nbodies)xNU in size where NU is the overall number of generalized velocity coordinates for the aggregated body subhinges. This matrix is the Jacobian from the embedded physical body subhinges to the embedded body relative spatial velocity contribution from them.

For a PhysicalModalBody body, the size is 6xNU, where NU is the number of modal coordinates. It returns the modal matrix for the pnode.

Returns:

coordinate map matrix

sanitizeCoords() bool#

Method to recenter or otherwise sanitize the subhinge’s coordinates

Some subhinge may have coordinates that need to be “sanitized” from time to time. An example if that of spherical subhinges, where the orientation coordinate representation may require recentering of the local charts when the values are nearing singularity. This method can specialized for subhinges that have this need. The return value should be true if any such sanitization was done to modify the coordinate values.

Returns:

true, is any sanitization was needed and carried out

class Karana.Dynamics.PhysicalSubhinge_T_0_0#

Bases: PhysicalSubhinge

@class PhysicalSubhinge Represents the abstract base class for physical articulation subhinges

This class is the base class for subhinges from which physical subhinge classes are derived. See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.PhysicalSubhinge_T_1_1#

Bases: PhysicalSubhinge

@class PhysicalSubhinge Represents the abstract base class for physical articulation subhinges

This class is the base class for subhinges from which physical subhinge classes are derived. See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.PhysicalSubhinge_T_3_3#

Bases: PhysicalSubhinge

@class PhysicalSubhinge Represents the abstract base class for physical articulation subhinges

This class is the base class for subhinges from which physical subhinge classes are derived. See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.PhysicalSubhinge_T_4_3#

Bases: PhysicalSubhinge

@class PhysicalSubhinge Represents the abstract base class for physical articulation subhinges

This class is the base class for subhinges from which physical subhinge classes are derived. See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.PinSubhinge#

Bases: Physical1DofSubhinge

class Karana.Dynamics.PrePostCallbackRegistry#
trace_callback_registry: bool#
__getitem__(key: str | SupportsInt) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], None]#

Get a function by name

__len__() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

__setitem__(key: str | SupportsInt, func: collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], None]) None#

Set a function with a string name or integer index

clear() None#

Clear out the entire CallbackRegistry. All callbacks will be removed.

dump(arg0: str) None#

Print out the string from dumpString. See dumpString for more details.

dumpString(arg0: str) str#

Create a string that lists all the functions by name.

erase(name: str) None#
erase(index: SupportsInt) None

Erase the callback at the provided index.

Parameters:

name (int) – The index of the callback to erase.

execute(arg0: float | numpy.timedelta64, arg1: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Execute all functions in the registry.

executeReverse(arg0: float | numpy.timedelta64, arg1: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Execute all functions in the registry in reverse.

pop(name: str) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], None]#
pop(index: SupportsInt) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], None]

Pop the callback at the provided index.

Parameters:

name (int) – The index of the callback to pop.

size() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

class Karana.Dynamics.Scheduler#

@class Scheduler The schedule class for the state propagator

executeAfterHopEvents(t: float | numpy.timedelta64) None#

Execute all the after hop events for the provided time.

Parameter t:
  • The time to execute all after hop events for.

executeBeforeHopEvents(t: float | numpy.timedelta64) None#

Execute all the before hop events for the provided time.

Parameter t:
  • The time to execute all before hop events for.

getNextExplicitHopEndTime() numpy.timedelta64#

Get the next explicit hop end time.

Returns:

The next explicit hop end time.

hasRegisteredTimedEvent(name: str, before_hop: bool) bool#

Determine whether a TimedEvent with the given name exists.

Parameter name:
  • The name of the TimedEvent.

Parameter before_hop:
  • Whether this is a before_hop timed event or not.

Returns:

true if a TimedEvent with the given name and before_hop setting exists, false otherwise.

registerTimedEvent(timed_event: TimedEvent, curr_time: float | numpy.timedelta64) None#

Register a TimedEvent.

Parameter timed_event:
  • The TimedEvent to register.

Parameter curr_time:
  • The current time. Used for error checking.

unregisterTimedEvent(name: str, before_hop: bool, okay_not_exists: bool) None#

Unregister a TimedEvent.

Parameter name:
  • The name of the TimedEvent.

Parameter before_hop:
  • Whether this is a before_hop timed event or not.

Parameter okay_not_exists:
  • If true, then do not error out if a timed event by this name

does not exist with the given before_hop setting, otherwise, error our if the given event is not found.

class Karana.Dynamics.ScrewSubhinge#

Bases: Physical1DofSubhinge

@class ScrewSubhinge Represents a 1 dof helical subhinge with coupled rotation/translation about a common axis

See Subhinges section for more information on physical subhinges.

getPitch() float#

Return the pitch value for the subhinge

The pitch is defined as meters of translation/radian.

Returns:

the pitch value

setPitch(arg0: SupportsFloat) None#

Set the pitch value for the subhinge

The pitch is defined as meters of translation/radian.

Parameter pitch:

the pitch value

class Karana.Dynamics.SpFunctions#

Struct with optional user-defined functions to be used by the state propagator

property post_deriv_fns: PrePostCallbackRegistry#

Optional function called after evaluating system derivative. Useful for passing state derivative values to models that needs them, and to perform data logging.

property post_hop_fns: PrePostCallbackRegistry#

Optional function called at the end of a hop step. Useful for processing external models that use the new state to set sensor inputs for closed-loop controllers, data logging, updating visualization, cleaning up the state to null out constraint errors etc.

property pre_deriv_fns: PrePostCallbackRegistry#

Optional function called before evaluating system derivative. Useful for setting gravity accel and other forces on the system.

property pre_hop_fns: PrePostCallbackRegistry#

Optional function called at the start of a hop step. Useful for propagating discrete states, sanitizing the input state (e.g., for changing coordinate chart origin), calling FSM step functions, processing external models to apply force inputs from closed-loop controllers etc.

property step_validate_fn: collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], bool]#

Optional function called at the end of a integration step to decide whether to accept the new state, or to roll back to the state at the start of the hop. Useful for repeating a the time step when the new state has invalid values.

property terminate_advance_to_fns: TerminateCrossingCallbackRegistry#

Optional function called to check whether to terminate the state propagation prematurely before the state advancement end time has been reached. Handy when the simulation has already reached an end state (possibly for an FSM) and there is no value in continuing on with the state propagation. This check is only done at the end of a hop, so there may be some timing slop in the check for an end state. This is in contrast with the zero-crossing check which is done within a hop to end the hop precisely when the zero-crossing condition is met.

property zero_crossing_fns: ZeroCrossingCallbackRegistry#

Optional function used for terminating a hop when a zero-crossing condition has been met. Useful for getting a simulation hop to terminate precisely when the implicitly defined zero-crossing condition occurs instead of continuing till the specified hop end time. See the Zero-crossings section for more discussion on zero crossing detection.

The zero crossing functions return a bool. This should be true if the zero has been crossed. The second argument to the function is a boolean. This will be true when we have reached the zero, and false otherwise.

class Karana.Dynamics.SpOptions#

Options for the state propagator */

property max_step_size: numpy.timedelta64#

Define the step size that advanceTo() should use to break up the overall time advancement into sub-steps. This is especially useful for fixed-step integrators to ensure that integrator steps are not too large. Also for cases where external interactions and data logging needs to be done at fixed step intervals.

property update_state_derivatives_hop_end: bool#

If true, then update the multibody state derivatives with the integrator states at the end of each hop.

class Karana.Dynamics.SpSolverType(value: SupportsInt)#

Members:

TREE_DYNAMICS : < ATBI forward dynamics for a tree system

INVERSE_DYNAMICS : < inverse dynamics for a tree system

TREE_AUGMENTED_DYNAMICS : < tree-augmented ATBI constrained forward dynamics

BAUMGARTE_DYNAMICS : < Baumgarte constrained forward dynamics

KINEMATICS : < kinematics simulation mode

UNDEFINED : < undefined solver type

BAUMGARTE_DYNAMICS: ClassVar[SpSolverType]#
INVERSE_DYNAMICS: ClassVar[SpSolverType]#
KINEMATICS: ClassVar[SpSolverType]#
TREE_AUGMENTED_DYNAMICS: ClassVar[SpSolverType]#
TREE_DYNAMICS: ClassVar[SpSolverType]#
UNDEFINED: ClassVar[SpSolverType]#
__members__: ClassVar[dict[str, SpSolverType]]#
__eq__(other: Any) bool#
__getstate__() int#
__hash__() int#
__index__() int#
__int__() int#
__ne__(other: Any) bool#
__repr__() str#
__setstate__(state: SupportsInt) None#
__str__() str#
property name: str#
property value: int#
class Karana.Dynamics.SpStatusEnum(value: SupportsInt)#

Enum with values to classify the reason for the termination of a step

Members:

UNKNOWN : < unknown

REACHED_END_TIME : < normal termination, reached requested end time

REACHED_ZERO_CROSSING : < premature end on reaching zero-crossing condition

FAILED_STEP_VALIDATION : < rolled back due to failing step validation check

FAILED_STEP_VALIDATION: ClassVar[SpStatusEnum]#
REACHED_END_TIME: ClassVar[SpStatusEnum]#
REACHED_ZERO_CROSSING: ClassVar[SpStatusEnum]#
UNKNOWN: ClassVar[SpStatusEnum]#
__members__: ClassVar[dict[str, SpStatusEnum]]#
__eq__(other: Any) bool#
__getstate__() int#
__hash__() int#
__index__() int#
__int__() int#
__ne__(other: Any) bool#
__repr__() str#
__setstate__(state: SupportsInt) None#
__str__() str#
property name: str#
property value: int#
class Karana.Dynamics.SphericalQuatSubhinge#

Bases: PhysicalSubhinge_T_4_3

@class SphericalQuatSubhinge Represents a 3 dof rotational subhinge using unit quaternion for generalized coords

See Subhinges section for more information on physical subhinges.

class Karana.Dynamics.SphericalSubhinge#

Bases: PhysicalSubhinge_T_3_3

@class SphericalSubhinge Represents a 1 dof rotational subhinge using minimal RotationVector coords

See Subhinges section for more information on physical subhinges.

getChartOffset() Karana.Math.UnitQuaternion#

Return the current offset for the RotationVector coordinates chart

Returns:

the chart offset UnitQuaternion

getMaxChartAngle() float#

Return the threshold for the RotationVector coordinates chart recentering

Return the max allowed angle before the chart is recentered when sanitizeCoords() is called.

Returns:

the threshold value

resetChart() None#
setMaxChartAngle(arg0: SupportsFloat) None#

Set the threshold for the RotationVector coordinates chart recentering

Set the max allowed angle before the chart is recentered when sanitizeCoords() is called.

Parameter val:

the threshold value

class Karana.Dynamics.StatePropagator(st: SubTree, integrator_type: Karana.Math.IntegratorType = Karana.Math.IntegratorType.RK4, integ_opts: Karana.Math.IntegratorOptions | None = None, sp_opts: SpOptions | None = None, solver_type: SpSolverType = ...)#

Bases: Karana.Core.LockingBase

trace_state_propagator: bool#
static create(st: SubTree, integrator_type: Karana.Math.IntegratorType = Karana.Math.IntegratorType.RK4, integ_opts: Karana.Math.IntegratorOptions | None = None, sp_opts: SpOptions | None = None, solver_type: SpSolverType = ...) StatePropagator#

Create an instance of the StatePropagator.

If the solver type is not specified, the constructor will use TREE_DYNAMICS if the specified st argument is a pure subtree (and not SubGraph), or if is the multibody instance itself with no bilateral constraints. For all other st, an error will be raised - and a legal solver type must be explicitly specified since there is no good way to infer one.

Parameter st:

the SubTree instance

Parameter integrator_type:

the numerical integrator type

Parameter integ_opts:

options for the numerical integrator

Parameter sp_opts:

options for the state propagator

Parameter solver_type:

the solver type

Returns:

An instance of the StatePropagator.

advanceBy(delta_time: float | numpy.timedelta64) SpStatusEnum#
advanceBy(delta_time: SupportsInt) SpStatusEnum

Method to advance the system state by a time interval

Parameter delta_time:

the time to advance by

Returns:

advancement status value

advanceTo(to_time: float | numpy.timedelta64) SpStatusEnum#
advanceTo(to_time: SupportsInt) SpStatusEnum

Method to advance the system state to a new time in the future

Parameter to_time:

the desired future time

Returns:

advancement status value

assembleState() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Combine the current associated SubTree state and continuous KModel states into one vector.

This state vector reflects the current state of the Multibody and KModels’ continuous states, which may be different than the state vector in the integrator.

The packing order is the same as the integrator. This can be used to create an initial state for the integrator as follows: state_propagator->setState(state_propagator->assembleState()).

Returns:

A state vector representing the Multibody and KModels’ continuous states of this StatePropagator.

assembleStateDeriv() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Combine the current associated SubTree state derivative and continuous KModel state derivatives into one vector.

This state derivative vector reflects the current state of the Multibody and KModels’ continuous states’ derivatives, which may be different than the state vector in the integrator.

The packing order is the same as the integrator. *

Returns:

A state vector derivative representing the Multibody and KModels’ continuous states’ derivatives of this StatePropagator.

computeJacobian() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Use numerical differentiation and the derivative function to compute the Jacobian (experimental)

Returns:

the Jacobian matrix

counters() StatePropagatorCounters#

Return the Counters struct that tracks propagation statistics

Returns:

the Counters counters struct

derivFunction(t: float | numpy.timedelta64, x: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], dx: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1], flags.writeable]) None#
derivFunction(t: SupportsInt, x: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], dx: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1], flags.writeable]) None

The derivative function for use by the integrator

This method is used to compute the state derivative by the numerical integrator for propagating system state.

Parameter t:

the current time

Parameter x:

the current state

Parameter dx:

the computed state derivative

getIntegrator() Karana.Math.Integrator#

Return the integrator instance

See Numerical integration section for more information on numerical integrators.

Returns:

the Integrator instance

getMaxStepSize() numpy.timedelta64#

Get the step size that advanceTo() is using to break up the overall time advancement into sub-steps.

This is especially useful for fixed-step integrators to ensure that integrator steps are not too large. Also for cases where external interactions and data logging needs to be done at fixed step intervals.

Returns:

The maximum step size that advanceTo will use.

getRegisteredModel(arg0: str) Karana.Models.BaseKModel#

Return the registered model with the specified name

Parameter name:

the name of the model being sought

Returns:

The registered model or null if there is no model with matching name

getRegisteredModels() list[Karana.Models.BaseKModel]#

Return a vector or registered models.

Returns:

A vector of registered models.

getSubTree() SubTree#

Return the SubTree used by this StatePropagator.

Returns:

The SubTree used by this StatePropagator.

getTime() numpy.timedelta64#

Return the current state propagation time value

Returns:

the Ktime time value

getTimeKeeper() TimeKeeper#

Return the TimeKeeper used by this StatePropagator.

Returns:

The TimeKeeper used by this StatePropagator.

getUpdateStateDerivativesHopEnd() bool#

Get the setting for updating the derivatives at hop end.

If true, then update the multibody state derivatives with the integrator states at the end of each hop.

Returns:

The the setting for updating the derivatives at hop end.

hardReset() None#

Reset the size of the internal state vector to match the size of the SubTree state + the size of all the continuous model states.

This method also uninitializes the state, so setState must be called afterwards.

hasRegisteredTimedEvent(name: str, before_hop: bool) bool#

Determine whether a TimedEvent with the given name exists.

Parameter name:
  • The name of the TimedEvent.

Parameter before_hop:
  • Whether this is a before_hop timed event or not.

Returns:

true if a TimedEvent with the given name and before_hop setting exists, false otherwise.

nstates() int#

Return the state vector size

Returns:

the state vector size

registerModel(model: Karana.Models.BaseKModel) None#

Register the provided BaseKModel model instance with the state propagator.

See KModel component models section for more discussion on component models and the Registering and unregistering models section on registering models.

Registering a model is a way to activate a model so that it is used in the physics computations. See KModel component models section for more discussion on component models.

Parameter model:
  • The model to register.

registerTimedEvent(timed_event: TimedEvent) None#

Register a TimedEvent. See Timed events section for more on using the TimedEvent class.

Parameter timed_event:

The TimedEvent to register.

setIntegrator(integrator: Karana.Math.Integrator) None#

Change to the specified integrator.

If there was a previous integrator, the time and state values are transferred as well.

See Numerical integration section for more information on numerical integrators.

Parameter integrator:

the new integrator

setMaxStepSize(max_step_size: float | numpy.timedelta64) None#

Set the step size that advanceTo() will use to break up the overall time advancement into sub-steps.

See getMaxStepSize for more details.

Parameter max_step_size:

The maximum step size that advanceTo will use.

setState(x: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Reset the integrator to the new state values

This is also referred to as a soft reset. This method assumes that only the state values have changed, and there have been no configuration changes causing changes to the size or structure of the state vector. The input state vector elements for subhinges should contain global coordinate values. This method resets the chart offsets for all regular and constraint subhinges for the sub graph.

The state itself is often created using the assembleState method.

See also

assembleState

Parameter x:

the new state value

setTime(t: float | numpy.timedelta64) None#

Reset the integrator to the new time value

This is also referred to as a soft reset. If the time set is different than the current time, this will attempt to rescheduled all TimedEvents appropriately; however, since TimedEvents can have arbitrary reschedule_fns, it is impossible to meet all corner cases. Use this with caution when you have non-uniform TimedEvents. See System state section for more on this topic.

Parameter t:

the new time

setUpdateStateDerivativesHopEnd(update_state_derivatives_hop_end: bool) None#

Set whether to update the derivatives at hop end or not.

If true, then update the multibody state derivatives with the integrator states at the end of each hop.

Parameter update_state_derivatives_hop_end:

The setting for updating the derivatives at hop end.

solverType() SpSolverType#

Return the solver type for the propagator

Returns:

the solver type

unregisterModel(model: Karana.Models.BaseKModel) None#

Unregister the provided BaseKModel model from the state propagator.

Unregistering a model is a way to deactivate a model so that it is no longer used in the physics computations. See the KModel component models section for more discussion on component models and the Registering and unregistering models section on registering models.

Parameter model:
  • The model to unregister.

unregisterTimedEvent(name: str, before_hop: bool, okay_not_exists: bool) None#

Unregister a TimedEvent. See Timed events section for more on using the TimedEvent class.

Parameter name:
  • The name of the timed event to remove.

Parameter before_hop:
  • Whether the event to remove is a before_hop or after_hop timed

event.

Parameter okay_not_exists:
  • If true, then do not error out if a timed event by this name

does not exist with the given before_hop setting, otherwise, error our if the given event is not found.

property fns: SpFunctions#

User defined functions to tailor the behavior of the state propagator

class Karana.Dynamics.StatePropagatorCounters#
property derivs: int#
property hops: int#
property integration_steps: int#
property zero_crossings: int#
class Karana.Dynamics.StickPartsConfig#
body_color: Karana.Scene.Color#
constraint_color: Karana.Scene.Color#
force_node_color: Karana.Scene.Color#
joint_color: Karana.Scene.Color#
sensor_node_color: Karana.Scene.Color#
__repr__() str#
property body_stick_radius: float#
property hinge_axes_length: float#
property layers: int#
property node_radius: float#
property pin_hinge_length: float#
property pin_hinge_radius: float#
property sphere_hinge_radius: float#
class Karana.Dynamics.SubGraph(parent_sg: SubGraph, name: str, new_root: BodyBase, constraints: collections.abc.Sequence[BilateralConstraintBase] = [], use_branches: collections.abc.Sequence[BodyBase] = [], stop_at: collections.abc.Sequence[BodyBase] = [])#

Bases: SubTree

@class SubGraph Represents a subtree of bodies with motion constraints

This class is a container for a sub-tree of bodies with possible motion constraints on them.

See the Physical bodies and hinges, Creating a tree multibody system, and Sub-Graphs with Constraints sections for more discussion related to the SubGraph class.

static create(parent_sg: SubGraph, name: str, new_root: BodyBase, constraints: collections.abc.Sequence[BilateralConstraintBase] = [], use_branches: collections.abc.Sequence[BodyBase] = [], stop_at: collections.abc.Sequence[BodyBase] = []) SubGraph#

Factory method to create a new SubGraph instance. See the SubTree documentation for more information on the bodies that are included in the sub-graph.

The constraints specified in the constraint list arguments are automatically added and enabled in the new sub-graph. There is also the option to instead call the inheritConstraints() later to add all relevant constraints from the parent SubGraph to this SubGraph in one swoop.

Parameter parent_sg:

The parent SubGraph for the new SubGraph

Parameter name:

The name for the new SubGraph

Parameter new_root:

The virtual root body for the new SubGraph

Parameter constraints:

The list of bilateral constraints for the SubGraph

Parameter use_branches:

The list of bodies that define branches whose bodies to include

Parameter stop_at:

The list of bodies whose descendants should not be included

Returns:

A new SubGraph instance

Gamma() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the OSCM related Gamma matrix for the constraint nodes

The Gamma matrix is used by the TA constraint dynamics algorithm to compute the Lagrange multipliers for the TA forward dynamics correction step.

Returns:

The Gamma matrix

accelError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the overall constraint spatial acceleration error for the enabled loop constraints

Returns:

the spatial acceleration error

aggregationSubGraph(arg0: str, arg1: collections.abc.Sequence[BilateralConstraintBase], arg2: bool) SubGraph#

Create and return an aggregation SubGraph for the list of constraints

For a set of bilateral constraints, the aggregation sub-graph is the smallest sub-graph that contains their constrained bodies, and is “path-induced” for the underlying sub-graph. A path-induced sub-graph includes all the bodies from the parent sub-graph that are connected to each other via hinges and bilateral constraints (and form a sub- tree if the constraints are ignored). If with_velocity_constraints is true (usually recommended), the velocity level non-hinge convel constraints are also considered when identifying the aggregation SubGraph. Aggregation SubGraphs are used for multibody system constraint-embedding.

Parameter name:

The name for the new SubGraph

Parameter constraints:

The input list of constraints

Parameter with_velocity_constraints:

If true, also use the non-hinge convel constraints when identifying the aggregation SubGraph

Returns:

the aggregation SubGraph

articulateSubhinge(shg: SubhingeBase, subhinge_index: SupportsInt, disable_ik: bool = False, rangeQ: SupportsFloat = 0.5, dQ: SupportsFloat = 0.01, pause: SupportsFloat = 0.01) None#

Sequentially articulate a regular or loop constraint subhinge for a physical body.

With graphics on, this step can be used to examine and debug issues with the model. If there are enabled loop constraints, this method will invoke the constraint kinematics solver each step to enforce the loop constraints.

Parameter shg:

subhinge to articulate

Parameter subhinge_index:

the index of the coordinate element to articulate

Parameter disable_ik:

if true, constraints solver is not invoked during articulation

Parameter range_q:

is the excursion angle range (in radians)

Parameter d_q:

is the angle step size (in radians)

Parameter pause:

time in seconds to sleep between articulation steps

cks() ConstraintKinematicsSolver#

Return the constraint kinematics solver for the registered constraints

See the Constraint kinematics section for more on the ConstraintKinematicsSolver class.

Returns:

the ConstraintKinematicsSolver instance

constraintCoordData() CoordData#

Return the CoordData for the loop constraint subhinges See The CoordData container section for more on the CoordData class.

Returns:

the constraints CoordData instance

constraintErrorAt(arg0: SupportsInt) tuple[Karana.Core.LockingBase, int]#

Return the constraint obj and its local offset in the overall constraint error vector

The constraint errors are organized as 6 elements for each hinge-loop constraint, followed by scalar entries for the non-hinge loop constraints, and then scalars for each of the coordinate constraints. Given an index value, this method returns the corresponding constraint and its local offset in this vector.

Not that this is also the organization of the rows in the matrices returned by the Algorithms::evalVelocityConstraintMatrix(True) method and the vector returned by the SubGraph::velError() method.

The related constraintResidualAt() method returns the constraint based on the packing order for constraint errors.

Parameter row_offset:

the overall row offset value

Returns:

The

Returns:

corresponding constraint instance and its local offset

constraintResidualAt(arg0: SupportsInt) tuple[Karana.Core.LockingBase, int]#

Return the constraint obj and its local offset in the overall constraint residuals vector

The constraint residuals are organized as the residual elements for each hinge-loop constraint (6-constraint.hinge().nU() size), followed by scalar entries for the non-hinge loop constraints, and then scalars for each of the coordinate constraints. Given an index value, this method returns the corresponding constraint and its local offset in this vector.

This method returns the constraint and its local offset for the specified overall row offset value in the matrix returned by the Algorithms::evalVelocityConstraintMatrix(False) method.

The related constraintErrorAt() method returns the constraint based on the packing order for constraint errors.

Parameter row_offset:

the input overall row offset value

Returns:

corresponding constraint instance and its local offset

constraintsErrorPoseGradient() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the pose error gradient matrix for all the constraints

Assemble the overall pose gradient matrix for all the constraint errors with respect to all SubGraph coords. The gradient matrix is thus (6*n_hlc+n_nhlc+n_cc, nU) in size, where n_hlc denotes the number of hinge loop constraints, n_nhlc the number of non-hinge loop constraints, and n_cc the number of coordinate constraints. This is used by the solveQ() method of the CK solver.

Returns:

the constraint pose error gradient matrix

constraintsErrorVelJacobian() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the velocity error Jacobian matrix for all the constraints

Assemble the overall velocity Jacobian matrix for all the constraints with respect to all SubGraph coords. The Jacobian matrix is thus (6*n_hlc+n_nhlc+n_cc, nU) in size, where n_hlc denotes the number of hinge loop constraints, n_nhlc the number of non-hinge loop constraints, and n_cc the number of coordinate constraints. This is used by the solveU() and solveUdot() methods of the CK solver.

Returns:

the constraint velocity error Jacobian matrix

constraintsErrorVelJacobianDot() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the time derivative of the velocity error Jacobian matrix for all the constraints

The Jacobian matrix time derivative is thus (6*n_hlc+n_nhlc+n_cc, nU) in size, where n_hlc denotes the number of hinge loop constraints, n_nhlc the number of non-hinge loop constraints, and n_cc the number of coordinate constraints. This is used for constraint embedding.

Returns:

the constraint velocity error Jacobian matrix

constraintsGc() Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the Gc overall constraint matrix for the loop constraints (WIP)

The Gc constraint matrix defines the overall velocity level constraints for the generalized velocity coordinates based on the loop closure constraints. Thus Gc*U=0 when the velocity constraints are satisfied. Gc itself is Q * Jacobian.

The column space of Gc^* defines the squeeze forces, i.e (Gc^* x Y) generalized forces cause no motion for arbitrary Y.

Returns:

The velocity constraint Gc matrix

disableConstraint(arg0: BilateralConstraintBase) None#

Disable a constraint for the SubGraph

Remove this constraint from the enabled constraints list for this SubGraph. See Bilateral closure constraints section for more info on enabling/disabling constraints.

Parameter constraint:

the constraint

enableConstraint(arg0: BilateralConstraintBase) None#

Enable a constraint for the SubGraph

If not already, add this loop constraint to the enabled list for use in constraint kinematics, and TA dynamics etc algorithms. See Bilateral closure constraints section for more info on enabling/disabling loop constraints.

Parameter constraint:

the new constraint

enabledConstraints() list[BilateralConstraintBase]#

Return the list of enabled constraints for the SubGraph

This returns the list of constraints that are currently “active” for this SubGraph. See Bilateral closure constraints section for more info on enabling/disabling constraints.

Returns:

the list of enabled constraints

enabledCoordinateConstraints() list[CoordinateConstraint]#

Return the list of enabled coordinate constraints for the SubGraph

This returns the list of coordinate constraints that are currently “active” for this SubGraph. See Coordinate constraints section for more info on enabling/disabling coordinate constraints.

Returns:

the list of enabled coordinate constraints

enabledHingeLoopConstraints() list[LoopConstraintHinge]#

Return the list of enabled hinge-loop constraints for the SubGraph

This returns the list of hinge-loop constraints that are currently “active” for this SubGraph. See Bilateral closure constraints section for more info on enabling/disabling constraints.

Returns:

the list of enabled hinge loop-constraints

enabledNonHingeLoopConstraints() list[LoopConstraintConVel]#

Return the list of enabled non-hinge-loop (convel) constraints for the SubGraph

This returns the list of non-hinge-loop constraints that are currently “active” for this SubGraph. See Bilateral closure constraints section for more info on enabling/disabling constraints.

Returns:

the list of enabled non-hinge loop-constraints

getBodyCoordinateConstraints(arg0: PhysicalBody) list[CoordinateConstraint]#

Return coordinate constraints connected to a body. See Bilateral closure constraints section for more info on constraints.

Parameter body:

the body instance

Returns:

the list of coordinate constraints involving the body

getBodyLoopConstraints(arg0: PhysicalBody) list[LoopConstraintBase]#

Return loop constraints connected to a body. See Bilateral closure constraints section for more info on constraints.

Parameter body:

the body instance

Returns:

the list of loop constraints involving the body

getEnabledConstraint(arg0: str) BilateralConstraintBase#

Look up an enabled constraint by name. See Bilateral closure constraints section for more info on loop constraints.

Parameter name:

the constraint’s name

Returns:

the constraint instance, or null if there is no enabled constraint with the specified name

getLoopConstraintBodies(arg0: LoopConstraintBase) list[PhysicalBody]#

Return PhysicalBody instances involved in a loop for a loop constraint

The Karana::Frame::Frame pair associated with a loop constraint define a pair of bodies whose relative motion is constrained. All PhysicalBody instances belonging to the minimal spanning tree containing this pair of bodies is effected by the loop constraint, and are included in the list of bodies returned by this method. See the Bilateral closure constraints section for more info on loop constraints.

Parameter c:

the constraint instance

Returns:

the list of bodies in the loop

graphCoordData() CoordData#

Return the subhinge+body+constraints CoordData for the SubGraph

This CoordData is a combination of the subhinge, body and constraint CoordDatas

See The CoordData container for more on the CoordData class.

Returns:

the CoordData for the SubGraph

inheritConstraints() None#

Add all loop and coordinate constraints from the parent SubGraph that are legal for this SubGraph.

This method is a helper method to populate a new SubGraph with all the constraints from the parent SubGraph.

kinematicsAnalysis()#

Carry out kinematics analysis of the sub-graph with constraints.

selfSubGraph

The sub-graph whose kinematics analysis to do

For systems with constraints, this method will generate a report based on kinematics analysis, The report will included information such as the best choice of independent coordinates, the number of independent constraints, and carry out checks on the velocity constraint matrix, and possible coordinate-partitioning options.

nLoopConstraintResiduals() int#

Return the size of the residuals vector for loop constraints

This returns the combined length of the residuals for the hinge and non-hinge loop constraints. See Coordinate constraints section for more info on enabling/disabling coordinate constraints.

Returns:

the size of the residuals vector

poseError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the overall constraints pose error vector for the enabled constraints

Returns:

the pose error vector

showBodiesGraph(*, name_to_label_map: dict[str, str] | None = None, buttons: list[Button] | None = None, extra_edges: dict[str, dict[str, dict]] | None = None, port: int = 8765, title: str = 'Multibody System', autorun: str = True, log_level: str = 'warning', launch_client=False) MultibodyGraphServer#

Display the sub-graph bodies and constraints as a nodes graph.

selfSubGraph

The sub-graph whose bodies to display

node_id_to_label_map: dict[str, str] | None

Dictionary defining the labels to use for each body in the graph display

buttons: list[Button] | None

Extra buttons to display with server-side callbacks on press

extra_edges: dict[str, dict[str, dict]] | None

Extra edges to add to the graph. The key will be an identifier, and the value will be a color, and a list of edges

port: int

Port to bind to - defaults to 8765.

title: str

Title of the graph

autorun: bool

Automatically start the server - defaults to True.

log_level: str

Terminal verbosity level - defaults to “warning”.

launch_client: bool

Automatically open the frontend in a local browser tab. Defaults to False.

MultibodyGraphServer

Handle to the server hosting the graph visualization

velError() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the overall constraint spatial velocity error for the enabled constraints

Returns:

the spatial velocity error

class Karana.Dynamics.SubTree(parent_subtree: SubTree, name: str, new_root: BodyBase, use_branches: collections.abc.Sequence[BodyBase] = [], stop_at: collections.abc.Sequence[BodyBase] = [])#

Bases: Karana.Core.LockingBase

@class SubTree Represents a SubTree with connected bodies

This class is for a sub-tree of connected bodies

See the Physical bodies and hinges, Creating a tree multibody system, and Sub-Trees sections for more discussion related to the SubTree class.

enable_dump_dynamics: bool#
static create(parent_subtree: SubTree, name: str, new_root: BodyBase, use_branches: collections.abc.Sequence[BodyBase] = [], stop_at: collections.abc.Sequence[BodyBase] = []) SubTree#

Factory method to create a new SubTree instance

Create a new SubTree from the bodies in this SubTree starting at the new_root body. If new_leaves is empty, then the sub-tree will contain all the descending bodies. Otherwise, the sub-tree will consist of the spanning tree made of the new root and the new leaves.

Parameter parent_subtree:

The parent SubTree for the new SubTree

Parameter name:

The name for the new SubTree

Parameter new_root:

The virtual root body for the new SubTree

Parameter use_branches:

The branches to get bodies from

Parameter stop_at:

list of last bodies on a branch

Returns:

A new SubTree instance

accumUniformGravAccel(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Accumulate the uniform gravity accel value for all the physical bodies in the SubTree

The input value is in the specified reference frame. If no reference frame is provided, then the newtonian root frame is assumed to be the reference frame.

Parameter g:

the gravity accel vector

Parameter ref_frame:

the reference frame

ancestorBody(bd: BodyBase, bd1: BodyBase) BodyBase#

Return the common ancestor body for the pair of BodyBase bodies in this SubTree

Parameter bd:

the first body

Parameter bd1:

the other body

Returns:

the common ancestor BodyBase body

articulateBodies(rangeQ: SupportsFloat = 0.5, dQ: SupportsFloat = 0.01, pause: SupportsFloat = 0.01) None#

Sequentially articulate all the 1 dof subhinges for the physical bodies.

With graphics on, this step can be used to examine and debug any issues with the model.

Parameter range_q:

is the excursion angle range (in radians)

Parameter d_q:

is the angle step size (in radians)

Parameter pause:

time in seconds to sleep between articulation steps

articulateSubhinge(shg: SubhingeBase, subhinge_index: SupportsInt, rangeQ: SupportsFloat = 0.5, dQ: SupportsFloat = 0.01, pause: SupportsFloat = 0.01, cb: collections.abc.Callable[[], None] = None) None#

Sequentially articulate a subhinge for a physical body.

With graphics on, this step can be used to examine and debug issues with the model.

Parameter shg:

subhinge to articulate

Parameter subhinge_index:

the index of the coordinate element to articulate

Parameter range_q:

is the excursion angle range (in radians)

Parameter d_q:

is the angle step size (in radians)

Parameter pause:

time in seconds to sleep between articulation steps

Parameter cb:

callback to invoke every time the Q coordinate is changed

baseBodies() list[BodyBase]#

Return the list of BodyBase base bodies for the SubTree

Base bodies are the immediate children of the SubTree’s virtual root body.

Returns:

the list of BodyBase base bodies

bodyCoordData() CoordData#

Return the CoordData for the body deformation coords See The CoordData container for more on the CoordData class.

Returns:

the CoordData for the body deformation coords

bodyOSCM(arg0: collections.abc.Sequence[BodyBase]) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the OSCM matrix for the specified bodies

The returned matrix is square and symmetric. The block entries for deformable bodies will have more than 6 rows/columns.

Parameter bodies:

the input list of bodies

Returns:

the bodies OSCM matrix

bodyPnodesOSCM(arg0: collections.abc.Sequence[BodyBase]) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the OSCM matrix for the pnodes for the specified bodies

The returned matrix is square and symmetric and of 6xnbodies row/column size

Parameter bodies:

the input list of bodies

Returns:

the pnodes OSCM matrix

childrenBodies(body: BodyBase) list[BodyBase]#

Return the list of BodyBase child bodies for a body for this subtree.

The list may include physical and compound bodies.

Parameter bd:

the input body

Returns:

list of BodyBase children bodies

cmFrame() Karana.Frame.Frame#

Return the SubTree’s center of mass (CM) Karana::Frame::Frame instance

Returns:

the CM frame Frame instance

containsBody(bd: BodyBase) bool#

Return true if the specified BodyBase body belongs to the SubTree or to any of its nested hierarchy of SubTrees

Parameter bd:

the input body

Returns:

true if the body belongs to the SubTree

coordAt(arg0: SupportsInt) tuple[CoordBase, int]#
coordAt(arg0: SupportsInt) tuple[CoordBase, int]

Returns coord obj and its coord offset corresponding to overall U offset

A SubTree has multiple CoordData which are packed and unpacked the coordinate values for its set of CoordBase instances. This method returns the CoordBase and its local coordinate offset corresponding to the specified overall U offset value. This method returns the CoordBase and its local offset for the specified overall column offset value in the matrix returned by the Algorithms::evalVelocityConstraintMatrix() method, or the vector returned by the SubTree::getU() method.

Parameter u_offset:

the input overall U offset value

Returns:

The CoordBase instance and its local U coord offset

coordOffsets(arg0: CoordBase) CoordDataCoordOffset#

Returns the packing offset for the specified CoordBase

The SubTree has get/set methods to pack and unpack the coordinate values for its set of CoordBase and CoordData instances. This method returns the offsets for the Q and U values for the specified CoordBase in these combined arrays.

Parameter c:

The CoordBase to check for

Returns:

A CoordOffset struct with the Q and U offsets

crossUpsilonMatrix(arg0: HingePnode, arg1: HingePnode) Annotated[numpy.typing.NDArray[numpy.float64], [6, 6]]#

Return the cross Upsilon(left, right) matrix for a pair of pnodes

This method requires that the left pnode be an ancestor of the right pnode.

Parameter left:

the pnode on the left

Parameter right:

the pnode on the right

Returns:

the cross Upsilon(left, right) matrix

disableAlgorithmicUse() None#

Disable the running of dynamics algorithms for the SubTree

This methods unsets this SubTree from algorithmic use if it has not been unset already. See the Dynamics Computations section for more on the available SubTree level computational algorithms.

displayModel(prefix: str = '') None#

Display information about the SubTree and its bodies

Parameter prefix:

the prefix for each line in the output

dumpDynamics(prefix: str = '') None#

Dump the details of the tree forward dynamics computations

This is a debugging function that prints out the full state, the generalized forces, the external and constraint forces, and the gravity acceleration involved in the computation of the state derivative. This method will be called with each call to Algorithms::evalForwardDynamics if the enable_dump_dynamics public member flag has been set to true. The flag can be set to false to disable the dump calls.

Parameter prefix:

the prefix for each line in the output

dumpTree(prefix: str = '', options: SubTreeDumpTreeOptions = ...) None#

Display the body tree. The contents of the options struct can be used to control the content and verbosity of the displayed output.

Parameter prefix:

the prefix for each line in the output

Parameter options:

Options to tailor the output of dumpTree

enableAlgorithmicUse() None#

Enable the running of dynamics algorithms for the SubTree

This methods sets up this SubTree for algorithmic use if it has not been setup as such already. Note, that algorithmic use is permissible only if this SubTree is disjoint from all other algorithmic SubTrees (i.e. the physical bodies are not shared). See the Dynamics Computations section for more on the available SubTree level computational algorithms.

framesOSCM(arg0: collections.abc.Sequence[Karana.Frame.Frame], arg1: collections.abc.Sequence[PhysicalSubhinge]) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the OSCM matrix for the list of frames

The returned matrix is square and symmetric and of 6xnframes row/column size. Each frame in the input list is required to be downstream of a body. If subhinges are provided, then the returned matrix also contains additional rows and columns for the subhinges from the mass-matrix, along with cross-terms.

Parameter body_frames:

the input list of body frames

Parameter subhinges:

the input list of body frames

Returns:

the frames OSCM matrix

getBodies(name: str) list[BodyBase]#

Look up BodyBase bodies in the SubTree with the specified name.

Parameter name:

the body name

Returns:

the list of BodyBase body instances

getBody(name: str) BodyBase#

Look up a BodyBase body in the SubTree by name.

This method will throw an error if there are multiple bodies with the same specified name. This method will return a nullptr if there is no body with the matching name.

Parameter name:

the body’s name

Returns:

the BodyBase body instance

getBodyPairPhiMatrix(arg0: BodyBase, arg1: BodyBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the regular phi(left, right) matrix for the body pair (from left pframe to right pframe)

This method requires that the left body be an ancestor of the right body.

Parameter left:

the body on the left

Parameter right:

the body on the right

Returns:

the phi(left, right) matrix

getBodyPairPnodePsiMatrix(arg0: BodyBase, arg1: BodyBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the ATBI psi(left.pnode(), right.pnode()) matrix for the pnodes of the body pair

This method requires that the left body be an ancestor of the right body.

Parameter left:

the body on the left

Parameter right:

the body on the right

Returns:

the psi(left.pnode(), right.pnode()) matrix

getBodyPairPsiMatrix(arg0: BodyBase, arg1: BodyBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the ATBI psi(left, right) matrix for the body pair

The regular psi = phi * tauper This method requires that the left body be an ancestor of the right body.

Parameter left:

the body on the left

Parameter right:

the body on the right

Returns:

the psi(left, right) matrix

getContainingCompoundBody(bd: BodyBase) CompoundBody#

Look up the containing compound body for a body contained by the subtree

A body contained in a SubTree, may be a direct child, or be embedded at some level in a compound body in the subtree. This method will return the direct child compound body that contains the input body at some level in its nested hierarchy of embedded bodies. This method will return nullptr if the input body is not contained in the subtree.

Parameter the:

input body

Returns:

the CompoundBody instance containing the body

getCoordBasePairOframePsiMatrix(arg0: CoordBase, arg1: CoordBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the oframe variant psi(left, right) matrix for the CoordBase pair (from left oframe to right oframe)

The oframe variant psi = tauper * phi This method requires that the left CoordBase be an ancestor of the right CoordBase. For a subhinge, its oframe is its regular oframe. For a flex body, the oframe is the body pnode.

Parameter left:

the CoordBase on the left

Parameter right:

the CoordBase on the right

Returns:

the psi(left, right) matrix

getCoordBasePairPhiMatrix(arg0: CoordBase, arg1: CoordBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the 6x6 phi(left, right) lhs pframe to rhs pframe phi matrix for the CoordBase pair

This method requires that the left CoordBase be an ancestor of the right CoordBase. For a subhinge, its pframe is its regular pframe. For a flex body, the pframe is the body frame.

Parameter left:

the CoordBase on the left

Parameter right:

the CoordBase on the right

Returns:

the 6x6 phi(left, right) matrix

getCoordBasePairPsiMatrix(arg0: CoordBase, arg1: CoordBase) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Return the psi(left, right) matrix for the CoordBase pair (from left pframe to right pframe)

This method requires that the left CoordBase be an ancestor of the right CoordBase. The returned matrix is of size (left.nU()+6, right.nU()+6), with the lhs in the left pframe, and the rhs in the right frame. For a subhinge, its pframe is its regular pframe. For a flex body, the pframe is the body frame.

Parameter left:

the CoordBase on the left

Parameter right:

the CoordBase on the right

Returns:

the psi(left, right) matrix

getCrossUpsilonMatrix(arg0: PhysicalBody, arg1: PhysicalBody) Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#

Compute the body frame referenced cross-OSCM Upsilon matrix.

For a rigid body the value is a 6x6 matrix, but is larger by the number of modes for a deformable body.

Parameter lbd:

the left-hand body for the cross-OSCM Upsilon value

Parameter rbd:

the right-hand body for the cross-OSCM Upsilon value

Returns:

the cross-OSCM Upsilon matrix

getQ() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Q coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

getT() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the T generalized forces as an array

Returns:

Array of values

getU() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the U velocity coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

getUdot() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Return the Udot acceleration coordinates as an array

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

Array of values

hasBody(bd: BodyBase) bool#

Return true if the specified BodyBase body directly belongs to the SubTree

This method will return false if the input body is embedded within one its bodies.

Parameter bd:

the input body

Returns:

true if the body belongs to the SubTree

isBaseBody(body: BodyBase) bool#

Return true if the BodyBase body is a base body for this sub-tree

Parameter bd:

the input body

Returns:

true, if the body is a base body in the SubTree

leafBodies() list[BodyBase]#

Return the list of BodyBase leaf bodies for the SubTree

Leaf bodies are the bodies with children in the SubTree

Returns:

the list of leaf BodyBase bodies

multibody() Multibody#

Return the parent Multibody instance

Returns:

the Multibody instance

nQ() int#

The number of Q generalized coords for the CoordBase in the SubTree.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

the number of coordinates

nU() int#

The number of U velocity coords for the CoordBase.

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Returns:

the number of velocity coordinates

numBodies() int#

Return the number of bodies in the tree

Returns:

the number of bodies

parentBody(body: BodyBase) BodyBase#

Return the specified body’s BodyBase parent body in this SubTree

Since a SubTree can have physical and compound bodies, the returned parent body can be a physical or a compound body.

Parameter body:

the specified body

Returns:

the parent body

resetData() None#

Clear out the external spatial forces, gravity accel and gravity gradient values for all bodies, and all generalized coord, velocities, accels and forces. This is a helper method to initialize the SubTree to a zero state.

This method should be used with caution. By initializing setting all coordinates etc to 0 values, it renders the isFinalized() method ineffective for detecting uninitialized state and other values.

sanitizedCoords() bool#

Call sanitizeCoords() on all SubTree subhinges with coordinates sanitization needs

Return true if any of them actually did a sanitization action.

Returns:

true if any of the subhinges had to sanitize their coordinates

setQ(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setQ(val: SupportsFloat) None

Set the Q coordinates to a constant value

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter fill_value:

Fill value.

setT(arg0: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setT(arg0: SupportsFloat) None

Set the U velocity coordinates to a constant value

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter fill_value:

Fill value.

setU(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setU(val: SupportsFloat) None

Set the U velocity coordinates to a constant value

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter fill_value:

Fill value.

setUdot(vals: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]) None#
setUdot(val: SupportsFloat) None

Set the Udot acceleration coordinates to a constant value

See Generalized Q, U etc coordinates section for more on Q, U etc generalized coordinates.

Parameter fill_value:

Fill value.

setUniformGravAccel(g: Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]], ref_frame: Karana.Frame.Frame = None) None#

Set the uniform gravity accel value for all the physical bodies in the SubTree

The input value is in the specified reference frame. If no reference frame is provided, then the newtonian root frame is assumed to be the reference frame. This method can only be called on a SubTree that is current.

Parameter g:

the gravity accel vector

Parameter ref_frame:

the Frame reference frame

showState(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Display a breakdown of the elements of the state vector into its component elements.

The state vector is typically associated with the StatePropagator state. See System state section for more on the state vector, and the The state propagator for the StatePropagator class.

Parameter x:

The state vector

sortedBodiesList() list[BodyBase]#

Compute and return the sorted list of bodies in the tree. This will be a mix of PhysicalBody and CompoundBody instances.

Returns:

A vector containing the bodies of the SubTree.

sortedPhysicalBodiesList() list[PhysicalBody]#

Compute and return the topologically sorted list of PhysicalBody instances in the tree

The list includes all physical bodies, even those embedded within CompoundBody bodies in the SubTree.

Returns:

the list of PhysicalBody instances

subhingeCoordData() CoordData#

Return the CoordData for the subhinges See The CoordData container for more on the CoordData class.

Returns:

the CoordData for the subhinges

treeCoordData() CoordData#

Return the subhinge+body tree CoordData for the SubTree

This CoordData is a combination of the subhinge and body CoordDatas

See The CoordData container for more on the CoordData class.

Returns:

the CoordData for the tree

virtualRoot() BodyBase#

Returns the virtual root BodyBase body for the tree.

Returns:

The virtual root body.

class Karana.Dynamics.SubTreeDumpTreeOptions(hinge_type: bool = True, lock_Status: bool = False, ref_count: bool = False, hinge_ref_count: bool = False, id: bool = False)#
current_status: bool#
hinge_ref_count: bool#
hinge_type: bool#
id: bool#
ref_count: bool#
__repr__() str#
class Karana.Dynamics.SubhingeBase#

Bases: CoordBase

getPrescribed() bool#

Return the prescribed flag for the subhinge

Returns:

the prescribed mode status

parentHinge() HingeBase#

Return the parent hinge for the subhinge

Returns:

the PhysicalHinge parent hinge

setPrescribed(flag: bool) None#

Set the prescribed flag for the subhinge

Parameter flag:

the enable/disable flag

subhingeType() SubhingeType#

Helper method to return the subhinge type

Returns:

the subhinge type

subhingeTypeString() str#

Helper method to return the string name for a SubhingeType subhinge type

Parameter shtype:

the subhinge type

Returns:

the subhinge type as a string

class Karana.Dynamics.SubhingeType(value: SupportsInt)#

Members:

LOCKED

PIN

LINEAR

LINEAR3

SPHERICAL

SPHERICAL_QUAT

SCREW

COMPOUND

COMPOUND: ClassVar[SubhingeType]#
LINEAR: ClassVar[SubhingeType]#
LINEAR3: ClassVar[SubhingeType]#
LOCKED: ClassVar[SubhingeType]#
PIN: ClassVar[SubhingeType]#
SCREW: ClassVar[SubhingeType]#
SPHERICAL: ClassVar[SubhingeType]#
SPHERICAL_QUAT: ClassVar[SubhingeType]#
__members__: ClassVar[dict[str, SubhingeType]]#
static to_json(o: SubhingeType) dict[str, Any]#

Class method used to represent SubhingeType in a json file.

classmethod from_json(d: dict[str, Any]) Self#

Construct a SubhingeType from json file data.

classmethod from_yaml(_, node) Self#

Construct a SubhingeType from yaml file data.

classmethod to_yaml(representer, node)#

Class method used to represent SubhingeType in a yaml file.

__eq__(other: Any) bool#
__getstate__() int#
__getstate__() str
__hash__() int#
__index__() int#
__int__() int#
__ne__(other: Any) bool#
__repr__()#
__setstate__(state: SupportsInt) None#
__setstate__(arg0: str) None
__str__() str#
property name: str#
property value: int#
class Karana.Dynamics.TerminateCrossingCallbackRegistry#
trace_callback_registry: bool#
__getitem__(key: str | SupportsInt) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], bool]#

Get a function by name

__len__() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

__setitem__(key: str | SupportsInt, func: collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], bool]) None#

Set a function with a string name or integer index

clear() None#

Clear out the entire CallbackRegistry. All callbacks will be removed.

dump(arg0: str) None#

Print out the string from dumpString. See dumpString for more details.

dumpString(arg0: str) str#

Create a string that lists all the functions by name.

erase(name: str) None#
erase(index: SupportsInt) None

Erase the callback at the provided index.

Parameters:

name (int) – The index of the callback to erase.

execute(arg0: float | numpy.timedelta64, arg1: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) list[bool]#

Execute all functions in the registry.

executeReverse(arg0: float | numpy.timedelta64, arg1: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) list[bool]#

Execute all functions in the registry in reverse.

pop(name: str) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], bool]#
pop(index: SupportsInt) collections.abc.Callable[[float | numpy.timedelta64, Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]], bool]

Pop the callback at the provided index.

Parameters:

name (int) – The index of the callback to pop.

size() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

class Karana.Dynamics.TimeKeeper(fc: Karana.Frame.FrameContainer)#
class Karana.Dynamics.TimeKeeper(other: TimeKeeper)

Bases: Karana.Core.Base

Keeps track of time.

static utcTimeToEphemeris(utc_time: str) float#

Convert a time in UTC to an ephemeris.

Parameter utc_time:

The utc_time given as a string in the form “YYYY-MM- DDThh:mm:ss.ss” where Y is the year, M is the month, D is the day, h is the hour, m is the minute, and s is the second. The seconds can have decimals.

Returns:

The utc_time as an ephemeris.

getTime() numpy.timedelta64#

Get the time from TimeKeeper.

Returns:

The current time.

isFinalized() bool#

Determine if the TimeKeeper is initialized.

Returns:

true if initialized, false otherwise.

setInitialEphemeris(initial_ephemeris: SupportsFloat) None#
setInitialEphemeris(utc_time: str) None

Set the initial ephemeris.

Parameter utc_time:

The UTC time as a string in the form “YYYY-MM-DDThh:mm:ss.ss” where Y is the year, M is the month, D is the day, h is the hour, m is the minute, and s is the second. The seconds can have decimals.

setTime(time: float | numpy.timedelta64) None#

Set the TimeKeeper’s time.

Parameter time:

The current time.

class Karana.Dynamics.TimedEvent(name: str, t: float | numpy.timedelta64, fn: collections.abc.Callable[[float | numpy.timedelta64], None], before_hop: bool)#

Bases: Karana.Core.Base

This class is used to execute events at a given time. The initial time and function to execute are constructor arguments. The callback function itself can be get/set afterwards as well using the f member variable. The period and reschedule_fn are member variables that are used for recurring callbacks. If the period is non-zero, then the TimedEvent will be rescheduled using that period. If the period is 0, and the reschedule_fn is set, then the result of the reschedule_fn will be used to determine the next reschedule time. If the period is 0 and the reschedule_fn is not set, then the callback will not be rescheduled.

static create(name: str, t: float | numpy.timedelta64, fn: collections.abc.Callable[[float | numpy.timedelta64], None], before_hop: bool) TimedEvent#

Constructor for TimedEvent.

Parameter name:

The event’s name.

Parameter t:

The time to execute the TimedEvent at.

Parameter fn:

The function to execute.

Parameter before_hop:

This determines whether the timed event runs before or after the hop.

Returns:

the TimedEvent instance

__gt__(other: TimedEvent) bool#

Comparison operator. Used mainly to order TimedEvents on a heap.

First time is used to compare. If this is the same, then priority is used. If this is also the same, then the id is used.

Parameter other:
  • The TimedEvent to compare this one against.

Returns:

comparison status

dumpString(prefix: str = '', options: Karana.Core.DumpOptionsBase = None) str#

Dump the TimedEvent information to a string.

Returns:

A string with the dump info for this TimedEvent.

isBeforeHop() bool#

Returns whether the TimedEvent is a before hop timed event or not.

Returns:

true if the TimedEvent is a before hop timed event. false otherwise.

nextEventTime() numpy.timedelta64#

Get the next time this TimedEvent will execute its event function at.

Returns:

The next time this TimedEvent will execute its event function at.

reschedule() bool#

Reschedules the callback if appropriate. This will update the internal time with the new time if it should be rescheduled.

Returns:

true if the TimedEvent is rescheduled and false otherwise.

property fn: collections.abc.Callable[[float | numpy.timedelta64], None]#

The callback function that runs when this timed event is called

property period: numpy.timedelta64#

The period to reschedule this callback at. If 0, then the reschedule_fn will be used.

property priority: int#

The priority for this callback. This differentiates callbacks that are running at the same time. Lower is a higher priority.

property reschedule_fn: collections.abc.Callable[[float | numpy.timedelta64], numpy.timedelta64 | None]#

The reschedule_fn is used if and only if the period is 0. If the period is 0 and the reschedule_fn is not defined, then this timed event will not be rescheduled. If the reschedule_fn returns std::nullopt, then this will not be rescheduled.

class Karana.Dynamics.ZeroCrossingCallbackRegistry#
trace_callback_registry: bool#
__getitem__(key: str | SupportsInt) collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], bool], bool]#

Get a function by name

__len__() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

__setitem__(key: str | SupportsInt, func: collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], bool], bool]) None#

Set a function with a string name or integer index

clear() None#

Clear out the entire CallbackRegistry. All callbacks will be removed.

dump(arg0: str) None#

Print out the string from dumpString. See dumpString for more details.

dumpString(arg0: str) str#

Create a string that lists all the functions by name.

erase(name: str) None#
erase(index: SupportsInt) None

Erase the callback at the provided index.

Parameters:

name (int) – The index of the callback to erase.

execute(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], arg1: bool) list[bool]#

Execute all functions in the registry.

executeReverse(arg0: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], arg1: bool) list[bool]#

Execute all functions in the registry in reverse.

pop(name: str) collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], bool], bool]#
pop(index: SupportsInt) collections.abc.Callable[[Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]], bool], bool]

Pop the callback at the provided index.

Parameters:

name (int) – The index of the callback to pop.

size() int#

Get the number of callbacks registered to the CallbackRegistry.

Returns:

Number of callbacks registered in the CallbackRegistry.

Return type:

int

class Karana.Dynamics.ModalNodeDeformationProvider#

Bases: Karana.Dynamics.NodeDeformationProvider

@class ModalNodeDeformationProvider Node deformation provider class for modeling small deformation via modal representation

See Flexible body systems section for more information of deformation provider classes.

deformedRotFrame() Karana.Frame.Frame#

Return the deformed rotational frame

Returns:

the deformed rotational Frame instance

deformedTransFrame() Karana.Frame.Frame#

Return the deformed translational frame

Returns:

the deformed translational Frame instance

getNodalMatrix() Annotated[numpy.typing.NDArray[numpy.float64], [6, n]]#

Return the nodal deformation matrix

Returns:

the nodal matrix

setNodalMatrix(matrix: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, n]]) None#

Set the nodal deformation matrix

Parameter nodal_matrix:

the nodal matrix

undeformedFrame() Karana.Frame.Frame#

Return the undeformed frame

Returns:

the undeformed Frame instance

class Karana.Dynamics.PhysicalModalBody#

Bases: Karana.Dynamics.PhysicalBody

@class PhysicalModalBody Flexible body class supporting assumed modes based small deformation

See the Flexible body systems section for more discussion on flexible bodies.

static addSerialChain(name: str, nbodies: SupportsInt, root: Karana.Dynamics.PhysicalBody = None, htype: Karana.Dynamics.HingeType = ..., params: Karana.Dynamics.PhysicalBodyParams = None) list[Karana.Dynamics.PhysicalBody]#

Add a serial chain of flexible physical bodies to the multibody system

Add a serial chain of flexible bodies to the multibody system to the specified root body with the specified mass properties, hinge type and hinge connection properties. This method is mainly used for procedurally generating large test systems.

Parameter name:

prefix string to use for the new body names

Parameter nbodies:

number of bodies

Parameter root:

the parent body to attach the chain to

Parameter htype:

the hinge type

Parameter params:

the body params for each body

Returns:

the list of new flexible bodies

static addTree(name: str, branch_length: SupportsInt, nbranches: SupportsInt, depth: SupportsInt, root: Karana.Dynamics.PhysicalBody = None, htype: Karana.Dynamics.HingeType = ..., param: Karana.Dynamics.PhysicalBodyParams = None) list[Karana.Dynamics.PhysicalBody]#

Add a sub-tree of flexible physical bodies to the multibody system

Add a sub-tree of flexible bodies to the multibody system to the specified root body with the specified mass properties, hinge type and hinge connection properties. This method is mainly used for procedurally generating large test systems.

Parameter name:

prefix string to use for the new body names

Parameter branch_length:

the number of bodies in a branch

Parameter nbranches:

the number of children branches

Parameter depth:

the number of branching levels to create

Parameter root:

the parent body to attach the chain to

Parameter htype:

the hinge type

Parameter params:

the body params for each body

Returns:

the list of new rigid bodies

static create(name: str, mbs: Karana.Dynamics.Multibody, nmodes: SupportsInt) PhysicalModalBody#

Factory method to create a PhysicalModalBody instance

Parameter name:

the body’s name

Parameter mbs:

the Multibody instance

Parameter nmodes:

the number of deformation modes

Returns:

a new PhysicalModalBody instance

getDampingVector() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Get the damping vector for the body.

Returns:

The new damping vector for the body.

getStiffnessVector() Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#

Get the stiffness vector for the body.

Returns:

The stiffness vector for the body.

setDampingVector(damping: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Set the damping vector for the body.

Parameter damping:

The new damping vector for the body.

setStiffnessVector(stiffness: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]]) None#

Set the stiffness vector for the body.

Parameter stiffness:

The new stiffness vector for the body.

class Karana.Dynamics.PhysicalModalBodyParams(spI: Karana.Math.SpatialInertia = ..., axes: collections.abc.Sequence[Annotated[numpy.typing.ArrayLike, numpy.float64, [3, 1]]] = ..., body_to_joint_transform: Karana.Math.HomTran = ..., inb_to_joint_transform: Karana.Math.HomTran = ..., scene_parts: collections.abc.Sequence[Karana.Scene.ScenePartSpec] = [], nmodes: SupportsInt = 4, stiffness: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]] = ..., damping: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, 1]] = ..., pnode_nodal_matrix: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, n]] = ..., onode_nodal_matrix: Annotated[numpy.typing.ArrayLike, numpy.float64, [m, n]] = ...)#

Bases: Karana.Dynamics.PhysicalBodyParams

property damping: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#
property nmodes: int#
property onode_nodal_matrix: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
property pnode_nodal_matrix: Annotated[numpy.typing.NDArray[numpy.float64], [m, n]]#
property stiffness: Annotated[numpy.typing.NDArray[numpy.float64], [m, 1]]#