joint_test.cpp
Go to the documentation of this file.
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #include "box2d/box2d.h"
24 #include "doctest.h"
25 #include <stdio.h>
26 
27 DOCTEST_TEST_CASE("joint reactions")
28 {
29  b2Vec2 gravity(0, -10.0f);
30  b2World world = b2World(gravity);
31 
32  b2BodyDef bodyDef;
33  b2Body* ground = world.CreateBody(&bodyDef);
34 
35  b2CircleShape circle;
36  circle.m_radius = 1.0f;
37 
38  b2FixtureDef fixtureDef;
39 
40  // Disable collision
41  fixtureDef.filter.maskBits = 0;
42  fixtureDef.density = 1.0f;
43  fixtureDef.shape = &circle;
44 
45  bodyDef.type = b2_dynamicBody;
46  bodyDef.position.Set(-2.0f, 3.0f);
47 
48  b2Body* bodyA = world.CreateBody(&bodyDef);
49  b2Body* bodyB = world.CreateBody(&bodyDef);
50  b2Body* bodyC = world.CreateBody(&bodyDef);
51 
52  b2MassData massData;
53  circle.ComputeMass(&massData, fixtureDef.density);
54  const float mg = massData.mass * gravity.y;
55 
56  bodyA->CreateFixture(&fixtureDef);
57  bodyB->CreateFixture(&fixtureDef);
58  bodyC->CreateFixture(&fixtureDef);
59 
60  b2DistanceJointDef distanceJointDef;
61  distanceJointDef.Initialize(ground, bodyA, bodyDef.position + b2Vec2(0.0f, 4.0f), bodyDef.position);
62  distanceJointDef.minLength = distanceJointDef.length;
63  distanceJointDef.maxLength = distanceJointDef.length;
64 
65  b2PrismaticJointDef prismaticJointDef;
66  prismaticJointDef.Initialize(ground, bodyB, bodyDef.position, b2Vec2(1.0f, 0.0f));
67 
68  b2RevoluteJointDef revoluteJointDef;
69  revoluteJointDef.Initialize(ground, bodyC, bodyDef.position);
70 
71  b2DistanceJoint* distanceJoint = (b2DistanceJoint*)world.CreateJoint(&distanceJointDef);
72  b2PrismaticJoint* prismaticJoint = (b2PrismaticJoint*)world.CreateJoint(&prismaticJointDef);
73  b2RevoluteJoint* revoluteJoint = (b2RevoluteJoint*)world.CreateJoint(&revoluteJointDef);
74 
75  const float timeStep = 1.f / 60.f;
76  const float invTimeStep = 60.0f;
77  const int32 velocityIterations = 6;
78  const int32 positionIterations = 2;
79 
80  world.Step(timeStep, velocityIterations, positionIterations);
81 
82  const float tol = 1e-5f;
83  {
84  b2Vec2 F = distanceJoint->GetReactionForce(invTimeStep);
85  float T = distanceJoint->GetReactionTorque(invTimeStep);
86  CHECK(F.x == 0.0f);
87  CHECK(b2Abs(F.y + mg) < tol);
88  CHECK(T == 0.0f);
89  }
90 
91  {
92  b2Vec2 F = prismaticJoint->GetReactionForce(invTimeStep);
93  float T = prismaticJoint->GetReactionTorque(invTimeStep);
94  CHECK(F.x == 0.0f);
95  CHECK(b2Abs(F.y + mg) < tol);
96  CHECK(T == 0.0f);
97  }
98 
99  {
100  b2Vec2 F = revoluteJoint->GetReactionForce(invTimeStep);
101  float T = revoluteJoint->GetReactionTorque(invTimeStep);
102  CHECK(F.x == 0.0f);
103  CHECK(b2Abs(F.y + mg) < tol);
104  CHECK(T == 0.0f);
105  }
106 }
b2RevoluteJoint::GetReactionTorque
float GetReactionTorque(float inv_dt) const override
Definition: b2_revolute_joint.cpp:339
b2Vec2::y
float y
Definition: b2_math.h:128
b2PrismaticJoint
Definition: b2_prismatic_joint.h:91
b2Filter::maskBits
uint16 maskBits
Definition: b2_fixture.h:51
b2RevoluteJointDef::Initialize
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchor)
Definition: b2_revolute_joint.cpp:41
b2MassData::mass
float mass
The mass of the shape, usually in kilograms.
Definition: b2_shape.h:36
b2RevoluteJoint
Definition: b2_revolute_joint.h:94
b2DistanceJoint::GetReactionTorque
float GetReactionTorque(float inv_dt) const override
Definition: b2_distance_joint.cpp:332
b2DistanceJointDef::length
float length
The rest length of this joint. Clamped to a stable minimum value.
Definition: b2_distance_joint.h:59
b2Body
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2CircleShape
A solid circle shape.
Definition: b2_circle_shape.h:30
b2FixtureDef
Definition: b2_fixture.h:61
b2Vec2::Set
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2Vec2
A 2D column vector.
Definition: b2_math.h:41
b2RevoluteJointDef
Definition: b2_revolute_joint.h:39
f
f
b2World::Step
void Step(float timeStep, int32 velocityIterations, int32 positionIterations)
Definition: b2_world.cpp:905
b2DistanceJointDef::maxLength
float maxLength
Maximum length. Must be greater than or equal to the minimum length.
Definition: b2_distance_joint.h:65
b2BodyDef::type
b2BodyType type
Definition: b2_body.h:74
b2World::CreateJoint
b2Joint * CreateJoint(const b2JointDef *def)
Definition: b2_world.cpp:220
b2_dynamicBody
@ b2_dynamicBody
Definition: b2_body.h:47
b2FixtureDef::filter
b2Filter filter
Contact filtering data.
Definition: b2_fixture.h:99
b2PrismaticJoint::GetReactionTorque
float GetReactionTorque(float inv_dt) const override
Get the reaction torque on bodyB in N*m.
Definition: b2_prismatic_joint.cpp:468
b2Shape::m_radius
float m_radius
Definition: b2_shape.h:102
b2PrismaticJointDef
Definition: b2_prismatic_joint.h:35
b2FixtureDef::density
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
b2DistanceJointDef::minLength
float minLength
Minimum length. Clamped to a stable minimum value.
Definition: b2_distance_joint.h:62
b2Vec2::x
float x
Definition: b2_math.h:128
b2DistanceJointDef::Initialize
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchorA, const b2Vec2 &anchorB)
Definition: b2_distance_joint.cpp:44
b2BodyDef
Definition: b2_body.h:52
b2FixtureDef::shape
const b2Shape * shape
Definition: b2_fixture.h:76
box2d.h
b2World::CreateBody
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2RevoluteJoint::GetReactionForce
b2Vec2 GetReactionForce(float inv_dt) const override
Definition: b2_revolute_joint.cpp:333
b2DistanceJoint::GetReactionForce
b2Vec2 GetReactionForce(float inv_dt) const override
Definition: b2_distance_joint.cpp:326
doctest.h
int32
signed int int32
Definition: b2_types.h:28
b2DistanceJointDef
Definition: b2_distance_joint.h:33
b2BodyDef::position
b2Vec2 position
Definition: b2_body.h:78
b2DistanceJoint
Definition: b2_distance_joint.h:76
b2World
Definition: b2_world.h:46
b2MassData
This holds the mass data computed for a shape.
Definition: b2_shape.h:33
DOCTEST_TEST_CASE
DOCTEST_TEST_CASE("joint reactions")
Definition: joint_test.cpp:27
b2PrismaticJoint::GetReactionForce
b2Vec2 GetReactionForce(float inv_dt) const override
Get the reaction force on bodyB at the joint anchor in Newtons.
Definition: b2_prismatic_joint.cpp:463
b2CircleShape::ComputeMass
void ComputeMass(b2MassData *massData, float density) const override
Definition: b2_circle_shape.cpp:98
CHECK
#define CHECK
Definition: doctest.h:2471
b2Abs
T b2Abs(T a)
Definition: b2_math.h:610
b2PrismaticJointDef::Initialize
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchor, const b2Vec2 &axis)
Definition: b2_prismatic_joint.cpp:73
b2Body::CreateFixture
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:08