#include "UnitTests.hpp"
#include <stdexcept>
TEST(PulleyJointConf, DefaultConstruction)
{
PulleyJointConf def;
EXPECT_EQ(def.collideConnected, true);
EXPECT_EQ(def.lengthA, 0_m);
EXPECT_EQ(def.lengthB, 0_m);
EXPECT_EQ(def.ratio,
Real(1));
EXPECT_EQ(def.impulse, 0_Ns);
EXPECT_EQ(def.uA, UnitVec());
EXPECT_EQ(def.uB, UnitVec());
EXPECT_EQ(def.mass, 0_kg);
}
TEST(PulleyJointConf, InitializingConstructor)
{
const auto gndA =
Length2{-5_m, -4.2_m};
const auto gndB =
Length2{+2.3_m, +3.1_m};
const auto locA =
Length2{-1.1_m, +0.2_m};
const auto locB =
Length2{-1.4_m, +2.9_m};
const auto lenA = 2.2_m;
const auto lenB = 0.24_m;
EXPECT_EQ(PulleyJointConf(bA, bB).bodyA, bA);
EXPECT_EQ(PulleyJointConf(bA, bB).bodyB, bB);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB).groundAnchorA, gndA);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB).groundAnchorB, gndB);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB, locA, locB).localAnchorA, locA);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB, locA, locB).localAnchorB, locB);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB, locA, locB, lenA, lenB).lengthA, lenA);
EXPECT_EQ(PulleyJointConf(bA, bB, gndA, gndB, locA, locB, lenA, lenB).lengthB, lenB);
}
TEST(PulleyJointConf, GetPulleyJointConfThrows)
{
}
TEST(PulleyJointConf, GetPulleyJointConfForWorld)
{
auto world = World{};
const auto posA =
Length2{+1_m, +1_m};
const auto posB =
Length2{-1_m, -1_m};
const auto bA =
CreateBody(world, BodyConf{}.UseLocation(posA));
const auto bB =
CreateBody(world, BodyConf{}.UseLocation(posB));
const auto gA =
Length2{2.2_m, 3.0_m};
const auto gB =
Length2{-1.0_m, 1_m};
const auto aA =
Length2{+10_m, 10_m};
const auto aB =
Length2{-10_m, 10_m};
EXPECT_EQ(conf.bodyA, bA);
EXPECT_EQ(conf.bodyB, bB);
EXPECT_EQ(conf.groundAnchorA, gA);
EXPECT_EQ(conf.groundAnchorB, gB);
EXPECT_EQ(conf.localAnchorA, aA - posA);
EXPECT_EQ(conf.localAnchorB, aB - posB);
EXPECT_NEAR(
static_cast<double>(
Real(conf.lengthA / 1_m)), 10.4805, 0.0001);
EXPECT_NEAR(
static_cast<double>(
Real(conf.lengthB / 1_m)), 12.7279, 0.0001);
}
TEST(PulleyJointConf, GetPulleyJointConfForJoint)
{
const auto gndA =
Length2{-5_m, -4.2_m};
const auto gndB =
Length2{+2.3_m, +3.1_m};
const auto locA =
Length2{-1.1_m, +0.2_m};
const auto locB =
Length2{-1.4_m, +2.9_m};
const auto lenA = 2.2_m;
const auto lenB = 0.24_m;
const auto joint = Joint{PulleyJointConf{bA, bB, gndA, gndB, locA, locB, lenA, lenB}};
EXPECT_EQ(conf.bodyA, bA);
EXPECT_EQ(conf.bodyB, bB);
EXPECT_EQ(conf.groundAnchorA, gndA);
EXPECT_EQ(conf.groundAnchorB, gndB);
EXPECT_EQ(conf.localAnchorA, locA);
EXPECT_EQ(conf.localAnchorB, locB);
EXPECT_EQ(conf.lengthA, lenA);
EXPECT_EQ(conf.lengthB, lenB);
}
TEST(PulleyJointConf, UseRatio)
{
const auto value =
Real(31);
EXPECT_NE(PulleyJointConf{}.ratio, value);
EXPECT_EQ(PulleyJointConf{}.UseRatio(value).ratio, value);
}
TEST(PulleyJoint, Construction)
{
PulleyJointConf def;
Joint joint{def};
EXPECT_EQ(
GetType(joint), GetTypeID<PulleyJointConf>());
#if 0
#endif
}
TEST(PulleyJoint, GetAnchorAandB)
{
auto world = World{};
const auto loc0 =
Length2{+1_m, -3_m};
const auto b0 =
CreateBody(world, BodyConf{}.UseLocation(loc0));
const auto b1 =
CreateBody(world, BodyConf{}.UseLocation(loc1));
auto jd = PulleyJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
auto joint = Joint{jd};
#if 0
EXPECT_EQ(joint.GetAnchorA(world), loc0 + jd.localAnchorA);
EXPECT_EQ(joint.GetAnchorB(world), loc1 + jd.localAnchorB);
#endif
}
{
PulleyJointConf def;
Joint joint{def};
const auto newOrigin =
Length2{1_m, 1_m};
}
TEST(PulleyJoint, GetCurrentLength)
{
auto world = World{};
const auto loc0 =
Length2{+1_m, -3_m};
const auto b0 =
CreateBody(world, BodyConf{}.UseLocation(loc0));
const auto b1 =
CreateBody(world, BodyConf{}.UseLocation(loc1));
auto jd = PulleyJointConf{};
jd.bodyA = b0;
jd.bodyB = b1;
jd.localAnchorA =
Length2(4_m, 5_m);
jd.localAnchorB =
Length2(6_m, 7_m);
auto joint = Joint{jd};
const auto lenA =
const auto lenB =
}
TEST(PulleyJointConf, InitVelocityThrowsOutOfRange)
{
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
EXPECT_THROW(
InitVelocity(jd, bodies, StepConf{}, ConstraintSolverConf{}), std::out_of_range);
bodies.push_back(BodyConstraint{});
EXPECT_NO_THROW(
InitVelocity(jd, bodies, StepConf{}, ConstraintSolverConf{}));
}
TEST(PulleyJointConf, InitVelocityWithDefaultConstructed)
{
std::vector<BodyConstraint> bodies;
bodies.push_back(BodyConstraint{});
bodies.push_back(BodyConstraint{});
ASSERT_EQ(bodies.size(), 2u);
auto jd = PulleyJointConf{};
const auto copy = jd;
ASSERT_EQ(jd.bodyA,
BodyID(0u));
ASSERT_EQ(jd.bodyB,
BodyID(1u));
ASSERT_EQ(jd.mass, 0_kg);
ASSERT_EQ(jd.impulse, 0_Ns);
ASSERT_EQ(jd.uA, UnitVec());
ASSERT_EQ(jd.uB, UnitVec());
EXPECT_NO_THROW(
InitVelocity(jd, bodies, StepConf{}, ConstraintSolverConf{}));
EXPECT_EQ(jd.bodyA, copy.bodyA);
EXPECT_EQ(jd.bodyB, copy.bodyB);
EXPECT_EQ(jd.collideConnected, copy.collideConnected);
EXPECT_EQ(jd.mass, copy.mass);
EXPECT_EQ(jd.impulse, copy.impulse);
EXPECT_NE(jd.uA, copy.uA);
EXPECT_NE(jd.uB, copy.uB);
EXPECT_NE(jd.rA, copy.rA);
EXPECT_NE(jd.rB, copy.rB);
EXPECT_EQ(jd.rA,
Length2(-1_m, 0_m));
EXPECT_EQ(jd.rB,
Length2(+1_m, 0_m));
}
TEST(PulleyJointConf, InitVelocityWarmStartUpdatesImpulse)
{
auto stepConf = StepConf{};
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
bodies.push_back(BodyConstraint{});
bodies.push_back(BodyConstraint{});
stepConf.dtRatio =
Real(3);
stepConf.doWarmStart = true;
const auto originalImpulse = 2_Ns;
jd.impulse = originalImpulse;
EXPECT_NO_THROW(
InitVelocity(jd, bodies, stepConf, ConstraintSolverConf{}));
EXPECT_EQ(jd.impulse, originalImpulse * stepConf.dtRatio);
}
TEST(PulleyJointConf, InitVelocityColdStartResetsImpulse)
{
auto stepConf = StepConf{};
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
bodies.push_back(BodyConstraint{});
bodies.push_back(BodyConstraint{});
stepConf.dtRatio =
Real(3);
stepConf.doWarmStart = false;
const auto originalImpulse = 2_Ns;
jd.impulse = originalImpulse;
EXPECT_NO_THROW(
InitVelocity(jd, bodies, stepConf, ConstraintSolverConf{}));
EXPECT_EQ(jd.impulse, 0_Ns);
}
{
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
auto stepConf = StepConf{};
EXPECT_NO_THROW(
InitVelocity(jd, bodies, stepConf, ConstraintSolverConf{}));
EXPECT_THROW(
InitVelocity(jd, bodies, stepConf, ConstraintSolverConf{}), std::out_of_range);
bodies.push_back(
bodies.push_back(
stepConf.dtRatio =
Real(1);
stepConf.doWarmStart = false;
ASSERT_EQ(jd.mass, 0_kg);
EXPECT_NO_THROW(
InitVelocity(jd, bodies, stepConf, ConstraintSolverConf{}));
EXPECT_EQ(jd.mass, 2_kg);
}
{
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
auto result = false;
EXPECT_TRUE(result);
EXPECT_THROW(
SolveVelocity(jd, bodies, StepConf{}), std::out_of_range);
bodies.push_back(BodyConstraint{});
bodies.push_back(BodyConstraint{});
}
{
auto jd = PulleyJointConf{};
std::vector<BodyConstraint> bodies;
auto result = false;
EXPECT_NO_THROW(result =
SolvePosition(jd, bodies, ConstraintSolverConf{}));
EXPECT_TRUE(result);
EXPECT_NO_THROW(
SolvePosition(jd, bodies, ConstraintSolverConf{}));
EXPECT_THROW(
SolvePosition(jd, bodies, ConstraintSolverConf{}), std::out_of_range);
const auto posA = Position{
Length2{-5_m, 0_m}, 0_deg};
const auto posB = Position{
Length2{+5_m, 0_m}, 0_deg};
jd.groundAnchorA = posA.linear +
Length2{0_m, 8_m};
jd.groundAnchorB = posB.linear +
Length2{0_m, 8_m};
auto solved = false;
EXPECT_NO_THROW(solved =
SolvePosition(jd, bodies, ConstraintSolverConf{}));
EXPECT_FALSE(solved);
EXPECT_NO_THROW(solved =
SolvePosition(jd, bodies, ConstraintSolverConf{}));
EXPECT_TRUE(solved);
}
TEST(PulleyJointConf, EqualsOperator)
{
EXPECT_TRUE(PulleyJointConf() == PulleyJointConf());
{
auto conf = PulleyJointConf{};
conf.localAnchorA =
Length2{1.2_m, -3_m};
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(PulleyJointConf() == conf);
}
{
auto conf = PulleyJointConf{};
conf.localAnchorB =
Length2{1.2_m, -3_m};
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(PulleyJointConf() == conf);
}
{
auto conf = PulleyJointConf{};
conf.lengthA = 12_m;
EXPECT_TRUE(conf == conf);
EXPECT_FALSE(PulleyJointConf() == conf);
}
}
TEST(PulleyJointConf, NotEqualsOperator)
{
EXPECT_FALSE(PulleyJointConf() != PulleyJointConf());
{
auto conf = PulleyJointConf{};
conf.lengthB = 1.9_m;
EXPECT_FALSE(conf != conf);
EXPECT_TRUE(PulleyJointConf() != conf);
}
}
{
EXPECT_STREQ(
GetName(GetTypeID<PulleyJointConf>()),
"d2::PulleyJointConf");
}
Definition of the BodyConstraint class and closely related code.
Definition of the ConstraintSolverConf class and closely related code.
Definition of the Joint class and closely related code.
Definition of the PulleyJointConf 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.
Definitions of the World class and closely related code.
static constexpr UnitVec GetDown() noexcept
Gets the down-ward oriented unit vector.
Definition: UnitVec.hpp:140
static constexpr UnitVec GetZero() noexcept
Gets the non-oriented unit vector.
Definition: UnitVec.hpp:143
auto GetMagnitude(const T &value) noexcept(noexcept(sqrt(GetMagnitudeSquared(value)))) -> decltype(sqrt(GetMagnitudeSquared(value)))
Gets the magnitude of the given value.
Definition: Math.hpp:289
detail::angular_momentum AngularMomentum
Angular momentum quantity.
Definition: Units.hpp:390
detail::inverse_moment_of_inertia InvRotInertia
Inverse rotational inertia quantity.
Definition: Units.hpp:368
constexpr auto Meter
Meter unit of Length.
Definition: Units.hpp:423
bool SolveVelocity(DistanceJointConf &object, const Span< BodyConstraint > &bodies, const StepConf &step)
Solves velocity constraint.
Definition: DistanceJointConf.cpp:169
Velocity GetVelocity(const Body &body) noexcept
Gets the velocity.
Definition: Body.hpp:1292
Position GetPosition(const Body &body) noexcept
Gets the body's position.
Definition: Body.hpp:1056
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
Length2 GetGroundAnchorB(const Joint &object)
Definition: Joint.cpp:658
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
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
PulleyJointConf GetPulleyJointConf(const Joint &joint)
Gets the definition data for the given joint.
Definition: PulleyJointConf.cpp:73
Length2 GetWorldPoint(const Body &body, const Length2 &localPoint) noexcept
Gets the world coordinates of a point given in coordinates relative to the body's origin.
Definition: Body.hpp:1352
BodyID GetBodyA(const Joint &object) noexcept
Gets the first body attached to this joint.
Definition: Joint.hpp:290
Length2 GetGroundAnchorA(const Joint &object)
Definition: Joint.cpp:649
Length GetCurrentLengthA(const World &world, JointID id)
Get the current length of the segment attached to body-A.
Definition: WorldJoint.cpp:272
Length GetCurrentLengthB(const World &world, JointID id)
Get the current length of the segment attached to body-B.
Definition: WorldJoint.cpp:277
constexpr auto GetLengthA(const PulleyJointConf &object) noexcept
Free function for getting the length A value of the given configuration.
Definition: PulleyJointConf.hpp:239
constexpr auto GetLengthB(const PulleyJointConf &object) noexcept
Free function for getting the length B value of the given configuration.
Definition: PulleyJointConf.hpp:246
JointID CreateJoint(AabbTreeWorld &world, Joint def)
Creates a joint to constrain one or more bodies.
Definition: AabbTreeWorld.cpp:1132
Length2 GetLocalAnchorA(const GearJointConf &conf)
Gets the local anchor A property of the given joint.
Definition: GearJointConf.cpp:502
constexpr auto GetRatio(const GearJointConf &object) noexcept
Free function for getting the ratio value of the given configuration.
Definition: GearJointConf.hpp:263
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
constexpr AngularMomentum GetAngularReaction(const DistanceJointConf &) noexcept
Gets the current angular reaction for the given configuration.
Definition: DistanceJointConf.hpp:182
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< Length > Length2
2-element vector of Length quantities.
Definition: Vector2.hpp:51
detail::IndexingNamedType< BodyCounter, struct BodyIdentifier > BodyID
Body identifier.
Definition: BodyID.hpp:44
Angle angular
Angular position.
Definition: Position.hpp:56
static constexpr Length2 DefaultGroundAnchorB
Default ground anchor B.
Definition: PulleyJointConf.hpp:73
static constexpr Length2 DefaultGroundAnchorA
Default ground anchor A.
Definition: PulleyJointConf.hpp:70
static constexpr Length2 DefaultLocalAnchorA
Default local anchor A.
Definition: PulleyJointConf.hpp:76
static constexpr Length2 DefaultLocalAnchorB
Default local anchor B.
Definition: PulleyJointConf.hpp:79