opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
recalculate_wrap_ellipsoid_dimensions_from_station_scaling_step.h
Go to the documentation of this file.
1#pragma once
2
9
11#include <OpenSim/Simulation/Model/Station.h>
12#include <OpenSim/Simulation/Wrap/WrapEllipsoid.h>
13#include <SimTKcommon/SmallMatrix.h>
14#include <SimTKcommon/internal/Transform.h>
15
16#include <sstream>
17#include <string>
18#include <vector>
19
20namespace OpenSim { class Model; }
21
22namespace opyn
23{
26 public:
27 OpenSim_DECLARE_PROPERTY(station_path, std::string, "Absolute path (e.g. `/componentset/some_station`) to a `Station` component in the model");
28 OpenSim_DECLARE_PROPERTY(wrap_ellipsoid_path, std::string, "Absolute path (e.g. `/bodyset/body/wrap_ellipsoid`) to a `WrapEllipsoid` component in the model");
29 OpenSim_DECLARE_PROPERTY(dimensions_scale_factors, SimTK::Vec3, "A scaling factor that's multiplied by the calculated distance when calculating each dimension of the `WrapEllipsoid`");
30
32 ScalingStep{"Recalculate WrapEllipsoid `dimensions` from distance to Station"}
33 {
34 setDescription("Recalculates the 'dimensions' of a `WrapEllipsoid` component, located at `wrap_ellipsoid_path`, as the distance between the `Station`, located at `station_path`, to the `WrapEllipsoid`'s origin, scaled by `dimensions_scale_factors`.");
35 constructProperty_station_path("");
36 constructProperty_wrap_ellipsoid_path("");
37 constructProperty_dimensions_scale_factors(SimTK::Vec3{1.0});
38 }
39 private:
40 std::vector<ScalingStepValidationMessage> implValidate(
42 const ScalingParameters&,
43 const OpenSim::Model& model) const final
44 {
45 std::vector<ScalingStepValidationMessage> messages;
46
47 // Ensure `station_path` exists in the model (and is a `Station`)
48 const auto* station = FindComponent<OpenSim::Station>(model, get_station_path());
49 if (not station) {
50 std::stringstream msg;
51 msg << get_station_path() << ": Cannot find `station_path` in the source model (or it isn't a Station).";
52 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
53 }
54
55 // Ensure `wrap_ellipsoid_path` exists in the model (and is a `WrapEllipsoid`)
56 const auto* wrapEllipsoid = FindComponent<OpenSim::WrapEllipsoid>(model, get_wrap_ellipsoid_path());
57 if (not wrapEllipsoid) {
58 std::stringstream msg;
59 msg << get_wrap_ellipsoid_path() << ": Cannot find 'wrap_ellipsoid_path' in the source model (or it isn't a `WrapEllipsoid`).";
60 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
61 }
62
63 return messages;
64 }
65
68 const ScalingParameters&,
69 const OpenSim::Model&,
70 OpenSim::Model& resultModel) const final
71 {
72 const auto* station = FindComponent<OpenSim::Station>(resultModel, get_station_path());
73 OSC_ASSERT_ALWAYS(station && "could not find a station in the model");
74 auto* wrapEllipsoid = FindComponentMut<OpenSim::WrapEllipsoid>(resultModel, get_wrap_ellipsoid_path());
75 OSC_ASSERT_ALWAYS(wrapEllipsoid && "could not find a `WrapEllipsoid` in the model");
76
77 // Put the station into the `WrapEllipsoid`'s reference frame.
78 const SimTK::Transform ellipsoid2ellipsoidFrame = wrapEllipsoid->getTransform();
79 const SimTK::Transform ellipsoidFrame2ground = wrapEllipsoid->getFrame().getTransformInGround(resultModel.getWorkingState());
80 const SimTK::Transform ground2ellipsoid = (ellipsoidFrame2ground * ellipsoid2ellipsoidFrame).invert();
81 const SimTK::Vec3 stationInEllipsoid = ground2ellipsoid * station->getLocationInGround(resultModel.getWorkingState());
82
83 const auto euclidianDistanceToOrigin = stationInEllipsoid.norm();
84
85 // The new dimensions of the `WrapEllipsoid` is the multiplication of the distance to
86 // the origin and the scale factors.
87 const SimTK::Vec3 newEllipsoidDimensions = euclidianDistanceToOrigin * get_dimensions_scale_factors();
88
89 // Update the `WrapEllipsoid` accordingly and reinitialize the model.
90 wrapEllipsoid->set_dimensions(newEllipsoidDimensions);
91 InitializeModel(resultModel);
92 InitializeState(resultModel);
93 }
94 };
95}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition recalculate_wrap_ellipsoid_dimensions_from_station_scaling_step.h:24
void implApplyScalingStep(ScalingCache &, const ScalingParameters &, const OpenSim::Model &, OpenSim::Model &resultModel) const final
Definition recalculate_wrap_ellipsoid_dimensions_from_station_scaling_step.h:66
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &model) const final
Definition recalculate_wrap_ellipsoid_dimensions_from_station_scaling_step.h:40
Definition scaling_cache.h:30
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 &)
SimTK::State & InitializeState(OpenSim::Model &)