Skip to main content
Ctrl+K
kdFlex 1.0.1 documentation - Home
  • Chatbot

Contents:

  • Chatbot
  • Quick Start
  • Usage Guide
  • Examples
    • Importing a robot arm multibody model from a URDF file
    • 2-link Pendulum
    • Load Mars 2020 rover model from a URDF file
    • n-link Pendulum
    • Spice Frames
    • Import/Export Multibodies
    • Graphics demo
    • Data Logging
    • Slider crank example
    • Double-Wishbone
    • 2-link Pendulum Collision Example
    • Procedural n-link pendulum collision example
    • Flexible Slider-Crank
    • Flexible Double-Wishbone
    • \(n\)-link Pendulum Benchmark Comparison
    • Fully Augmented \(n\)-link Pendulum Benchmark Comparison
    • ATRVjr Driving
    • Cart Pole Reinforcement Learning
    • ATRVjr Reinforcement Learning
    • ATRVjr ROS Integration
  • Program skeletons
  • Recipes
  • API
    • kdFlex Python API
      • Karana
        • Karana.Collision
        • Karana.Core
        • Karana.Dynamics
        • Karana.Frame
        • Karana.KUtils
        • Karana.Math
        • Karana.Models
        • Karana.Scene
        • Karana.WebUI
        • Karana.version
    • kdFlex C++ API
      • Namespace coal
      • Namespace Eigen
      • Namespace Karana
      • Namespace Karana::Collision
      • Namespace Karana::Core
      • Namespace Karana::Dynamics
      • Namespace Karana::Frame
      • Namespace Karana::KUtils
      • Namespace Karana::Math
      • Namespace Karana::Models
      • Namespace Karana::Scene
      • Namespace Karana::WebUI
      • Namespace kf
      • Namespace kf::Frame
      • Namespace LockingBase
      • Namespace pybind11
      • Namespace pybind11::detail
      • Namespace pybind11::typing
      • Namespace spdlog
      • Namespace spdlog::sinks
      • Namespace std
      • Template Struct has_pybind11_caster
      • Struct FrameContact
      • Struct Base::DumpOptions
      • Struct BasicDAGImpl::Node
      • Struct BasicTreeImpl::Node
      • Struct DebugManager
      • Struct EdgeHash
      • Struct LockingBase::DumpOptions
      • Struct Algorithms::ModalAnalysis
      • Struct CompoundBody::ATBIDataCaches
      • Struct CompoundBody::DumpOptions
      • Struct CompoundBody::InvDynVectors
      • Struct CompoundSubhinge::ATBIFilterVectors
      • Struct CompoundSubhinge::ATBIMatrices
      • Struct CoordBase::ATBIFilterVectors
      • Struct CoordBase::ATBIMatrices
      • Struct CoordData::CoordOffset
      • Struct HingeBase::HingeParams
      • Struct HingeNode::DumpOptions
      • Struct HingeOnodeATBIDataCaches
      • Struct HingeOnodeATBIFilterVectors
      • Struct HingeOnodeATBIMatrices
      • Struct HingeOnodeATBISmootherVectors
      • Struct HingeOnodeInvDynVectors
      • Struct HingeOnodeUpsilonMatrices
      • Struct HingePnode::ATBIDataCaches
      • Struct HingePnode::ATBIFilterVectors
      • Struct HingePnode::ATBIMatrices
      • Struct HingePnode::ATBISmootherVectors
      • Struct HingePnode::InvDynVectors
      • Struct HingePnode::UpsilonMatrices
      • Struct LoopConstraintBase::QMats
      • Struct ModalNodeDeformationProvider::DeformationParams
      • Struct Multibody::StickPartsConfig
      • Struct NodeDeformationProvider::DeformationParams
      • Struct Physical1DofSubhinge::PhysicalSubhingeParams
      • Struct PhysicalBody::DumpOptions
      • Struct PhysicalBody::GatherSweepFlags
      • Struct PhysicalBody::InvDynVectors
      • Struct PhysicalBodyParams
      • Struct PhysicalModalBody::ATBIFilterVectors
      • Struct PhysicalModalBody::ATBIMatrices
      • Struct PhysicalModalBody::ATBISmootherVectors
      • Struct PhysicalModalBody::ModalUpsilonMatrices
      • Struct PhysicalModalBody::SZNodeMatrices
      • Struct PhysicalModalBodyParams
      • Struct PhysicalSubhinge::PhysicalSubhingeParams
      • Struct PhysicalSubhinge_T::ATBIFilterVectors
      • Struct PhysicalSubhinge_T::ATBIMatrices
      • Struct ScrewSubhinge::PhysicalSubhingeParams
      • Struct SphericalSubhinge::PhysicalSubhingeParams
      • Struct StatePropagator::Counters
      • Struct StatePropagator::SpFunctions
      • Struct StatePropagator::SpOptions
      • Struct SubTree::DumpTreeOptions
      • Struct Frame::DumpFrameTreeOptions
      • Struct FrameContainer::DumpOptions
      • Struct FrameToFrame::DumpOptions
      • Struct OrientedChainedFrameToFrame::DumpOptions
      • Template Struct extract_matrix_dimensions
      • Template Struct extract_matrix_dimensions< Eigen::Matrix< double, _rows, 1 > >
      • Template Struct extract_matrix_dimensions< Eigen::Matrix< double, _rows, _cols, Eigen::RowMajor > >
      • Template Struct extract_rows
      • Template Struct extract_rows< Eigen::Matrix< double, rows, 1 > >
      • Template Struct is_eigen_type
      • Template Struct is_eigen_type< Eigen::Matrix< double, Rows, 1 > >
      • Template Struct is_eigen_type< Eigen::Matrix< double, Rows, Cols, Eigen::RowMajor > >
      • Template Struct is_eigen_vector
      • Template Struct is_eigen_vector< Eigen::Matrix< double, Rows, 1 > >
      • Struct ArkExplicitIntegrator::IntegratorOptions
      • Struct CVodeIntegrator::IntegratorOptions
      • Struct DynamicFunctor
      • Struct DynamicFunctorNoJac
      • Template Struct Functor
      • Struct IdaIntegrator::IntegratorOptions
      • Struct Integrator::IntegratorOptions
      • Template Struct NumDiffBaseFunctor
      • Struct NumDiffFunctor
      • Struct StateSpace::SS
      • Struct ClientSceneData
      • Struct CollisionInfo
      • Struct Contact
      • Struct DistanceInfo
      • Struct ImportResult
      • Struct OrthographicProjection
      • Struct PerspectiveProjection
      • Struct PhongMaterialInfo
      • Struct PhysicalMaterialInfo
      • Struct RGBABuffer
      • Struct ScenePartSpec
      • Struct TextParameters
      • Struct LocalClientOptions
      • Template Struct handle_type_name< typing::Sequence< T > >
      • Template Struct PyTypeWrapper
      • Template Class duration_caster
      • Class ContactForceBase
      • Class ContactForceManager
      • Class FrameCollider
      • Class HuntCrossley
      • Class HuntCrossley::HuntCrossleyParams
      • Class Base
      • Class BaseContainer
      • Template Class BasicDAGImpl
      • Template Class BasicTreeImpl
      • Template Class CallbackRegistry
      • Template Class DAG
      • Template Class DataCache
      • Class IdGenerator
      • Class IdHashStruct
      • Class JsonLogger
      • Class LockingBase
      • Class MsgLogger
      • Class my_formatter_flag
      • Template Class RegistryList
      • Class SideEffect
      • Class StderrLog
      • Class StdoutLog
      • Template Class Tree
      • Template Class UsageTrackingMap
      • Class Algorithms
      • Class BilateralConstraintBase
      • Class BodyBase
      • Class CECompoundBody
      • Class CECompoundSubhinge
      • Class CompoundBody
      • Class CompoundHinge
      • Class CompoundSubhinge
      • Class ConstraintKinematicsSolver
      • Class ConstraintNode
      • Class CoordBase
      • Template Class CoordBase_T
      • Class CoordData
      • Class CoordinateConstraint
      • Class FramePairHinge
      • Class FrameToFrameJacobianGenerator
      • Class GearedCompoundBody
      • Class HingeBase
      • Class HingeNode
      • Class HingeOnode
      • Class HingePnode
      • Class Linear3Subhinge
      • Class LinearSubhinge
      • Class LockedSubhinge
      • Class LoopConstraintBase
      • Class LoopConstraintConVel
      • Class LoopConstraintHinge
      • Class LoopsCompoundBody
      • Class ModalNodeDeformationProvider
      • Class Multibody
      • Class MultiJacobianGenerator
      • Class Node
      • Class NodeDeformationProvider
      • Class Physical1DofSubhinge
      • Class PhysicalBody
      • Class PhysicalHinge
      • Class PhysicalModalBody
      • Class PhysicalSubhinge
      • Template Class PhysicalSubhinge_T
      • Class PinSubhinge
      • Class Scheduler
      • Class ScrewSubhinge
      • Class SphericalQuatSubhinge
      • Class SphericalSubhinge
      • Class StatePropagator
      • Class SubGraph
      • Class SubhingeBase
      • Class SubTree
      • Class TimedEvent
      • Class TimeKeeper
      • Class ChainedFrameToFrame
      • Class EdgeFrameToFrame
      • Class Frame
      • Class FrameContainer
      • Class FrameToFrame
      • Class OrientedChainedFrameToFrame
      • Class PrescribedFrameToFrame
      • Class SpiceFrame
      • Class SpiceFrameToFrame
      • Class H5Writer
      • Class PacketTableConfig
      • Class AABB
      • Class AkimaSplineInterpolator
      • Class ArkExplicitIntegrator
      • Class BaseInterpolator
      • Class ConstantInterpolator
      • Class CubicHermiteInterpolator
      • Class CVodeIntegrator
      • Class EulerIntegrator
      • Class HomTran
      • Class IdaIntegrator
      • Class Integrator
      • Class Jacobian
      • Class LinearInterpolator
      • Class NearestNeighborInterpolator
      • Class NonlinearSolver
      • Class NoopIntegrator
      • Class RK4Integrator
      • Class RotationMatrix
      • Class RotationVector
      • Class SimTran
      • Class SpatialInertia
      • Class SpatialVector
      • Class StateSpace
      • Class UnitQuaternion
      • Class BaseKModel
      • Class ComputedTorque
      • Class DataLogger
      • Class DataLoggerParams
      • Class GraphicalSceneMovie
      • Class GraphicalSceneMovieParams
      • Template Class KModel
      • Class KModelContinuousStates
      • Class KModelDiscreteStates
      • Class KModelParams
      • Class KModelScratch
      • Class NoContinuousStates
      • Class NoDiscreteStates
      • Class NoParams
      • Class NoScratch
      • Class PenaltyContact
      • Class PID
      • Class PIDParams
      • Class PinJointLimits
      • Class PinJointLimitsParams
      • Class PointMassGravity
      • Class PointMassGravityParams
      • Class ProjectConstraintError
      • Class ProjectConstraintErrorParams
      • Class SpringDamper
      • Class SpringDamperParams
      • Class SpringDamperScratch
      • Class SubhingeForceLimits
      • Class SubhingeForceLimitsParams
      • Class SubhingeSpringDamper
      • Class SubhingeSpringDamperParams
      • Class SyncRealTime
      • Class TimeDisplay
      • Class TimeDisplayParams
      • Class UniformGravity
      • Class UniformGravityParams
      • Class UpdateProxyScene
      • Class AbstractImporter
      • Class AbstractStaticGeometry
      • Class AssimpImporter
      • Class BoxGeometry
      • Class CapsuleGeometry
      • Class ClientRegistry
      • Class CoalGeometryCache
      • Class CoalScene
      • Class CoalSceneNode
      • Class CoalScenePart
      • Class CollisionScene
      • Class CollisionSceneNode
      • Class CollisionScenePart
      • Class Color
      • Class ConeGeometry
      • Class CylinderGeometry
      • Class ExtMime
      • Class GraphicalScene
      • Class GraphicalSceneCamera
      • Class GraphicalSceneNode
      • Class GraphicalScenePart
      • Class GrayscaleTexture
      • Class ImplDatabase
      • Class PhongMaterial
      • Class PhysicalMaterial
      • Class ProxyScene
      • Class ProxySceneNode
      • Class ProxyScenePart
      • Class RoundFrustumGeometry
      • Class Scene
      • Class SceneNode
      • Class ScenePart
      • Class SphereGeometry
      • Class StaticMeshGeometry
      • Class Texture
      • Class WebResourceManager
      • Class WebScene
      • Class WebSceneCamera
      • Class WebSceneNode
      • Class WebScenePart
      • Class Connection
      • Class Server
      • Template Class Sequence
      • Template Class type_caster< std::chrono::duration< Rep, Period > >
      • Template Class type_caster< std::chrono::time_point< Clock, Duration > >
      • Enum IntegratorType
      • Enum SolverType
      • Enum Alignment
      • Function cast
      • Function Karana::Core::_dummy
      • Function Karana::Core::_ensureRegisteredPy
      • Function Karana::Core::_numTraceCheck
      • Function Karana::Core::_numTraceInt(std::string_view)
      • Function Karana::Core::_numTraceInt(msg_f)
      • Template Function Karana::Core::_numTraceInt(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Core::allCurrent
      • Function Karana::Core::allDestroyed
      • Function Karana::Core::allFinalized
      • Template Function Karana::Core::CallbackRegistryPybind11
      • Template Function Karana::Core::const_pointer_cast
      • Template Function Karana::Core::createSharedPtrDiscard
      • Function Karana::Core::debug(std::string_view)
      • Function Karana::Core::debug(msg_f)
      • Template Function Karana::Core::debug(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Core::debugJson(const nlohmann::ordered_json&, OrderedJsonToString)
      • Function Karana::Core::debugJson(const nlohmann::json&, JsonToString)
      • Function Karana::Core::defaultJsonToString
      • Function Karana::Core::defaultOrderedJsonToString
      • Function Karana::Core::deprecated
      • Template Function Karana::Core::deprecatedWrapper
      • Template Function Karana::Core::discard
      • Template Function Karana::Core::dynamic_pointer_cast
      • Function Karana::Core::error(std::string_view)
      • Function Karana::Core::error(msg_f)
      • Template Function Karana::Core::error(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Core::info(std::string_view)
      • Function Karana::Core::info(msg_f)
      • Template Function Karana::Core::info(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Core::sharedPtrDiscard
      • Function Karana::Core::sharedPtrDiscardVec
      • Template Function Karana::Core::static_pointer_cast
      • Function Karana::Core::trace(std::string_view)
      • Function Karana::Core::trace(msg_f)
      • Template Function Karana::Core::trace(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Core::traceJson(const nlohmann::ordered_json&, OrderedJsonToString)
      • Function Karana::Core::traceJson(const nlohmann::json&, JsonToString)
      • Function Karana::Core::warn(std::string_view)
      • Function Karana::Core::warn(msg_f)
      • Template Function Karana::Core::warn(spdlog::format_string_t<Args…>, Args&&…)
      • Function Karana::Math::buildNaNWithPayload
      • Template Function Karana::Math::dump
      • Template Function Karana::Math::dumpString
      • Template Function Karana::Math::getIndepColIndices
      • Template Function Karana::Math::getIndepRowColIndices
      • Template Function Karana::Math::getRank
      • Template Function Karana::Math::getSingularValues
      • Template Function Karana::Math::isInitialized(const Eigen::MatrixBase<Derived>&)
      • Template Function Karana::Math::isInitialized(const Eigen::ArrayBase<Derived>&)
      • Function Karana::Math::isNaNWithPayload
      • Function Karana::Math::isUninitialized
      • Function Karana::Math::isUninitializedNaN
      • Function Karana::Math::ktimeToSeconds
      • Function Karana::Math::secondsToKtime
      • Function Karana::Math::strToIntegratorType
      • Function Karana::Math::tilde
      • Function Karana::Math::uninitialize(Ktime&)
      • Template Function Karana::Math::uninitialize(Eigen::DenseBase<Derived>&)
      • Template Function Karana::Models::addToDSMethod
      • Template Function Karana::Models::KModelPybind11
      • Function Karana::Scene::defaultGeometry
      • Function Karana::Scene::defaultMaterial
      • Function load
      • Function localtime_thread_safe
      • Function operator<<
      • Function PYBIND11_DECLARE_HOLDER_TYPE
      • Function PYBIND11_MODULE
      • Function PYBIND11_TYPE_CASTER
      • Variable has_pybind11_caster_v
      • Variable Karana::KUtils::extract_cols_v
      • Variable Karana::KUtils::extract_rows_v
      • Variable Karana::KUtils::extract_vector_rows_v
      • Variable Karana::KUtils::is_eigen_type_v
      • Variable Karana::KUtils::is_eigen_vector_v
      • Variable Karana::Math::uninitializedNaN
      • Variable Karana::Math::uninitializedPayload
      • Variable Karana::Scene::LAYER_ALL
      • Variable Karana::Scene::LAYER_COLLISION
      • Variable Karana::Scene::LAYER_CUSTOM0
      • Variable Karana::Scene::LAYER_CUSTOM1
      • Variable Karana::Scene::LAYER_CUSTOM10
      • Variable Karana::Scene::LAYER_CUSTOM11
      • Variable Karana::Scene::LAYER_CUSTOM12
      • Variable Karana::Scene::LAYER_CUSTOM13
      • Variable Karana::Scene::LAYER_CUSTOM14
      • Variable Karana::Scene::LAYER_CUSTOM15
      • Variable Karana::Scene::LAYER_CUSTOM16
      • Variable Karana::Scene::LAYER_CUSTOM17
      • Variable Karana::Scene::LAYER_CUSTOM18
      • Variable Karana::Scene::LAYER_CUSTOM19
      • Variable Karana::Scene::LAYER_CUSTOM2
      • Variable Karana::Scene::LAYER_CUSTOM20
      • Variable Karana::Scene::LAYER_CUSTOM21
      • Variable Karana::Scene::LAYER_CUSTOM22
      • Variable Karana::Scene::LAYER_CUSTOM23
      • Variable Karana::Scene::LAYER_CUSTOM3
      • Variable Karana::Scene::LAYER_CUSTOM4
      • Variable Karana::Scene::LAYER_CUSTOM5
      • Variable Karana::Scene::LAYER_CUSTOM6
      • Variable Karana::Scene::LAYER_CUSTOM7
      • Variable Karana::Scene::LAYER_CUSTOM8
      • Variable Karana::Scene::LAYER_CUSTOM9
      • Variable Karana::Scene::LAYER_GRAPHICS
      • Variable Karana::Scene::LAYER_NONE
      • Variable Karana::Scene::LAYER_ORNAMENTAL
      • Variable Karana::Scene::LAYER_PHYSICAL
      • Variable Karana::Scene::LAYER_PHYSICAL_GRAPHICS
      • Variable Karana::Scene::LAYER_RESERVED0
      • Variable Karana::Scene::LAYER_RESERVED1
      • Variable Karana::Scene::LAYER_RESERVED2
      • Variable Karana::Scene::LAYER_RESERVED3
      • Variable Karana::Scene::LAYER_RESERVED4
      • Variable Karana::Scene::LAYER_RESERVED5
      • Variable Karana::Scene::LAYER_RESERVED6
      • Variable Karana::Scene::LAYER_RESERVED7
      • Variable Karana::Scene::LAYER_STICK_FIGURE
      • Define KARANA_MODIFIED
      • Define KARANA_VERSION_MAJOR
      • Define KARANA_VERSION_MINOR
      • Define KARANA_VERSION_PATCH
      • Define KARANA_VERSION_STRING
      • Define MATH_EPSILON
      • Define numTrace
      • Typedef Karana::Core::Allocator
      • Typedef Karana::Core::id_t
      • Typedef Karana::Core::JsonToString
      • Typedef Karana::Core::ks_ptr
      • Typedef Karana::Core::msg_f
      • Typedef Karana::Core::OrderedJsonToString
      • Typedef Karana::Dynamics::f
      • Typedef Karana::Math::Array
      • Typedef Karana::Math::ArrayVec
      • Typedef Karana::Math::ConstMatSlice
      • Typedef Karana::Math::ConstVec3Slice
      • Typedef Karana::Math::ConstVecSlice
      • Typedef Karana::Math::cost_fn
      • Typedef Karana::Math::DerivativeFunction
      • Typedef Karana::Math::DynamicFunctorNumJac
      • Typedef Karana::Math::fn
      • Typedef Karana::Math::functor_type
      • Typedef Karana::Math::jac_fn
      • Typedef Karana::Math::Ktime
      • Typedef Karana::Math::lin_fn
      • Typedef Karana::Math::Mat
      • Typedef Karana::Math::Mat33
      • Typedef Karana::Math::Mat44
      • Typedef Karana::Math::Mat66
      • Typedef Karana::Math::Mat6n
      • Typedef Karana::Math::MatSlice
      • Typedef Karana::Math::num_diff_functor_type
      • Typedef Karana::Math::ResidualsFunction
      • Typedef Karana::Math::solver_type
      • Typedef Karana::Math::Vec
      • Typedef Karana::Math::Vec3
      • Typedef Karana::Math::Vec3Slice
      • Typedef Karana::Math::Vec4
      • Typedef Karana::Math::Vec6
      • Typedef Karana::Math::VecSlice
      • Typedef Karana::Scene::layer_t
      • Typedef Karana::Scene::TextureCache
      • Typedef Karana::Scene::TextureData
      • Typedef Karana::Scene::VarMaterial
      • Typedef Karana::Scene::VarProjection
      • Typedef Karana::Scene::VarStaticGeometry
      • Typedef type
  • .ipynb

Fully Augmented n-link Pendulum Benchmark Comparison

Contents

  • Define a Method to Create the Multibody
  • Run simulations for each model
  • Benchmark Simulation Runtimes
  • Summary
  • Further Readings

Fully Augmented \(n\)-link Pendulum Benchmark Comparison#

In this notebook we use the \(n\)-link pendulum example to compare the performance of kdFlex’s default SOA-base \(O(N)\) dynamics algorithm with the conventional \(O(N^{3}\)) methods for a fully augmented (FA) model. This notebook is similar to the \(n\)-link pendulum but is designed for benchmarking kdFlex’s simulation performance.

Requirements:

  • n-link Pendulum

In this tutorial we will:

  • Define a method to create the multibody

  • Run simulations for each model

  • Benchmark simulation runtimes

For a more in-depth descriptions of kdflex concepts see usage.

import os
import gc
import numpy as np
import time
from typing import cast
import pandas as pd
import plotly.express as px
from Karana.Core import discard, allFinalized
from Karana.Frame import FrameContainer
from Karana.Math import IntegratorType
from Karana.Dynamics import (
    Multibody,
    PhysicalBody,
    PhysicalBody,
    HingeType,
    StatePropagator,
    TimedEvent,
    SpSolverType,
    PhysicalBodyParams,
)
from Karana.Math import SpatialInertia, HomTran
from Karana.Models import UniformGravity

Define a Method to Create the Multibody#

Define a method that procedurally creates a n-link multibody for use when we run simulations with increasing number of links. This is the same as in the n-link Pendulum

See Multibody or Frames for more information relating to this step.

def createMbody(fc: FrameContainer, n_links: int):
    """Create the multibody.

    Parameters
    ----------
    n_links : int
        The number of pendulum links to use.
    """
    mb = Multibody("mb", fc)

    # Here, we use the addSerialChain method to add multiple instances of the same body
    # connected in a chain. We add n instances of the pendulum link with the following parameters:
    params = PhysicalBodyParams(
        SpatialInertia(2.0, np.zeros(3), np.diag([3, 2, 1])),
        [np.array([0.0, 1.0, 0.0])],
        HomTran(np.array([0, 0, 0.5])),
        HomTran(np.array([0, 0, -0.5])),
    )
    PhysicalBody.addSerialChain(
        "link", n_links, cast(PhysicalBody, mb.virtualRoot()), htype=HingeType.PIN, params=params
    )

    # finalize and verify the multibody
    mb.ensureCurrent()
    mb.resetData()
    assert allFinalized()

    return mb

Because we run multiple simulations, we write a method ahead of time to cleanup everything whenever the simulation ends. This requires us to delete local variables and discard our containers and scene.

def cleanup():
    """Cleanup the simulation."""
    global integrator, bd1
    del integrator, bd1

    discard(sp)
    gc.collect()

    discard(mb)
    discard(fc)

Run simulations for each model#

Below is the run loop for each simulation. It loops through each sim with an increasing number of links and collects the time it takes to complete.

# Number of links we will run at

n_links_list = [3, 5, 8, 10, 13, 16, 20, 25]

sim_types = ["MinCoord", "fullyAugmented"]

for sim in sim_types:

    runtimes = []
    deriv_calls = []

    for n_links in n_links_list:

        # initialization
        fc = FrameContainer("root")
        mb = createMbody(fc, n_links)

        # Modify the initial multibody state. Here we will set the first pendulum to 0.5 radians.
        bd1 = mb.getBody("link_0")
        bd1.parentHinge().subhinge(0).setQ([0.5])
        bd1.parentHinge().subhinge(0).setU([0.0])

        # Switching to fully augmented model
        if sim == "fullyAugmented":
            mb.toFullyAugmentedModel()

        # Set up state propagator and select integrator type: rk4 or cvode
        stype = (
            SpSolverType.TREE_DYNAMICS
            if sim == "MinCoord"
            else SpSolverType.TREE_AUGMENTED_DYNAMICS
        )
        sp = StatePropagator(mb, IntegratorType.RK4, None, None, stype)
        integrator = sp.getIntegrator()

        # add a gravitational model to the state propagator
        ug = UniformGravity("grav_model", sp, mb)
        ug.params.g = np.array([0, 0, -9.81])
        del ug

        # Initialize integrator state
        t_init = np.timedelta64(0, "ns")
        x_init = sp.assembleState()
        sp.setTime(t_init)
        sp.setState(x_init)

        # register the timed event
        h = np.timedelta64(int(1e7), "ns")
        t = TimedEvent("hop_size", h, lambda _: None, False)
        t.period = h
        sp.registerTimedEvent(t)
        del t

        # Keeping track of runtime when advancing simulation
        start_time = time.time()
        sp.advanceTo(2.0)
        end_time = time.time()
        run_time = end_time - start_time
        runtimes.append(run_time)
        derivs = sp.counters().derivs
        deriv_calls.append(derivs)

        # General output
        print(f"Number of links: {n_links}")
        print(f"Time to run: {run_time}, derivs={derivs}, simtype={sim}")

        # Cleanup
        cleanup()

    if sim == "fullyAugmented":
        runtimesFA = runtimes
    else:
        runtimesMinCoord = runtimes
Number of links: 3
Time to run: 0.5896553993225098, derivs=800, simtype=MinCoord
Number of links: 5
Time to run: 0.9507579803466797, derivs=800, simtype=MinCoord
Number of links: 8
Time to run: 1.4788484573364258, derivs=800, simtype=MinCoord
Number of links: 10
Time to run: 1.8719995021820068, derivs=800, simtype=MinCoord
Number of links: 13
Time to run: 2.416515588760376, derivs=800, simtype=MinCoord
Number of links: 16
Time to run: 3.036313533782959, derivs=800, simtype=MinCoord
Number of links: 20
Time to run: 3.672475814819336, derivs=800, simtype=MinCoord
Number of links: 25
Time to run: 4.5920729637146, derivs=800, simtype=MinCoord
Number of links: 3
Time to run: 3.931762456893921, derivs=800, simtype=fullyAugmented
Number of links: 5
Time to run: 7.254469156265259, derivs=800, simtype=fullyAugmented
Number of links: 8
Time to run: 14.218537330627441, derivs=800, simtype=fullyAugmented
Number of links: 10
Time to run: 20.672817707061768, derivs=800, simtype=fullyAugmented
Number of links: 13
Time to run: 32.69570302963257, derivs=800, simtype=fullyAugmented
Number of links: 16
Time to run: 48.51436686515808, derivs=800, simtype=fullyAugmented
Number of links: 20
Time to run: 77.32109498977661, derivs=800, simtype=fullyAugmented
Number of links: 25
Time to run: 127.00069570541382, derivs=800, simtype=fullyAugmented

Benchmark Simulation Runtimes#

Below the benchmark results are plotted for normalized simulation run times with respect to the number of links. This is the time the simulation takes to run divided by the number of bodies. The Fully Augmented absolute coordinate model is compared to kdFlex’s minimal coordinate tree dynamics simulation.

runtimes = runtimesMinCoord

normalized_times = np.array(runtimes) / np.array(n_links_list)
normalized_times_FA = np.array(runtimesFA) / np.array(n_links_list)

run_data_MinCoord_df = pd.DataFrame(
    {
        "NLinks": n_links_list,
        "RunTimes": runtimes,
        "NormalizedTimes": normalized_times,
    }
)
run_data_MinCoord_df["sim_type"] = "MinCoord Dynamics"

run_data_FA_df = pd.DataFrame(
    {
        "NLinks": n_links_list,
        "RunTimes": runtimesFA,
        "NormalizedTimes": normalized_times_FA,
    }
)
run_data_FA_df["sim_type"] = "Fully Augmented"

run_data = pd.concat([run_data_MinCoord_df, run_data_FA_df], ignore_index=True)

# Create scatter plot
fig = px.scatter(
    run_data,
    x="NLinks",
    y="NormalizedTimes",
    color="sim_type",
    title="Computational Time vs Number of Bodies",
    labels={"NLinks": "Number of Bodies", "NormalizedTimes": "Time per Body"},
    log_x=True,
)

# Show plot if not running in a test environment
if not os.getenv("DTEST_RUNNING", False):
    fig.show()

Summary#

By running simulations using Minimal Coordinate Dynamics and Fully Augmented systems, you can see how the performance compares and scales.

Further Readings#

Benchmark the n-link pendulum
Simulate collisions with a n-link pendulum

previous

\(n\)-link Pendulum Benchmark Comparison

next

ATRVjr Driving

Contents
  • Define a Method to Create the Multibody
  • Run simulations for each model
  • Benchmark Simulation Runtimes
  • Summary
  • Further Readings

By Karana Dynamics Inc.

© Copyright 2025, Karana Dynamics Inc. Generated on 18 December 2025 18:38 UTC.