Skip to content

Commit 44123f7

Browse files
committed
Prevent crash when objects move to invalid poses
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 <addisu@openrobotics.org>
1 parent 0b92e3d commit 44123f7

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

dartsim/src/Base.hh

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct ModelInfo
9797
std::vector<std::shared_ptr<LinkInfo>> links {};
9898
std::vector<std::shared_ptr<JointInfo>> joints {};
9999
std::vector<std::size_t> nestedModels = {};
100+
std::optional<Eigen::VectorXd> lastGoodPositions = {};
100101
};
101102

102103
struct ShapeInfo

dartsim/src/SimulationFeatures.cc

+33
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*
1616
*/
1717

18+
#include <Eigen/Geometry>
1819
#include <limits>
1920
#include <memory>
21+
#include <sstream>
2022
#include <string>
2123
#include <unordered_map>
2224
#include <utility>
@@ -30,6 +32,7 @@
3032
#include <dart/constraint/ContactSurface.hpp>
3133
#endif
3234

35+
#include <gz/common/Console.hh>
3336
#include <gz/common/Profiler.hh>
3437

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

107110
// TODO(MXG): Parse input
108111
world->step();
112+
113+
for (auto &[ignore, modelInfo] : this->models.idToObject)
114+
{
115+
Eigen::VectorXd positions = modelInfo->model->getPositions();
116+
if (positions.hasNaN())
117+
{
118+
std::stringstream ss;
119+
ss << "Some links in model '" << modelInfo->localName
120+
<< "' have invalid poses. ";
121+
if (modelInfo->lastGoodPositions)
122+
{
123+
ss << "Resetting to last known poses.";
124+
modelInfo->model->setPositions(*modelInfo->lastGoodPositions);
125+
}
126+
else
127+
{
128+
ss << "Resetting to zero poses.";
129+
modelInfo->model->resetPositions();
130+
}
131+
gzerr << ss.str()
132+
<< " Also resetting velocities and accelerations to zero."
133+
<< std::endl;
134+
modelInfo->model->resetVelocities();
135+
modelInfo->model->resetAccelerations();
136+
}
137+
else
138+
{
139+
modelInfo->lastGoodPositions = positions;
140+
}
141+
}
109142
this->WriteRequiredData(_h);
110143
this->Write(_h.Get<ChangedWorldPoses>());
111144
// TODO(MXG): Fill in state

0 commit comments

Comments
 (0)