Program Listing for File double_pendulum_system.cpp¶
↰ Return to documentation for file (src/bitrl/systems/double_pendulum_system.cpp)
//
// Created by alex on 11/15/25.
//
#include "bitrl/bitrl_config.h"
#ifdef BITRL_CHRONO
#include "bitrl/systems/double_pendulum_system.h"
#include "bitrl/bitrl_consts.h"
#include <chrono/physics/ChBodyEasy.h>
#include <chrono/physics/ChLinkRevolute.h>
#include <chrono/utils/ChUtilsCreators.h>
#include <chrono/core/ChQuaternion.h>
namespace bitrl
{
namespace systems
{
DoublePendulumSystem::DoublePendulumSystem()
:
system_()
{}
void
DoublePendulumSystem::enable_gravity()
{
system_.SetGravitationalAcceleration(chrono::ChVector3d(0, -9.81, 0));
gravity_enabled_ = true;
}
void
DoublePendulumSystem::build_system(const DoublePendulumProperties& props)
{
if (is_initialized_)
{
throw std::runtime_error("DoublePendulumSystem already initialized");
}
// -------------------------
// Create ground (fixed)
// -------------------------
auto ground = chrono_types::make_shared<chrono::ChBody>();
ground -> SetFixed(true);
ground -> SetName("Ground");
system_.AddBody(ground);
// -------------------------
// Create first pendulum body
// -------------------------
auto pend1 = chrono_types::make_shared<chrono::ChBodyEasyCylinder>(chrono::ChAxis::Z, props.r1, props.l1,
props.density, true, true);
// hanging from origin downward
pend1->SetPos(chrono::ChVector3d(0.0, 0.0,props.l1 * 0.5));
{
// align cylinder along Y
chrono::ChQuaterniond q;
chrono::ChVector3d axis(0, 0, 1);
axis.Normalize();
q.SetFromAngleAxis(consts::maths::PI * 0.5, axis);
pend1->SetRot(q);
pend1 -> SetName("Pendulum-1");
}
system_.AddBody(pend1);
// -------------------------
// Create second pendulum body
// -------------------------
auto pend2 = chrono_types::make_shared<chrono::ChBodyEasyCylinder>(chrono::ChAxis::Z,props.r2, props.l2,
props.density, true, true);
{
pend2->SetPos(chrono::ChVector3d(0, -props.l1 - props.l2 * 0.5, 0));
chrono::ChQuaterniond q;
chrono::ChVector3d axis(0, 0, 1);
axis.Normalize();
q.SetFromAngleAxis(consts::maths::PI * 0.5, axis);
pend2->SetRot(q);
pend2 -> SetName("Pendulum-2");
}
system_.AddBody(pend2);
// -------------------------
// Joint: ground → pendulum 1
// -------------------------
auto joint1 = chrono_types::make_shared<chrono::ChLinkRevolute>();
joint1->Initialize(
ground,
pend1,
chrono::ChFrame<>(chrono::ChVector3d(0, 0, 0), chrono::QUNIT) // pivot at origin
);
system_.AddLink(joint1);
// -------------------------
// Joint: pendulum 1 → pendulum 2
// -------------------------
auto joint2 = chrono_types::make_shared<chrono::ChLinkRevolute>();
joint2->Initialize(
pend1,
pend2,
chrono::ChFrame<>(chrono::ChVector3d(0, -props.l1, 0), chrono::QUNIT)
);
system_.AddLink(joint2);
is_initialized_ = true;
}
}
}
#endif