Torque

model Torque "Torque acting between two frames, defined by 3 input signals and resolved in frame world, frame_a, frame_b or frame_resolve"
    import Modelica.SIunits.Conversions.to_unit1;

    extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames;

    Interfaces.Frame_resolve frame_resolve if resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_resolve "The input signals are optionally resolved in this frame"
        annotation (Placement(transformation(
            origin = {40, 100},
            extent = {
                {-16, -16}, 
                {16, 16}},
            rotation = 90)));
    Modelica.Blocks.Interfaces.RealInput torque[3](each final quantity = "Torque", each final unit = "N.m") "x-, y-, z-coordinates of torque resolved in frame defined by resolveInFrame"
        annotation (Placement(transformation(
            origin = {-60, 120},
            extent = {
                {-20, -20}, 
                {20, 20}},
            rotation = 270)));
    parameter Boolean animation = true "= true, if animation shall be enabled";
    parameter Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB resolveInFrame = Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_b "Frame in which input force is resolved (1: world, 2: frame_a, 3: frame_b, 4: frame_resolve)";
    parameter Real Nm_to_m(unit = "N.m/m") = world.defaultNm_to_m "Torque arrow scaling (length = torque/Nm_to_m)"
        annotation (Dialog(
            group = "if animation = true",
            enable = animation));
    input SI.Diameter torqueDiameter = world.defaultArrowDiameter "Diameter of torque arrow"
        annotation (Dialog(
            group = "if animation = true",
            enable = animation));
    input SI.Diameter connectionLineDiameter = torqueDiameter "Diameter of line connecting frame_a and frame_b"
        annotation (Dialog(
            group = "if animation = true",
            enable = animation));
    input Types.Color torqueColor = Modelica.Mechanics.MultiBody.Types.Defaults.TorqueColor "Color of torque arrow"
        annotation (Dialog(
            colorSelector = true,
            group = "if animation = true",
            enable = animation));
    input Types.Color connectionLineColor = Modelica.Mechanics.MultiBody.Types.Defaults.SensorColor "Color of line connecting frame_a and frame_b"
        annotation (Dialog(
            colorSelector = true,
            group = "if animation = true",
            enable = animation));
    input Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)"
        annotation (Dialog(
            group = "if animation = true",
            enable = animation));
protected
    SI.Position t_in_m[3] = frame_b.t / Nm_to_m "Torque mapped from Nm to m for animation";
    Visualizers.Advanced.DoubleArrow torqueArrow(diameter = torqueDiameter, color = torqueColor, specularCoefficient = specularCoefficient, R = frame_b.R, r = frame_b.r_0, r_tail = t_in_m, r_head = -t_in_m) if world.enableAnimation and animation;
    Visualizers.Advanced.Shape connectionLine(shapeType = "cylinder", lengthDirection = to_unit1(basicTorque.r_0), widthDirection = {0, 1, 0}, length = Modelica.Math.Vectors.length(basicTorque.r_0), width = connectionLineDiameter, height = connectionLineDiameter, color = connectionLineColor, specularCoefficient = specularCoefficient, r = frame_a.r_0) if world.enableAnimation and animation;
public
    Internal.BasicTorque basicTorque(resolveInFrame = resolveInFrame) annotation (Placement(transformation(extent = {
        {-8, -10}, 
        {12, 10}})));
protected
    Interfaces.ZeroPosition zeroPosition if not resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_resolve annotation (Placement(transformation(extent = {
        {34, 10}, 
        {54, 30}})));
