Skip to content

Commit a369e18

Browse files
authored
Prevent crash when objects move to invalid poses (#706)
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 a369e18

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+
const 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)