#include "UnitTests.hpp"
#include <cstring>
TEST(RevoluteJointConf, DefaultConstruction)
{
const auto jd = RevoluteJointConf{};
EXPECT_EQ(jd.collideConnected, false);
EXPECT_EQ(jd.localAnchorA,
Length2());
EXPECT_EQ(jd.localAnchorB,
Length2());
EXPECT_EQ(jd.impulse,
Vec3());
EXPECT_EQ(jd.referenceAngle, 0_deg);
EXPECT_EQ(jd.enableLimit, false);
EXPECT_EQ(jd.lowerAngle, 0_deg);
EXPECT_EQ(jd.upperAngle, 0_deg);
EXPECT_EQ(jd.enableMotor, false);
EXPECT_EQ(jd.motorSpeed, 0_rpm);
EXPECT_EQ(jd.maxMotorTorque,
Torque());
EXPECT_EQ(jd.mass,
Mat33());
}
TEST(RevoluteJoint, Construction)
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.collideConnected = true;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
jd.enableLimit = true;
jd.enableMotor = true;
jd.maxMotorTorque = 1_Nm;
jd.lowerAngle = 33_deg;
jd.upperAngle = 40_deg;
jd.referenceAngle = 45_deg;
auto joint = Joint{jd};
EXPECT_EQ(
GetType(joint), GetTypeID<RevoluteJointConf>());
}
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
auto joint = Joint{jd};
}
TEST(RevoluteJoint, EnableMotorInWorld)
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
const auto newValue = 5_Nm;
const auto shape =
CreateShape(world, DiskShapeConf{}.UseRadius(1_m).UseDensity(1_kgpm2));
auto stepConf = StepConf{};
stepConf.doWarmStart = false;
stepConf.doWarmStart = true;
stepConf.doWarmStart = true;
}
TEST(RevoluteJoint, MotorSpeed)
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
auto joint = Joint{jd};
}
{
auto world = World{};
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
jd.enableLimit = false;
auto stepConf = StepConf{};
const auto shape =
CreateShape(world, DiskShapeConf{}.UseRadius(1_m).UseDensity(1_kgpm2));
}
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
const auto upperValue = +5_deg;
const auto lowerValue = -8_deg;
auto joint = Joint{jd};
}
TEST(RevoluteJoint, MaxMotorTorque)
{
World world;
auto jd = RevoluteJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
const auto newValue = 5_Nm;
const auto shape =
CreateShape(world, DiskShapeConf{}.UseRadius(1_m).UseDensity(1_kgpm2));
auto stepConf = StepConf{};
stepConf.doWarmStart = false;
}
TEST(RevoluteJoint, MovesDynamicCircles)
{
World world;
const auto p1 =
Length2{-1_m, 0_m};
const auto p2 =
Length2{+1_m, 0_m};
.UseLocation(p1)
.UseLocation(p2)
const auto circle =
CreateShape(world, DiskShapeConf{}.UseRadius(0.2_m));
auto jd = RevoluteJointConf{};
jd.bodyA = b1;
jd.bodyB = b2;
auto step = StepConf{};
step.deltaTime = 1_s;
}
TEST(RevoluteJoint, LimitEnabledDynamicCircles)
{
World world;
const auto p1 =
Length2{-1_m, 0_m};
const auto p2 =
Length2{+1_m, 0_m};
.UseLocation(p1)
.UseLocation(p2)
const auto circle =
CreateShape(world, DiskShapeConf{}.UseRadius(0.2_m).UseDensity(1_kgpm2));
auto jd = RevoluteJointConf{b1, b2,
Length2{}};
jd.enableLimit = true;
ASSERT_EQ(jd.lowerAngle, 0_deg);
ASSERT_EQ(jd.upperAngle, 0_deg);
ASSERT_EQ(
GetAngle(world, joint), 0_deg);
auto step = StepConf{};
step.deltaTime = 1_s;
EXPECT_EQ(
GetAngle(world, joint), 0_deg);
}
TEST(RevoluteJoint, DynamicJoinedToStaticStaysPut)
{
auto world = World{};
const auto p2 =
Length2{0_m, -2_m};
const auto shape1 =
CreateShape(world, PolygonShapeConf{}.SetAsBox(1_m, 1_m));
const auto shape2 =
CreateShape(world, PolygonShapeConf{}.SetAsBox(0.5_m, 0.5_m).UseDensity(1_kgpm2));
for (auto i = 0; i < 1000; ++i) {
}
for (auto i = 0; i < 10; ++i) {
}
}
TEST(RevoluteJointConf, GetRevoluteJointConfThrows)
{
}
TEST(RevoluteJointConf, GetRevoluteJointConfFromJoint)
{
conf.UseCollideConnected(true);
conf.referenceAngle = 20_deg;
conf.enableLimit = true;
conf.lowerAngle = 10_deg;
conf.upperAngle = 30_deg;
conf.enableMotor = true;
conf.motorSpeed = 3_rpm;
auto result = RevoluteJointConf{};
EXPECT_EQ(result.bodyA, conf.bodyA);
EXPECT_EQ(result.bodyB, conf.bodyB);
EXPECT_EQ(result.collideConnected, conf.collideConnected);
EXPECT_EQ(result.localAnchorA, conf.localAnchorA);
EXPECT_EQ(result.localAnchorB, conf.localAnchorB);
EXPECT_EQ(result.impulse, conf.impulse);
EXPECT_EQ(result.angularMotorImpulse, conf.angularMotorImpulse);
EXPECT_EQ(result.referenceAngle, conf.referenceAngle);
EXPECT_EQ(result.enableLimit, conf.enableLimit);
EXPECT_EQ(result.lowerAngle, conf.lowerAngle);
EXPECT_EQ(result.upperAngle, conf.upperAngle);
EXPECT_EQ(result.enableMotor, conf.enableMotor);
EXPECT_EQ(result.motorSpeed, conf.motorSpeed);
}
{
auto world = World{};
auto conf = RevoluteJointConf{bodyA, bodyB};
EXPECT_NO_THROW(angle =
GetAngle(world, conf));
EXPECT_EQ(angle, 0_deg);
}
{
auto world = World{};
auto conf = RevoluteJointConf{bodyA, bodyB};
EXPECT_EQ(angularVelocity, 0_rpm);
}
{
auto copy = RevoluteJointConf{};
std::memcpy(©, &jd, sizeof(RevoluteJointConf));
EXPECT_TRUE(std::memcmp(&jd, ©, sizeof(RevoluteJointConf)) == 0);
}
{
auto conf = RevoluteJointConf{};
EXPECT_EQ(conf.angularMass, rotInertia);
}
TEST(RevoluteJointConf, GetLocalXAxisAThrowsInvalidArgument)
{
EXPECT_THROW(
GetLocalXAxisA(Joint{RevoluteJointConf{}}), std::invalid_argument);
}
TEST(RevoluteJointConf, GetLocalYAxisAThrowsInvalidArgument)
{
EXPECT_THROW(
GetLocalYAxisA(Joint{RevoluteJointConf{}}), std::invalid_argument);
}
TEST(RevoluteJointConf, GetMaxMotorForceThrowsInvalidArgument)
{
EXPECT_THROW(
GetMaxMotorForce(Joint{RevoluteJointConf{}}), std::invalid_argument);
}
TEST(RevoluteJointConf, GetLinearLowerLimitThrowsInvalidArgument)
{
}
TEST(RevoluteJointConf, GetLinearUpperLimitThrowsInvalidArgument)
{
}
TEST(RevoluteJointConf, GetLinearMotorImpulseThrowsInvalidArgument)
{
}
TEST(RevoluteJointConf, EqualsOperator)
{
EXPECT_TRUE(RevoluteJointConf() == RevoluteJointConf());
{
auto conf = RevoluteJointConf{};
conf.localAnchorA =
Length2{1.2_m, -3_m};
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(RevoluteJointConf() == conf);
}
{
auto conf = RevoluteJointConf{};
conf.localAnchorB =
Length2{1.2_m, -3_m};
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(RevoluteJointConf() == conf);
}
{
auto conf = RevoluteJointConf{};
conf.referenceAngle = 12_deg;
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(RevoluteJointConf() == conf);
}
}
TEST(RevoluteJointConf, NotEqualsOperator)
{
EXPECT_FALSE(RevoluteJointConf() != RevoluteJointConf());
{
auto conf = RevoluteJointConf{};
conf.enableMotor = !RevoluteJointConf{}.enableMotor;
EXPECT_FALSE(conf != conf);
EXPECT_TRUE(RevoluteJointConf() != conf);
}
}
{
EXPECT_STREQ(
GetName(GetTypeID<RevoluteJointConf>()),
"d2::RevoluteJointConf");
}
{
auto conf = RevoluteJointConf{};
std::vector<BodyConstraint> bodies;
EXPECT_NO_THROW(
InitVelocity(conf, bodies, StepConf{}, ConstraintSolverConf{}));
EXPECT_THROW(
InitVelocity(conf, bodies, StepConf{}, ConstraintSolverConf{}), std::out_of_range);
const auto posA = Position{
Length2{-5_m, 0_m}, 0_deg};
EXPECT_NO_THROW(
InitVelocity(conf, bodies, StepConf{}, ConstraintSolverConf{}));
}
{
auto conf = RevoluteJointConf{};
std::vector<BodyConstraint> bodies;
auto result = false;
EXPECT_NO_THROW(result =
SolveVelocity(conf, bodies, StepConf{}));
EXPECT_TRUE(result);
EXPECT_THROW(
SolveVelocity(conf, bodies, StepConf{}), std::out_of_range);
const auto posA = Position{
Length2{-5_m, 0_m}, 0_deg};
EXPECT_NO_THROW(result =
SolveVelocity(conf, bodies, StepConf{}));
}
{
auto conf = RevoluteJointConf{};
std::vector<BodyConstraint> bodies;
auto result = false;
EXPECT_NO_THROW(result =
SolvePosition(conf, bodies, ConstraintSolverConf{}));
EXPECT_TRUE(result);
EXPECT_THROW(
SolvePosition(conf, bodies, ConstraintSolverConf{}), std::out_of_range);
const auto posA = Position{
Length2{-5_m, 0_m}, 0_deg};
EXPECT_NO_THROW(result =
SolvePosition(conf, bodies, ConstraintSolverConf{}));
}
Declarations of BodyConf class & free functions associated with it.
Definition of the BodyConstraint class and closely related code.
Definition of the ConstraintSolverConf class and closely related code.
Definition of the DiskShapeConf class and closely related code.
Definition of the Joint class and closely related code.
Definition of the PolygonShapeConf class and closely related code.
Definition of the RevoluteJointConf class and closely related code.
Declarations of the StepConf class, and free functions associated with it.
Declarations of free functions of World for bodies identified by BodyID.
Declarations of free functions of World for joints identified by JointID.
Declarations of free functions of World for unidentified information.
Declarations of free functions of World for shapes identified by ShapeID.
Definitions of the World class and closely related code.
detail::torque Torque
Torque quantity.
Definition: Units.hpp:341
detail::angular_momentum AngularMomentum
Angular momentum quantity.
Definition: Units.hpp:390
detail::moment_of_inertia RotInertia
Rotational inertia quantity.
Definition: Units.hpp:360
detail::angular_velocity AngularVelocity
Angular velocity quantity.
Definition: Units.hpp:311
detail::inverse_moment_of_inertia InvRotInertia
Inverse rotational inertia quantity.
Definition: Units.hpp:368
detail::plane_angle Angle
Angle quantity.
Definition: Units.hpp:301
constexpr auto MeterPerSquareSecond
Meter per square second unit of linear acceleration.
Definition: Units.hpp:431
constexpr auto RadianPerSquareSecond
Radian per square second unit of angular acceleration.
Definition: Units.hpp:478
constexpr auto RadianPerSecond
Radian per second unit of angular velocity.
Definition: Units.hpp:468
constexpr auto SquareRadian
Square radian unit type.
Definition: Units.hpp:463
constexpr auto Meter
Meter unit of Length.
Definition: Units.hpp:423
constexpr auto NewtonMeter
Newton meter unit of torque.
Definition: Units.hpp:492
constexpr auto NewtonMeterSecond
Newton meter second unit of angular momentum.
Definition: Units.hpp:502
bool SolveVelocity(DistanceJointConf &object, const Span< BodyConstraint > &bodies, const StepConf &step)
Solves velocity constraint.
Definition: DistanceJointConf.cpp:169
bool IsAwake(const Body &body) noexcept
Gets the awake/asleep state of this body.
Definition: Body.hpp:884
Velocity GetVelocity(const Body &body) noexcept
Gets the velocity.
Definition: Body.hpp:1292
bool IsMotorEnabled(const Joint &object)
Gets the specified joint's motor property value if it supports one.
Definition: Joint.cpp:563
constexpr auto GetY(const UnitVec &value) -> decltype(get< 1 >(value))
Gets the "Y" element of the given value - i.e. the second element.
Definition: UnitVec.hpp:499
constexpr Momentum2 GetLinearReaction(const DistanceJointConf &object) noexcept
Gets the current linear reaction for the given configuration.
Definition: DistanceJointConf.hpp:175
Length2 GetLocalAnchorB(const GearJointConf &conf)
Gets the local anchor B property of the given joint.
Definition: GearJointConf.cpp:510
Angle GetAngle(const Body &body) noexcept
Gets the body's angle.
Definition: Body.cpp:280
AngularVelocity GetAngularVelocity(const Body &body) noexcept
Gets the angular velocity.
Definition: Body.hpp:1322
BodyID CreateBody(AabbTreeWorld &world, Body body=Body{})
Creates a rigid body that's a copy of the given one.
Definition: AabbTreeWorld.cpp:1019
BodyID GetBodyB(const Joint &object) noexcept
Gets the second body attached to this joint.
Definition: Joint.hpp:295
Angle GetReferenceAngle(const Joint &object)
Gets the reference angle of the joint if it has one.
Definition: Joint.cpp:218
Momentum GetLinearMotorImpulse(const Joint &object)
Definition: Joint.cpp:667
Angle GetAngularLowerLimit(const Joint &object)
Definition: Joint.cpp:509
BodyType GetType(const Body &body) noexcept
Gets the type of this body.
Definition: Body.hpp:748
void ShiftOrigin(AabbTreeWorld &world, const Length2 &newOrigin)
Shifts the world origin.
Definition: AabbTreeWorld.cpp:2221
bool SolvePosition(const DistanceJointConf &object, const Span< BodyConstraint > &bodies, const ConstraintSolverConf &conf)
Solves the position constraint.
Definition: DistanceJointConf.cpp:203
NonNegativeFF< InvRotInertia > GetInvRotInertia(const Body &body) noexcept
Gets the inverse rotational inertia of the body.
Definition: Body.hpp:1114
ShapeID CreateShape(AabbTreeWorld &world, Shape def)
Creates an identifiable copy of the given shape within this world.
Definition: AabbTreeWorld.cpp:1234
Torque GetMotorTorque(const Joint &joint, Frequency inv_dt)
Gets the current motor torque for the given joint given the inverse time step.
Definition: Joint.hpp:672
void SetAwake(Body &body) noexcept
Awakens this body.
Definition: Body.hpp:898
Length GetLinearLowerLimit(const Joint &object)
Definition: Joint.cpp:481
RevoluteJointConf GetRevoluteJointConf(const Joint &joint)
Gets the definition data for the given joint.
Definition: RevoluteJointConf.cpp:103
Angle GetAngularUpperLimit(const Joint &object)
Gets the upper joint limit.
Definition: Joint.cpp:518
BodyID GetBodyA(const Joint &object) noexcept
Gets the first body attached to this joint.
Definition: Joint.hpp:290
void Attach(AabbTreeWorld &world, BodyID id, ShapeID shapeID)
Associates a validly identified shape with the validly identified body.
Definition: AabbTreeWorld.cpp:2896
void Destroy(AabbTreeWorld &world, BodyID id)
Destroys the identified body.
Definition: AabbTreeWorld.cpp:1062
Length2 GetLocation(const Body &body) noexcept
Gets the body's origin location.
Definition: Body.hpp:930
void SetMaxMotorTorque(Joint &object, Torque value)
Sets the given joint's max motor torque if its type supports that.
Definition: Joint.cpp:366
void SetMotorSpeed(Joint &object, AngularVelocity value)
Sets the given joint's motor speed if its type supports that.
Definition: Joint.cpp:272
UnitVec GetLocalYAxisA(const Joint &object)
Gets the given joint's local Y axis A if its type supports that.
Definition: Joint.cpp:245
BodyCounter GetWorldIndex(const World &, BodyID id) noexcept
Gets the world index for the given body.
Definition: WorldBody.cpp:226
UnitVec GetLocalXAxisA(const Joint &object)
Gets the given joint's local X axis A if its type supports that.
Definition: Joint.cpp:233
LimitState GetLimitState(const Joint &object)
Definition: Joint.cpp:634
bool IsEnabled(const Body &body) noexcept
Gets the enabled/disabled state of the body.
Definition: Body.hpp:850
constexpr auto EarthlyGravity
Earthly gravity in 2-dimensions.
Definition: Vector2.hpp:128
Torque GetMaxMotorTorque(const Joint &object)
Gets the given joint's max motor torque if its type supports that.
Definition: Joint.cpp:354
Length2 GetAnchorB(const World &world, JointID id)
Definition: WorldJoint.cpp:179
bool IsLimitEnabled(const Joint &object)
Gets the specified joint's limit property if it supports one.
Definition: Joint.cpp:537
RotInertia GetAngularMass(const Joint &object)
Gets the given joint's angular mass.
Definition: Joint.cpp:290
JointID CreateJoint(AabbTreeWorld &world, Joint def)
Creates a joint to constrain one or more bodies.
Definition: AabbTreeWorld.cpp:1132
Length2 GetAnchorA(const World &world, JointID id)
Definition: WorldJoint.cpp:171
void SetAngularLimits(Joint &object, Angle lower, Angle upper)
Sets the joint limits.
Definition: Joint.cpp:527
Length2 GetLocalAnchorA(const GearJointConf &conf)
Gets the local anchor A property of the given joint.
Definition: GearJointConf.cpp:502
bool GetCollideConnected(const Joint &object) noexcept
Gets collide connected.
Definition: Joint.hpp:300
constexpr auto GetX(const UnitVec &value)
Gets the "X" element of the given value - i.e. the first element.
Definition: UnitVec.hpp:493
void EnableMotor(Joint &object, bool value)
Enables the specified joint's motor property if it supports one.
Definition: Joint.cpp:578
Force GetMaxMotorForce(const Joint &object)
Gets the given joint's max motor force if its type supports that.
Definition: Joint.cpp:335
void SetAccelerations(World &world, F fn)
Sets the accelerations of all the world's bodies.
Definition: World.hpp:411
Length GetLinearUpperLimit(const Joint &object)
Definition: Joint.cpp:490
void EnableLimit(Joint &object, bool value)
Enables the specified joint's limit property if it supports one.
Definition: Joint.cpp:549
StepStats Step(AabbTreeWorld &world, const StepConf &conf)
Steps the world simulation according to the given configuration.
Definition: AabbTreeWorld.cpp:2144
constexpr AngularMomentum GetAngularReaction(const DistanceJointConf &) noexcept
Gets the current angular reaction for the given configuration.
Definition: DistanceJointConf.hpp:182
AngularMomentum GetAngularMotorImpulse(const Joint &object)
Gets the angular motor impulse of the joint if it has this property.
Definition: Joint.cpp:450
AngularVelocity GetMotorSpeed(const Joint &object)
Gets the given joint's motor speed if its type supports that.
Definition: Joint.cpp:257
void UnsetAwake(Body &body) noexcept
Sets this body to asleep if sleeping is allowed.
Definition: Body.hpp:913
void InitVelocity(DistanceJointConf &object, const Span< BodyConstraint > &bodies, const StepConf &step, const ConstraintSolverConf &conf)
Initializes velocity constraint data based on the given solver data.
Definition: DistanceJointConf.cpp:81
const char * GetName(Manifold::Type type) noexcept
Gets a unique name for the given manifold type.
Definition: Manifold.cpp:633
Definition: ArrayList.hpp:43
Vector2< Momentum > Momentum2
2-element vector of Momentum quantities.
Definition: Vector2.hpp:76
float Real
Real-number type.
Definition: Real.hpp:69
constexpr auto InvalidBodyID
Invalid body ID value.
Definition: BodyID.hpp:50
Vector2< LinearAcceleration > LinearAcceleration2
2-element vector of linear acceleration (LinearAcceleration) quantities.
Definition: Vector2.hpp:62
Vector3< Real > Vec3
A 3-dimensional column vector with 3 elements.
Definition: Vector3.hpp:45
constexpr auto InvalidJointID
Invalid joint ID value.
Definition: JointID.hpp:50
Vector2< Length > Length2
2-element vector of Length quantities.
Definition: Vector2.hpp:51
@ e_inactiveLimit
Inactive limit.
@ e_equalLimits
Equal limit.
@ e_atUpperLimit
At-upper limit.
@ e_atLowerLimit
At-lower limit.
detail::IndexingNamedType< BodyCounter, struct BodyIdentifier > BodyID
Body identifier.
Definition: BodyID.hpp:44
Matrix33< Real > Mat33
3 by 3 matrix of Real elements.
Definition: Matrix.hpp:215