opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
thin_plate_spline_body_center_of_mass_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
9
11#include <OpenSim/Simulation/SimbodyEngine/Body.h>
12#include <SimTKcommon/SmallMatrix.h>
13
14#include <sstream>
15#include <string>
16#include <vector>
17
18namespace OpenSim { class Model; }
19
20namespace opyn
21{
22 // A `ScalingStep` that applies the Thin-Plate Spline (TPS) warp the centers
23 // of mass of the given bodies (opensim-creator#1147).
26
27 OpenSim_DECLARE_LIST_PROPERTY(bodies, std::string, "Query paths (e.g. `/bodyset/*`) that the engine should use to find bodies in the source model that should be warped by this scaling step.");
28
29 public:
31 ToggleableThinPlateSplineScalingStep{"Apply Thin-Plate Spline (TPS) to Body Centers of Mass"}
32 {
33 setDescription("Warps the locations of body centers of mass in the model using the Thin-Plate Spline (TPS) warping algorithm.");
34 constructProperty_bodies();
35 }
36 private:
37 std::vector<ScalingStepValidationMessage> implValidate(
38 ScalingCache& cache,
39 const ScalingParameters& params,
40 const OpenSim::Model& sourceModel) const final
41 {
42 // Get base class validation messages.
43 auto messages = ToggleableThinPlateSplineScalingStep::implValidate(cache, params, sourceModel);
44
45 // Ensure every entry in `bodies` can be found in the source model.
46 for (int i = 0; i < getProperty_bodies().size(); ++i) {
47 if (not FindComponent<OpenSim::Body>(sourceModel, get_bodies(i))) {
48 std::stringstream msg;
49 msg << get_bodies(i) << ": Cannot find a Body in 'bodies' in the source model (or it isn't a Body)";
50 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
51 }
52 }
53
54 return messages;
55 }
56
58 ScalingCache& scalingCache,
59 const ScalingParameters& parameters,
60 const OpenSim::Model& sourceModel,
61 OpenSim::Model& resultModel) const final
62 {
63 const auto commonParams = calcTPSScalingStepCommonParams(parameters, sourceModel, resultModel);
64
65 // Warp each specified center of mass, ensuring that the CoM is correctly
66 // transformed into the TPS warp's coordinate system.
67 for (int i = 0; i < getProperty_bodies().size(); ++i) {
68
69 // Find the CoM in the source model.
70 const auto* sourceBody = FindComponent<OpenSim::Body>(sourceModel, get_bodies(i));
71 OSC_ASSERT_ALWAYS(sourceBody && "could not find a body in the source model");
72
73 // Find the CoM in the result model (i.e. the one that's midway through warping).
74 const auto* resultBody = FindComponent<OpenSim::Body>(resultModel, get_bodies(i));
75 OSC_ASSERT_ALWAYS(resultBody && "could not find a body in the result model");
76
77 // Warp the CoM, while accounting for different frames etc. between the TPS
78 // landmarks and the CoM.
79 const SimTK::Vec3 warpedLocation = scalingCache.lookupTPSWarpedRigidPoint(
80 sourceModel,
81 resultModel,
82 sourceBody->get_mass_center(),
83 resultBody->get_mass_center(),
84 *sourceBody,
85 *resultBody,
86 *commonParams.sourceLandmarksFrame,
87 *commonParams.resultLandmarksFrame,
88 commonParams.tpsInputs,
89 commonParams.compensateForFrameChanges
90 );
91
92 // Update the body with the new CoM
93 auto* resultBodyMut = FindComponentMut<OpenSim::Body>(resultModel, get_bodies(i));
94 OSC_ASSERT_ALWAYS(resultBodyMut && "could not find a corresponding body in the result model");
95 resultBodyMut->set_mass_center(warpedLocation);
96 }
97 InitializeModel(resultModel);
98 InitializeState(resultModel);
99 }
100 };
101}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition scaling_cache.h:30
SimTK::Vec3 lookupTPSWarpedRigidPoint(const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel, const SimTK::Vec3 &sourceLocation, const SimTK::Vec3 &resultLocation, const OpenSim::Frame &sourceParentFrame, const OpenSim::Frame &resultParentFrame, const OpenSim::Frame &sourceLandmarksFrame, const OpenSim::Frame &resultLandmarksFrame, const ThinPlateSplineCommonInputs &tpsInputs, bool compensateForFrameChanges)
Definition scaling_cache.h:82
Definition scaling_parameters.h:14
virtual std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &) const
Definition scaling_step.h:92
virtual void implApplyScalingStep(ScalingCache &, const ScalingParameters &, const OpenSim::Model &, OpenSim::Model &) const
Definition scaling_step.h:103
Definition thin_plate_spline_body_center_of_mass_scaling_step.h:24
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &sourceModel) const override
Definition thin_plate_spline_scaling_step.h:71
Definition toggleable_thin_plate_spline_scaling_step.h:14
CommonParameters calcTPSScalingStepCommonParams(const ScalingParameters &parameters, const OpenSim::Model &sourceModel, const OpenSim::Model &resultModel) const
Definition toggleable_thin_plate_spline_scaling_step.h:32
Definition static_component_registries.h:3
Definition component_registry.h:14
void InitializeModel(OpenSim::Model &)
SimTK::State & InitializeState(OpenSim::Model &)