Skip to content

Commit a65d04a

Browse files
authored
Fix robot shaking in emulator, correct keepConstantSpeed logic (#2112)
Fix robot shaking in emulator, correct keepConstantSpeed logic. Fixes the robot "shaking/vibration" issue in the 2D emulator when realisticMotors is disabled. The robot now moves straight and maintains constant speed as expected. The keepConstantSpeed(float speed) function in box2DWheel.cpp was incorrectly applying velocity impulses: Original behavior: The function calculated speedDiff as desiredSpeed - currentForwardSpeed, but desiredSpeed was computed as currentForwardSpeed + speedDelta, where speedDelta = |speed| / acceleration. With acceleration = 1, this made speedDiff == speed, meaning the full target speed was applied as an impulse every frame — not the difference needed to reach the target. Result: Instead of smoothly correcting toward the desired speed, the wheel received a maximum-magnitude impulse each simulation step (~10ms), causing oscillation and visible "shaking" in the emulator.
1 parent 57f572a commit a65d04a

1 file changed

Lines changed: 27 additions & 35 deletions

File tree

  • plugins/robots/common/twoDModel/src/engine/model/physics/parts

plugins/robots/common/twoDModel/src/engine/model/physics/parts/box2DWheel.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,28 @@ using namespace twoDModel::model::physics::parts;
2727
Box2DWheel::Box2DWheel(twoDModel::model::RobotModel * const robotModel,
2828
Box2DPhysicsEngine *engine
2929
, b2Vec2 positionBox2D, b2Rot rotationBox2D, Box2DRobot &robot)
30-
: mRobot(robot)
30+
: mBodyId(b2_nullBodyId)
31+
, mRobot(robot)
3132
, mEngine(engine)
3233
, mWheelHeightM(engine->pxToM(robotModel->parameters()->wheelDiameter() / 2))
3334
, mWheelWidthM(engine->pxToM(robotModel->parameters()->wheelDiameter()))
3435
, mPolygon(new b2Vec2[8])
3536
{
36-
b2BodyDef bodyDef = b2DefaultBodyDef();
37+
auto bodyDef = b2DefaultBodyDef();
3738
bodyDef.type = b2_dynamicBody;
3839
bodyDef.position = positionBox2D;
3940
bodyDef.rotation = rotationBox2D;
4041
mBodyId = b2CreateBody(engine->box2DWorldId(), &bodyDef);
4142

42-
b2ShapeDef fixtureDef = b2DefaultShapeDef();
43-
fixtureDef.material.restitution = robotModel->parameters()->wheelRestitution();
44-
fixtureDef.material.friction = robotModel->parameters()->wheelFriction();
45-
fixtureDef.density = engine->computeDensity(
43+
auto fixtureDef = b2DefaultShapeDef();
44+
fixtureDef.material.restitution = static_cast<float>(robotModel->parameters()->wheelRestitution());
45+
fixtureDef.material.friction = static_cast<float>(robotModel->parameters()->wheelFriction());
46+
fixtureDef.density = static_cast<float>(engine->computeDensity(
4647
QPolygonF(QRectF(0, 0, robotModel->parameters()->wheelDiameter() / 2,
4748
robotModel->parameters()->wheelDiameter()))
48-
, robotModel->parameters()->wheelMass());
49+
, robotModel->parameters()->wheelMass()));
4950

50-
b2Vec2 center = b2Vec2{0.5f * mWheelWidthM, 0.5f * mWheelHeightM};
51+
const auto &center = b2Vec2{0.5f * mWheelWidthM, 0.5f * mWheelHeightM};
5152
mPolygon[0] = b2Vec2{0.2f * mWheelWidthM, mWheelHeightM} - center;
5253
mPolygon[1] = b2Vec2{0.8f * mWheelWidthM, mWheelHeightM} - center;
5354
mPolygon[2] = b2Vec2{mWheelWidthM, 0.6f * mWheelHeightM} - center;
@@ -57,12 +58,12 @@ Box2DWheel::Box2DWheel(twoDModel::model::RobotModel * const robotModel,
5758
mPolygon[6] = b2Vec2{0.0f, 0.4f * mWheelHeightM} - center;
5859
mPolygon[7] = b2Vec2{0.0f, 0.6f * mWheelHeightM} - center;
5960

60-
b2Hull hull = b2ComputeHull(mPolygon, 8);
61-
b2Polygon polygon = b2MakePolygon(&hull, 0.0f);
62-
b2ShapeId polygonShapeId = b2CreatePolygonShape(mBodyId, &fixtureDef, &polygon);
61+
const auto &hull = b2ComputeHull(mPolygon, 8);
62+
const auto &polygon = b2MakePolygon(&hull, 0.0f);
63+
const auto &polygonShapeId = b2CreatePolygonShape(mBodyId, &fixtureDef, &polygon);
6364
b2Body_SetUserData(mBodyId, this);
6465

65-
auto finalPolygon = b2Shape_GetPolygon(polygonShapeId);
66+
const auto &finalPolygon = b2Shape_GetPolygon(polygonShapeId);
6667
for (int i = 0; i < finalPolygon.count; ++i) {
6768
auto position = b2Body_GetPosition(mBodyId);
6869
mDebuggingDrawPolygon.append(mEngine->positionToScene(finalPolygon.vertices[i] + position));
@@ -84,55 +85,46 @@ b2BodyId Box2DWheel::getBodyId() {
8485
}
8586

8687
b2Vec2 Box2DWheel::getLateralVelocity() const {
87-
b2Vec2 currentRightNormal = b2Body_GetWorldVector(mBodyId, {0, 1});
88+
const auto &currentRightNormal = b2Body_GetWorldVector(mBodyId, {0, 1});
8889
return b2Dot(currentRightNormal, b2Body_GetLinearVelocity(mBodyId)) * currentRightNormal;
8990
}
9091

9192
b2Vec2 Box2DWheel::getForwardVelocity() const {
92-
b2Vec2 currentForwardNormal = b2Body_GetWorldVector(mBodyId, {1, 0});
93+
const auto &currentForwardNormal = b2Body_GetWorldVector(mBodyId, {1, 0});
9394
return b2Dot(currentForwardNormal, b2Body_GetLinearVelocity(mBodyId)) * currentForwardNormal;
9495
}
9596

9697
void Box2DWheel::keepConstantSpeed(float speed) {
97-
const int acceleration = 1;//20;
9898
if (qAbs(prevSpeed - speed) > FLT_EPSILON){
9999
mRobot.applyForceToCenter(
100-
b2Body_GetWorldVector(mBodyId, b2Vec2{0.1f * mathUtils::Math::sign(speed), 0}), true);
100+
b2Body_GetWorldVector(mBodyId, b2Vec2{0.1f *
101+
static_cast<float>(mathUtils::Math::sign(speed)), 0}), true);
101102
prevSpeed = speed;
102103
}
103104

104-
// clears lateral velocity
105-
b2Vec2 lateralImpulse = b2Body_GetMass(mBodyId) * -getLateralVelocity();
106-
auto center = b2Body_GetWorldCenterOfMass(mBodyId);
107-
b2Body_ApplyLinearImpulse(mBodyId, lateralImpulse, center, true);
105+
const auto &lateralImpulse = b2Body_GetMass(mBodyId) * -getLateralVelocity();
106+
b2Body_ApplyLinearImpulseToCenter(mBodyId, lateralImpulse, true);
108107

109-
b2Vec2 forwardVelocity = getForwardVelocity();
110-
float scalar = b2Dot(forwardVelocity,
111-
b2Body_GetWorldVector(mBodyId, {1, 0})) < 0 ? -1 : 1;
112-
113-
float currentForwardSpeed = b2Length(forwardVelocity) * scalar;
108+
auto currentForwardSpeed =
109+
b2Dot(b2Body_GetLinearVelocity(mBodyId),
110+
b2Body_GetWorldVector(mBodyId, {1, 0}));
114111

115112
if (mathUtils::Math::eq(currentForwardSpeed, speed)) {
116113
return;
117114
}
118115

119-
float speedDelta = qAbs(speed) / acceleration * (currentForwardSpeed < speed ? 1 : -1);
120-
float desiredSpeed = currentForwardSpeed + speedDelta;
121-
122-
float speedDiff = desiredSpeed - currentForwardSpeed;
123-
b2Vec2 forwardNormal = b2Body_GetWorldVector(mBodyId, {1, 0});
124-
b2Vec2 linearImpulse = speedDiff * b2Body_GetMass(mBodyId) * forwardNormal;
116+
auto speedDiff = speed - currentForwardSpeed;
125117

126-
//break stop
127118
if (qAbs(speedDiff) < FLT_EPSILON) {
128119
stop();
129120
return;
130121
}
131122

132-
center = b2Body_GetWorldCenterOfMass(mBodyId);
133-
b2Body_ApplyLinearImpulse(mBodyId, linearImpulse, center, true);
134-
}
123+
const auto &forwardNormal = b2Body_GetWorldVector(mBodyId, {1, 0});
124+
const auto &linearImpulse = speedDiff * b2Body_GetMass(mBodyId) * forwardNormal;
135125

126+
b2Body_ApplyLinearImpulseToCenter(mBodyId, linearImpulse, true);
127+
}
136128

137129
void Box2DWheel::stop() {
138130
b2Body_SetLinearVelocity(mBodyId, {0, 0});

0 commit comments

Comments
 (0)