opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
recalculate_wrap_cylinder_radius_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/WrapCylinder.h>
13#include <SimTKcommon/SmallMatrix.h>
14#include <SimTKcommon/internal/Transform.h>
15
16#include <sstream>
17#include <string>
18#include <utility>
19#include <vector>
20
21namespace OpenSim { class Model; }
22
23namespace opyn
24{
27 public:
28 OpenSim_DECLARE_PROPERTY(station_path, std::string, "Absolute path (e.g. `/componentset/some_station`) to a `Station` component in the model");
29 OpenSim_DECLARE_PROPERTY(wrap_cylinder_path, std::string, "Absolute path (e.g. `/bodyset/body/wrap_cylinder_2`) to a `WrapCylinder` component in the model");
30
32 ScalingStep{"Recalculate WrapCylinder `radius` from Station Projection onto its Midline"}
33 {
34 setDescription("Recalculates the 'radius' of a `WrapCylinder` component, located at `wrap_cylinder_path`, as the distance between the `Station`, located at `station_path`, and the cylinder's (infinitely long) midline.");
35 constructProperty_station_path("");
36 constructProperty_wrap_cylinder_path("");
37 }
38 private:
39 std::vector<ScalingStepValidationMessage> implValidate(
41 const ScalingParameters&,
42 const OpenSim::Model& model) const final
43 {
44 std::vector<ScalingStepValidationMessage> messages;
45
46 // Ensure `station_path` exists in the model (and is a `Station`)
47 const auto* station = FindComponent<OpenSim::Station>(model, get_station_path());
48 if (not station) {
49 std::stringstream msg;
50 msg << get_station_path() << ": Cannot find `station_path` in the source model (or it isn't a Station).";
51 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
52 }
53
54 // Ensure `wrap_cylinder_path` exists in the model (and is a `WrapCylinder`)
55 const auto* wrapCylinder = FindComponent<OpenSim::WrapCylinder>(model, get_wrap_cylinder_path());
56 if (not wrapCylinder) {
57 std::stringstream msg;
58 msg << get_wrap_cylinder_path() << ": Cannot find 'wrap_cylinder_path' in the source model (or it isn't a `WrapCylinder`).";
59 messages.emplace_back(ScalingStepValidationState::Error, std::move(msg).str());
60 }
61
62 return messages;
63 }
64
67 const ScalingParameters&,
68 const OpenSim::Model&,
69 OpenSim::Model& resultModel) const final
70 {
71 const auto* station = FindComponent<OpenSim::Station>(resultModel, get_station_path());
72 OSC_ASSERT_ALWAYS(station && "could not find a station in the model");
73 auto* wrapCylinder = FindComponentMut<OpenSim::WrapCylinder>(resultModel, get_wrap_cylinder_path());
74 OSC_ASSERT_ALWAYS(wrapCylinder && "could not find a wrap cylinder in the model");
75
76 // Put the station into the cylinder's reference frame
77 const SimTK::Transform cylinder2cylinderFrame = wrapCylinder->getTransform();
78 const SimTK::Transform cylinderFrame2ground = wrapCylinder->getFrame().getTransformInGround(resultModel.getWorkingState());
79 const SimTK::Transform ground2cylinder = (cylinderFrame2ground * cylinder2cylinderFrame).invert();
80 const SimTK::Vec3 pCylinder = ground2cylinder * station->getLocationInGround(resultModel.getWorkingState());
81
82 // In the cylinder's frame, Z (from origin) is the centerline of the cylinder, so the easiest way to
83 // figure out the new radius is just to compute the XY norm from the origin and ignore Z.
84 const auto newRadius = SimTK::Vec2{pCylinder[0], pCylinder[1]}.norm();
85
86 // Update accordingly
87 wrapCylinder->set_radius(newRadius);
88 InitializeModel(resultModel);
89 InitializeState(resultModel);
90 }
91 };
92}
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:25
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &model) const final
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:39
void implApplyScalingStep(ScalingCache &, const ScalingParameters &, const OpenSim::Model &, OpenSim::Model &resultModel) const final
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:65
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 &)