Demonstrate line force with two point masses using a JointUPS and alternatively a LineForceWithTwoMasses component. It is demonstrated how to implement line force components
that shall have mass properties. Two alternative implementations
are given:

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model LineForceWithTwoMasses
  "Demonstrate line force with two point masses using a JointUPS and alternatively a LineForceWithTwoMasses component"
  extends Modelica.Icons.Example;
  parameter SI.Mass m=1 "Mass of point masses";
  SI.Force rod_f_diff[3]=rod1.frame_b.f - rod3.frame_b.f
    "Difference of cut-forces in rod1 and rod3";
  SI.Force body_f_diff[3]=bodyBox1.frame_b.f - bodyBox2.frame_b.f
    "Difference of cut-forces in bodyBox1 and bodyBox2";

  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute1(phi(fixed=true), w(
        fixed=true))
  Modelica.Mechanics.MultiBody.Parts.BodyBox bodyBox1(r={0.7,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod1(
    r={0,-0.9,0},
    width=0.01,
    animation=false)
  Modelica.Mechanics.MultiBody.Joints.Assemblies.JointUPS jointUPS(nAxis_ia={0.7,1.2,0}, animation=
       true)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    r_CM=0.2*jointUPS.eAxis_ia,
    cylinderDiameter=0.05,
    animation=true,
    m=m,
    I_11=0,
    I_22=0,
    I_33=0)
  Modelica.Mechanics.MultiBody.Parts.Body body2(
    r_CM=-0.2*jointUPS.eAxis_ia,
    cylinderDiameter=0.05,
    animation=true,
    m=m,
    I_11=0,
    I_22=0,
    I_33=0)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod2(
    r={0,0.3,0},
    width=0.01,
    animation=false)
  Modelica.Mechanics.Translational.Components.Damper damper1(
                                                  d=3)
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute2(phi(fixed=true), w(
        fixed=true))
  Modelica.Mechanics.MultiBody.Parts.BodyBox bodyBox2(r={0.7,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod3(
    width=0.01,
    r={0,-0.9,0.3},
    animation=false)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod4(
    width=0.01,
    r={0,0.3,0.3},
    animation=false)
  Modelica.Mechanics.Translational.Components.Damper damper2(
                                                  d=3)
  Modelica.Mechanics.MultiBody.Forces.LineForceWithTwoMasses
    lineForceWithTwoMasses(
    L_a=0.2,
    L_b=0.2,
    cylinderLength_a=0.2,
    cylinderLength_b=1.2,
    massDiameterFaction=2.2,
    m_a=m,
    m_b=m)
equation
  connect(jointUPS.bearing, damper1.flange_a)
  connect(jointUPS.axis, damper1.flange_b)
  connect(jointUPS.frame_ib, body2.frame_a)
  connect(world.frame_b, rod2.frame_a)
  connect(world.frame_b, rod1.frame_a)
  connect(rod2.frame_b, revolute1.frame_a)
  connect(revolute1.frame_b, bodyBox1.frame_a)
  connect(bodyBox1.frame_b, jointUPS.frame_b)
  connect(body1.frame_a, jointUPS.frame_ia)
  connect(rod1.frame_b, jointUPS.frame_a)
  connect(rod4.frame_b, revolute2.frame_a)
  connect(revolute2.frame_b, bodyBox2.frame_a)
  connect(world.frame_b, rod4.frame_a)
  connect(rod3.frame_a, rod4.frame_a)
  connect(lineForceWithTwoMasses.frame_a, rod3.frame_b)
  connect(lineForceWithTwoMasses.frame_b, bodyBox2.frame_b)
  connect(lineForceWithTwoMasses.flange_b, damper2.flange_b)
  connect(lineForceWithTwoMasses.flange_a, damper2.flange_a)
end LineForceWithTwoMasses;


within Modelica.Mechanics.MultiBody.Examples;
package Elementary "Elementary examples to demonstrate various features of the MultiBody library"
  extends Modelica.Icons.ExamplesPackage;
end Elementary;


Simple pendulum with one revolute joint and one body. This simple model demonstrates that by just dragging components
default animation is defined that shows the structure of the
assembled system.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model Pendulum "Simple pendulum with one revolute joint and one body"
  extends Modelica.Icons.Example;
  inner Modelica.Mechanics.MultiBody.World world(gravityType=Modelica.Mechanics.MultiBody.Types.GravityTypes.
        UniformGravity)
  Modelica.Mechanics.MultiBody.Joints.Revolute rev(n={0,0,1},useAxisFlange=true,
    phi(fixed=true),
    w(fixed=true))
  Modelica.Mechanics.Rotational.Components.Damper damper(
                                              d=0.1)
  Modelica.Mechanics.MultiBody.Parts.Body body(m=1.0, r_CM={0.5,0,0})
equation
  connect(world.frame_b, rev.frame_a)
  connect(damper.flange_b, rev.axis)
  connect(rev.support, damper.flange_a)
  connect(body.frame_a, rev.frame_b)
end Pendulum;


Simple spring/damper/mass system. A body is attached on a revolute and prismatic joint.
A 3-dim. spring and a 3-dim. damper are connected between the body
and a point fixed in the world frame:

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model PendulumWithSpringDamper "Simple spring/damper/mass system"
  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  inner Modelica.Mechanics.MultiBody.World world(axisLength=0.6)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    m=1,
    animation=animation,
    I_11=1,
    I_22=1,
    I_33=1,
    r_CM={0,0,0},
    cylinderDiameter=0.05,
    sphereDiameter=0.2)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar1(animation=animation, r={0.3,0,0})
  Modelica.Mechanics.MultiBody.Forces.Spring spring1(
    coilWidth=0.01,
    numberOfWindings=5,
    c=20,
    s_unstretched=0.2)
  Modelica.Mechanics.MultiBody.Forces.Damper damper1(
    d=1,
    length_a=0.1,
    diameter_a=0.08,
    animation=false)
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute(phi(fixed=true), w(
        fixed=true))
  Modelica.Mechanics.MultiBody.Joints.Prismatic prismatic(
    boxWidth=0.04,
    boxColor={255,65,65},
    s(fixed=true, start=0.5),
    v(fixed=true))
equation
  connect(world.frame_b, bar1.frame_a)
  connect(revolute.frame_a, bar1.frame_b)
  connect(prismatic.frame_a, revolute.frame_b)
  connect(damper1.frame_a, bar1.frame_b)
  connect(damper1.frame_b, prismatic.frame_b)
  connect(spring1.frame_a, bar1.frame_b)
  connect(spring1.frame_b, prismatic.frame_b)
  connect(body1.frame_a, prismatic.frame_b)
end PendulumWithSpringDamper;


Two point masses in a point gravity field. This model demonstrates a point gravity field. Two bodies
are placed in the gravity field. The initial positions and velocities of
these bodies are selected such that one body rotates on a circle and
the other body rotates on an ellipse around the center of the
point gravity field.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model PointGravity "Two point masses in a point gravity field"
  extends Modelica.Icons.Example;
  inner Modelica.Mechanics.MultiBody.World world(
    mu=1,
    gravitySphereDiameter=0.1,
    gravityType=Modelica.Mechanics.MultiBody.Types.GravityTypes.PointGravity)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    m=1,
    sphereDiameter=0.1,
    I_11=0.1,
    I_22=0.1,
    I_33=0.1,
    r_0(start={0,0.6,0}, each fixed=true),
    v_0(start={1,0,0}, each fixed=true),
    angles_fixed=true,
    w_0_fixed=true,
    r_CM={0,0,0})
  Modelica.Mechanics.MultiBody.Parts.Body body2(
    m=1,
    sphereDiameter=0.1,
    I_11=0.1,
    I_22=0.1,
    I_33=0.1,
    r_0(start={0.6,0.6,0}, each fixed=true),
    v_0(start={0.6,0,0}, each fixed=true),
    angles_fixed=true,
    w_0_fixed=true,
    r_CM={0,0,0})
end PointGravity;


Two point masses in a point gravity field (rotation of bodies is neglected). This model demonstrates the usage of model Parts.PointMass in a
point gravity field. The PointMass model has the feature that
the rotation is not taken into account and can therefore also not be
calculated. This example demonstrates two cases where this does not matter:
If a PointMass is not connected (body1, body2), the orientation object in
these point masses is set to a unit rotation.
If a PointMass is connected by a line force element, such as
the used Forces.LineForceWithMass component, then the orientation object
is set to a unit rotation within the line force element.
These are the two cases where the rotation is automatically set to
a default value, when the physical system does not provide the equations.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model PointGravityWithPointMasses
  "Two point masses in a point gravity field (rotation of bodies is neglected)"
  extends Modelica.Icons.Example;
  inner Modelica.Mechanics.MultiBody.World world(
    mu=1,
    gravitySphereDiameter=0.1,
    gravityType=Modelica.Mechanics.MultiBody.Types.GravityTypes.PointGravity)
  Modelica.Mechanics.MultiBody.Parts.PointMass body1(
    m=1,
    sphereDiameter=0.1,
    r_0(start={0,0.6,0}, each fixed=true),
    v_0(start={1,0,0}, each fixed=true))
  Modelica.Mechanics.MultiBody.Parts.PointMass body2(
    m=1,
    sphereDiameter=0.1,
    r_0(start={0.6,0.6,0}, each fixed=true),
    v_0(start={0.6,0,0}, each fixed=true))
  Modelica.Mechanics.MultiBody.Parts.PointMass body3(
    m=1,
    sphereDiameter=0.1,
    r_0(start={0,0.8,0}, each fixed=true),
    v_0(start={0.6,0,0}, each fixed=true))
  Modelica.Mechanics.MultiBody.Parts.PointMass body4(
    m=1,
    sphereDiameter=0.1,
    r_0(start={0.3,0.8,0}, each fixed=true),
    v_0(start={0.6,0,0}, each fixed=true))
  Forces.Spring spring(showMass=false, c=10,
    fixedRotationAtFrame_b=true,
    fixedRotationAtFrame_a=true)
equation

  connect(spring.frame_a, body3.frame_a)
  connect(spring.frame_b, body4.frame_a)
end PointGravityWithPointMasses;


Rigidly connected point masses in a point gravity field. Point mass used at all places in this example (has a mass  of 1 kg and a blue color)

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model PointGravityWithPointMasses2
  "Rigidly connected point masses in a point gravity field"
  extends Modelica.Icons.Example;
  model PointMass = Modelica.Mechanics.MultiBody.Parts.PointMass (
    m=1, sphereColor={255,0,0}) "Point mass used at all places of this example"

  PointMass pointMass1(
    r_0(start={3,0,0}, each fixed=true),
    v_0(start={0,0,-1}, each fixed=true))
  PointMass pointMass2
  PointMass pointMass3(
    r_0(start={2,1,0}, fixed={true,false,false}),
    v_0(start={0,0,-1}, fixed={true,false,false}))
  PointMass pointMass4(
    r_0(start={2,-1,0}, fixed={false,false,true}),
    v_0(start={0,0,-1}, fixed={false,false,true}))
  PointMass pointMass5(
    r_0(start={2,0,1}, fixed={false,false,true}),
    v_0(start={0,0,-1}, fixed={false,false,true}))
  PointMass pointMass6

  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation(r={1,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation1(r={-1,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation2(r={0,1,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation3(r={0,-1,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation4(r={0,0,1})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation5(r={0,0,-1})
  inner World world(
    gravitySphereDiameter=0.1,
    gravityType=Modelica.Mechanics.MultiBody.Types.GravityTypes.PointGravity,
    mu=5)
  Joints.FreeMotion freeMotion
  SystemWithStandardBodies referenceSystem

  model SystemWithStandardBodies
    "For comparison purposes, an equivalent model with Bodies instead of PointMasses"

    model PointMass = Modelica.Mechanics.MultiBody.Parts.Body (
      final m=1,
      final r_CM={0,0,0},
      final I_11=0,
      final I_22=0,
      final I_33=0,
      final I_21=0,
      final I_31=0,
      final I_32=0)
      "Body used at all places of the comparison model with zero inertia tensor"

    PointMass pointMass1(
      r_0(start={3,0,0}, each fixed=true),
      v_0(start={0,0,-1}, each fixed=true),
      angles_fixed=true,
      w_0_fixed=true)
    PointMass pointMass2
    PointMass pointMass3
    PointMass pointMass4
    PointMass pointMass5
    PointMass pointMass6

    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation(r={1,0,0})
    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation1(r={-1,0,0})
    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation2(r={0,1,0})
    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation3(r={0,-1,0})
    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation4(r={0,0,1})
    Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation5(r={0,0,-1})

  equation
    connect(fixedTranslation1.frame_a, fixedTranslation.frame_a)
    connect(fixedTranslation1.frame_a, fixedTranslation2.frame_a)
    connect(fixedTranslation3.frame_a, fixedTranslation.frame_a)
    connect(fixedTranslation1.frame_a, fixedTranslation4.frame_a)
    connect(fixedTranslation5.frame_a, fixedTranslation.frame_a)
    connect(fixedTranslation2.frame_b, pointMass3.frame_a)
    connect(fixedTranslation3.frame_b, pointMass4.frame_a)
    connect(pointMass5.frame_a, fixedTranslation4.frame_b)
    connect(fixedTranslation5.frame_b, pointMass6.frame_a)
    connect(fixedTranslation.frame_b, pointMass1.frame_a)
    connect(fixedTranslation1.frame_b, pointMass2.frame_a)
  end SystemWithStandardBodies;

equation
  connect(fixedTranslation1.frame_a, fixedTranslation.frame_a)
  connect(fixedTranslation1.frame_a, fixedTranslation2.frame_a)
  connect(fixedTranslation3.frame_a, fixedTranslation.frame_a)
  connect(fixedTranslation1.frame_a, fixedTranslation4.frame_a)
  connect(fixedTranslation5.frame_a, fixedTranslation.frame_a)
  connect(fixedTranslation2.frame_b, pointMass3.frame_a)
  connect(fixedTranslation3.frame_b, pointMass4.frame_a)
  connect(pointMass5.frame_a, fixedTranslation4.frame_b)
  connect(fixedTranslation5.frame_b, pointMass6.frame_a)
  connect(fixedTranslation.frame_b, pointMass1.frame_a)
  connect(fixedTranslation1.frame_b, pointMass2.frame_a)
  connect(world.frame_b, freeMotion.frame_a)
  connect(freeMotion.frame_b, fixedTranslation1.frame_a)
end PointGravityWithPointMasses2;


Single wheel rolling on ground starting from an initial speed. Demonstrates how a single wheel is rolling on ground
(starting with an initial velocity).

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model RollingWheel
  "Single wheel rolling on ground starting from an initial speed"
   extends Modelica.Icons.Example;

  Modelica.Mechanics.MultiBody.Parts.RollingWheel wheel1(
    radius=0.3,
    m=2,
    I_axis=0.06,
    I_long=0.12,
    hollowFraction=0.6,
    x(start=0.2),
    y(start=0.2),
    der_angles(start={0,5,1}))
  inner Modelica.Mechanics.MultiBody.World world(
    label2="z",
    n={0,0,-1},
    animateGround=true,
    groundLength_u=4,
    groundColor={130,200,130})
end RollingWheel;


Rolling wheel set that is driven by torques driving the wheels. Demonstrates how a RollingWheelSet (two wheels rigidly coupled together) is rolling
on ground when driven by some external torques.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model RollingWheelSetDriving
  "Rolling wheel set that is driven by torques driving the wheels"
   extends Modelica.Icons.Example;

  inner Modelica.Mechanics.MultiBody.World world(
    label2="z",
    n={0,0,-1},
    animateGround=true,
    groundLength_u=3,
    groundColor={130,200,130})
  Modelica.Mechanics.MultiBody.Parts.RollingWheelSet wheelSet(
    R_wheel=0.1,
    m_wheel=0.5,
    I_wheelAxis=0.01,
    I_wheelLong=0.02,
    track=0.5,
    x(start=0.1, fixed=true),
    y(start=0.1, fixed=true),
    phi(fixed=true),
    theta1(fixed=true),
    theta2(fixed=true),
    der_theta1(fixed=true),
    der_theta2(fixed=true))
  Modelica.Mechanics.MultiBody.Parts.Body body(m=0.01, r_CM={0,0,0},
    animation=false)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation(
                       r={0.2,0,0},
    animation=true,
    width=0.04)
  Modelica.Blocks.Sources.Sine sine1(f=1, amplitude=2)
  Modelica.Blocks.Sources.Sine sine2(
    f=1,
    amplitude=2,
    phase=1.5707963267949)
  Modelica.Mechanics.Rotational.Sources.Torque2 torque1
  Modelica.Mechanics.Rotational.Sources.Torque2 torque2
  Modelica.Mechanics.MultiBody.Visualizers.FixedShape shape(
    final lengthDirection={0,1,0},
    final widthDirection={1,0,0},
    final shapeType="pipe",
    final r_shape={0,-wheelSet.width_wheel,0},
    final length=2*wheelSet.width_wheel,
    final width=2*wheelSet.R_wheel,
    final height=2*wheelSet.R_wheel,
    final color={0,128,255},
    final extra=0.8)
equation
  connect(fixedTranslation.frame_a, wheelSet.frameMiddle)
  connect(fixedTranslation.frame_b, body.frame_a)
  connect(wheelSet.axis1, torque1.flange_a)
  connect(torque1.flange_b, wheelSet.support)
  connect(wheelSet.axis2, torque2.flange_a)
  connect(wheelSet.support, torque2.flange_b)
  connect(sine1.y, torque1.tau)
  connect(sine2.y, torque2.tau)
  connect(shape.frame_a, fixedTranslation.frame_b)
end RollingWheelSetDriving;


Rolling wheel set that is pulled by a force. Demonstrates how a RollingWheelSet (two wheels rigidly coupled together) is rolling
on ground when pulled by an external force.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model RollingWheelSetPulling "Rolling wheel set that is pulled by a force"
   extends Modelica.Icons.Example;

  Modelica.Mechanics.MultiBody.Forces.WorldForce force(animation=false)
  inner Modelica.Mechanics.MultiBody.World world(
    label2="z",
    n={0,0,-1},
    animateGround=true,
    groundLength_u=3,
    groundColor={130,200,130})
  Modelica.Mechanics.MultiBody.Parts.RollingWheelSet wheelSet(
    R_wheel=0.1,
    m_wheel=0.5,
    I_wheelAxis=0.01,
    I_wheelLong=0.02,
    track=0.5,
    x(start=0.1, fixed=true),
    y(start=0.1, fixed=true),
    phi(fixed=true),
    theta1(fixed=true),
    theta2(fixed=true),
    der_theta1(fixed=true),
    der_theta2(fixed=true))
  Modelica.Mechanics.MultiBody.Parts.Body body(m=0.01, r_CM={0,0,0},
    animation=false)
  Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(
    table=[0,1,0,0; 1,1,0,0; 2,0,2,0; 3,0,2,0])
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation(
    r={0.2,0,0},
    animation=true,
    width=0.04)
  Modelica.Mechanics.MultiBody.Visualizers.FixedShape shape(
    final lengthDirection={0,1,0},
    final widthDirection={1,0,0},
    final shapeType="pipe",
    final r_shape={0,-wheelSet.width_wheel,0},
    final length=2*wheelSet.width_wheel,
    final width=2*wheelSet.R_wheel,
    final height=2*wheelSet.R_wheel,
    final color={0,128,255},
    final extra=0.8)
equation
  connect(combiTimeTable.y, force.force)
  connect(fixedTranslation.frame_a, wheelSet.frameMiddle)
  connect(fixedTranslation.frame_b, body.frame_a)
  connect(force.frame_b, fixedTranslation.frame_b)
  connect(shape.frame_a, fixedTranslation.frame_b)
end RollingWheelSetPulling;


Simple spring/damper/mass system. This example demonstrates:

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model SpringDamperSystem "Simple spring/damper/mass system"
  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    m=1,
    animation=animation,
    r_CM={0,-0.2,0},
    cylinderDiameter=0.05,
    sphereDiameter=0.15,
    I_11=0.1,
    I_22=0.1,
    I_33=0.1,
    r_0(start={0.3,-0.2,0}, each fixed=true),
    v_0(each fixed=true),
    angles_fixed=true,
    w_0_fixed=true,
    w_0_start(each displayUnit="deg/s") = {0,0,0.03490658503988659})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar1(animation=animation, r={0.3,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar2(animation=animation, r={0.6,0,0})
  Modelica.Mechanics.MultiBody.Parts.Body body2(
    m=1,
    animation=animation,
    cylinderDiameter=0.05,
    sphereDiameter=0.15,
    r_CM={0,0,0})
  Modelica.Mechanics.MultiBody.Joints.Prismatic p2(useAxisFlange=true,
    n={0,-1,0},
    animation=animation,
    boxWidth=0.05,
    stateSelect=StateSelect.always,
    v(fixed=true),
    s(fixed=true, start=0.1))
  Modelica.Mechanics.MultiBody.Forces.Spring spring2(
    c=30,
    s_unstretched=0.1,
    coilWidth=0.01,
    width=0.1)
  Modelica.Mechanics.MultiBody.Forces.Spring spring1(
    s_unstretched=0.1,
    coilWidth=0.01,
    c=30,
    numberOfWindings=10,
    width=0.1)
  Modelica.Mechanics.MultiBody.Forces.Damper damper1(d=2)
equation
  connect(world.frame_b, bar1.frame_a)
  connect(bar1.frame_b, bar2.frame_a)
  connect(bar2.frame_b, p2.frame_a)
  connect(p2.frame_b, body2.frame_a)
  connect(bar2.frame_b, spring2.frame_a)
  connect(body2.frame_a, spring2.frame_b)
  connect(damper1.frame_a, bar1.frame_b)
  connect(spring1.frame_a, bar1.frame_b)
  connect(damper1.frame_b, body1.frame_a)
  connect(spring1.frame_b, body1.frame_a)
end SpringDamperSystem;


Mass attached with a spring to the world frame. This example shows the two different ways how force laws
can be utilized:

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model SpringMassSystem "Mass attached with a spring to the world frame"
  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Joints.Prismatic p1(useAxisFlange=true,
    n={0,-1,0},
    animation=animation,
    boxWidth=0.05,
    s(fixed=true, start=0.1),
    v(fixed=true))
  Modelica.Mechanics.Translational.Components.Spring spring1(
                                                  c=30, s_rel0=0.1)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    m=1,
    sphereDiameter=0.2,
    animation=animation,
    r_CM={0,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar1(animation=animation, r={0.3,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar2(animation=animation, r={0.3,0,0})
  Modelica.Mechanics.MultiBody.Parts.Body body2(
    m=1,
    sphereDiameter=0.2,
    animation=animation,
    r_CM={0,0,0})
  Modelica.Mechanics.MultiBody.Joints.Prismatic p2(useAxisFlange=true,
    n={0,-1,0},
    animation=animation,
    boxWidth=0.05,
    stateSelect=StateSelect.always,
    s(fixed=true, start=0.1),
    v(fixed=true))
  Modelica.Mechanics.MultiBody.Forces.Spring spring2(
    c=30,
    s_unstretched=0.1,
    width=0.1)
equation
  connect(body1.frame_a, p1.frame_b)
  connect(world.frame_b, bar1.frame_a)
  connect(bar1.frame_b, p1.frame_a)
  connect(spring1.flange_b, p1.axis)
  connect(bar1.frame_b, bar2.frame_a)
  connect(bar2.frame_b, p2.frame_a)
  connect(p2.frame_b, body2.frame_a)
  connect(bar2.frame_b, spring2.frame_a)
  connect(body2.frame_a, spring2.frame_b)
  connect(spring1.flange_a, p1.support)
end SpringMassSystem;


Point mass hanging on a spring. This example shows that a force component may have a mass.
The 3-dimensional spring as used in this example, has an optional
point mass between the two points where the spring is attached.
In the animation, this point mass is represented by a small,
light blue, sphere.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model SpringWithMass "Point mass hanging on a spring"
  extends Modelica.Icons.Example;
  inner Modelica.Mechanics.MultiBody.World world(animateGravity=false)
  Modelica.Mechanics.MultiBody.Forces.Spring spring(
    s_unstretched=0.2,
    m=0.5,
    c=40,
    width=0.1,
    massDiameter=0.07)
  Modelica.Mechanics.MultiBody.Parts.Body body(
    r_0(start={0,-0.3,0}, each fixed=true),
    v_0(each fixed=true),
    angles_fixed=true,
    w_0_fixed=true,
    r_CM={0,0,0},
    m=1)
equation
  connect(world.frame_b, spring.frame_a)
  connect(body.frame_a, spring.frame_b)
end SpringWithMass;


Demonstrate the visualization of a sine surface, as well as a torus and a wheel constructed from a surface. This example demonstrates the use of the
Surface
visualizer that visualizes a moving, parameterized surface.
The \"sine-wave\" surface is a direct application of the surface model.
Furthermore, the \"torus\" surface is an instance of
Torus,
the \"wheel\" surface is an instance of
VoluminousWheel,
and the \"pipeWithScalarField surface is an instance of
PipeWithScalarField.
All latter visual shapes are constructed with the surface model.
The following image shows a screen-shot of this example model:

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model Surfaces
  "Demonstrate the visualization of a sine surface, as well as a torus and a wheel constructed from a surface"
  extends Modelica.Icons.Example;
  parameter Real x_min=-1 "Minimum value of x";
  parameter Real x_max=+1 "Maximum value of x";
  parameter Real y_min=-1 "Minimum value of y";
  parameter Real y_max=+1 "Maximum value of y";
  parameter Real z_min=0 "Minimum value of z";
  parameter Real z_max=1 "Maximum value of z";
  Real wz = time;
  Modelica.Mechanics.MultiBody.Visualizers.Advanced.Surface surface(
    redeclare function surfaceCharacteristic =
        Modelica.Mechanics.MultiBody.Examples.Elementary.Utilities.sineSurface (
           x_min=x_min,
           x_max=x_max,
           y_min=y_min,
           y_max=y_max,
           z_min=z_min,
           z_max=z_max,
           wz=wz),
    multiColoredSurface=false,
    nu=50,
    nv=50)
  inner World world(
    axisLength=1,
    n={0,0,-1},
    animateGround=true,
    groundLength_u=4,
    groundColor={215,215,215})
  Visualizers.Torus torus
  Joints.Prismatic prismatic(useAxisFlange=true, animation=false,
    v(fixed=true))
  Translational.Sources.Position position
  Blocks.Sources.Sine sine(amplitude=2, f=0.5)
  Parts.FixedTranslation fixedTranslation1(r={0,-1.3,torus.R + torus.r},
      animation=false)
  Parts.FixedTranslation fixedTranslation2(
      animation=false, r={0,-1.6,wheel.rTire})
  Visualizers.VoluminousWheel wheel
  Visualizers.PipeWithScalarField pipeWithScalarField(
    rOuter=0.3,
    length=1,
    T_min=0,
    T_max=2,
    T=Modelica.Math.sin(Modelica.Constants.pi*pipeWithScalarField.xsi)*
      Modelica.Math.cos(Modelica.Constants.pi*time) .+ 1,
    n_colors=32)
  Parts.FixedTranslation fixedTranslation3(
      animation=false, r={0,-2.2,0})
equation
  connect(world.frame_b, prismatic.frame_a)
  connect(position.flange, prismatic.axis)
  connect(sine.y, position.s_ref)
  connect(prismatic.frame_b, fixedTranslation1.frame_a)
  connect(fixedTranslation1.frame_b, torus.frame_a)
  connect(prismatic.frame_b, fixedTranslation2.frame_a)
  connect(fixedTranslation2.frame_b, wheel.frame_a)
  connect(world.frame_b, fixedTranslation3.frame_a)
  connect(fixedTranslation3.frame_b, pipeWithScalarField.frame_a)
end Surfaces;


3-dim. springs in series and parallel connection. This example demonstrates that 3-dimensional line force elements
(here: Modelica.Mechanics.MultiBody.Forces.Spring elements) can be connected together
in series without having a body with mass at the
connection point (as usually required by multi-body programs).
This is advantageous since stiff systems can be avoided, say, due to
a stiff spring and a small mass at the connection point.

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model ThreeSprings "3-dim. springs in series and parallel connection"
  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  inner Modelica.Mechanics.MultiBody.World world(animateWorld=animation)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    animation=animation,
    r_CM={0,-0.2,0},
    m=0.8,
    I_11=0.1,
    I_22=0.1,
    I_33=0.1,
    sphereDiameter=0.2,
    r_0(start={0.5,-0.3,0}, each fixed=true),
    v_0(each fixed=true),
    angles_fixed=true,
    w_0_fixed=true)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar1(animation=animation, r={0.3,0,0})
  Modelica.Mechanics.MultiBody.Forces.Spring spring1(
    lineForce(r_rel_0(start={-0.2,-0.2,0.2})),
    s_unstretched=0.1,
    width=0.1,
    coilWidth=0.005,
    numberOfWindings=5,
    c=20,
    animation=animation)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar2(animation=animation, r={0,0,0.3})
  Modelica.Mechanics.MultiBody.Forces.Spring spring2(
    s_unstretched=0.1,
    width=0.1,
    coilWidth=0.005,
    numberOfWindings=5,
    c=40,
    animation=animation)
  Modelica.Mechanics.MultiBody.Forces.Spring spring3(
    s_unstretched=0.1,
    width=0.1,
    coilWidth=0.005,
    numberOfWindings=5,
    c=20,
    animation=animation,
    fixedRotationAtFrame_b=true)
equation
  connect(world.frame_b, bar1.frame_a)
  connect(world.frame_b, bar2.frame_a)
  connect(bar1.frame_b, spring1.frame_a)
  connect(bar2.frame_b, spring3.frame_a)
  connect(spring2.frame_b, body1.frame_a)
  connect(spring3.frame_b, spring1.frame_b)
  connect(spring2.frame_a, spring1.frame_b)
end ThreeSprings;


Demonstrate the modeling of a user-defined gravity field. This example demonstrates a user defined gravity field.
Function \"world.gravityAcceleration\" is redeclared to function
theoreticalNormalGravityWGS84
that computes the theoretical gravity of the
WGS84 ellipsoid earth model at and close to
the earth ellipsoid surface. In the gravity field, a large, single pendulum is present. Via parameter \"geodeticLatitude\", the geodetic latitude on the earth can be defined, where the pendulum is present. The world frame is located at the WGS84 earth ellipsoid at this latitude. The result variable
\"gravity\" is the gravity vector at the center of mass of the pendulum mass.
Since the height of this mass is changing, the value of the gravity is also changing
(the difference is in the order of 0.00001).

within Modelica.Mechanics.MultiBody.Examples.Elementary;
model UserDefinedGravityField
  "Demonstrate the modeling of a user-defined gravity field"
   extends Modelica.Icons.Example;
   parameter Modelica.Units.NonSI.Angle_deg geodeticLatitude = 0
    "Geodetic latitude";
   parameter SI.Position height = 20
    "Height of pendulum attachment point over WGS84 earth ellipsoid";
   SI.Acceleration gravity[3]=body.g_0
    "Gravity acceleration at center of mass of body";
  inner Modelica.Mechanics.MultiBody.World world(
    gravityType=Modelica.Mechanics.MultiBody.Types.GravityTypes.NoGravity,
      redeclare function gravityAcceleration =
        Modelica.Mechanics.MultiBody.Examples.Elementary.Utilities.theoreticalNormalGravityWGS84 (
         phi=geodeticLatitude),
    axisLength=10,
    nominalLength=10)
  Joints.Revolute rev(n={0,0,1},useAxisFlange=true,
    phi(fixed=true),
    w(fixed=true))
  Rotational.Components.Damper damper(d=0.1)
  Parts.Body body(r_CM={10,0,0},
    m=1000.0,
    sphereDiameter=1)
  Parts.FixedTranslation fixedTranslation(r={0,height,0}, width=0.3)
equation
  connect(damper.flange_b,rev. axis)
  connect(rev.support,damper. flange_a)
  connect(body.frame_a,rev. frame_b)
  connect(world.frame_b, fixedTranslation.frame_a)
  connect(fixedTranslation.frame_b, rev.frame_a)
end UserDefinedGravityField;


within Modelica.Mechanics.MultiBody.Examples.Elementary;
package Utilities "Utility classes for elementary multi-body example models"
  extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Model of one cylinder engine. This is a model of the mechanical part of one cylinder of an engine.
The combustion is not modelled. The \"inertia\" component at the lower
left part is the output inertia of the engine driving the gearbox.
The angular velocity of the output inertia has a start value of 10 rad/s
in order to demonstrate the movement of the engine.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Engine1a "Model of one cylinder engine"
  extends Modelica.Icons.Example;
  extends Utilities.Engine1Base;
  Modelica.Mechanics.MultiBody.Joints.Revolute b1(
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.05)
  Joints.RevolutePlanarLoopConstraint b2(
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.05)
  Modelica.Mechanics.MultiBody.Joints.Prismatic cylinder(
    boxWidth=0.02,
    n={0,-1,0},
    s(start=0.15))
equation
  connect(cylPosition.frame_b, cylinder.frame_a)
  connect(b2.frame_a, mid.frame_b)
  connect(b2.frame_b, connectingRod.frame_b)
  connect(connectingRod.frame_a, b1.frame_b)
  connect(b1.frame_a, piston.frame_b)
  connect(cylinder.frame_b, piston.frame_a)
end Engine1a;


Model of one cylinder engine with gas force and preparation for assembly joint JointRRP. This is a model of the mechanical part of one cylinder of an engine.
It is similar to
Loops.Engine1a.
The difference is that a simple
model for the gas force in the cylinder is added and that the
model is restructured in such a way, that the central part of
the planar kinematic loop can be easily replaced by the
assembly joint \"Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRP\".
This exchange of the kinematic loop is shown in
Loops.Engine1b_analytic.
The advantage of using JointRRP is, that the
non-linear algebraic equation of this loop is solved analytically, and
not numerically as in this model (Engine1b).

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Engine1b
  "Model of one cylinder engine with gas force and preparation for assembly joint JointRRP"
  extends Modelica.Icons.Example;
  extends Utilities.Engine1bBase;
  Modelica.Mechanics.MultiBody.Joints.Revolute b1(
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.05)
  Joints.RevolutePlanarLoopConstraint b2(
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.05)
  Modelica.Mechanics.MultiBody.Joints.Prismatic cylinder(
    useAxisFlange=true,
    boxWidth=0.02,
    n={0,-1,0})
  Parts.FixedTranslation rod1(r={0,-0.2,0},animation=false)
  Parts.FixedTranslation rod3(r={0,-0.1,0}, animation=false)
equation
  connect(cylinder.frame_b, rod3.frame_a)
  connect(cylPosition.frame_b, cylinder.frame_a)
  connect(gasForce.flange_a, cylinder.support)
  connect(gasForce.flange_b, cylinder.axis)
  connect(piston.frame_a, cylinder.frame_b)
  connect(rod3.frame_b, b1.frame_a)
  connect(mid.frame_b, b2.frame_a)
  connect(b2.frame_b, connectingRod.frame_b)
  connect(b2.frame_b, rod1.frame_b)
  connect(b1.frame_b, rod1.frame_a)
end Engine1b;


Model of one cylinder engine with gas force and analytic loop handling. This is the same model as
Loops.Engine1b.
The only difference is that the central part of
the planar kinematic loop has been replaced by the
assembly joint \"Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRP\".
The advantage of using JointRRP is, that the
non-linear algebraic equation of this loop is solved analytically, and
not numerically as in
Loops.Engine1b.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Engine1b_analytic
  "Model of one cylinder engine with gas force and analytic loop handling"
  extends Modelica.Icons.Example;
  extends Utilities.Engine1bBase;
  Joints.Assemblies.JointRRP jointRRP(
    n_a={1,0,0},
    n_b={0,-1,0},
    animation=false,
    rRod1_ia={0,0.2,0},
    rRod2_ib={0,-0.1,0})
equation
  connect(mid.frame_b, jointRRP.frame_a)
  connect(jointRRP.frame_b, cylPosition.frame_b)
  connect(gasForce.flange_a, jointRRP.bearing)
  connect(gasForce.flange_b, jointRRP.axis)
  connect(jointRRP.frame_ib, piston.frame_a)
  connect(connectingRod.frame_b, jointRRP.frame_ia)
end Engine1b_analytic;


V6 engine with 6 cylinders, 6 planar loops and 1 degree-of-freedom. This is a V6 engine with 6 cylinders. It is hierarchically built
up by using instances of one cylinder. For more details on the
modeling of one cylinder, see example
Engine1b.
An animation of the engine is shown in the figure below.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model EngineV6
  "V6 engine with 6 cylinders, 6 planar loops and 1 degree-of-freedom"

  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  output Modelica.Units.NonSI.AngularVelocity_rpm
    engineSpeed_rpm=
         Modelica.Units.Conversions.to_rpm(load.w) "Engine speed";
  output SI.Torque engineTorque = filter.u
    "Torque generated by engine";
  output SI.Torque filteredEngineTorque = filter.y
    "Filtered torque generated by engine";

  Modelica.Mechanics.MultiBody.Joints.Revolute bearing(useAxisFlange=true,
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.06,
    animation=animation)
  inner Modelica.Mechanics.MultiBody.World world(animateWorld=false,
      animateGravity = false)
  Utilities.Cylinder cylinder1(
    crankAngleOffset=Cv.from_deg(-30),
    cylinderInclinationAngle=Cv.from_deg(-30),
    animation=animation)
  Utilities.Cylinder cylinder2(
    crankAngleOffset=Cv.from_deg(90),
    cylinderInclinationAngle=Cv.from_deg(30),
    animation=animation)
  Utilities.Cylinder cylinder3(
    cylinderInclinationAngle=Cv.from_deg(-30),
    animation=animation,
    crankAngleOffset=Cv.from_deg(210))
  Utilities.Cylinder cylinder4(
    cylinderInclinationAngle=Cv.from_deg(30),
    animation=animation,
    crankAngleOffset=Cv.from_deg(210))
  Utilities.Cylinder cylinder5(
    cylinderInclinationAngle=Cv.from_deg(-30),
    animation=animation,
    crankAngleOffset=Cv.from_deg(90))
  Utilities.Cylinder cylinder6(
    cylinderInclinationAngle=Cv.from_deg(30),
    animation=animation,
    crankAngleOffset=Cv.from_deg(-30))
  Modelica.Mechanics.Rotational.Components.Inertia load(
                          phi(
      start=0,
      fixed=true), w(
      start=10,
      fixed=true),
    stateSelect=StateSelect.always,
    J=1)
  Modelica.Mechanics.Rotational.Sources.QuadraticSpeedDependentTorque load2(
                                                 tau_nominal=-100, w_nominal=
        200,
    useSupport=false)
  Rotational.Sensors.TorqueSensor torqueSensor
  Blocks.Continuous.CriticalDamping filter(
    n=2,
    initType=Modelica.Blocks.Types.Init.SteadyState,
    f=5)
equation

  connect(bearing.frame_b, cylinder1.crank_a)
  connect(cylinder1.crank_b, cylinder2.crank_a)
  connect(cylinder2.crank_b, cylinder3.crank_a)
  connect(cylinder3.crank_b, cylinder4.crank_a)
  connect(cylinder4.crank_b, cylinder5.crank_a)
  connect(cylinder5.crank_b, cylinder6.crank_a)
  connect(cylinder5.cylinder_b, cylinder6.cylinder_a)
  connect(cylinder4.cylinder_b, cylinder5.cylinder_a)
  connect(cylinder4.cylinder_a, cylinder3.cylinder_b)
  connect(cylinder3.cylinder_a, cylinder2.cylinder_b)
  connect(cylinder2.cylinder_a, cylinder1.cylinder_b)
  connect(world.frame_b, cylinder1.cylinder_a)
  connect(world.frame_b, bearing.frame_a)
  connect(load2.flange, load.flange_b)
  connect(torqueSensor.flange_b, load.flange_a)
  connect(torqueSensor.tau,filter. u)
  connect(torqueSensor.flange_a, bearing.axis)
end EngineV6;


V6 engine with 6 cylinders, 6 planar loops, 1 degree-of-freedom and analytic handling of kinematic loops. This is a similar model as the example \"EngineV6\". However, the cylinders
have been built up with component Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRR that
solves the non-linear system of equations in an aggregation of 3 revolution
joints analytically and only one body is used that holds the total
mass of the crank shaft:

within Modelica.Mechanics.MultiBody.Examples.Loops;
model EngineV6_analytic
  "V6 engine with 6 cylinders, 6 planar loops, 1 degree-of-freedom and analytic handling of kinematic loops"

  extends Modelica.Icons.Example;
  parameter Boolean animation=true "= true, if animation shall be enabled";
  output Modelica.Units.NonSI.AngularVelocity_rpm
    engineSpeed_rpm=
         Modelica.Units.Conversions.to_rpm(load.w) "Engine speed";
  output SI.Torque engineTorque = filter.u
    "Torque generated by engine";
  output SI.Torque filteredEngineTorque = filter.y
    "Filtered torque generated by engine";

  inner Modelica.Mechanics.MultiBody.World world(animateWorld=false,
      animateGravity =                                                              false)
  Utilities.EngineV6_analytic engine(redeclare model Cylinder =
        Modelica.Mechanics.MultiBody.Examples.Loops.Utilities.Cylinder_analytic_CAD)
  Modelica.Mechanics.Rotational.Components.Inertia load(
                                             phi(
      start=0,
      fixed=true), w(
      start=10,
      fixed=true),
    stateSelect=StateSelect.always,
    J=1)
  Modelica.Mechanics.Rotational.Sources.QuadraticSpeedDependentTorque load2(
                                                 tau_nominal=-100, w_nominal=
        200,
    useSupport=false)
  Rotational.Sensors.TorqueSensor torqueSensor
  Blocks.Continuous.CriticalDamping filter(
    n=2,
    initType=Modelica.Blocks.Types.Init.SteadyState,
    f=5)
equation

  connect(world.frame_b, engine.frame_a)
  connect(load2.flange, load.flange_b)
  connect(torqueSensor.flange_a, engine.flange_b)
  connect(torqueSensor.flange_b, load.flange_a)
  connect(torqueSensor.tau, filter.u)
end EngineV6_analytic;


One kinematic loop with four bars (with only revolute joints; 5 non-linear equations). This is a simple kinematic loop consisting of 6 revolute joints, 1 prismatic joint
and 4 bars that is often used as basic constructing unit in mechanisms.
This example demonstrates that usually no particular knowledge
of the user is needed to handle kinematic loops.
Just connect the joints and bodies together according
to the real system. In particular no cut-joints or a spanning tree has
to be determined. In this case, the initial condition of the angular velocity
of revolute joint j1 is set to 300 deg/s in order to drive this loop.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Fourbar1
  "One kinematic loop with four bars (with only revolute joints; 5 non-linear equations)"
  extends Modelica.Icons.Example;

  output SI.Angle j1_phi "Angle of revolute joint j1";
  output SI.Position j2_s "Distance of prismatic joint j2";
  output SI.AngularVelocity j1_w "Axis speed of revolute joint j1";
  output SI.Velocity j2_v "Axis velocity of prismatic joint j2";

  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Joints.Revolute j1(
    n={1,0,0},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    w(displayUnit="deg/s",
      start=5.235987755982989,
      fixed=true))
  Modelica.Mechanics.MultiBody.Joints.Prismatic j2(
    n={1,0,0},
    s(start=-0.2),
    boxWidth=0.05)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b1(r={0,0.5,0.1}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b2(r={0,0.2,0}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b3(r={-1,0.3,0.1}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Joints.Revolute rev(n={0,1,0})
  Modelica.Mechanics.MultiBody.Joints.Revolute rev1
  Modelica.Mechanics.MultiBody.Joints.Revolute j3(n={1,0,0})
  Modelica.Mechanics.MultiBody.Joints.Revolute j4(n={0,1,0})
  Modelica.Mechanics.MultiBody.Joints.Revolute j5(n={0,0,1})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation b0(animation=false, r={1.2,0,0})
equation
  connect(j2.frame_b, b2.frame_a)
  connect(j1.frame_b, b1.frame_a)
  connect(rev.frame_a, b2.frame_b)
  connect(rev.frame_b, rev1.frame_a)
  connect(rev1.frame_b, b3.frame_a)
  connect(world.frame_b, j1.frame_a)
  connect(b1.frame_b, j3.frame_a)
  connect(j3.frame_b, j4.frame_a)
  connect(j4.frame_b, j5.frame_a)
  connect(j5.frame_b, b3.frame_b)
  connect(b0.frame_a, world.frame_b)
  connect(b0.frame_b, j2.frame_a)
  j1_phi = j1.phi;
  j2_s = j2.s;
  j1_w = j1.w;
  j2_v = j2.v;
end Fourbar1;


One kinematic loop with four bars (with UniversalSpherical joint; 1 non-linear equation). This is a second version of the \"four-bar\" mechanism, see figure:

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Fourbar2
  "One kinematic loop with four bars (with UniversalSpherical joint; 1 non-linear equation)"
  extends Modelica.Icons.Example;

  output SI.Angle j1_phi "Angle of revolute joint j1";
  output SI.Position j2_s "Distance of prismatic joint j2";
  output SI.AngularVelocity j1_w "Axis speed of revolute joint j1";
  output SI.Velocity j2_v "Axis velocity of prismatic joint j2";

  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Joints.Revolute j1(
    n={1,0,0},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    useAxisFlange=false,
    w(displayUnit="deg/s",
      start=5.235987755983,
      fixed=true))
  Modelica.Mechanics.MultiBody.Joints.Prismatic j2(
    n={1,0,0},
    boxWidth=0.05,
    s(fixed=true, start=-0.2))
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b1(r={0,0.5,0.1}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b2(r={0,0.2,0}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Joints.UniversalSpherical universalSpherical(
    n1_a={0,1,0},
    computeRodLength=true,
    rRod_ia={-1,0.3,0.1})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation b3(r={1.2,0,0}, animation=false)
  Modelica.Mechanics.MultiBody.Visualizers.FixedFrame fixedFrame(color_x={0,0,255})
equation
  j1_phi = j1.phi;
  j2_s = j2.s;
  j1_w = j1.w;
  j2_v = j2.v;
  connect(j2.frame_b, b2.frame_a)
  connect(j1.frame_b, b1.frame_a)
  connect(j1.frame_a, world.frame_b)
  connect(b1.frame_b, universalSpherical.frame_b)
  connect(universalSpherical.frame_a, b2.frame_b)
  connect(b3.frame_a, world.frame_b)
  connect(b3.frame_b, j2.frame_a)
  connect(fixedFrame.frame_a, universalSpherical.frame_ia)
end Fourbar2;


One kinematic loop with four bars (with JointSSP joint; analytic solution of non-linear algebraic loop). This is a third version of the \"four-bar\" mechanism, see figure:

within Modelica.Mechanics.MultiBody.Examples.Loops;
model Fourbar_analytic
  "One kinematic loop with four bars (with JointSSP joint; analytic solution of non-linear algebraic loop)"
  extends Modelica.Icons.Example;

  output SI.Angle j1_phi "Angle of revolute joint j1";
  output SI.Position j2_s "Distance of prismatic joint j2";
  output SI.AngularVelocity j1_w "Axis speed of revolute joint j1";
  output SI.Velocity j2_v "Axis velocity of prismatic joint j2";

  inner Modelica.Mechanics.MultiBody.World world(animateGravity=false)
  Modelica.Mechanics.MultiBody.Joints.Revolute j1(
    n={1,0,0},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    useAxisFlange=false,
    w(displayUnit="deg/s",
      start=5.235987755983,
      fixed=true))
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b1(r={0,0.5,0.1}, diameter=0.05)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation b3(r={1.2,0,0}, animation=false)
  Modelica.Mechanics.MultiBody.Joints.Assemblies.JointSSP jointSSP(
    rod1Length=sqrt({-1,0.3,0.1}*{-1,0.3,0.1}),
    n_b={1,0,0},
    s_offset=-0.2,
    rRod2_ib={0,0.2,0},
    rod1Color={0,128,255},
    rod2Color={0,128,255},
    checkTotalPower=true)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder b2(
    r={0,0.2,0},
    diameter=0.05,
    animation=false)
equation
  j1_phi = j1.phi;
  j2_s = jointSSP.prismatic.distance;
  j1_w = j1.w;
  j2_v = der(jointSSP.prismatic.distance);
  connect(j1.frame_b, b1.frame_a)
  connect(j1.frame_a, world.frame_b)
  connect(b3.frame_a, world.frame_b)
  connect(b1.frame_b, jointSSP.frame_a)
  connect(b3.frame_b, jointSSP.frame_b)
  connect(b2.frame_a, jointSSP.frame_ib)
end Fourbar_analytic;


Examples with kinematic loops

within Modelica.Mechanics.MultiBody.Examples;
package Loops "Examples with kinematic loops"
  extends Modelica.Icons.ExamplesPackage;
end Loops;


Planar four bars mechanism with one kinematic loop (with RevolutePlanarLoopConstraint joint). A planar four link mechanism demonstrating possible usage of the
RevolutePlanarLoopConstraint.
In this planar example, all the revolute joints rotate about axes perpendicular
to the x-y plane, i.e. they all are parallel to each other.
To enable a unique numerical solution in such a case,
one RevolutePlanarLoopConstraint has to be introduced
instead of the common revolute joint.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model PlanarFourbar "Planar four bars mechanism with one kinematic loop (with RevolutePlanarLoopConstraint joint)"
  extends Modelica.Icons.Example;

  Joints.Revolute revolute1(
    animation=true,
    n={0,0,1},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    w(fixed=true),
    useAxisFlange=true)
  Joints.Revolute revolute2(animation=true, n={0,0,1})
  Joints.Revolute revolute3(animation=true, n={0,0,1})
  Joints.RevolutePlanarLoopConstraint revolute4cut
  Parts.BodyBox body1(
    width=0.5*world.defaultJointLength, r={0.4,0,0})
  Parts.BodyBox body2(
    width=body1.width, r={0.1,1.1,0})
  Parts.BodyBox body3(
    width=body1.width, r={-0.15,1,0})
  Parts.BodyBox body4(
    r=body1.r + body2.r - body3.r,
    width=body1.width)
  inner Modelica.Mechanics.MultiBody.World world(enableAnimation=true)
  Rotational.Components.Damper                    damper(d=0.1)
  Sensors.RelativeSensor sensorJoint4(
    animation=false,
    resolveInFrame=Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_a,
    get_w_rel=true,
    get_z_rel=true,
    get_angles=true,
    sequence={1,2,3})
equation
  connect(revolute1.frame_b, body1.frame_a)
  connect(revolute2.frame_a, body1.frame_b)
  connect(revolute2.frame_b, body2.frame_a)
  connect(world.frame_b, revolute1.frame_a)
  connect(world.frame_b, body3.frame_a)
  connect(body3.frame_b, revolute3.frame_a)
  connect(revolute3.frame_b, body4.frame_a)
  connect(body4.frame_b, revolute4cut.frame_a)
  connect(body2.frame_b, revolute4cut.frame_b)
  connect(damper.flange_b, revolute1.axis)
  connect(revolute1.support,damper. flange_a)
  connect(sensorJoint4.frame_a, revolute4cut.frame_a)
  connect(sensorJoint4.frame_b, revolute4cut.frame_b)
end PlanarFourbar;


Mechanism with three planar kinematic loops and one degree-of-freedom with analytic loop handling (with JointRRR joints). It is demonstrated how the Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRR joint can be
used to solve the non-linear equations of coupled planar loops analytically.
In the mechanism below no non-linear equation occurs any more from the tool
view, since these equations are solved analytically in the JointRRR joints.
For more details, see

MultiBody.UsersGuide.Tutorial.LoopStructures.AnalyticLoopHandling.

within Modelica.Mechanics.MultiBody.Examples.Loops;
model PlanarLoops_analytic
  "Mechanism with three planar kinematic loops and one degree-of-freedom with analytic loop handling (with JointRRR joints)"
  extends Modelica.Icons.Example;
  parameter SI.Length rh[3]={0.5,0,0}
    "Position vector from 'lower left' revolute to 'lower right' revolute joint for all the 3 loops";
  parameter SI.Length rv[3]={0,0.5,0}
    "Position vector from 'lower left' revolute to 'upper left' revolute joint in the first loop";

  parameter SI.Length r1b[3]={0.1,0.5,0}
    "Position vector from 'lower right' revolute to 'upper right' revolute joint in the first loop";
  final parameter SI.Length r1a[3]=r1b + rh - rv
    "Position vector from 'upper left' revolute to 'upper right' revolute joint in the first loop";

  parameter SI.Length r2b[3]={0.1,0.6,0}
    "Position vector from 'lower right' revolute to 'upper right' revolute joint in the second loop";
  final parameter SI.Length r2a[3]=r2b + rh - r1b
    "Position vector from 'upper left' revolute to 'upper right' revolute joint in the second loop";

  parameter SI.Length r3b[3]={0,0.55,0}
    "Position vector from 'lower right' revolute to 'upper right' revolute joint in the third loop";
  final parameter SI.Length r3a[3]=r3b + rh - r2b
    "Position vector from 'upper left' revolute to 'upper right' revolute joint in the third loop";

  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRR jointRRR1(
    rRod1_ia=r1a,
    rRod2_ib=r1b,
    checkTotalPower=true)
  Modelica.Mechanics.MultiBody.Joints.Revolute rev(useAxisFlange=true,w(fixed=true))
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod1(r=rv)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod2(r=rh)
  Modelica.Mechanics.MultiBody.Parts.Body body1(
    m=1,
    cylinderColor={155,155,155},
    r_CM=jointRRR1.rRod1_ia/2)
  Modelica.Mechanics.Rotational.Sources.Position position(useSupport=true)
  Modelica.Blocks.Sources.Sine sine(amplitude=0.7, f=1)
  Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRR jointRRR2(
    rRod1_ia=r2a,
    rRod2_ib=r2b,
    checkTotalPower=true)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod3(r=rh)
  Modelica.Mechanics.MultiBody.Parts.Body body2(
    m=1,
    cylinderColor={155,155,155},
    r_CM=jointRRR2.rRod1_ia/2)
  Modelica.Mechanics.MultiBody.Joints.Assemblies.JointRRR jointRRR3(
    rRod1_ia=r3a,
    rRod2_ib=r3b,
    checkTotalPower=true)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation rod4(r=rh)
  Modelica.Mechanics.MultiBody.Parts.Body body3(
    m=1,
    cylinderColor={155,155,155},
    r_CM=jointRRR3.rRod1_ia/2)
  Parts.Mounting1D mounting1D
equation
  connect(world.frame_b, rev.frame_a)
  connect(rod1.frame_a, rev.frame_b)
  connect(rod1.frame_b, jointRRR1.frame_a)
  connect(rod2.frame_a, world.frame_b)
  connect(rod2.frame_b, jointRRR1.frame_b)
  connect(jointRRR1.frame_ia, body1.frame_a)
  connect(rod3.frame_a, rod2.frame_b)
  connect(rod3.frame_b, jointRRR2.frame_b)
  connect(jointRRR2.frame_ia, body2.frame_a)
  connect(jointRRR1.frame_im, jointRRR2.frame_a)
  connect(rod3.frame_b, rod4.frame_a)
  connect(rod4.frame_b, jointRRR3.frame_b)
  connect(jointRRR2.frame_im, jointRRR3.frame_a)
  connect(jointRRR3.frame_ia, body3.frame_a)
  connect(sine.y, position.phi_ref)
  connect(mounting1D.flange_b, position.support)
  connect(mounting1D.frame_a, world.frame_b)
  connect(position.flange, rev.axis)
end PlanarLoops_analytic;


Cylinder with rod and crank of a combustion engine. Cylinder with rod and crank of a combustion engine.
Used as submodel in Loops.EngineV6.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
model Cylinder "Cylinder with rod and crank of a combustion engine"
  parameter Boolean animation=true "= true, if animation shall be enabled";
  parameter SI.Length cylinderTopPosition=0.42
    "Length from crank shaft to end of cylinder.";
  parameter SI.Length pistonLength=0.1 "Length of cylinder";
  parameter SI.Length rodLength=0.2 "Length of rod";
  parameter SI.Length crankLength=0.2 "Length of crank shaft in x direction";
  parameter SI.Length crankPinOffset=0.1
    "Offset of crank pin from center axis";
  parameter SI.Length crankPinLength=0.1
    "Offset of crank pin from center axis";
  parameter SI.Angle cylinderInclinationAngle=0 "Inclination of cylinder";
  parameter SI.Angle crankAngleOffset=0 "Offset for crank angle";
  parameter SI.Length cylinderLength=cylinderTopPosition - (pistonLength +
      rodLength - crankPinOffset) "Maximum length of cylinder volume";

  Modelica.Mechanics.MultiBody.Parts.BodyCylinder piston(
    diameter=0.1,
    r={0,pistonLength,0},
    color={180,180,180},
    animation=animation)
  Modelica.Mechanics.MultiBody.Parts.BodyBox connectingRod(
    widthDirection={1,0,0},
    height=0.06,
    color={0,0,200},
    width=0.02,
    r_shape={0,-0.02,0},
    r={0,rodLength,0},
    animation=animation)
  Modelica.Mechanics.MultiBody.Joints.Revolute b2(
    n={1,0,0},
    cylinderLength=0.02,
    animation=animation,
    cylinderDiameter=0.055)
  Modelica.Mechanics.MultiBody.Parts.BodyBox crank4(
    height=0.05,
    widthDirection={1,0,0},
    width=0.02,
    r={0,-crankPinOffset,0},
    animation=animation)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder crank3(
    r_shape={-0.01,0,0},
    length=0.12,
    diameter=0.03,
    r={crankPinLength,0,0},
    color={180,180,180},
    animation=animation)
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder crank1(
    diameter=0.05,
    r_shape={-0.01,0,0},
    length=0.12,
    r={crankLength - crankPinLength,0,0},
    color={180,180,180},
    animation=animation)
  Modelica.Mechanics.MultiBody.Parts.BodyBox crank2(
    height=0.05,
    widthDirection={1,0,0},
    width=0.02,
    r={0,crankPinOffset,0},
    animation=animation)
  Joints.RevolutePlanarLoopConstraint b1(
    n={1,0,0},
    cylinderLength=0.02,
    animation=animation,
    cylinderDiameter=0.055)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation mid(r={crankPinLength/2,0,0}, animation=
        false)
  Modelica.Mechanics.MultiBody.Joints.Prismatic cylinder(useAxisFlange=true,
    s(start=-0.3),
    n={0,-1,0},
    boxWidth=0.02)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation mounting(r={crankLength,0,0}, animation=
        false)
  Modelica.Mechanics.MultiBody.Parts.FixedRotation cylinderInclination(
    r={crankLength - crankPinLength/2,0,0},
    n_y={0,Modelica.Math.cos(cylinderInclinationAngle),Modelica.Math.sin(cylinderInclinationAngle)},
    animation=false,
    rotationType=Modelica.Mechanics.MultiBody.Types.RotationTypes.TwoAxesVectors)
  Modelica.Mechanics.MultiBody.Parts.FixedRotation crankAngle1(
    n_y={0,Modelica.Math.cos(crankAngleOffset),Modelica.Math.sin(crankAngleOffset)},
    animation=false,
    rotationType=Modelica.Mechanics.MultiBody.Types.RotationTypes.TwoAxesVectors)
  Modelica.Mechanics.MultiBody.Parts.FixedRotation crankAngle2(
    n_y={0,Modelica.Math.cos(-crankAngleOffset),Modelica.Math.sin(-crankAngleOffset)},
    animation=false,
    rotationType=Modelica.Mechanics.MultiBody.Types.RotationTypes.TwoAxesVectors)
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation cylinderTop(r={0,cylinderTopPosition,0},
      animation=false)
  GasForce2 gasForce(L=cylinderLength, d=0.1)
  Interfaces.Frame_a cylinder_a
  Interfaces.Frame_a cylinder_b
  Interfaces.Frame_a crank_a
  Interfaces.Frame_a crank_b
equation
  connect(b1.frame_a, mid.frame_b)
  connect(connectingRod.frame_a, b1.frame_b)
  connect(cylinder.frame_b, piston.frame_b)
  connect(crank1.frame_a, crankAngle1.frame_b)
  connect(b2.frame_a, piston.frame_a)
  connect(connectingRod.frame_b, b2.frame_b)
  connect(crank4.frame_b, crankAngle2.frame_a)
  connect(cylinderInclination.frame_b, cylinderTop.frame_a)
  connect(crank1.frame_b, crank2.frame_a)
  connect(crank3.frame_b, crank4.frame_a)
  connect(crank3.frame_a, crank2.frame_b)
  connect(crank2.frame_b, mid.frame_a)
  connect(cylinderTop.frame_b, cylinder.frame_a)
  connect(cylinderInclination.frame_a, cylinder_a)
  connect(mounting.frame_a, cylinder_a)
  connect(mounting.frame_b, cylinder_b)
  connect(crankAngle1.frame_a, crank_a)
  connect(crankAngle2.frame_b, crank_b)

  connect(cylinder.axis, gasForce.flange_b)
  connect(cylinder.support, gasForce.flange_a)
end Cylinder;


One cylinder with analytic handling of kinematic loop. Slider-crank mechanism with analytic handling of kinematic loop to model one cylinder in an engine.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
model CylinderBase "One cylinder with analytic handling of kinematic loop"
  parameter Boolean animation=true "= true, if animation shall be enabled";
  parameter SI.Length cylinderTopPosition=0.42
    "Length from crank shaft to end of cylinder.";
  parameter SI.Length crankLength=0.14 "Length of crank shaft in x direction";
  parameter SI.Length crankPinOffset=0.05
    "Offset of crank pin from center axis";
  parameter SI.Length crankPinLength=0.1
    "Offset of crank pin from center axis";
  parameter Modelica.Units.NonSI.Angle_deg cylinderInclinationAngle=0
    "Inclination of cylinder";
  parameter Modelica.Units.NonSI.Angle_deg crankAngleOffset=0
    "Offset for crank angle";
  parameter SI.Length pistonLength=0.1 "Length of cylinder"
  parameter SI.Length pistonCenterOfMass=pistonLength/2
    "Distance from frame_a to center of mass of piston"
  parameter SI.Mass pistonMass(min=0) = 6 "Mass of piston"
  parameter SI.Inertia pistonInertia_11(min=0) = 0.0088
    "Inertia 11 of piston with respect to center of mass frame, parallel to frame_a"
  parameter SI.Inertia pistonInertia_22(min=0) = 0.0076
    "Inertia 22 of piston with respect to center of mass frame, parallel to frame_a"
  parameter SI.Inertia pistonInertia_33(min=0) = 0.0088
    "Inertia 33 of piston with respect to center of mass frame, parallel to frame_a"

  parameter SI.Length rodLength=0.175 "Length of rod"
  parameter SI.Length rodCenterOfMass=rodLength/2
    "Distance from frame_a to center of mass of piston"
  parameter SI.Mass rodMass(min=0) = 1 "Mass of rod"
  parameter SI.Inertia rodInertia_11(min=0) = 0.006
    "Inertia 11 of rod with respect to center of mass frame, parallel to frame_a"
  parameter SI.Inertia rodInertia_22(min=0) = 0.0005
    "Inertia 22 of rod with respect to center of mass frame, parallel to frame_a"
  parameter SI.Inertia rodInertia_33(min=0) = 0.006
    "Inertia 33 of rod with respect to center of mass frame, parallel to frame_a"
  final parameter SI.Length cylinderLength=cylinderTopPosition - (
      pistonLength + rodLength - crankPinOffset)
    "Maximum length of cylinder volume";

  Modelica.Mechanics.MultiBody.Parts.FixedTranslation mid(animation=false, r={crankLength -
        crankPinLength/2,crankPinOffset,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation mounting(r={crankLength,0,0}, animation=
        false)
  Modelica.Mechanics.MultiBody.Parts.FixedRotation cylinderInclination(
    r={crankLength - crankPinLength/2,0,0},
    animation=false,
    rotationType=Modelica.Mechanics.MultiBody.Types.RotationTypes.RotationAxis,
    n={1,0,0},
    angle=cylinderInclinationAngle)
  Modelica.Mechanics.MultiBody.Parts.FixedRotation crankAngle(
    animation=false,
    rotationType=Modelica.Mechanics.MultiBody.Types.RotationTypes.RotationAxis,
    n={1,0,0},
    angle=crankAngleOffset)
  Joints.Assemblies.JointRRP jointRRP(
    n_a={1,0,0},
    n_b={0,-1,0},
    rRod1_ia={0,rodLength,0},
    animation=false,
    rRod2_ib=-{0,pistonLength,0},
    s_offset=-cylinderTopPosition)
  Modelica.Mechanics.MultiBody.Parts.BodyShape connectingRod(
    animation=animation,
    r={0,rodLength,0},
    r_CM={0,rodLength/2,0},
    shapeType="modelica://Modelica/Resources/Data/Shapes/Engine/rod.dxf",
    lengthDirection={1,0,0},
    widthDirection={0,0,-1},
    length=rodLength/1.75,
    width=rodLength/1.75,
    height=rodLength/1.75,
    color={155,155,155},
    extra=1,
    r_shape={0,0,0},
    animateSphere=false,
    m=rodMass,
    I_11=rodInertia_11,
    I_22=rodInertia_22,
    I_33=rodInertia_33)
  Modelica.Mechanics.MultiBody.Parts.BodyShape piston(
    animation=animation,
    r={0,pistonLength,0},
    r_CM={0,pistonLength/2,0},
    shapeType="modelica://Modelica/Resources/Data/Shapes/Engine/piston.dxf",
    length=0.08,
    width=0.08,
    height=0.08,
    extra=1,
    lengthDirection={1,0,0},
    widthDirection={0,0,-1},
    color={180,180,180},
    animateSphere=false,
    m=pistonMass,
    I_11=pistonInertia_11,
    I_22=pistonInertia_22,
    I_33=pistonInertia_33)
  GasForce2 gasForce(L=cylinderLength, d=0.1)

  Modelica.Mechanics.MultiBody.Parts.FixedTranslation crank(animation=false, r={crankLength,0,0})
  Interfaces.Frame_a cylinder_a
  Interfaces.Frame_a cylinder_b
  Interfaces.Frame_a crank_a
  Interfaces.Frame_a crank_b
equation

  connect(jointRRP.frame_ia, connectingRod.frame_a)
  connect(mid.frame_b, jointRRP.frame_a)
  connect(jointRRP.frame_ib, piston.frame_b)
  connect(jointRRP.frame_b, cylinderInclination.frame_b)
  connect(crankAngle.frame_b, mid.frame_a)
  connect(cylinder_a, cylinderInclination.frame_a)
  connect(cylinder_a, mounting.frame_a)
  connect(cylinder_b, mounting.frame_b)
  connect(crankAngle.frame_a, crank_a)
  connect(crank_a, crank.frame_a)
  connect(crank.frame_b, crank_b)
  connect(gasForce.flange_a, jointRRP.bearing)
  connect(gasForce.flange_b, jointRRP.axis)
end CylinderBase;


One cylinder with analytic handling of kinematic loop and CAD visualization. Slider-crank mechanism with analytic handling of kinematic loop to model one cylinder in an engine.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
model Cylinder_analytic_CAD
  "One cylinder with analytic handling of kinematic loop and CAD visualization"
  extends CylinderBase;
  Visualizers.FixedShape crankShape(
    animation=animation,
    shapeType="modelica://Modelica/Resources/Data/Shapes/Engine/crank.dxf",
    lengthDirection={1,0,0},
    extra=1,
    widthDirection={0,1,0},
    length=crankPinOffset/0.5,
    width=crankPinOffset/0.5,
    height=crankPinOffset/0.5,
    r_shape={crankLength - crankPinLength/2 - 0.002,0,0})
equation

  connect(crankShape.frame_a, crankAngle.frame_b)
end Cylinder_analytic_CAD;


Base model for one cylinder engine. This is a model of the mechanical part of one cylinder of an engine.
The combustion is not modelled. The \"inertia\" component at the lower
left part is the output inertia of the engine driving the gearbox.
The angular velocity of the output inertia has a start value of 10 rad/s
in order to demonstrate the movement of the engine.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
partial block Engine1Base
  "Base model for one cylinder engine"

  inner Modelica.Mechanics.MultiBody.World world
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder piston(diameter=0.1, r={0,-0.1,0})
  Modelica.Mechanics.MultiBody.Parts.BodyBox connectingRod(
    widthDirection={1,0,0},
    width=0.02,
    height=0.06,
    color={0,0,200},
    r={0,-0.2,0})
  Modelica.Mechanics.MultiBody.Joints.Revolute bearing(useAxisFlange=true,
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.05)
  Modelica.Mechanics.Rotational.Components.Inertia inertia(
    stateSelect=StateSelect.always,
    J=1,
    w(fixed=true,
      start = 10),
    phi(
      fixed=true,
      start=0.0,
      displayUnit="rad"))
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder crank1(diameter=0.05, r={0.1,0,0})
  Modelica.Mechanics.MultiBody.Parts.BodyBox crank2(
    height=0.05,
    widthDirection={1,0,0},
    width=0.02,
    r={0,0.1,0})
  Modelica.Mechanics.MultiBody.Parts.BodyCylinder crank3(r={0.1,0,0}, diameter=0.03)
  Modelica.Mechanics.MultiBody.Parts.BodyBox crank4(
    height=0.05,
    widthDirection={1,0,0},
    width=0.02,
    r={0,-0.1,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation mid(r={0.05,0,0})
  Modelica.Mechanics.MultiBody.Parts.FixedTranslation cylPosition(
    animation=false,
    r = {0.15,0.45,0})
equation
  connect(world.frame_b, bearing.frame_a)
  connect(crank2.frame_a, crank1.frame_b)
  connect(bearing.frame_b, crank1.frame_a)
  connect(world.frame_b, cylPosition.frame_a)
  connect(crank3.frame_b, crank4.frame_a)
  connect(inertia.flange_b, bearing.axis)
  connect(crank2.frame_b, crank3.frame_a)
  connect(crank2.frame_b, mid.frame_a)
end Engine1Base;


Base model for one cylinder engine with gas force.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
partial block Engine1bBase
  "Base model for one cylinder engine with gas force"
  extends Engine1Base;

  GasForce2 gasForce(d=0.1, L=0.35)
end Engine1bBase;


V6 engine with analytic loop handling. Model of one cylinder of an engine with analytic loop handling of the slider crank mechanism.

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
model EngineV6_analytic "V6 engine with analytic loop handling"
  parameter Boolean animation=true "= true, if animation shall be enabled";
  replaceable model Cylinder = Cylinder_analytic_CAD constrainedby CylinderBase
                 "Cylinder type"

  Cylinder cylinder1(
    crankAngleOffset=-30,
    cylinderInclinationAngle=-30,
    animation=animation)
  Cylinder cylinder2(
    crankAngleOffset=90,
    cylinderInclinationAngle=30,
    animation=animation)
  Cylinder cylinder3(
    cylinderInclinationAngle=-30,
    animation=animation,
    crankAngleOffset=210)
  Cylinder cylinder4(
    cylinderInclinationAngle=30,
    animation=animation,
    crankAngleOffset=210)
  Cylinder cylinder5(
    cylinderInclinationAngle=-30,
    animation=animation,
    crankAngleOffset=90)
  Cylinder cylinder6(
    cylinderInclinationAngle=30,
    animation=animation,
    crankAngleOffset=-30)
  Joints.Revolute bearing(useAxisFlange=true,
    n={1,0,0},
    cylinderLength=0.02,
    cylinderDiameter=0.06,
    animation=true)
  Parts.BodyShape crank(
    animation=false,
    r={0,0,0},
    r_CM={6*0.1/2,0,0},
    I_22=1.e-5,
    I_33=1.e-5,
    m=6*30,
    I_11=0.1)
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
  Interfaces.Frame_a frame_a
equation
  connect(cylinder1.crank_b, cylinder2.crank_a)
  connect(cylinder2.cylinder_a, cylinder1.cylinder_b)
  connect(cylinder3.cylinder_a, cylinder2.cylinder_b)
  connect(cylinder3.crank_a, cylinder2.crank_b)
  connect(cylinder3.cylinder_b, cylinder4.cylinder_a)
  connect(cylinder3.crank_b, cylinder4.crank_a)
  connect(cylinder4.cylinder_b, cylinder5.cylinder_a)
  connect(cylinder4.crank_b, cylinder5.crank_a)
  connect(cylinder5.cylinder_b, cylinder6.cylinder_a)
  connect(cylinder5.crank_b, cylinder6.crank_a)
  connect(bearing.frame_b, crank.frame_a)
  connect(crank.frame_b, cylinder1.crank_a)
  connect(bearing.axis, flange_b)
  connect(frame_a, bearing.frame_a)
  connect(bearing.frame_a, cylinder1.cylinder_a)
end EngineV6_analytic;


Rough approximation of gas force in a combustion engine's cylinder. The gas force in a cylinder of a combustion engine is computed as function of the relative
distance of the two flanges. It is required that s_rel = flange_b.s - flange_a.s
is in the range

within Modelica.Mechanics.MultiBody.Examples.Loops.Utilities;
model GasForce2 "Rough approximation of gas force in a combustion engine's cylinder"
  import Modelica.Constants.pi;

  extends Modelica.Mechanics.Translational.Interfaces.PartialCompliant;
  parameter SI.Length L "Length of cylinder";
  parameter SI.Length d "Diameter of cylinder";
  parameter SI.Volume k0=0.01
    "Volume V = k0 + k1*(1-x), with x = 1 - s_rel/L";
  parameter SI.Volume k1=1
    "Volume V = k0 + k1*(1-x), with x = 1 - s_rel/L";
  parameter SI.HeatCapacity k=1 "Gas constant (p*V = k*T)";

/*
  parameter Real k0=0.01;
  parameter Real k1=1;
  parameter Real k=1;
*/
  Real x "Normalized position of cylinder (= 1 - s_rel/L)";
  SI.AbsolutePressure press "Cylinder pressure";
  SI.Volume V;
  SI.Temperature T;
  SI.Velocity v_rel "Relative piston velocity (<0: compression;  >0: expansion)";

equation
  x = 1 - s_rel/L;
  v_rel = der(s_rel);

  press = 1e5 * (
    if v_rel < 0 then (
      if x < 0.986061 then 177.4132*x^4 - 287.2189*x^3 + 151.8252*x^2 - 24.9973*x + 2.4
      else 2836360*x^4 - 10569296*x^3 + 14761814*x^2 - 9158505*x + 2129670)
    else (
      if x > 0.933 then -3929704*x^4 + 14748765*x^3 - 20747000*x^2 + 12964477*x - 3036495
      else 145.930*x^4 - 131.707*x^3 + 17.3438*x^2 + 17.9272*x + 2.4));

  f = -press*pi*d^2/4;

  V = k0 + k1*(1 - x);
  press*V = k*T;

  assert(s_rel >= -1e-12, "flange_b.s - flange_a.s (= " + String(s_rel,
    significantDigits=14) + ") >= 0 required for GasForce2 component.\n" +
    "Most likely, the component has to be flipped.");
  assert(s_rel <= L + 1e-12, " flange_b.s - flange_a.s (= " + String(s_rel,
    significantDigits=14) + ") <= L (= " + String(L, significantDigits=14) +
    ") required for GasForce2 component.\n" +
    "Most likely, parameter L is not correct.");
end GasForce2;


within Modelica.Mechanics.MultiBody.Examples.Loops;
package Utilities "Utility classes for examples of kinematic loops"
  extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Demonstrates usage of models Rotor1D and Mounting1D. This example demonstrates how to utilize the
Rotor1D
and Mounting1D models and
compares the implementation with a standard multi-body implementation.
Note, the solution with Rotor1D is much more efficient.

within Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects;
model ActuatedDrive "Demonstrates usage of models Rotor1D and Mounting1D"
  extends Modelica.Icons.Example;
  Parts.BodyShape bodyCylinder(
    r={0.5,0,0},
    m=0,
    I_11=2,
    I_22=0,
    I_33=0,
    shapeType="cylinder",
    width=0.1,
    animateSphere=false,
    r_shape={0.1,0,0},
    r_CM={0,0,0})
  Joints.Revolute revolute(
    n={1,0,0},
    a(fixed=false),
    phi(fixed=true),
    w(fixed=true))
  inner World world(g=0, driveTrainMechanics3D=true)
  Forces.Torque torque
  Blocks.Sources.Sine sine[3](amplitude={1,0,0}, f={1,1,1})
  inner Parts.Fixed fixed
  Parts.Rotor1D rotor1D(
    J=2,
    phi(fixed=true),
    w(fixed=true))
  Rotational.Sources.Torque torque1(useSupport=true)
  Parts.Mounting1D mounting1D
equation
  connect(world.frame_b, revolute.frame_a)
  connect(revolute.frame_b, bodyCylinder.frame_a)
  connect(torque.frame_b, bodyCylinder.frame_b)
  connect(torque.frame_a, world.frame_b)
  connect(sine.y, torque.torque)
  connect(fixed.frame_b, rotor1D.frame_a)
  connect(torque1.flange, rotor1D.flange_a)
  connect(mounting1D.flange_b, torque1.support)
  connect(mounting1D.frame_a, fixed.frame_b)
  connect(sine[1].y, torque1.tau)
end ActuatedDrive;


Demonstrates the usage of a BevelGear1D model and how to calculate the power of such an element. This model consists of a drive train with two inertias that are coupled by a bevel gear
(with 90 degree angle between the two gear flanges).
This drive train is mounted on a body that is rotated along three axes.
The drive train is modeled with 1D rotational elements that take into account 3D effects.

within Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects;
model BevelGear1D
  "Demonstrates the usage of a BevelGear1D model and how to calculate the power of such an element"
  import Modelica.Mechanics.MultiBody.Frames;
  extends Modelica.Icons.Example;
  parameter Modelica.Mechanics.MultiBody.Types.Axis na={1,0,0}
    "Axis of rotation of left gear axis";
  parameter Modelica.Mechanics.MultiBody.Types.Axis nb={0,1,0}
    "Axis of rotation of right gear axis";

  inner Modelica.Mechanics.MultiBody.World world(final driveTrainMechanics3D=true)
  Modelica.Mechanics.MultiBody.Parts.Rotor1D       inertia1(
    J=1.1,
    a(fixed=false),
    phi(fixed=true, start=0),
    w(fixed=true, start=0),
    n=na)
  Modelica.Mechanics.MultiBody.Parts.Rotor1D       inertia2(J=18.2, n=nb)
  Modelica.Mechanics.MultiBody.Parts.BevelGear1D bevelGear(
    ratio=10,
    n_a=na,
    n_b=nb)
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute1(useAxisFlange=true, n={
        1,0,0},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    w(fixed=true))
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute2(useAxisFlange=true, n={
        0,1,0},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    w(fixed=true))
  Modelica.Mechanics.MultiBody.Joints.Revolute revolute3(useAxisFlange=true, n={
        0,0,1},
    stateSelect=StateSelect.always,
    phi(fixed=true),
    w(fixed=true))
  Modelica.Mechanics.Rotational.Sources.Torque torque1
  Modelica.Mechanics.Rotational.Sources.Torque torque2
  Modelica.Mechanics.Rotational.Sources.Torque torque3
  Modelica.Blocks.Sources.Sine sine1(amplitude=110, f=5)
  Modelica.Blocks.Sources.Sine sine2(amplitude=120, f=6)
  Modelica.Blocks.Sources.Sine sine3(amplitude=130, f=7)
  Modelica.Mechanics.MultiBody.Parts.Mounting1D mounting1D(n=na)
  Modelica.Mechanics.Rotational.Sources.Torque torque(useSupport=true)
  Modelica.Blocks.Sources.Sine sine4(amplitude=140, f=8)
  Modelica.Mechanics.MultiBody.Parts.BodyBox bodyBox(
    r={0.1,0.1,0.1},
    length=0.1,
    width=0.1)
  Sensors.AbsoluteAngularVelocity sensor1(resolveInFrame=Modelica.Mechanics.MultiBody.Types.ResolveInFrameA.frame_a)
  Sensors.CutTorque sensor2(resolveInFrame=Modelica.Mechanics.MultiBody.Types.ResolveInFrameA.frame_a,
      animation=false)
  SI.AngularVelocity ws[3] = sensor1.w;
  SI.Power bevelGearPower;
equation
  bevelGearPower = (ws + der(bevelGear.flange_a.phi)*na)*bevelGear.flange_a.tau*na +
                   (ws + der(bevelGear.flange_b.phi)*nb)*bevelGear.flange_b.tau*nb +
                   ws*sensor2.torque;
  assert(abs(bevelGearPower) < 1e-3, "Error, energy balance of bevel gear is wrong");

  connect(inertia1.flange_b, bevelGear.flange_a)
  connect(bevelGear.flange_b, inertia2.flange_a)
  connect(world.frame_b, revolute1.frame_a)
  connect(revolute1.frame_b, revolute2.frame_a)
  connect(revolute2.frame_b, revolute3.frame_a)
  connect(torque1.flange, revolute1.axis)
  connect(torque2.flange, revolute2.axis)
  connect(torque3.flange, revolute3.axis)
  connect(sine1.y, torque1.tau)
  connect(torque2.tau, sine2.y)
  connect(torque3.tau, sine3.y)
  connect(torque.flange, inertia1.flange_a)
  connect(torque.support, mounting1D.flange_b)
  connect(mounting1D.frame_a, revolute3.frame_b)
  connect(torque.tau, sine4.y)
  connect(revolute3.frame_b, bodyBox.frame_a)
  connect(inertia1.frame_a, revolute3.frame_b)
  connect(inertia2.frame_a, revolute3.frame_b)
  connect(bevelGear.frame_a, sensor1.frame_a)
  connect(bevelGear.frame_a, sensor2.frame_b)
  connect(sensor2.frame_a, revolute3.frame_b)
equation
  bevelGearPower = (ws + der(bevelGear.flange_a.phi)*na)*bevelGear.flange_a.tau*na +
                   (ws + der(bevelGear.flange_b.phi)*nb)*bevelGear.flange_b.tau*nb +
                   ws*bevelGear.frame_a.t;

The total energy flow bevelGearPower must be zero. If a relative tolerance of 1e-4 is used
for simulation, bevelGearPower is in the order of 1e-8 (and smaller for a smaller relative
tolerance).

"),
    experiment(StopTime=1.0));
end BevelGear1D;


Demonstrate usage of GearConstraint model. This model demonstrates the usage of the
GearConstraint
model to model a gearbox with multi-body elements. The formulation is compared with
a one-dimensional model that is mounted with an
Mounting1D element.

within Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects;
model GearConstraint "Demonstrate usage of GearConstraint model"
  extends Modelica.Icons.Example;
  Joints.GearConstraint gearConstraint(
    ratio=10,
    phi_b(fixed=true),
    w_b(fixed=true),
    checkTotalPower=true)
  inner World world(driveTrainMechanics3D=true, g=0)
  Parts.BodyCylinder cyl1(
    diameter=0.1,
    color={0,128,0},
    r={0.4,0,0})
  Parts.BodyCylinder cyl2(r={0.4,0,0}, diameter=0.2)
  Forces.Torque torque1
  Blocks.Sources.Sine sine[3](amplitude={2,0,0}, f={1,1,1})
  Parts.Fixed fixed
  Rotational.Components.Inertia inertia1(
    J=cyl1.I[1, 1],
    a(fixed=false),
    phi(fixed=true, start=0),
    w(fixed=true, start=0))
  Rotational.Components.IdealGear idealGear(ratio=10, useSupport=true)
  Rotational.Components.Inertia inertia2(J=cyl2.I[1, 1])
  Rotational.Sources.Torque torque2(useSupport=true)
  Parts.Mounting1D mounting1D
equation
  connect(world.frame_b, gearConstraint.bearing)
  connect(cyl1.frame_b, gearConstraint.frame_a)
  connect(gearConstraint.frame_b, cyl2.frame_a)
  connect(torque1.frame_b, cyl1.frame_a)
  connect(torque1.frame_a, world.frame_b)
  connect(sine.y, torque1.torque)
  connect(inertia1.flange_b, idealGear.flange_a)
  connect(idealGear.flange_b, inertia2.flange_a)
  connect(torque2.flange, inertia1.flange_a)
  connect(sine[1].y, torque2.tau)
  connect(mounting1D.flange_b, idealGear.support)
  connect(mounting1D.flange_b, torque2.support)
  connect(fixed.frame_b, mounting1D.frame_a)
end GearConstraint;


Demonstrates that a cylindrical body can be replaced by Rotor1D model. This example consists of a body that is attached to the world system
with a spherical joint. On this body, a \"rotor\", i.e., a body with rotational
symmetry is present. Two kinds of models are shown:

within Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects;
model GyroscopicEffects
  "Demonstrates that a cylindrical body can be replaced by Rotor1D model"
  extends Modelica.Icons.Example;

  inner World world(driveTrainMechanics3D=true)
  Joints.Spherical spherical1(
    angles_fixed=true,
    w_rel_a_fixed=true,
    z_rel_a_fixed=false)
  Parts.BodyCylinder bodyCylinder1(r={0.25,0,0}, diameter=0.05)
  Parts.FixedRotation fixedRotation1(angle=45, n={0,1,0})
  Joints.Revolute revolute(
    n={1,0,0},
    a(fixed=false),
    phi(fixed=true),
    w(fixed=true, start=10))
  Parts.FixedTranslation fixedTranslation(r={-0.1,0,0})
  Parts.BodyCylinder bodyCylinder2(diameter=0.1, r={0.2,0,0})
  Parts.Fixed fixed
  Joints.Spherical spherical2(
    angles_fixed=true,
    w_rel_a_fixed=true,
    z_rel_a_fixed=false)
  Parts.BodyCylinder bodyCylinder3(
    r={0.25,0,0},
    diameter=0.05,
    color={0,128,0})
  Parts.FixedRotation fixedRotation2(n={0,1,0}, angle=45)
  Parts.FixedTranslation fixedTranslation1(r={-0.1,0,0})
  Parts.BodyCylinder bodyCylinder4(
    diameter=0.1,
    r={0.2,0,0},
    color={0,128,0})
  Parts.Rotor1D rotor1D(
    J=bodyCylinder4.I[1, 1],
    n={1,0,0},
    a(fixed=false),
    phi(fixed=true),
    w(fixed=true, start=10))
equation
  connect(world.frame_b, spherical1.frame_a)
  connect(spherical1.frame_b, bodyCylinder1.frame_a)
  connect(bodyCylinder1.frame_b, fixedRotation1.frame_a)
  connect(fixedRotation1.frame_b, revolute.frame_a)
  connect(revolute.frame_b, fixedTranslation.frame_a)
  connect(fixedTranslation.frame_b, bodyCylinder2.frame_a)
  connect(spherical2.frame_b, bodyCylinder3.frame_a)
  connect(bodyCylinder3.frame_b, fixedRotation2.frame_a)
  connect(fixed.frame_b, spherical2.frame_a)
  connect(fixedTranslation1.frame_b, bodyCylinder4.frame_a)
  connect(fixedRotation2.frame_b, fixedTranslation1.frame_a)
  connect(rotor1D.frame_a, fixedRotation2.frame_b)
end GyroscopicEffects;


Demonstrates usage of model Rotor1D mounted on a moving body. This model demonstrates how a moving drive train modelled with 3-dim. multi-body elements
(revolute, bodyCylinder) can alternatively be modeled with component rotor1D to speed up
simulation. The movement of the two systems is identical and also the cut-torques in the
various frames (such as: r1.frame_b.t and r2.frame_b.t).

within Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects;
model MovingActuatedDrive
  "Demonstrates usage of model Rotor1D mounted on a moving body"
  extends Modelica.Icons.Example;
  Parts.BodyShape bodyCylinder(
    r={0.5,0,0},
    m=0,
    I_11=2,
    I_22=0,
    I_33=0,
    shapeType="cylinder",
    width=0.1,
    animateSphere=false,
    r_shape={0.1,0,0},
    r_CM={0,0,0})
  Joints.Revolute revolute(
    n={1,0,0},
    a(fixed=false),
    phi(fixed=true),
    w(fixed=true))
  inner World world(g=0, driveTrainMechanics3D=true)
  Forces.Torque torque
  Blocks.Sources.Sine sine1[3](amplitude={1,0,0}, f={1,1,1})
  Parts.Rotor1D rotor1D(
    J=2,
    phi(fixed=true),
    w(fixed=true))
  Rotational.Sources.Torque torque1(useSupport=true)
  Parts.Mounting1D mounting1D
  Joints.Revolute r1(useAxisFlange=true, n={0,1,0})
  Rotational.Sources.Position position1(useSupport=true, w(fixed=true))
  Blocks.Sources.Sine sine2(amplitude=2, f=1)
  Parts.Mounting1D mounting1D1(n={0,1,0})
  Joints.Revolute r2(useAxisFlange=true, n={0,1,0})
  Rotational.Sources.Position position2(useSupport=true, w(fixed=true))
  Parts.Mounting1D mounting1D2(n={0,1,0})
  Parts.Fixed fixed
equation
  connect(revolute.frame_b, bodyCylinder.frame_a)
  connect(torque.frame_b, bodyCylinder.frame_b)
  connect(sine1.y, torque.torque)
  connect(torque1.flange, rotor1D.flange_a)
  connect(mounting1D.flange_b, torque1.support)
  connect(r1.frame_a, world.frame_b)
  connect(position1.flange, r1.axis)
  connect(position1.support, mounting1D1.flange_b)
  connect(mounting1D1.frame_a, world.frame_b)
  connect(sine2.y, position1.phi_ref)
  connect(r1.frame_b, revolute.frame_a)
  connect(torque.frame_a, revolute.frame_a)
  connect(position2.flange, r2.axis)
  connect(position2.support, mounting1D2.flange_b)
  connect(fixed.frame_b, r2.frame_a)
  connect(fixed.frame_b, mounting1D2.frame_a)
  connect(sine2.y, position2.phi_ref)
  connect(r2.frame_b, rotor1D.frame_a)
  connect(r2.frame_b, mounting1D.frame_a)
  connect(sine1[1].y, torque1.tau)
end MovingActuatedDrive;


within Modelica.Mechanics.MultiBody.Examples;
package Rotational3DEffects "Demonstrates the usage of 1-dim. rotational elements with all 3-dim. effects included"
  extends Modelica.Icons.ExamplesPackage;
end Rotational3DEffects;


within Modelica.Mechanics.MultiBody.Examples;
package Systems "Examples of complete system models including 3-dimensional mechanics"
  extends Modelica.Icons.ExamplesPackage;
end Systems;


Six degree of freedom robot with path planning, controllers, motors, brakes, gears and mechanics. This example animates a motion of a detailed model of the robot
with predefined axes' angles over time.
For animation, CAD data is used.
Translate and simulate with the default settings
(default simulation stop time = 2 s).

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3;
model FullRobot
  "Six degree of freedom robot with path planning, controllers, motors, brakes, gears and mechanics"
  extends Modelica.Icons.Example;

  parameter SI.Mass mLoad(min=0) = 15 "Mass of load";
  parameter SI.Position rLoad[3]={0.1,0.25,0.1}
    "Distance from last flange to load mass";
  parameter SI.Acceleration g=9.81 "Gravity acceleration";
  parameter SI.Time refStartTime=0 "Start time of reference motion";
  parameter SI.Time refSwingTime=0.5
    "Additional time after reference motion is in rest before simulation is stopped";

  parameter Modelica.Units.NonSI.Angle_deg startAngle1 = -60 "Start angle of axis 1"
  parameter Modelica.Units.NonSI.Angle_deg startAngle2 = 20 "Start angle of axis 2"
  parameter Modelica.Units.NonSI.Angle_deg startAngle3 = 90 "Start angle of axis 3"
  parameter Modelica.Units.NonSI.Angle_deg startAngle4 = 0 "Start angle of axis 4"
  parameter Modelica.Units.NonSI.Angle_deg startAngle5 = -110 "Start angle of axis 5"
  parameter Modelica.Units.NonSI.Angle_deg startAngle6 = 0 "Start angle of axis 6"

  parameter Modelica.Units.NonSI.Angle_deg endAngle1 = 60 "End angle of axis 1"
  parameter Modelica.Units.NonSI.Angle_deg endAngle2 = -70 "End angle of axis 2"
  parameter Modelica.Units.NonSI.Angle_deg endAngle3 = -35 "End angle of axis 3"
  parameter Modelica.Units.NonSI.Angle_deg endAngle4 = 45 "End angle of axis 4"
  parameter Modelica.Units.NonSI.Angle_deg endAngle5 = 110 "End angle of axis 5"
  parameter Modelica.Units.NonSI.Angle_deg endAngle6 = 45 "End angle of axis 6"

  parameter SI.AngularVelocity refSpeedMax[6]={3,1.5,5,3.1,3.1,4.1}
    "Maximum reference speeds of all joints"
  parameter SI.AngularAcceleration refAccMax[6]={15,15,15,60,60,60}
    "Maximum reference accelerations of all joints"

  parameter Real kp1=5 "Gain of position controller"
  parameter Real ks1=0.5 "Gain of speed controller"
  parameter SI.Time Ts1=0.05
    "Time constant of integrator of speed controller"
  parameter Real kp2=5 "Gain of position controller"
  parameter Real ks2=0.5 "Gain of speed controller"
  parameter SI.Time Ts2=0.05
    "Time constant of integrator of speed controller"
  parameter Real kp3=5 "Gain of position controller"
  parameter Real ks3=0.5 "Gain of speed controller"
  parameter SI.Time Ts3=0.05
    "Time constant of integrator of speed controller"
  parameter Real kp4=5 "Gain of position controller"
  parameter Real ks4=0.5 "Gain of speed controller"
  parameter SI.Time Ts4=0.05
    "Time constant of integrator of speed controller"
  parameter Real kp5=5 "Gain of position controller"
  parameter Real ks5=0.5 "Gain of speed controller"
  parameter SI.Time Ts5=0.05
    "Time constant of integrator of speed controller"
  parameter Real kp6=5 "Gain of position controller"
  parameter Real ks6=0.5 "Gain of speed controller"
  parameter SI.Time Ts6=0.05
    "Time constant of integrator of speed controller"
  Utilities.MechanicalStructure mechanics(
    mLoad=mLoad,
    rLoad=rLoad,
    g=g)
  Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities.PathPlanning6 pathPlanning(
    naxis=6,
    angleBegDeg={startAngle1,startAngle2,startAngle3,startAngle4,startAngle5,startAngle6},
    angleEndDeg={endAngle1,endAngle2,endAngle3,endAngle4,endAngle5,endAngle6},
    speedMax=refSpeedMax,
    accMax=refAccMax,
    startTime=refStartTime,
    swingTime=refSwingTime)

  Utilities.AxisType1 axis1(
    w=4590,
    ratio=-105,
    c=43,
    cd=0.005,
    Rv0=0.4,
    Rv1=(0.13/160),
    kp=kp1,
    ks=ks1,
    Ts=Ts1)
  Utilities.AxisType1 axis2(
    w=5500,
    ratio=210,
    c=8,
    cd=0.01,
    Rv1=(0.1/130),
    Rv0=0.5,
    kp=kp2,
    ks=ks2,
    Ts=Ts2)

  Utilities.AxisType1 axis3(
    w=5500,
    ratio=60,
    c=58,
    cd=0.04,
    Rv0=0.7,
    Rv1=(0.2/130),
    kp=kp3,
    ks=ks3,
    Ts=Ts3)
  Utilities.AxisType2 axis4(
    k=0.2365,
    w=6250,
    D=0.55,
    J=1.6e-4,
    ratio=-99,
    Rv0=21.8,
    Rv1=9.8,
    peak=26.7/21.8,
    kp=kp4,
    ks=ks4,
    Ts=Ts4)
  Utilities.AxisType2 axis5(
    k=0.2608,
    w=6250,
    D=0.55,
    J=1.8e-4,
    ratio=79.2,
    Rv0=30.1,
    Rv1=0.03,
    peak=39.6/30.1,
    kp=kp5,
    ks=ks5,
    Ts=Ts5)
  Utilities.AxisType2 axis6(
    k=0.0842,
    w=7400,
    D=0.27,
    J=4.3e-5,
    ratio=-99,
    Rv0=10.9,
    Rv1=3.92,
    peak=16.8/10.9,
    kp=kp6,
    ks=ks6,
    Ts=Ts6)
protected
  Utilities.ControlBus controlBus
equation
  connect(axis2.flange, mechanics.axis2)
  connect(axis1.flange, mechanics.axis1)
  connect(axis3.flange, mechanics.axis3)
  connect(axis4.flange, mechanics.axis4)
  connect(axis5.flange, mechanics.axis5)
  connect(axis6.flange, mechanics.axis6)
  connect(controlBus, pathPlanning.controlBus)
  connect(controlBus.axisControlBus1, axis1.axisControlBus)

  connect(controlBus.axisControlBus2, axis2.axisControlBus)

  connect(controlBus.axisControlBus3, axis3.axisControlBus)

  connect(controlBus.axisControlBus4, axis4.axisControlBus)
  connect(controlBus.axisControlBus5, axis5.axisControlBus)
  connect(controlBus.axisControlBus6, axis6.axisControlBus)
end FullRobot;


Model of one axis of robot (controller, motor, gearbox) with simple load. With this model one axis of the r3 robot is checked.
The mechanical structure is replaced by a simple
load inertia.

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3;
model OneAxis
  "Model of one axis of robot (controller, motor, gearbox) with simple load"

  extends Modelica.Icons.Example;
  parameter SI.Mass mLoad(min=0)=15 "Mass of load";
  parameter SI.Radius rg = 1.14 "Radius of gyration of load";
  parameter Real kp=5 "Gain of position controller of axis";
  parameter Real ks=0.5 "Gain of speed controller of axis";
  parameter SI.Time Ts=0.05
    "Time constant of integrator of speed controller of axis";
  parameter Modelica.Units.NonSI.Angle_deg startAngle = 0 "Start angle of axis";
  parameter Modelica.Units.NonSI.Angle_deg endAngle = 120 "End angle of axis";

  parameter SI.Time swingTime=0.5
    "Additional time after reference motion is in rest before simulation is stopped";
  parameter SI.AngularVelocity refSpeedMax=3 "Maximum reference speed";
  parameter SI.AngularAcceleration refAccMax=10
    "Maximum reference acceleration";

  Utilities.AxisType1 axis(
    w=5500,
    ratio=210,
    c=8,
    cd=0.01,
    Rv0=0.5,
    Rv1=(0.1/130),
    kp=kp,
    ks=ks,
    Ts=Ts)
  Modelica.Mechanics.Rotational.Components.Inertia load(J=rg^2*mLoad)
  Utilities.PathPlanning1 pathPlanning(
    swingTime=swingTime,
    angleBegDeg=startAngle,
    angleEndDeg=endAngle,
    speedMax=refSpeedMax,
    accMax=refAccMax)
protected
  Utilities.ControlBus controlBus
equation
  connect(axis.flange, load.flange_a)
  connect(pathPlanning.controlBus, controlBus)
  connect(controlBus.axisControlBus1, axis.axisControlBus)
end OneAxis;


within Modelica.Mechanics.MultiBody.Examples.Systems;
package RobotR3 "Library to demonstrate robot system models based on the Manutec r3 robot"
  extends Modelica.Icons.ExamplesPackage;

end RobotR3;


Axis model of the r3 joints 1,2,3. Model of axis 1, 2, 3 of the robot r3. An axis consists of a gearbox with modelled gear elasticity and bearing friction,
a model of the electrical motor and a continuous-time cascade controller.

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities;
model AxisType1 "Axis model of the r3 joints 1,2,3"
  extends AxisType2(redeclare GearType1 gear(c=c, d=cd))
  parameter SI.RotationalSpringConstant c = 43 "Spring constant"
  parameter SI.RotationalDampingConstant cd = 0.005 "Damper constant"
end AxisType1;


Axis model of the r3 joints 4,5,6. The axis model consists of the controller, the motor including current
controller and the gearbox including gear elasticity and bearing friction.
The only difference to the axis model of joints 4,5,6 (= model axisType2) is
that elasticity and damping in the gear boxes are not neglected.

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities;
model AxisType2 "Axis model of the r3 joints 4,5,6"
  parameter Real kp=10 "Gain of position controller"
  parameter Real ks=1 "Gain of speed controller"
  parameter SI.Time Ts=0.01
    "Time constant of integrator of speed controller"
  parameter Real k=1.1616 "Gain of motor"
  parameter Real w=4590 "Time constant of motor"
  parameter Real D=0.6 "Damping constant of motor"
  parameter SI.Inertia J(min=0) = 0.0013 "Moment of inertia of motor"
  parameter Real ratio=-105 "Gear ratio"
  parameter SI.Torque Rv0=0.4
    "Viscous friction torque at zero velocity"
  parameter Real Rv1(unit="N.m.s/rad") = (0.13/160)
    "Viscous friction coefficient"
  parameter Real peak=1
    "Maximum static friction torque is peak*Rv0 (peak >= 1)"

  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange
  replaceable GearType2 gear(
    Rv0=Rv0,
    Rv1=Rv1,
    peak=peak,
    i=ratio)
  Motor motor(
    J=J,
    k=k,
    w=w,
    D=D)
  Controller controller(
    kp=kp,
    ks=ks,
    Ts=Ts,
    ratio=ratio)
  Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities.AxisControlBus axisControlBus
  Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor
  Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor
  Modelica.Mechanics.Rotational.Sensors.AccSensor accSensor
  Modelica.Mechanics.Rotational.Components.InitializeFlange
    initializeFlange(                          stateSelect=StateSelect.prefer)
  Blocks.Sources.Constant const(k=0)
equation
  connect(gear.flange_b, flange)
  connect(gear.flange_b, angleSensor.flange)
  connect(gear.flange_b, speedSensor.flange)
  connect(motor.flange_motor, gear.flange_a)
  connect(gear.flange_b, accSensor.flange)
  connect(motor.axisControlBus, axisControlBus)
  connect(angleSensor.phi, axisControlBus.angle)
  connect(speedSensor.w, axisControlBus.speed)
  connect(accSensor.a, axisControlBus.acceleration)
  connect(axisControlBus.angle_ref, initializeFlange.phi_start)
  connect(axisControlBus.speed_ref, initializeFlange.w_start)
  connect(initializeFlange.flange, flange)
  connect(const.y, initializeFlange.a_start)
  connect(controller.axisControlBus, axisControlBus)
end AxisType2;


P-PI cascade controller for one axis. This controller has an inner PI controller to control the motor speed,
and an outer P controller to control the motor position of one axis.
The reference signals are with respect to the gear-output, and the
gear ratio is used in the controller to determine the motor
reference signals. All signals are communicated via the
\"axisControlBus\".

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities;
model Controller "P-PI cascade controller for one axis"
  extends Blocks.Icons.Block;

  parameter Real kp=10 "Gain of position controller";
  parameter Real ks=1 "Gain of speed controller";
  parameter SI.Time Ts=0.01
    "Time constant of integrator of speed controller";
  parameter Real ratio=1 "Gear ratio of gearbox";

  Modelica.Blocks.Math.Gain gain1(k=ratio)
  Modelica.Blocks.Continuous.PI PI(k=ks, T=Ts)
  Modelica.Blocks.Math.Feedback feedback1
  Modelica.Blocks.Math.Gain P(k=kp)
  Modelica.Blocks.Math.Add3 add3(k3=-1)
  Modelica.Blocks.Math.Gain gain2(k=ratio)
  Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities.AxisControlBus axisControlBus
equation
  connect(gain1.y, feedback1.u1)
  connect(feedback1.y, P.u)
  connect(P.y, add3.u2)
  connect(gain2.y, add3.u1)
  connect(add3.y, PI.u)
  connect(gain2.u, axisControlBus.speed_ref)
  connect(gain1.u, axisControlBus.angle_ref)
  connect(feedback1.u2, axisControlBus.motorAngle)
  connect(add3.u3, axisControlBus.motorSpeed)
  connect(PI.y, axisControlBus.current_ref)
end Controller;


Motor inertia and gearbox model for r3 joints 1,2,3. Models the gearbox used in the first three joints with all its effects,
like elasticity and friction.
Coulomb friction is approximated by a friction element acting
at the \"motor\"-side. In reality, bearing friction should be
also incorporated at the driven side of the gearbox. However,
this would require considerable more effort for the measurement
of the friction parameters.
Default values for all parameters are given for joint 1.
Model relativeStates is used to define the relative angle
and relative angular velocity across the spring (=gear elasticity)
as state variables. The reason is, that a default initial
value of zero of these states makes always sense.
If the absolute angle and the absolute angular velocity of model
Jmotor would be used as states, and the load angle (= joint angle of
robot) is NOT zero, one has always to ensure that the initial values
of the motor angle and of the joint angle are modified correspondingly.
Otherwise, the spring has an unrealistic deflection at initial time.
Since relative quantities are used as state variables, this simplifies
the definition of initial values considerably.

within Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.Utilities;
model GearType1 "Motor inertia and gearbox model for r3 joints 1,2,3"
  extends Modelica.Mechanics.Rotational.Icons.Gearbox;
  extends Modelica.Mechanics.Rotational.Interfaces.PartialTwoFlanges;

  parameter Real i=-105 "Gear ratio";
  parameter SI.RotationalSpringConstant c = 43 "Spring constant";
  parameter SI.RotationalDampingConstant d = 0.005 "Damper constant";
  parameter SI.Torque Rv0=0.4 "Viscous friction torque at zero velocity";
  parameter Real Rv1(unit="N.m.s/rad") = (0.13/160)
    "Viscous friction coefficient (R=Rv0+Rv1*abs(qd))";
  parameter Real peak=1
    "Maximum static friction torque is peak*Rv0 (peak >= 1)";
  SI.AngularAcceleration a_rel=der(spring.w_rel)
    "Relative angular acceleration of spring";
  constant SI.AngularVelocity unitAngularVelocity = 1;
  constant SI.Torque unitTorque = 1;

  Modelica.Mechanics.Rotational.Components.IdealGear gear(
    ratio=i, useSupport=false)
  Modelica.Mechanics.Rotational.Components.SpringDamper spring(
    c=c, d=d)
  Modelica.Mechanics.Rotational.Components.BearingFriction bearingFriction(
    tau_pos=[0,
         Rv0/unitTorque; 1, (Rv0 + Rv1*unitAngularVelocity)/unitTorque],
      useSupport=false)
equation
  connect(spring.flange_b, gear.flange_a)
  connect(bearingFriction.flange_b, spring.flange_a)
  connect(gear.flange_b, flange_b)
  connect(bearingFriction.flange_a, flange_a)
initial equation
  spring.w_rel = 0;
  a_rel = 0;
end GearType1;