bulletphysics / bullet3

Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.
http://bulletphysics.org
Other
12.49k stars 2.87k forks source link

updateAction function calling order [bullet3.25] #4620

Closed hdy117 closed 4 months ago

hdy117 commented 4 months ago

I have a vehicle model, and I am using ActionInterface to simulate force to keep vehicle from falling instead of a static ground.

And I am planning to implement magic formular tire model later. That is why I want to handle tire force all by myself.

Here is the code of WheelHeightMaintainer by spring-damper:

WheeHeightMaintainer::WheeHeightMaintainer(btRigidBody* body,
                                           btScalar gnd_target_z,
                                           btScalar wheel_radius,
                                           btScalar spring_constant,
                                           btScalar damping_factor)
    : body_(body),
      gnd_target_z_(gnd_target_z),
      spring_constant_(spring_constant),
      damping_factor_(damping_factor),
      wheel_radius_(wheel_radius) {}

void WheeHeightMaintainer::updateAction(btCollisionWorld* collisionWorld,
                                        btScalar deltaTimeStep) {
  const btVector3& pos = body_->getWorldTransform().getOrigin();
  // as free length
  btScalar target_wheel_z = gnd_target_z_ + wheel_radius_;
  btScalar delta_z = pos.getZ() - target_wheel_z;
  btScalar velocity_z = body_->getLinearVelocity().getZ();

  // Spring force = -k*x - c*v
  btScalar force_z = -spring_constant_ * delta_z - damping_factor_ * velocity_z;

  LOG_I << "target_wheel_z:" << target_wheel_z << ", pos.getZ():" << pos.getZ()
        << ", delta_z:" << delta_z << ", force_z:" << force_z
        << ", deltaTimeStep:" << deltaTimeStep << ", velocity_z:" << velocity_z
        << ", isStaticOrKinematicObject:" << body_->isStaticOrKinematicObject();

  // Apply the calculated force to the body
  body_->applyCentralForce(btVector3(0, 0, force_z));
}

since force applied to rigid body is cleard after internalSingleStepSimulation. this ActionInterface never got chance to hold the vehicle. I have to move the calling of function updateActions(timeStep) before solveConstraints(getSolverInfo()) in internalSingleStepSimulation;

And it works.

here is how I modified bullet3.25 source code

void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) {
  BT_PROFILE("internalSingleStepSimulation");

  if (0 != m_internalPreTickCallback) {
    (*m_internalPreTickCallback)(this, timeStep);
  }

  /// apply gravity, predict motion
  predictUnconstraintMotion(timeStep);

  btDispatcherInfo& dispatchInfo = getDispatchInfo();

  dispatchInfo.m_timeStep = timeStep;
  dispatchInfo.m_stepCount = 0;
  dispatchInfo.m_debugDraw = getDebugDrawer();

  createPredictiveContacts(timeStep);

  /// perform collision detection
  performDiscreteCollisionDetection();

  calculateSimulationIslands();

  getSolverInfo().m_timeStep = timeStep;

  /// update vehicle simulation, <here is changed code>
  updateActions(timeStep);

  /// solve contact and other joint constraints
  solveConstraints(getSolverInfo());

  /// CallbackTriggers();

  /// integrate transforms

  integrateTransforms(timeStep);

  // ///update vehicle simulation, <here is original code>
  // updateActions(timeStep);

  updateActivationState(timeStep);

  if (0 != m_internalTickCallback) {
    (*m_internalTickCallback)(this, timeStep);
  }
}

And I want to know if I am using it correctly? Any suggestion would be appreciated

hdy117 commented 4 months ago

follow btRaycastVehicle