Skip to content

Commit b7350ff

Browse files
authored
Merge pull request #128 from JuliaComputing/wheelsurface
add surface parameter to rolling wheel
2 parents c71d6f7 + ceb3565 commit b7350ff

File tree

3 files changed

+91
-9
lines changed

3 files changed

+91
-9
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Render = ["Makie"]
2424

2525
[compat]
2626
CoordinateTransformations = "0.6"
27-
DataInterpolations = "5"
27+
DataInterpolations = "5, 6"
2828
FileIO = "1"
2929
JuliaSimCompiler = "0.1.12"
3030
LinearAlgebra = "1.6"

src/wheels.jl

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ this frame.
2121
2222
# Arguments and parameters:
2323
24-
name: Name of the rolling wheel joint component
25-
radius: Radius of the wheel
26-
angles: Angles to rotate world-frame into frame_a around y-, z-, x-axis
24+
- `radius`: Radius of the wheel
25+
- `angles`: Angles to rotate world-frame into frame_a around y-, z-, x-axis
26+
- `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)`.
2727
2828
# Variables:
2929
- `x`: x-position of the wheel axis
@@ -52,7 +52,7 @@ angles: Angles to rotate world-frame into frame_a around y-, z-, x-axis
5252
# Connector frames
5353
- `frame_a`: Frame for the wheel joint
5454
"""
55-
@component function RollingWheelJoint(; name, radius, angles = zeros(3), der_angles=zeros(3), x0=0, y0 = radius, z0=0, sequence = [2, 3, 1], iscut=false)
55+
@component function RollingWheelJoint(; name, radius, angles = zeros(3), der_angles=zeros(3), x0=0, y0 = radius, z0=0, sequence = [2, 3, 1], iscut=false, surface = nothing)
5656
@parameters begin radius = radius, [description = "Radius of the wheel"] end
5757
@variables begin
5858
(x(t) = x0), [state_priority = 15, description = "x-position of the wheel axis"]
@@ -116,18 +116,32 @@ angles: Angles to rotate world-frame into frame_a around y-, z-, x-axis
116116

117117
Rarot = axes_rotations(sequence, angles, -der_angles) # The - is the neg_w change
118118

119+
equations = if surface === nothing
120+
[ # Road description
121+
r_road_0 .~ [s, 0, w]
122+
e_n_0 .~ [0, 1, 0]
123+
e_s_0 .~ [1, 0, 0]
124+
]
125+
else
126+
sy = surface(s, w)
127+
e_w_0 = _normalize([0, expand_derivatives(Differential(w)(sy)), 1])
128+
# @show sy, expand_derivatives(Differential(s)(sy)), expand_derivatives(Differential(w)(sy))
129+
[
130+
r_road_0 .~ [s, sy, w]
131+
e_s_0 .~ _normalize([1, expand_derivatives(Differential(s)(sy)), 0])
132+
e_n_0 .~ _normalize(cross(e_w_0, e_s_0))
133+
]
134+
end
135+
119136
equations = [
137+
equations;
120138
connect_orientation(Ra, Rarot; iscut) # Ra ~ Rarot
121139
Ra.w ~ Rarot.w
122140

123141
# frame_a.R is computed from generalized coordinates
124142
collect(frame_a.r_0) .~ [x, y, z]
125143
der_angles .~ D.(angles)
126144

127-
# Road description
128-
r_road_0 .~ [s, 0, w]
129-
e_n_0 .~ [0, 1, 0]
130-
e_s_0 .~ [1, 0, 0]
131145

132146
# Coordinate system at contact point (e_long_0, e_lat_0, e_n_0)
133147
e_axis_0 .~ resolve1(Ra, [0, 0, 1])

test/test_wheels.jl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,74 @@ sol = solve(prob, Tsit5(), abstol=1e-8, reltol=1e-8)
4747
# ])
4848

4949

50+
# ==============================================================================
51+
## Rolling wheel on interesting surface ===============================================================
52+
# ==============================================================================
53+
using LinearAlgebra
54+
# The wheel does not need the world
55+
# @testset "Rolling wheel" begin
56+
@mtkmodel WheelInWorld begin
57+
@structural_parameters begin
58+
surface
59+
end
60+
@components begin
61+
# world = World(n=[0,0,-1])
62+
world = W()
63+
wheel = RollingWheel(; radius = 0.3, m = 2, I_axis = 0.06,
64+
I_long = 0.12,
65+
x0 = 0.2,
66+
z0 = 0.2,
67+
surface,
68+
der_angles = [0, 0, 0])
69+
end
70+
end
71+
72+
@named worldwheel = WheelInWorld(surface = (x,z)->0)
73+
worldwheel = complete(worldwheel)
74+
75+
# pars = collect(worldwheel.world.n) .=> [0,0,-1];
76+
defs = Dict([
77+
# collect(worldwheel.world.n) .=> [0,0,-1];
78+
worldwheel.wheel.body.r_0[1] => 0.2;
79+
worldwheel.wheel.body.r_0[2] => 0.3;
80+
worldwheel.wheel.body.r_0[3] => 0.2;
81+
collect(worldwheel.wheel.rollingWheel.der_angles) .=> [0, 5, 1];
82+
# collect(D.(cwheel.rollingWheel.angles)) .=> [0, 5, 1]
83+
])
84+
85+
ssys = structural_simplify(IRSystem(worldwheel))
86+
prob = ODEProblem(ssys, defs, (0, 4))
87+
sol = solve(prob, FBDF(autodiff=false), abstol=1e-8, reltol=1e-8)
88+
@test SciMLBase.successful_retcode(sol)
89+
# first(Multibody.render(worldwheel, sol, 0, show_axis=true))
90+
@test sol(4, idxs=[worldwheel.wheel.x; worldwheel.wheel.z]) [0.162547, -2.23778] atol=1e-3
91+
92+
@named worldwheel = WheelInWorld(surface = (x,z)->x)
93+
worldwheel = complete(worldwheel)
94+
95+
defs = Dict([
96+
# collect(worldwheel.world.n) .=> [0,0,-1];
97+
worldwheel.wheel.body.r_0[1] => 0.0;
98+
worldwheel.wheel.body.r_0[2] => 0.3/sqrt(2);
99+
worldwheel.wheel.body.r_0[3] => 0.0;
100+
collect(worldwheel.wheel.rollingWheel.der_angles) .=> [0, 0, 0];
101+
])
102+
103+
ssys = structural_simplify(IRSystem(worldwheel))
104+
prob = ODEProblem(ssys, defs, (0, 4))
105+
sol = solve(prob, FBDF(autodiff=false), abstol=1e-8, reltol=1e-8)
106+
# plot(sol)
107+
tv = 0:0.5:4
108+
@test sol(tv, idxs=worldwheel.wheel.body.r_0[1]) sol(tv, idxs=worldwheel.wheel.body.r_0[2]) .- 0.3*sqrt(2) rtol=1e-6 # The sqrt(2) is to account for the shifted contact point at a 45 degree plane
109+
110+
dd = diff(sol(tv, idxs=worldwheel.wheel.rollingWheel.der_angles[2]).u) # angular acceleration
111+
@test norm(dd .- dd[1]) < 1e-10 # constant acceleration
112+
@test abs(dd[1]) < 9.81
113+
@test abs(dd[1]) > 5
114+
115+
116+
117+
50118
## Rolling wheel with axis ====================================================
51119
import ModelingToolkitStandardLibrary.Blocks
52120
@mtkmodel WheelWithAxis begin

0 commit comments

Comments
 (0)