Skip to content

Commit 84c9ba1

Browse files
Remove hash map allocation on every update step (#1005)
Signed-off-by: Luca Della Vedova <lucadv@intrinsic.ai>
1 parent 92b5f16 commit 84c9ba1

6 files changed

Lines changed: 16 additions & 36 deletions

File tree

bullet-featherstone/src/Base.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <algorithm>
4040
#include <limits>
4141
#include <memory>
42+
#include <optional>
4243
#include <string>
4344
#include <unordered_map>
4445
#include <unordered_set>
@@ -48,6 +49,7 @@
4849

4950
#include <gz/common/Console.hh>
5051
#include <gz/math/eigen3/Conversions.hh>
52+
#include <gz/math/Pose3.hh>
5153
#include <gz/math/SemanticVersion.hh>
5254
#include <gz/physics/Implements.hh>
5355

@@ -236,6 +238,8 @@ struct LinkInfo
236238
std::unordered_map<std::string, std::size_t> collisionNameToEntityId = {};
237239
// Link is either static, fixed to world, or has zero dofs
238240
bool isStaticOrFixed = false;
241+
// Cached pose from the previous physics step for performance optimization
242+
mutable std::optional<math::Pose3d> prevPose = std::nullopt;
239243
};
240244

241245
struct CollisionInfo

bullet-featherstone/src/SimulationFeatures.cc

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,31 +370,21 @@ void SimulationFeatures::Write(ChangedWorldPoses &_changedPoses) const
370370
_changedPoses.entries.clear();
371371
_changedPoses.entries.reserve(this->links.size());
372372

373-
std::unordered_map<std::size_t, math::Pose3d> newPoses;
374-
375373
for (const auto &[id, info] : this->links)
376374
{
377375
const auto &model = this->ReferenceInterface<ModelInfo>(info->model);
378376
WorldPose wp;
379377
wp.pose = gz::math::eigen3::convert(GetWorldTransformOfLink(*model, *info));
380378
wp.body = id;
381379

382-
auto iter = this->prevLinkPoses.find(id);
383-
if ((iter == this->prevLinkPoses.end()) ||
384-
!iter->second.Pos().Equal(wp.pose.Pos(), 1e-6) ||
385-
!iter->second.Rot().Equal(wp.pose.Rot(), 1e-6))
380+
if (!info->prevPose.has_value() ||
381+
!info->prevPose->Pos().Equal(wp.pose.Pos(), 1e-6) ||
382+
!info->prevPose->Rot().Equal(wp.pose.Rot(), 1e-6))
386383
{
387384
_changedPoses.entries.push_back(wp);
388-
newPoses[id] = wp.pose;
385+
info->prevPose = wp.pose;
389386
}
390-
else
391-
newPoses[id] = iter->second;
392387
}
393-
394-
// Save the new poses so that they can be used to check for updates in the
395-
// next iteration. Re-setting this->prevLinkPoses with the contents of
396-
// newPoses ensures that we aren't caching data for links that were removed
397-
this->prevLinkPoses = std::move(newPoses);
398388
}
399389
} // namespace bullet_featherstone
400390
} // namespace physics

bullet-featherstone/src/SimulationFeatures.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ class SimulationFeatures :
5757

5858
public: std::vector<ContactInternal> GetContactsFromLastStep(
5959
const Identity &_worldID) const override;
60-
61-
/// \brief link poses from the most recent pose change/update.
62-
/// The key is the link's ID, and the value is the link's pose
63-
private: mutable std::unordered_map<std::size_t, math::Pose3d> prevLinkPoses;
6460
};
6561

6662
} // namespace bullet_featherstone

dartsim/src/Base.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <gz/common/Console.hh>
3838
#include <gz/math/eigen3/Conversions.hh>
3939
#include <gz/math/Inertial.hh>
40+
#include <gz/math/Pose3.hh>
4041
#include <gz/math/SemanticVersion.hh>
4142
#include <gz/physics/detail/EntityStorage.hh>
4243
#include <gz/physics/Implements.hh>
@@ -82,6 +83,9 @@ struct LinkInfo
8283
/// \brief The total link inertia, which may be split between the `link` and
8384
/// `weldedNodes` body nodes.
8485
std::optional<math::Inertiald> inertial;
86+
/// \brief Cached pose from the previous physics step, used for performance
87+
/// optimization.
88+
std::optional<math::Pose3d> prevPose;
8589
};
8690

8791
struct JointInfo

dartsim/src/SimulationFeatures.cc

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ void SimulationFeatures::Write(ChangedWorldPoses &_changedPoses) const
169169
_changedPoses.entries.clear();
170170
_changedPoses.entries.reserve(this->links.size());
171171

172-
std::unordered_map<std::size_t, math::Pose3d> newPoses;
173-
174172
for (const auto &[id, info] : this->links.idToObject)
175173
{
176174
// make sure the link exists
@@ -183,23 +181,15 @@ void SimulationFeatures::Write(ChangedWorldPoses &_changedPoses) const
183181

184182
// If the link's pose is new or has changed, save this new pose and
185183
// add it to the output poses. Otherwise, keep the existing link pose
186-
auto iter = this->prevLinkPoses.find(id);
187-
if ((iter == this->prevLinkPoses.end()) ||
188-
!iter->second.Pos().Equal(wp.pose.Pos(), 1e-6) ||
189-
!iter->second.Rot().Equal(wp.pose.Rot(), 1e-6))
184+
if (!info->prevPose.has_value() ||
185+
!info->prevPose->Pos().Equal(wp.pose.Pos(), 1e-6) ||
186+
!info->prevPose->Rot().Equal(wp.pose.Rot(), 1e-6))
190187
{
191188
_changedPoses.entries.push_back(wp);
192-
newPoses[id] = wp.pose;
189+
info->prevPose = wp.pose;
193190
}
194-
else
195-
newPoses[id] = iter->second;
196191
}
197192
}
198-
199-
// Save the new poses so that they can be used to check for updates in the
200-
// next iteration. Re-setting this->prevLinkPoses with the contents of
201-
// newPoses ensures that we aren't caching data for links that were removed
202-
this->prevLinkPoses = std::move(newPoses);
203193
}
204194

205195
SimulationFeatures::RayIntersectionInternal

dartsim/src/SimulationFeatures.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,6 @@ class SimulationFeatures :
142142
const std::vector<BatchRayQuery> &_rays,
143143
BatchedRayIntersectionData &_output) const override;
144144

145-
/// \brief link poses from the most recent pose change/update.
146-
/// The key is the link's ID, and the value is the link's pose
147-
private: mutable std::unordered_map<std::size_t, math::Pose3d> prevLinkPoses;
148-
149145
private: std::optional<ContactInternal> convertContact(
150146
const dart::collision::Contact& _contact) const;
151147

0 commit comments

Comments
 (0)