@@ -49,13 +49,10 @@ class sdf::Collision::Implementation
49
49
// / \brief The collision's surface parameters.
50
50
public: sdf::Surface surface;
51
51
52
- // / \brief Density of the collision. Default is 1000.0
53
- public: double density{ 1000.0 } ;
52
+ // / \brief Density of the collision if it has been set.
53
+ public: std::optional< double > density;
54
54
55
- // / \brief True if density was set during load from sdf.
56
- public: bool densitySetAtLoad = false ;
57
-
58
- // / \brief SDF element pointer to <moi_calculator_params> tag
55
+ // / \brief SDF element pointer to <auto_inertia_params> tag
59
56
public: sdf::ElementPtr autoInertiaParams{nullptr };
60
57
61
58
// / \brief The SDF element pointer used during load.
@@ -130,7 +127,6 @@ Errors Collision::Load(ElementPtr _sdf, const ParserConfig &_config)
130
127
if (_sdf->HasElement (" density" ))
131
128
{
132
129
this ->dataPtr ->density = _sdf->Get <double >(" density" );
133
- this ->dataPtr ->densitySetAtLoad = true ;
134
130
}
135
131
136
132
// Load the auto_inertia_params element
@@ -155,10 +151,20 @@ void Collision::SetName(const std::string &_name)
155
151
this ->dataPtr ->name = _name;
156
152
}
157
153
154
+ // ///////////////////////////////////////////////
155
+ double Collision::DensityDefault ()
156
+ {
157
+ return 1000.0 ;
158
+ }
159
+
158
160
// ///////////////////////////////////////////////
159
161
double Collision::Density () const
160
162
{
161
- return this ->dataPtr ->density ;
163
+ if (this ->dataPtr ->density )
164
+ {
165
+ return *this ->dataPtr ->density ;
166
+ }
167
+ return DensityDefault ();
162
168
}
163
169
164
170
// ///////////////////////////////////////////////
@@ -256,23 +262,59 @@ void Collision::CalculateInertial(
256
262
gz::math::Inertiald &_inertial,
257
263
const ParserConfig &_config)
258
264
{
259
- // Check if density was not set during load & send a warning
260
- // about the default value being used
261
- if (!this ->dataPtr ->densitySetAtLoad )
265
+ this ->CalculateInertial (
266
+ _errors, _inertial, _config, std::nullopt , ElementPtr ());
267
+ }
268
+
269
+ // ///////////////////////////////////////////////
270
+ void Collision::CalculateInertial (
271
+ sdf::Errors &_errors,
272
+ gz::math::Inertiald &_inertial,
273
+ const ParserConfig &_config,
274
+ const std::optional<double > &_density,
275
+ sdf::ElementPtr _autoInertiaParams)
276
+ {
277
+ // Order of precedence for density:
278
+ double density;
279
+ // 1. Density explicitly set in this collision, either from the
280
+ // `//collision/density` element or from Collision::SetDensity.
281
+ if (this ->dataPtr ->density )
282
+ {
283
+ density = *this ->dataPtr ->density ;
284
+ }
285
+ // 2. Density passed into this function, which likely comes from the
286
+ // `//link/inertial/density` element or from Link::SetDensity.
287
+ else if (_density)
288
+ {
289
+ density = *_density;
290
+ }
291
+ // 3. DensityDefault value.
292
+ else
262
293
{
294
+ // If density was not explicitly set, send a warning
295
+ // about the default value being used
296
+ density = DensityDefault ();
263
297
Error densityMissingErr (
264
298
ErrorCode::ELEMENT_MISSING,
265
299
" Collision is missing a <density> child element. "
266
- " Using a default density value of 1000.0 kg/m^3. "
300
+ " Using a default density value of " +
301
+ std::to_string (DensityDefault ()) + " kg/m^3. "
267
302
);
268
303
enforceConfigurablePolicyCondition (
269
304
_config.WarningsPolicy (), densityMissingErr, _errors
270
305
);
271
306
}
272
307
308
+ // If this Collision's auto inertia params have not been set, then use the
309
+ // params passed into this function.
310
+ sdf::ElementPtr autoInertiaParams = this ->dataPtr ->autoInertiaParams ;
311
+ if (!autoInertiaParams)
312
+ {
313
+ autoInertiaParams = _autoInertiaParams;
314
+ }
273
315
auto geomInertial =
274
316
this ->dataPtr ->geom .CalculateInertial (_errors, _config,
275
- this -> dataPtr -> density , this -> dataPtr -> autoInertiaParams );
317
+ density, autoInertiaParams);
276
318
277
319
if (!geomInertial)
278
320
{
@@ -309,6 +351,7 @@ sdf::ElementPtr Collision::Element() const
309
351
return this ->dataPtr ->sdf ;
310
352
}
311
353
354
+ // ///////////////////////////////////////////////
312
355
sdf::ElementPtr Collision::ToElement () const
313
356
{
314
357
sdf::Errors errors;
@@ -335,8 +378,11 @@ sdf::ElementPtr Collision::ToElement(sdf::Errors &_errors) const
335
378
poseElem->Set <gz::math::Pose3d>(_errors, this ->RawPose ());
336
379
337
380
// Set the density
338
- sdf::ElementPtr densityElem = elem->GetElement (" density" , _errors);
339
- densityElem->Set <double >(this ->Density ());
381
+ if (this ->dataPtr ->density .has_value ())
382
+ {
383
+ sdf::ElementPtr densityElem = elem->GetElement (" density" , _errors);
384
+ densityElem->Set <double >(this ->Density ());
385
+ }
340
386
341
387
// Set the geometry
342
388
elem->InsertElement (this ->dataPtr ->geom .ToElement (_errors), true );
0 commit comments