Skip to content

Commit

Permalink
Prevent crash when objects move to invalid poses
Browse files Browse the repository at this point in the history
DART seems to compute invalid poses for certain objects (e.g. Capsule, Ellipse) with large accelerations. The computed poses end up with `nan` values resulting in a crash. This patch detects this condition and reassigns the poses to the last known poses and resets velocities to zero to prevent the crash.

Signed-off-by: Addisu Z. Taddese <[email protected]>
  • Loading branch information
azeey committed Dec 18, 2024
1 parent 0b92e3d commit 44123f7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions dartsim/src/Base.hh
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct ModelInfo
std::vector<std::shared_ptr<LinkInfo>> links {};
std::vector<std::shared_ptr<JointInfo>> joints {};
std::vector<std::size_t> nestedModels = {};
std::optional<Eigen::VectorXd> lastGoodPositions = {};
};

struct ShapeInfo
Expand Down
33 changes: 33 additions & 0 deletions dartsim/src/SimulationFeatures.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
*
*/

#include <Eigen/Geometry>
#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
Expand All @@ -30,6 +32,7 @@
#include <dart/constraint/ContactSurface.hpp>
#endif

#include <gz/common/Console.hh>
#include <gz/common/Profiler.hh>

#include <gz/math/Pose3.hh>
Expand Down Expand Up @@ -106,6 +109,36 @@ void SimulationFeatures::WorldForwardStep(

// TODO(MXG): Parse input
world->step();

for (auto &[ignore, modelInfo] : this->models.idToObject)
{
Eigen::VectorXd positions = modelInfo->model->getPositions();
if (positions.hasNaN())
{
std::stringstream ss;
ss << "Some links in model '" << modelInfo->localName
<< "' have invalid poses. ";
if (modelInfo->lastGoodPositions)
{
ss << "Resetting to last known poses.";
modelInfo->model->setPositions(*modelInfo->lastGoodPositions);
}
else
{
ss << "Resetting to zero poses.";
modelInfo->model->resetPositions();
}
gzerr << ss.str()
<< " Also resetting velocities and accelerations to zero."
<< std::endl;
modelInfo->model->resetVelocities();
modelInfo->model->resetAccelerations();
}
else
{
modelInfo->lastGoodPositions = positions;
}
}
this->WriteRequiredData(_h);
this->Write(_h.Get<ChangedWorldPoses>());
// TODO(MXG): Fill in state
Expand Down

0 comments on commit 44123f7

Please sign in to comment.