Agents freeze after collision impulse in PCM Simulation
When running the PCM simulation, the agents freeze within a collision. After some research I found out, that the two components responsible for moving an agent stop updating the agent's driving attributes after the collision impulse. In more detail, the agents do the following after a collision:
-
Dynamics_Collision_Implementation
only acts in the moment of the collision impulse:
void Dynamics_Collision_Implementation::Trigger(int time)
{
Q_UNUSED(time);
CollisionState nextState = CollisionState::NOCOLLISION;
bool in_collisionOccurred = collisionOccurred.GetValue();
switch (collisionState)
{
... Determining the next state, can be NOCOLLISION, COLLISIONIMPULS or COLLISION ...
}
collisionState = nextState; // immediate transition
if (collisionState == CollisionState::COLLISIONIMPULS)
{
... Update the vehicle attributes with new velocity, xy-position, ...
}
...
}
- On the other side,
DynamicsMotionModelImplementation
updates an Agent only when it does not have any collision partners:
void DynamicsMotionModelImplementation::Trigger(int time)
{
Q_UNUSED(time);
if (GetAgent()->GetCollisionPartners().empty())
{
ReadPreviousState();
... Update the vehicle attributes with new velocity, xy-position, ...
}
...
}
In the timestep after the COLLISIONIMPULS the agent still has a non empty CollisionPartners vector. This causes both agents to freeze.
I found two possible solutions:
- Similar to the logic of
DynamicsPostCrashImplementation
,Dynamics_Collision_Implementation
could implement a fading dynamic and deceleration with a constant number, e.g. 10 m/s². The following code requires private bool variableisActive
which is initialized with false:
void Dynamics_Collision_Implementation::Trigger(int time)
{
Q_UNUSED(time);
CollisionState nextState = CollisionState::NOCOLLISION;
bool in_collisionOccurred = collisionOccurred.GetValue();
switch (collisionState)
{
... Determining the next state, can be NOCOLLISION, COLLISIONIMPULS or COLLISION ...
}
collisionState = nextState; // immediate transition
if (collisionState == CollisionState::COLLISIONIMPULS)
{
... Update the vehicle attributes with new velocity, xy-position, ...
isActive = true;
}
else if(isActive)
{
if(velocity > 0.0_mps)
{
SetFadingDynamics(time);
}
}
}
void Dynamics_Collision_Implementation::SetFadingDynamics(int time)
{
... Logic similar to the SetFadingDynamics method in DynamicsPostCrashImplementation
}
- Instead of stopping its procedure while the vector of CollisionPartners is not empty,
DynamicsMotionModelImplementation
could stop updating the vehicle only during the COLLISIONIMPULS and continue afterwards. The following code requires private bool variableisCollisionImpulse
which is initialized with false:
void DynamicsMotionModelImplementation::Trigger(int time)
{
Q_UNUSED(time);
if (!GetAgent()->GetCollisionPartners().empty())
{
isCollisionImpulse = !isCollisionImpulse;
}
else
{
isCollisionImpulse = false;
}
if (!isCollisionImpulse)
{
ReadPreviousState();
... Update the vehicle attributes with new velocity, xy-position, ...
}
Since the solution to this bug is more conceptual, I don't suggest any of the presented solutions but would like to initiate a discussion on how to fix this issue.
Paul Romahn, on behalf of Mercedes-Benz Tech Innovation GmbH, Provider Information