Skip to content

Commit

Permalink
Merge pull request #3999 from opensim-org/fix_ExpressionBasedBushingF…
Browse files Browse the repository at this point in the history
…orce-double-emission-and-nan-geom

Fix issues in `OpenSim::ExpressionBasedBushingForce::generateDecorations`
  • Loading branch information
nickbianco authored Jan 27, 2025
2 parents 864c17b + 2797614 commit 5a71c60
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ v4.6
- `OpenSim::ContactHalfSpace`, `OpenSim::ContactMesh`, and `OpenSim::ContactSphere` now check their associated `Appearance`'s `is_visible` flag when deciding whether to emit their associated decorations (#3993).
- The message associated with `OpenSim::PropertyException` now includes the full absolute path to the component that threw the exception (#3987).
- Add an improved uniform sampling check for `std::vector` containers to `CommonUtilities` and use the implemented method in the `TableUtilities::filterLowpass` method (#3968, #3978).

- Several bugs in `OpenSim::ExpressionBasedBushingForce::generateDecorations` were fixed:
- It will now check for `0.0` values for `visual_aspect_ratio`, `moment_visual_scale`,
and `force_visual_scale` when emitting decorations, skipping emission where `0.0` is
found (previously: it would emit objects scaled by 0.0, causing downstream issues).
- It will only emit decorations when called with `fixed` set to `false` (previously, frame
decorations were emitted for both `true` and `false`, resulting in double-emission).
- It will now check for NaNed vectors coming from the underlying expression, skipping emission
if one is detected (previously: it would emit decorations with `NaN`ed transforms).

v4.5.1
======
Expand Down
50 changes: 31 additions & 19 deletions OpenSim/Simulation/Model/ExpressionBasedBushingForce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,16 @@ void ExpressionBasedBushingForce::generateDecorations
SimTK::Array_<SimTK::DecorativeGeometry>& geometryArray) const
{
// invoke parent class method
Super::generateDecorations(fixed, hints ,s, geometryArray);
Super::generateDecorations(fixed, hints ,s, geometryArray);

if (fixed) {
return; // the remainder of this function only emits dynamic decorations
}

if (get_visual_aspect_ratio() == 0.0) {
return; // model has explicitly zeroed the aspect ratio: the modeller's probably trying to hide the geometry
}

// draw frame1 as red
SimTK::Vec3 frame1color(1.0,0.0,0.0);
// draw frame2 as blue
Expand Down Expand Up @@ -418,7 +427,7 @@ void ExpressionBasedBushingForce::generateDecorations

// if the model is moving and the state is adequately realized,
// calculate and draw the bushing forces.
if(!fixed && (s.getSystemStage() >= Stage::Dynamics)){
if (s.getSystemStage() >= Stage::Dynamics) {
SpatialVec F_GM(Vec3(0.0), Vec3(0.0));
SpatialVec F_GF(Vec3(0.0), Vec3(0.0));

Expand All @@ -432,24 +441,27 @@ void ExpressionBasedBushingForce::generateDecorations
SimTK::Vec3 p_GM_G = frame2.getTransformInGround(s).p();

// Add moment on frame2 as line vector starting at bushing location
SimTK::Vec3 scaled_M_GM(get_moment_visual_scale()*F_GM[0]);
SimTK::Real m_length(scaled_M_GM.norm());
SimTK::Real m_radius(m_length/get_visual_aspect_ratio()/2.0);
SimTK::Transform X_m2cylinder( SimTK::Rotation( SimTK::UnitVec3(scaled_M_GM), SimTK::YAxis), p_GM_G + scaled_M_GM/2.0);
SimTK::DecorativeCylinder frame2Moment(m_radius, m_length/2.0);
frame2Moment.setTransform(X_m2cylinder);
frame2Moment.setColor(moment2color);
geometryArray.push_back(frame2Moment);
if (get_moment_visual_scale() != 0.0 && F_GM[0].normSqr() > 0.0) {
SimTK::Vec3 scaled_M_GM(get_moment_visual_scale()*F_GM[0]);
SimTK::Real m_length(scaled_M_GM.norm());
SimTK::Real m_radius(m_length/get_visual_aspect_ratio()/2.0);
SimTK::Transform X_m2cylinder( SimTK::Rotation( SimTK::UnitVec3(scaled_M_GM), SimTK::YAxis), p_GM_G + scaled_M_GM/2.0);
SimTK::DecorativeCylinder frame2Moment(m_radius, m_length/2.0);
frame2Moment.setTransform(X_m2cylinder);
frame2Moment.setColor(moment2color);
geometryArray.push_back(frame2Moment);
}

// Add force on frame2 as line vector starting at bushing location
SimTK::Vec3 scaled_F_GM(get_force_visual_scale()*F_GM[1]);
SimTK::Real f_length(scaled_F_GM.norm());
SimTK::Real f_radius(f_length/get_visual_aspect_ratio()/2.0);
SimTK::Transform X_f2cylinder( SimTK::Rotation( SimTK::UnitVec3(scaled_F_GM), SimTK::YAxis), p_GM_G + scaled_F_GM/2.0);
SimTK::DecorativeCylinder frame2Force(f_radius, f_length/2.0);
frame2Force.setTransform(X_f2cylinder);
frame2Force.setColor(force2color);

geometryArray.push_back(frame2Force);
if (get_force_visual_scale() != 0.0 && F_GM[1].normSqr() > 0.0) {
SimTK::Vec3 scaled_F_GM(get_force_visual_scale()*F_GM[1]);
SimTK::Real f_length(scaled_F_GM.norm());
SimTK::Real f_radius(f_length/get_visual_aspect_ratio()/2.0);
SimTK::Transform X_f2cylinder( SimTK::Rotation( SimTK::UnitVec3(scaled_F_GM), SimTK::YAxis), p_GM_G + scaled_F_GM/2.0);
SimTK::DecorativeCylinder frame2Force(f_radius, f_length/2.0);
frame2Force.setTransform(X_f2cylinder);
frame2Force.setColor(force2color);
geometryArray.push_back(frame2Force);
}
}
}

0 comments on commit 5a71c60

Please sign in to comment.