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 <sstream>
13#include <utility>
14#include <vector>
15
16namespace OpenSim { class Model; }
17
18namespace opyn
19{
20 // A `ScalingStep` that scales the masses of bodies in the model.
22 OpenSim_DECLARE_CONCRETE_OBJECT(ModelMassToSubjectMassScalingStep, ScalingStep)
23 public:
25 ScalingStep{"Scale Model Mass to Subject Mass"}
26 {
27 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.");
28 }
29
30 private:
31 std::vector<ScalingStepValidationMessage> implValidate(
33 const ScalingParameters& parameters,
34 const OpenSim::Model& model) const final
35 {
36 std::vector<ScalingStepValidationMessage> messages;
37
38 if (parameters.lookup<double>("subject_mass").value_or(0.0) <= 0.0) {
39 std::stringstream msg;
40 msg << "The subject_mass scaling parameter must be greater than zero";
41 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
42 }
43
44 if (model.getTotalMass(model.getWorkingState()) <= 0.0) {
45 std::stringstream msg;
46 msg << "Cannot scale the model's mass to the subject's mass because the model itself has a mass of zero";
47 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
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:21
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:31
Definition scaling_cache.h:30
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