model RelativeForce "Input signal acting as force and torque on two frames"
extends PlanarMechanics.Interfaces.PartialTwoFrames;
parameter Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB resolveInFrame = Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_a "Frame in which output vector r_rel shall be resolved (1: world, 2: frame_a, 3: frame_b, 4: frame_resolve)";
parameter Boolean animation = true "= true, if animation shall be enabled";
parameter Real N_to_m(unit = "N/m") = planarWorld.defaultN_to_m "Force arrow scaling (length = force/N_to_m)"
annotation (Dialog(
tab = "Animation",
group = "If animation = true",
enable = animation));
parameter Real Nm_to_m(unit = "N.m/m") = planarWorld.defaultNm_to_m "Torque arrow scaling (length = torque/Nm_to_m)"
annotation (Dialog(
tab = "Animation",
group = "If animation = true",
enable = animation));
input SI.Diameter diameter = planarWorld.defaultArrowDiameter "Has no longer an effect and is only kept for backwards compatibility (arrow visualization by Vector now)"
annotation (Dialog(
tab = "Animation",
group = "If animation = true",
enable = animation));
parameter SI.Length zPosition = planarWorld.defaultZPosition "Position z of cylinder representing the fixed translation"
annotation (Dialog(
tab = "Animation",
group = "If animation = true",
enable = animation));
input MB.Types.Color color = PlanarMechanics.Types.Defaults.ForceColor "Color of arrow"
annotation (
HideResult = true,
Dialog(
tab = "Animation",
group = "If animation = true",
colorSelector = true,
enable = animation));
input MB.Types.SpecularCoefficient specularCoefficient = planarWorld.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)"
annotation (
HideResult = true,
Dialog(
tab = "Animation",
group = "If animation = true",
enable = animation));
Modelica.Blocks.Interfaces.RealInput force[3] annotation (Placement(transformation(
extent = {
{-20, -20},
{20, 20}},
origin = {-60, -120},
rotation = 90)));
Real R[2,2] "Rotation matrix";
SI.Angle phi "Rotation angle of the additional frame_c";
Interfaces.Frame_resolve frame_resolve(fx = 0, fy = 0, t = 0, phi = phi) if resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_resolve "Coordinate system in which vector is optionally resolved, if useExtraFrame is true"
annotation (Placement(transformation(
extent = {
{-16, -16},
{16, 16}},
rotation = 90,
origin = {40, -100})));
protected
SI.Position f_in_m[3] = {force[1], force[2], 0} / N_to_m "Force mapped from N to m for animation";
SI.Position t_in_m[3] = {0, 0, force[3]} / Nm_to_m "Torque mapped from N.m to m for animation";
MB.Frames.Orientation R_0 = MB.Frames.absoluteRotation(planarWorld.R, MB.Frames.planarRotation({0, 0, 1}, phi, der(phi)));
SI.Position rvisobj[3] = MB.Frames.resolve1(planarWorld.R, {frame_b.x, frame_b.y, zPosition}) + planarWorld.r_0;
MB.Visualizers.Advanced.Vector arrowForce(coordinates = f_in_m, color = color, specularCoefficient = specularCoefficient, r = rvisobj, quantity = Modelica.Mechanics.MultiBody.Types.VectorQuantity.Force, headAtOrigin = true, R = R_0) if planarWorld.enableAnimation and animation;
MB.Visualizers.Advanced.Vector arrowTorque(coordinates = t_in_m, color = color, specularCoefficient = specularCoefficient, r = rvisobj, quantity = Modelica.Mechanics.MultiBody.Types.VectorQuantity.Torque, headAtOrigin = true, R = planarWorld.R) if planarWorld.enableAnimation and animation;
equation
if resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_a then
phi = frame_a.phi;
elseif resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_b then
phi = frame_b.phi;
elseif resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.world then
phi = 0;
end if;
frame_a.t + frame_b.t = 0;
frame_a.fx + frame_b.fx = 0;
frame_a.fy + frame_b.fy = 0;
frame_b.t + force[3] = 0;
{frame_b.fx, frame_b.fy} + R * {force[1], force[2]} = {0, 0};
R = {{cos(phi), -sin(phi)}, {sin(phi), cos(phi)}};
annotation (
Icon(
coordinateSystem(
preserveAspectRatio = false,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(
points = {
{30, 0},
{30, -100}},
color = {95, 95, 95},
pattern = LinePattern.Dot),
Line(
points = {
{-60, -100},
{30, -100}},
color = {95, 95, 95},
pattern = LinePattern.Dot),
Polygon(
points = {
{14, 10},
{44, 10},
{44, 40},
{94, 0},
{44, -40},
{44, -10},
{14, -10},
{14, 10}},
lineColor = {0, 127, 0},
fillColor = {215, 215, 215},
fillPattern = FillPattern.Solid),
Polygon(
points = {
{-14, 10},
{-44, 10},
{-44, 40},
{-94, 0},
{-44, -40},
{-44, -10},
{-14, -10},
{-14, 10}},
lineColor = {0, 127, 0},
fillColor = {215, 215, 215},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-150, 110},
{150, 70}},
textString = "%name",
textColor = {0, 0, 255}),
Text(
extent = {
{-108, -24},
{-72, -49}},
textColor = {128, 128, 128},
textString = "a"),
Text(
extent = {
{72, -24},
{108, -49}},
textColor = {128, 128, 128},
textString = "b")}),
Documentation(
info = "<html>\n<p>\nThe <strong>3</strong> signals of the <strong>force</strong> connector contain force and torque.\nThe first and second signal are interpreted as the x- and y-coordinates of\na <strong>force</strong> and the third is torque, acting between two frame connectors\nto which <code>frame_a</code> and <code>frame_b</code> are attached respectively.\nNote that torque is a scalar quantity, which is exerted perpendicular\nto the x-y plane.\n</p>\n<p>\nParameter <code><strong>resolveInFrame</strong></code> defines in which frame the input\nforce shall be resolved.\n</p>\n\n<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n<tr>\n<th>Types.ResolveInFrameB.</th>\n<th>Meaning</th>\n</tr>\n<tr>\n<td valign=\"top\">world</td>\n<td valign=\"top\">Resolve input force in world frame (= default)</td>\n</tr>\n<tr>\n<td valign=\"top\">frame_a</td>\n<td valign=\"top\">Resolve input force in frame_a</td>\n</tr>\n<tr>\n<td valign=\"top\">frame_b</td>\n<td valign=\"top\">Resolve input force in frame_b</td>\n</tr>\n<tr>\n<td valign=\"top\">frame_resolve</td>\n<td valign=\"top\">Resolve input force in frame_resolve (frame_resolve must be connected)</td>\n</tr>\n</table>\n\n<p>\nIf resolveInFrame = Types.ResolveInFrameAB.frame_resolve,\nthe force coordinates shall be resolved in the frame, which is\nconnected to <strong>frame_resolve</strong>.\n</p>\n</html>",
revisions = "<html>\n<p>\n<img src=\"modelica://PlanarMechanics/Resources/Images/dlr_logo.png\" alt=\"DLR logo\">\n<strong>Developed 2010 at the DLR Institute of System Dynamics and Control</strong>\n</p>\n</html>"));
end RelativeForce;