Skip to content

Commit a1db611

Browse files
committed
improve slip wheel docs
1 parent 524df3f commit a1db611

File tree

2 files changed

+74
-14
lines changed

2 files changed

+74
-14
lines changed

docs/src/examples/wheel.md

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,35 @@ nothing # hide
7272
![wheel animation](worldwheel.gif)
7373

7474
### Add slip
75-
The example below is similar to that above, but models a wheel with slip properties instead of ideal rolling.
75+
The example below is similar to that above, but models a wheel with slip properties instead of ideal rolling. We start by showing the slip model
76+
```@example WHEEL
77+
using Plots
78+
vAdhesion = 0.2
79+
vSlide = 0.4
80+
mu_A = 0.95
81+
mu_S = 0.7
82+
v = range(0, stop=1, length=500) # Simulating the slip velocity
83+
μ = Multibody.PlanarMechanics.limit_S_triple.(vAdhesion, vSlide, mu_A, mu_S, v)
84+
plot(v, μ, label=nothing, lw=2, color=:black, xlabel = "\$v_{Slip}\$", ylabel = "\$\\mu\$")
85+
scatter!([vAdhesion, vSlide], [mu_A, mu_S], color=:white, markerstrokecolor=:black)
86+
hline!([mu_A, mu_S], linestyle=:dash, color=:black, alpha=0.5)
87+
vline!([vAdhesion, vSlide], linestyle=:dash, color=:black, alpha=0.5)
88+
plot!(
89+
xticks = ((vAdhesion, vSlide), ["\$v_{Adhesion}\$", "\$v_{Slide}\$"]),
90+
yticks = ((mu_A, mu_S), ["\$\\mu_{adhesion}\$", "\$\\mu_{slide}\$"]),
91+
framestyle = :zerolines,
92+
legend = false,
93+
)
94+
```
95+
The longitudinal force on the tire is given by
96+
```math
97+
f_{long} = - f_n \dfrac{\mu(v_{Slip})}{v_{Slip}} v_{SlipLong}
98+
```
99+
where `f_n` is the normal force on the tire, `μ` is the friction coefficient from the slip model, and `v_{Slip}` is the magnitude of the slip velocity.
100+
101+
The slip velocity is defined such that when the wheel is moving with positive velocity and increasing in speed (accelerating), the slip velocity is negative, i.e., the contact patch is moving slightly backwards. When the wheel is moving with positive velocity and decreasing in speed (braking), the slip velocity is positive, i.e., the contact patch is moving slightly forwards.
102+
103+
76104
```@example WHEEL
77105
@mtkmodel SlipWheelInWorld begin
78106
@components begin
@@ -85,7 +113,6 @@ The example below is similar to that above, but models a wheel with slip propert
85113
x0 = 0.2,
86114
z0 = 0.2,
87115
der_angles = [0, 25, 0.1],
88-
89116
mu_A = 0.95, # Friction coefficient at adhesion
90117
mu_S = 0.5, # Friction coefficient at sliding
91118
sAdhesion = 0.04, # Adhesion slippage
@@ -334,13 +361,22 @@ prob = ODEProblem(ssys, [
334361
D(model.revolute.frame_b.phi) => 0,
335362
D(model.prismatic.r0[2]) => 0,
336363
], (0.0, 15.0))
337-
sol = solve(prob, Rodas5Pr())
364+
sol = solve(prob, Rodas5P())
338365
render(model, sol, show_axis=false, x=0, y=0, z=4, traces=[model.slipBasedWheelJoint.frame_a], filename="slipwheel.gif", cache=false)
339366
nothing # hide
340367
```
341368

342369
![slipwheel animation](slipwheel.gif)
343370

371+
```@example WHEEL
372+
plot(sol, idxs=[
373+
model.slipBasedWheelJoint.w_roll
374+
model.slipBasedWheelJoint.v_long
375+
model.slipBasedWheelJoint.v_slip_long
376+
model.slipBasedWheelJoint.f_long
377+
], layout=4)
378+
```
379+
344380

