opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
model_mass_to_subject_mass_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
7
9
10#include <functional>
11#include <optional>
12#include <vector>
13
14namespace OpenSim { class Model; }
15
16namespace opyn
17{
18 // A `ScalingStep` that scales the masses of bodies in the model.
20 OpenSim_DECLARE_CONCRETE_OBJECT(ModelMassToSubjectMassScalingStep, ScalingStep)
21 public:
23 ScalingStep{"Scale Model Mass to Subject Mass"}
24 {
25 setDescription("Scales the masses of bodies in the model to match the subject mass, while preserving the overall mass disribution of each body in the model.");
26 }
27
28 private:
29 std::vector<ScalingStepValidationMessage> implValidate(
31 const ScalingParameters& parameters,
32 const OpenSim::Model& model) const final
33 {
34 std::vector<ScalingStepValidationMessage> messages;
35
36 if (parameters.lookup<double>("subject_mass").value_or(0.0) <= 0.0) {
37 messages.emplace_back(
39 "The subject_mass scaling parameter must be greater than zero"
40 );
41 }
42
43 if (model.getTotalMass(model.getWorkingState()) <= 0.0) {
44 messages.emplace_back(
46 "Cannot scale the model's mass to the subject's mass because the model itself has a mass of zero"
47 );
48 }
49
50 return messages;
51 }
52
53 void implForEachScalingParameterDeclaration(const std::function<void(const ScalingParameterDeclaration&)>& callback) const final
54 {
55 callback(ScalingParameterDeclaration{"blending_factor", 1.0});
56 callback(ScalingParameterDeclaration{"subject_mass", 75.0});
57 }
58
61 const ScalingParameters& parameters,
62 const OpenSim::Model&,
63 OpenSim::Model& resultModel) const final
64 {
65 const auto subjectMass = parameters.lookup<double>("subject_mass").value_or(0.0);
66 OSC_ASSERT_ALWAYS(subjectMass > 0.0 && "Subject mass must be greater than zero");
67
68 const std::optional<double> blendingFactor = parameters.lookup<double>("blending_factor");
69 OSC_ASSERT_ALWAYS(blendingFactor && "blending_factor was not set by the warping engine");
70
71 const auto effectiveTargetMass = osc::lerp(
72 resultModel.getTotalMass(resultModel.getWorkingState()),
73 subjectMass,
74 *blendingFactor
75 );
76
77 ScaleModelMassPreserveMassDistribution(resultModel, resultModel.getWorkingState(), effectiveTargetMass);
78 InitializeModel(resultModel);
79 InitializeState(resultModel);
80 }
81 };
82}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition model_mass_to_subject_mass_scaling_step.h:19
void implForEachScalingParameterDeclaration(const std::function< void(const ScalingParameterDeclaration &)> &callback) const final
Definition model_mass_to_subject_mass_scaling_step.h:53
void implApplyScalingStep(ScalingCache &, const ScalingParameters &parameters, const OpenSim::Model &, OpenSim::Model &resultModel) const final
Definition model_mass_to_subject_mass_scaling_step.h:59
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &parameters, const OpenSim::Model &model) const final
Definition model_mass_to_subject_mass_scaling_step.h:29
Definition scaling_cache.h:31
Definition scaling_parameter_declaration.h:16
Definition scaling_parameters.h:14
Definition scaling_step.h:25
Definition static_component_registries.h:3
Definition component_registry.h:14
void InitializeModel(OpenSim::Model &)
void ScaleModelMassPreserveMassDistribution(OpenSim::Model &model, const SimTK::State &state, double newMass)
SimTK::State & InitializeState(OpenSim::Model &)
constexpr auto lerp(const Rgba< T > &x, const Rgba< T > &y, TInterpolant t)
Definition rgba.h:230