model RollingWheelSet "Ideal rolling wheel set consisting of two ideal rolling wheels connected together by an axis"
Modelica.Mechanics.MultiBody.Interfaces.Frame_a frameMiddle "Frame fixed in middle of axis connecting both wheels (y-axis: along wheel axis, z-axis: upwards)"
annotation (Placement(
transformation(extent = {
{-16, 16},
{16, -16}}),
iconTransformation(
extent = {
{-16, -16},
{16, 16}},
rotation = 90,
origin = {0, -20})));
parameter Boolean animation = true "= true, if animation of wheel set shall be enabled";
parameter SI.Radius wheelRadius "Radius of one wheel";
parameter SI.Mass wheelMass "Mass of one wheel";
parameter SI.Inertia wheel_I_axis "Inertia along one wheel axis";
parameter SI.Inertia wheel_I_long "Inertia perpendicular to one wheel axis";
parameter SI.Distance wheelDistance "Distance between the two wheels";
parameter StateSelect stateSelect = StateSelect.always "Priority to use the generalized coordinates as states";
Modelica.SIunits.Position x(start = 0, fixed = true, stateSelect = stateSelect) "x coordinate of center between wheels";
Modelica.SIunits.Position y(start = 0, fixed = true, stateSelect = stateSelect) "y coordinate of center between wheels";
Modelica.SIunits.Angle phi(start = 0, fixed = true, stateSelect = stateSelect) "Orientation angle of wheel axis along z-axis";
Modelica.SIunits.Angle theta1(start = 0, fixed = true, stateSelect = stateSelect) "Angle of wheel 1";
Modelica.SIunits.Angle theta2(start = 0, fixed = true, stateSelect = stateSelect) "Angle of wheel 2";
Modelica.SIunits.AngularVelocity der_theta1(start = 0, fixed = true, stateSelect = stateSelect) "Derivative of theta 1";
Modelica.SIunits.AngularVelocity der_theta2(start = 0, fixed = true, stateSelect = stateSelect) "Derivative of theta 2";
parameter SI.Distance wheelWidth = 0.01 "Width of one wheel"
annotation (Dialog(
tab = "Animation",
group = "if animation = true",
enable = animation));
parameter Real hollowFraction = 0.8 "1.0: Completely hollow, 0.0: rigid cylinder"
annotation (Dialog(
tab = "Animation",
group = "if animation = true",
enable = animation));
parameter Modelica.Mechanics.MultiBody.Types.Color wheelColor = {30, 30, 30} "Color of wheels"
annotation (Dialog(
colorSelector = true,
tab = "Animation",
group = "if animation = true",
enable = animation));
Modelica.Mechanics.MultiBody.Interfaces.Frame_a frame1 "Frame fixed in center point of left wheel (y-axis: along wheel axis, z-axis: upwards)"
annotation (Placement(
transformation(extent = {
{-96, 16},
{-64, -16}}),
iconTransformation(extent = {
{-96, 16},
{-64, -16}})));
Modelica.Mechanics.MultiBody.Interfaces.Frame_b frame2 "Frame fixed in center point of right wheel (y-axis: along wheel axis, z-axis: upwards)"
annotation (Placement(transformation(extent = {
{64, 16},
{96, -16}})));
Modelica.Mechanics.MultiBody.Parts.Body body2(final r_CM = {0, 0, 0}, final I_21 = 0, final I_31 = 0, final I_32 = 0, animation = false, final m = wheelMass, final I_11 = wheel_I_long, final I_22 = wheel_I_axis, final I_33 = wheel_I_long) annotation (Placement(transformation(
extent = {
{10, -10},
{-10, 10}},
rotation = -90,
origin = {60, 30})));
Modelica.Mechanics.MultiBody.Visualizers.FixedShape shape2(final animation = animation, final lengthDirection = {0, 1, 0}, final widthDirection = {1, 0, 0}, final color = wheelColor, final extra = hollowFraction, final shapeType = "pipe", final r_shape = {0, -wheelWidth, 0}, final length = 2 * wheelWidth, final width = 2 * wheelRadius, final height = 2 * wheelRadius) if animation annotation (Placement(transformation(
extent = {
{10, -10},
{-10, 10}},
rotation = 90,
origin = {60, -38})));
Modelica.Mechanics.MultiBody.Parts.Body body1(final r_CM = {0, 0, 0}, final I_21 = 0, final I_31 = 0, final I_32 = 0, animation = false, final m = wheelMass, final I_11 = wheel_I_long, final I_22 = wheel_I_axis, final I_33 = wheel_I_long) annotation (Placement(transformation(
extent = {
{-10, -10},
{10, 10}},
rotation = 90,
origin = {-60, 30})));
Modelica.Mechanics.MultiBody.Visualizers.FixedShape shape1(final animation = animation, final lengthDirection = {0, 1, 0}, final widthDirection = {1, 0, 0}, final color = wheelColor, final extra = hollowFraction, final shapeType = "pipe", final r_shape = {0, -wheelWidth, 0}, final length = 2 * wheelWidth, final width = 2 * wheelRadius, final height = 2 * wheelRadius) if animation annotation (Placement(transformation(
extent = {
{-10, -10},
{10, 10}},
rotation = -90,
origin = {-60, -40})));
Modelica.Mechanics.Rotational.Interfaces.Flange_a axis1 "1-dim. rotational flange that drives the left wheel"
annotation (Placement(transformation(extent = {
{-110, 90},
{-90, 110}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_a axis2 "1-dim. rotational flange that drives the right wheel"
annotation (Placement(transformation(extent = {
{90, 90},
{110, 110}})));
Modelica.Mechanics.MultiBody.Joints.RollingWheelSet wheelSetJoint(animation = false, wheelRadius = wheelRadius, wheelDistance = wheelDistance, stateSelect = StateSelect.default, x(fixed = false), y(fixed = false), phi(fixed = false), theta1(fixed = false), theta2(fixed = false), der_theta1(fixed = false), der_theta2(fixed = false)) annotation (Placement(transformation(extent = {
{-10, 40},
{10, 60}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_b support "Support of 1D axes"
annotation (Placement(
transformation(extent = {
{-10, 70},
{10, 90}}),
iconTransformation(extent = {
{-10, 70},
{10, 90}})));
equation
connect(body1.frame_a,frame1) annotation (Line(
points = {
{-60, 20},
{-60, 0},
{-80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(body2.frame_a,frame2) annotation (Line(
points = {
{60, 20},
{60, 0},
{80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(shape1.frame_a,frame1) annotation (Line(
points = {
{-60, -30},
{-60, 0},
{-80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(shape2.frame_a,frame2) annotation (Line(
points = {
{60, -28},
{60, 0},
{80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(wheelSetJoint.axis1,axis1) annotation (Line(points = {
{-10, 60},
{-80, 60},
{-80, 100},
{-100, 100}}));
connect(wheelSetJoint.axis2,axis2) annotation (Line(points = {
{10, 60},
{80, 60},
{80, 100},
{100, 100}}));
connect(wheelSetJoint.frame1,frame1) annotation (Line(
points = {
{-8, 50},
{-30, 50},
{-30, 0},
{-80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(wheelSetJoint.frame2,frame2) annotation (Line(
points = {
{8, 50},
{30, 50},
{30, 0},
{80, 0}},
color = {95, 95, 95},
thickness = 0.5));
connect(wheelSetJoint.support,support) annotation (Line(points = {
{0, 58},
{0, 80}}));
connect(wheelSetJoint.frameMiddle,frameMiddle) annotation (Line(
points = {
{0, 48},
{0, 46},
{20, 46},
{20, 0},
{0, 0}},
color = {95, 95, 95},
thickness = 0.5));
der_theta1 = der(theta1);
der_theta2 = der(theta2);
wheelSetJoint.x = x;
wheelSetJoint.y = y;
wheelSetJoint.phi = phi;
wheelSetJoint.theta1 = theta1;
wheelSetJoint.theta2 = theta2;
annotation (
defaultComponentName = "wheelSet",
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(points = {
{0, 76},
{0, 4}}),
Ellipse(
extent = {
{42, 80},
{118, -80}},
fillColor = {215, 215, 215},
fillPattern = FillPattern.Sphere,
lineColor = {64, 64, 64}),
Ellipse(
extent = {
{42, 80},
{118, -80}},
lineColor = {64, 64, 64}),
Rectangle(
extent = {
{-100, -80},
{100, -100}},
fillColor = {175, 175, 175},
fillPattern = FillPattern.Solid,
pattern = LinePattern.None),
Text(
extent = {
{-150, -105},
{150, -145}},
textString = "%name",
lineColor = {0, 0, 255}),
Line(points = {
{86, 24},
{64, 24},
{64, 12},
{56, 12}}),
Line(points = {
{86, -24},
{64, -24},
{64, -12},
{56, -12}}),
Line(points = {
{100, 100},
{80, 100},
{80, -2}}),
Polygon(
points = {
{-62, 6},
{64, 6},
{64, -6},
{6, -6},
{6, -20},
{-6, -20},
{-6, -6},
{-62, -6},
{-62, 6}},
fillColor = {255, 255, 255},
fillPattern = FillPattern.Solid),
Ellipse(
extent = {
{-118, 80},
{-42, -80}},
fillColor = {215, 215, 215},
fillPattern = FillPattern.Sphere,
lineColor = {64, 64, 64}),
Line(points = {
{-96, 100},
{-80, 100},
{-80, 4}}),
Ellipse(
extent = {
{-118, 80},
{-42, -80}},
lineColor = {64, 64, 64}),
Line(points = {
{-100, -80},
{100, -80}})}),
Diagram(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(
points = {
{0, -106},
{0, -78}},
color = {0, 0, 255}),
Polygon(
points = {
{0, -60},
{-6, -78},
{6, -78},
{0, -60}},
lineColor = {0, 0, 255},
fillColor = {255, 255, 255},
fillPattern = FillPattern.Solid),
Text(
extent = {
{12, -68},
{30, -80}},
lineColor = {0, 0, 255},
textString = "x"),
Line(
points = {
{6, -100},
{-26, -100}},
color = {0, 0, 255}),
Polygon(
points = {
{-22, -94},
{-22, -106},
{-40, -100},
{-22, -94}},
lineColor = {0, 0, 255},
fillColor = {255, 255, 255},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-46, -80},
{-28, -92}},
lineColor = {0, 0, 255},
textString = "y")}),
Documentation(info = "<html>\n<p>\nTwo wheels are connected by an axis and can rotate around this axis.\nThe wheels are rolling on the x-y plane of the world frame.\nThe coordinate system attached to the center of the wheel axis (frameMiddle)\nis constrained so that it is always parallel to the x-y plane.\nIf all generalized coordinates are zero, frameMiddle is parallel\nto the world frame.\n</p>\n\n<h4>Note</h4>\n<p>\nTo work properly, the gravity acceleration vector g of the world must point in the negative z-axis, i.e.\n</p>\n<blockquote><pre>\n<span style=\"font-family:'Courier New',courier; color:#0000ff;\">inner</span> <span style=\"font-family:'Courier New',courier; color:#ff0000;\">Modelica.Mechanics.MultiBody.World</span> world(n={0,0,-1});\n</pre></blockquote>\n</html>"));
end RollingWheelSet;