345381
## Planar two-track model
346382
A more elaborate example with 4 wheels.

src/wheels.jl

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ end
267267
"""
268268
SlipWheelJoint(; name, radius, angles = zeros(3), der_angles = zeros(3), x0 = 0, y0 = radius, z0 = 0, sequence, iscut = false, surface = nothing, vAdhesion_min = 0.1, vSlide_min = 0.1, sAdhesion = 0.04, sSlide = 0.12, mu_A = 0.8, mu_S = 0.6, phi_roll = 0, w_roll = 0)
269269
270-
Joint for a wheel with slip rolling on a surface.
270+
Joint for a wheel with slip rolling on a surface. See https://people.inf.ethz.ch/fcellier/MS/andres_ms.pdf for details.
271271
272272
!!! tip "Integrator choice"
273273
The slip model contains a discontinuity in the second derivative at the transitions between adhesion and sliding. This can cause problems for integrators, in particular BDF-type integrators.
@@ -277,17 +277,39 @@ Joint for a wheel with slip rolling on a surface.
277277
278278
# Parameters
279279
- `radius`: Radius of the wheel
280-
- `vAdhesion_min`: Minimum adhesion velocity
281-
- `vSlide_min`: Minimum sliding velocity
282-
- `sAdhesion`: Adhesion slippage
283-
- `sSlide`: Sliding slippage
280+
- `vAdhesion_min`: Minimum velocity for the peak of the adhesion curve (regularization close to 0)
281+
- `vSlide_min`: Minimum velocity for the start of the flat region of the slip curve (regularization close to 0)
282+
- `sAdhesion`: Adhesion slippage. The peak of the adhesion curve appears when the wheel slip is equal to `sAdhesion`.
283+
- `sSlide`: Sliding slippage. The flat region of the adhesion curve appears when the wheel slip is greater than `sSlide`.
284284
- `mu_A`: Friction coefficient at adhesion
285285
- `mu_S`: Friction coefficient at sliding
286286
- `surface`: By default, the wheel is rolling on a flat xz plane. A function `surface = (x, z)->y` may be provided to define a road surface. The function should return the height of the road at `(x, z)`. Note: if a function that depends on parameters is provided, make sure the parameters are scoped appropriately using, e.g., `ParentScope`.
287287
- `state`: (structural) whether or not the component has angular state variables. Default is `true`.
288288
289289
# State and iscut
290290
When the wheel is mounted on an axis that is rooted, one may either supply `state=false` or `iscut = true`. With `state = false`, the angular state variables are not included in the wheel and there is thus no kinematic chain introduced. This reduces the total number of variables in the system. if the angular variables are required, one may instead pass `iscut=true` to cut the kinematic loop that is introduced when coupling the angles of the wheel to the orientation of the `frame_a`, unless this is cut elsewhere.
291+
292+
# Understaning the slip model
293+
The following Julia code draws the slip model with descriptive labels
294+
```
295+
using Plots
296+
vAdhesion = 0.2
297+
vSlide = 0.4
298+
mu_A = 0.95
299+
mu_S = 0.7
300+
v = range(0, stop=1, length=500) # Simulating the slip velocity
301+
μ = Multibody.PlanarMechanics.limit_S_triple.(vAdhesion, vSlide, mu_A, mu_S, v)
302+
plot(v, μ, label=nothing, lw=2, color=:black, xlabel = "\$v_{Slip}\$", ylabel = "\$\\mu\$")
303+
scatter!([vAdhesion, vSlide], [mu_A, mu_S], color=:white, markerstrokecolor=:black)
304+
hline!([mu_A, mu_S], linestyle=:dash, color=:black, alpha=0.5)
305+
vline!([vAdhesion, vSlide], linestyle=:dash, color=:black, alpha=0.5)
306+
plot!(
307+
xticks = ((vAdhesion, vSlide), ["\$v_{Adhesion}\$", "\$v_{Slide}\$"]),
308+
yticks = ((mu_A, mu_S), ["\$\\mu_{adhesion}\$", "\$\\mu_{slide}\$"]),
309+
framestyle = :zerolines,
310+
legend = false,
311+
)
312+
```
291313
"""
292314
@component function SlipWheelJoint(; name, radius, angles = zeros(3), der_angles=zeros(3), x0=0, y0 = radius, z0=0, sequence = [2, 3, 1], iscut=false, surface = nothing, vAdhesion_min = 0.05, vSlide_min = 0.15, sAdhesion = 0.04, sSlide = 0.12, mu_A = 0.8, mu_S = 0.6, phi_roll = 0, w_roll = 0, v_small = 1e-5, state=true)
293315
@parameters begin
@@ -296,7 +318,7 @@ When the wheel is mounted on an axis that is rooted, one may either supply `stat
296318
vSlide_min = vSlide_min, [description = "Minimum sliding velocity"]
297319
sAdhesion = sAdhesion, [description = "Adhesion slippage"]
298320
sSlide = sSlide, [description = "Sliding slippage"]
299-
mu_A = mu_A, [description = "Friction coefficient at adhesion"]
321+
mu_A = mu_A, [description = "Friction coefficient at adhesion peak"]
300322
mu_S = mu_S, [description = "Friction coefficient at sliding"]
301323
v_small = v_small, [description = "Small value added to v_slip to avoid division by zero in slip model."]
302324
end
@@ -362,9 +384,10 @@ When the wheel is mounted on an axis that is rooted, one may either supply `stat
362384
v_slip_long(t), [guess=0, description="Slip velocity in longitudinal direction"]
363385
v_slip_lat(t), [guess=0, description="Slip velocity in lateral direction"]
364386
v_slip(t), [description="Slip velocity, norm of component slip velocities"]
387+
slip_ratio(t)
365388
f(t), [description="Total traction force"]
366-
vAdhesion(t), [description="Adhesion velocity"]
367-
vSlide(t), [description="Sliding velocity"]
389+
vAdhesion(t), [description="Slip velocity at which adhesion is maximized"]
390+
vSlide(t), [description="Slip velocity at which the flat region of the slip model starts"]
368391
end
369392

