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>
20namespace OpenSim {
class Model; }
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_cylinder_path, std::string,
"Absolute path (e.g. `/bodyset/body/wrap_cylinder_2`) to a `WrapCylinder` component in the model");
31 ScalingStep{
"Recalculate WrapCylinder `radius` from Station Projection onto its Midline"}
33 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.");
34 constructProperty_station_path(
"");
35 constructProperty_wrap_cylinder_path(
"");
41 const OpenSim::Model&
model)
const final
43 std::vector<ScalingStepValidationMessage> messages;
46 const auto* station = FindComponent<OpenSim::Station>(
model, get_station_path());
48 messages.emplace_back(
50 std::format(
"{}: Cannot find `station_path` in the source model (or it isn't a Station).", get_station_path())
55 const auto* wrapCylinder = FindComponent<OpenSim::WrapCylinder>(
model, get_wrap_cylinder_path());
56 if (not wrapCylinder) {
57 messages.emplace_back(
59 std::format(
"{}: Cannot find 'wrap_cylinder_path' in the source model (or it isn't a `WrapCylinder`).", get_wrap_cylinder_path())
69 const OpenSim::Model&,
70 OpenSim::Model& resultModel)
const final
72 const auto* station = FindComponent<OpenSim::Station>(resultModel, get_station_path());
74 auto* wrapCylinder = FindComponentMut<OpenSim::WrapCylinder>(resultModel, get_wrap_cylinder_path());
78 const SimTK::Transform cylinder2cylinderFrame = wrapCylinder->getTransform();
79 const SimTK::Transform cylinderFrame2ground = wrapCylinder->getFrame().getTransformInGround(resultModel.getWorkingState());
80 const SimTK::Transform ground2cylinder = (cylinderFrame2ground * cylinder2cylinderFrame).invert();
81 const SimTK::Vec3 pCylinder = ground2cylinder * station->getLocationInGround(resultModel.getWorkingState());
85 const auto newRadius = SimTK::Vec2{pCylinder[0], pCylinder[1]}.norm();
88 wrapCylinder->set_radius(newRadius);
#define OSC_ASSERT_ALWAYS(expr)
Definition assertions.h:20
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:24
std::vector< ScalingStepValidationMessage > implValidate(ScalingCache &, const ScalingParameters &, const OpenSim::Model &model) const final
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:38
void implApplyScalingStep(ScalingCache &, const ScalingParameters &, const OpenSim::Model &, OpenSim::Model &resultModel) const final
Definition recalculate_wrap_cylinder_radius_from_station_scaling_step.h:66
Definition scaling_cache.h:31
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 &)