|
1 | 1 | # Wheels
|
2 | 2 |
|
| 3 | +When modeling wheels, there are several different assumptions that can be made, such as |
| 4 | +- Is the wheel able to leave the ground or not? |
| 5 | +- Can the wheel slip or does it roll perfectly? |
| 6 | + |
| 7 | +The wheel-related components available are |
| 8 | +- [`RollingWheel`](@ref): a wheel that can roll on the ground. It cannot slip and it cannot leave the ground. |
| 9 | +- [`RollingWheelJoint`](@ref): a lower-level component used in `RollingWheel` to model the kinematics of the wheel, without inertial or mass properties. |
| 10 | +- [`RollingWheelSet`](@ref): a set of two wheels connected by an axis. One of the wheels cannot slip, while the other one slips as required to allow the wheel set to turn (no differential is modeled). No wheel can leave the ground. |
| 11 | +- [`RollingWheelSetJoint`](@ref): A lower-level component used in `RollingWheelSet` to model the kinematics of the wheel set, without inertial or mass properties. |
| 12 | +- [`RollingConstraintVerticalWheel`](@ref): A low-level constraint that is used to enforce a perfectly rolling wheel that is always vertical, i.e., it can only roll forward and not fall down. |
| 13 | + |
| 14 | +All wheel components are limited to rolling on the ``xz`` plane, i.e., the gravity direction must be the default `[0, -1, 0]`. |
| 15 | + |
3 | 16 | ## Rolling wheel
|
4 | 17 | ```@example WHEEL
|
5 | 18 | using Multibody
|
@@ -55,6 +68,7 @@ nothing # hide
|
55 | 68 | 
|
56 | 69 |
|
57 | 70 | ## Wheel set
|
| 71 | +A [`RollingWheelSet`](@ref) is comprised out of two wheels mounted on a common axis through their axis of rotation. |
58 | 72 | ```@example WHEEL
|
59 | 73 | @mtkmodel DrivingWheelSet begin
|
60 | 74 | @components begin
|
@@ -97,3 +111,62 @@ nothing # hide
|
97 | 111 |
|
98 | 112 | 
|
99 | 113 |
|
| 114 | +The [`RollingWheelSet`](@ref) includes constraints that prevent the wheels from leaving the ground and the connector `frame_middle` from rotating around the wheel axis. This means that if two wheel sets are connected to the same body, the system will be over constrained. To solve this, pass `iscut = true` to one of the wheel sets, like below: |
| 115 | + |
| 116 | +```@example WHEEL |
| 117 | +wheel_mass = 15 |
| 118 | +I_axis=0.01 |
| 119 | +I_long=0.02 |
| 120 | +wheel_d = 2 |
| 121 | +wheel_radius = 0.25 |
| 122 | +tire_black = [0.1, 0.1, 0.1, 1] |
| 123 | +
|
| 124 | +@mtkmodel Car begin |
| 125 | + @structural_parameters begin |
| 126 | + l=4 |
| 127 | + end |
| 128 | + @parameters begin |
| 129 | + m=108 |
| 130 | + I=10 |
| 131 | + g=0 |
| 132 | + end |
| 133 | + @components begin |
| 134 | + world = W() |
| 135 | +
|
| 136 | + sine1 = Blocks.Sine(frequency=1, amplitude=150) |
| 137 | + sine2 = Blocks.Sine(frequency=1, amplitude=150, phase=pi/6) |
| 138 | + torque1 = Rotational.Torque() |
| 139 | + torque2 = Rotational.Torque() |
| 140 | + front_wheels = RollingWheelSet(radius=wheel_radius, m_wheel=wheel_mass, I_axis, I_long, track=wheel_d) |
| 141 | + rear_wheels = RollingWheelSet(radius=wheel_radius, m_wheel=wheel_mass, I_axis, I_long, track=wheel_d, iscut=true) |
| 142 | +
|
| 143 | + steering_joint = Revolute(n = [0,1,0], axisflange=true, state_priority=100) |
| 144 | + prefer_straight_ahead = Rotational.SpringDamper(d=10, c=10) |
| 145 | +
|
| 146 | + body = BodyShape(;m, r = [l, 0, 0], I_22 = I, radius=0.3) |
| 147 | + end |
| 148 | + @equations begin |
| 149 | + connect(sine1.output, torque1.tau) |
| 150 | + connect(sine2.output, torque2.tau) |
| 151 | + connect(torque1.flange, front_wheels.axis1) |
| 152 | + connect(torque2.flange, front_wheels.axis2) |
| 153 | + connect(front_wheels.frame_middle, steering_joint.frame_a) |
| 154 | +
|
| 155 | + connect(steering_joint.frame_b, body.frame_a) |
| 156 | + connect(rear_wheels.frame_middle, body.frame_b) |
| 157 | +
|
| 158 | + connect(prefer_straight_ahead.flange_a, steering_joint.axis) |
| 159 | + connect(prefer_straight_ahead.flange_b, steering_joint.support) |
| 160 | + end |
| 161 | +end |
| 162 | +@named model = Car() |
| 163 | +model = complete(model) |
| 164 | +ssys = structural_simplify(IRSystem(model)) |
| 165 | +
|
| 166 | +prob = ODEProblem(ssys, [], (0, 6)) |
| 167 | +sol = solve(prob, Tsit5()) |
| 168 | +
|
| 169 | +render(model, sol, framerate=30, filename="car.gif", x=6, z=6, y=5) |
| 170 | +``` |
| 171 | + |
| 172 | + |
0 commit comments