370393
angles,der_angles,r_road_0,f_wheel_0,e_axis_0,delta_0,e_n_0,e_lat_0,e_long_0,e_s_0,v_0,w_0,vContact_0,aux = collect.((angles,der_angles,r_road_0,f_wheel_0,e_axis_0,delta_0,e_n_0,e_lat_0,e_long_0,e_s_0,v_0,w_0,vContact_0,aux))
@@ -441,15 +464,16 @@ When the wheel is mounted on an axis that is rooted, one may either supply `stat
441464
v_slip ~ sqrt(v_slip_long^2 + v_slip_lat^2) + v_small
442465
# -f_long * radius ~ flange_a.tau # No longer needed?
443466
# frame_a.tau ~ 0
467+
slip_ratio ~ v_slip_long / (v_0'e_long_0)
444468
vAdhesion ~ max(vAdhesion_min, sAdhesion * abs(radius * w_roll))
445469
vSlide ~ max(vSlide_min, sSlide * abs(radius * w_roll))
446470

447471
f ~ f_n * PlanarMechanics.limit_S_triple(vAdhesion, vSlide, mu_A, mu_S, v_slip) # limit_S_triple(x_max, x_sat, y_max, y_sat, x)
448-
f_long ~ -f * v_slip_long / v_slip
449-
f_lat ~ -f * v_slip_lat / v_slip
472+
f_long ~ f * v_slip_long / v_slip
473+
f_lat ~ f * v_slip_lat / v_slip
450474

451475
# Contact force (world frame)
452-
f_wheel_0 .~ f_n * e_n_0 + f_lat * e_lat_0 + f_long * e_long_0
476+
f_wheel_0 .~ f_n * e_n_0 - f_lat * e_lat_0 - f_long * e_long_0
453477

454478
# Force and torque balance at the wheel center
455479
zeros(3) .~ collect(frame_a.f) + resolve2(Ra, f_wheel_0)

0 commit comments

Comments
 (0)