VariablePointMass

model VariablePointMass "Rigid body with variable mass where body rotation and inertia tensor is neglected (6 potential states)"
    import Modelica.Mechanics.MultiBody.Types;

    Modelica.Mechanics.MultiBody.Interfaces.Frame_a frame_a "Coordinate system fixed at center of mass point"
        annotation (Placement(transformation(extent = {
            {-16, -16}, 
            {16, 16}})));
    parameter Boolean animation = true "= true, if animation shall be enabled (show sphere)";
    input SI.Diameter sphereDiameter = world.defaultBodyDiameter "Diameter of sphere"
        annotation (Dialog(
            tab = "Animation",
            group = "if animation = true",
            enable = animation));
    input Types.Color sphereColor = Modelica.Mechanics.MultiBody.Types.Defaults.BodyColor "Color of sphere"
        annotation (Dialog(
            colorSelector = true,
            tab = "Animation",
            group = "if animation = true",
            enable = animation));
    input Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)"
        annotation (Dialog(
            tab = "Animation",
            group = "if animation = true",
            enable = animation));
    parameter StateSelect stateSelect = StateSelect.avoid "Priority to use frame_a.r_0, v_0 (= der(frame_a.r_0)) as states"
        annotation (Dialog(tab = "Advanced"));
    input Modelica.Blocks.Interfaces.RealInput m(unit = "kg") "Variable mass of the rigid body"
        annotation (Placement(
            visible = true,
            transformation(
                origin = {0, 80},
                extent = {
                    {-20, -20}, 
                    {20, 20}},
                rotation = -90),
            iconTransformation(
                origin = {0, 80},
                extent = {
                    {-20, -20}, 
                    {20, 20}},
                rotation = -90)));
    SI.Position r_0[3](start = {0, 0, 0}, each stateSelect = stateSelect) "Position vector from origin of world frame to origin of frame_a, resolved in world frame"
        annotation (Dialog(
            group = "Initialization",
            showStartAttribute = true));
    SI.Velocity v_0[3](start = {0, 0, 0}, each stateSelect = stateSelect) "Absolute velocity of frame_a, resolved in world frame (= der(r_0))"
        annotation (Dialog(
            group = "Initialization",
            showStartAttribute = true));
    SI.Acceleration a_0[3](start = {0, 0, 0}) "Absolute acceleration of frame_a resolved in world frame (= der(v_0))"
        annotation (Dialog(
            group = "Initialization",
            showStartAttribute = true));
protected
    outer Modelica.Mechanics.MultiBody.World world;
    Modelica.Mechanics.MultiBody.Visualizers.Advanced.Shape sphere(shapeType = "sphere", color = sphereColor, specularCoefficient = specularCoefficient, length = sphereDiameter, width = sphereDiameter, height = sphereDiameter, lengthDirection = {1, 0, 0}, widthDirection = {0, 1, 0}, r_shape = -0.5 * ({1, 0, 0} * sphereDiameter), r = frame_a.r_0, R = frame_a.R) if world.enableAnimation and animation;
equation
    if Connections.isRoot(frame_a.R) then 
        assert(cardinality(frame_a) == 0, "\n                    A Modelica.Mechanics.MultiBody.Parts.PointMass model is connected in\n                    a way, so that no equations are present to compute frame_a.R\n                    (the orientation object in the connector). Setting frame_a.R to\n                    an arbitrary value in the PointMass model, might lead to a wrong\n                    overall model, depending on how the PointMass model is used.\n                       You can avoid this message, by providing equations that\n                    compute the orientation object, e.g., by using the\n                    Modelica.Mechanics.MultiBody.Joints.FreeMotion joint.\n                       If a PointMass model is not connected at all, the\n                    orientation object is set to a unit rotation. But this is\n                    the only case where this is done.");
        frame_a.R = Modelica.Mechanics.MultiBody.Frames.nullRotation();
    else 
        frame_a.t = zeros(3);
    end if;
    Connections.potentialRoot(frame_a.R, 10000);
    a_0 = der(v_0);
    r_0 = frame_a.r_0;
    v_0 = der(r_0);
    frame_a.f = m * Modelica.Mechanics.MultiBody.Frames.resolve2(frame_a.R, a_0 - world.gravityAcceleration(r_0));

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Ellipse(
                    lineColor = {0, 24, 48},
                    fillColor = {0, 127, 255},
                    fillPattern = FillPattern.Sphere,
                    extent = {
                        {-50, 50}, 
                        {50, -50}})}),
        Documentation(info = "<html>\n                <p>\n                <strong>Rigid body</strong> where the inertia tensor is neglected.\n                This body is\n                solely defined by its mass.\n                By default, this component is visualized by a <strong>sphere</strong> that has\n                its center at frame_a. Note, that\n                the animation may be switched off via parameter animation = <strong>false</strong>.\n                </p>\n\n                <p>\n                Every PointMass has potential states. If possible a tool will select\n                the states of joints and not the states of PointMass because this is\n                usually the most efficient choice. In this case the position and\n                velocity of frame_a of the body will be computed\n                by the component that is connected to frame_a. However, if a PointMass is moving\n                freely in space, variables of the PointMass have to be used as states. The potential\n                states are: The <strong>position vector</strong> frame_a.r_0 from the origin of the\n                world frame to the origin of frame_a of the body, resolved in\n                the world frame and the <strong>absolute velocity</strong> v_0 of the origin of\n                frame_a, resolved in the world frame (= der(frame_a.r_0)).\n                </p>\n\n                <p>\n                Whether or not variables of the body are used as states is usually\n                automatically selected by the Modelica translator. If parameter\n                <strong>enforceStates</strong> is set to <strong>true</strong> in the \"Advanced\" menu,\n                then PointMass variables frame_a.r_0 and der(frame_a.r_0)\n                are forced to be used as states.\n                </p>\n                </html>"));
end VariablePointMass;