equation
    connect(basicTorque.frame_a,frame_a) annotation (Line(
        points = {
            {-8, 0}, 
            {-100, 0}},
        color = {95, 95, 95},
        thickness = 0.5));
    connect(basicTorque.frame_b,frame_b) annotation (Line(
        points = {
            {12, 0}, 
            {100, 0}},
        color = {95, 95, 95},
        thickness = 0.5));
    connect(basicTorque.torque,torque) annotation (Line(
        points = {
            {-4, 12}, 
            {-4, 60}, 
            {-60, 60}, 
            {-60, 120}},
        color = {0, 0, 127}));
    connect(basicTorque.frame_resolve,frame_resolve) annotation (Line(
        points = {
            {6, 10}, 
            {6, 60}, 
            {40, 60}, 
            {40, 100}},
        color = {95, 95, 95},
        pattern = LinePattern.Dot));
    connect(zeroPosition.frame_resolve,basicTorque.frame_resolve) annotation (Line(
        points = {
            {34, 20}, 
            {20, 20}, 
            {20, 10}, 
            {6, 10}},
        color = {95, 95, 95},
        pattern = LinePattern.Dot));

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Rectangle(
                    extent = {
                        {-98, 99}, 
                        {99, -98}},
                    lineColor = {255, 255, 255},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-59, 55}, 
                        {72, 30}},
                    lineColor = {192, 192, 192},
                    textString = "resolve"), 
                Text(
                    extent = {
                        {-150, -30}, 
                        {150, -70}},
                    textString = "%name",
                    lineColor = {0, 0, 255}), 
                Polygon(
                    points = {
                        {100, 20}, 
                        {84, 52}, 
                        {69, 39}, 
                        {100, 20}},
                    fillPattern = FillPattern.Solid), 
                Line(
                    points = {
                        {40, 100}, 
                        {76, 46}},
                    color = {95, 95, 95},
                    pattern = LinePattern.Dot), 
                Polygon(
                    points = {
                        {-99, 20}, 
                        {-86, 53}, 
                        {-70, 42}, 
                        {-99, 20}},
                    fillPattern = FillPattern.Solid), 
                Line(
                    points = {
                        {-60, 100}, 
                        {40, 100}},
                    color = {95, 95, 95},
                    pattern = LinePattern.Dot), 
                Line(points = {
                    {-79, 47}, 
                    {-70, 61}, 
                    {-59, 72}, 
                    {-45, 81}, 
                    {-32, 84}, 
                    {-20, 85}}), 
                Line(points = {
                    {77, 45}, 
                    {66, 60}, 
                    {55, 69}, 
                    {49, 74}, 
                    {41, 80}, 
                    {31, 84}, 
                    {20, 85}})}),
        Documentation(info = "<html>\n<p>\nThe <strong>3</strong> signals of the <strong>torque</strong> connector are interpreted\nas the x-, y- and z-coordinates of a <strong>torque</strong> acting at the frame\nconnector to which frame_b of this component is attached.\nVia parameter <strong>resolveInFrame</strong> it is defined, in which frame these\ncoordinates shall be resolved:\n</p>\n\n<table border=1 cellspacing=0 cellpadding=2>\n<tr><th><strong>Types.ResolveInFrameAB.</strong></th><th><strong>Meaning</strong></th></tr>\n<tr><td>world</td>\n    <td>Resolve input torque in world frame</td></tr>\n\n<tr><td>frame_a</td>\n    <td>Resolve input torque in frame_a</td></tr>\n\n<tr><td>frame_b</td>\n    <td>Resolve input torque in frame_b (= default)</td></tr>\n\n<tr><td>frame_resolve</td>\n    <td>Resolve input torque in frame_resolve (frame_resolve must be connected)</td></tr>\n</table>\n\n<p>\nIf resolveInFrame = ResolveInFrameAB.frame_resolve, the torque coordinates\nare with respect to the frame, that is connected to <strong>frame_resolve</strong>.\n</p>\n\n<p>\nIf torque={100,0,0}, and for all parameters the default setting is used,\nthen the interpretation is that a torque of 100 N.m is acting along the positive\nx-axis of frame_b.\n</p>\n\n<p>\nNote, the cut-forces in frame_a and frame_b (frame_a.f, frame_b.f) are\nalways set to zero and the cut-torque at frame_a (frame_a.t) is the same\nas the cut-torque at frame_b (frame_b.t) but with opposite sign.\n</p>\n\n<p>\nAn example how to use this model is given in the\nfollowing figure:\n</p>\n\n<p>\n<img src=\"modelica://Modelica/Resources/Images/Mechanics/MultiBody/Forces/Torque1.png\">\n</p>\n\n<p>\nThis leads to the following animation (the yellow cylinder\ncharacterizes the line between frame_a and frame_b of the\nTorque component, i.e., the torque acts with negative sign\nalso on the opposite side of this cylinder, but for\nclarity this is not shown in the animation):\n</p>\n\n<p>\n<img src=\"modelica://Modelica/Resources/Images/Mechanics/MultiBody/Forces/Torque2.png\">\n</p>\n\n</html>"));
end Torque;