Skip to content

Commit 1aaa808

Browse files
authored
Merge pull request #1 from JuliaComputing/bgc/animation
Animation Script Setup
2 parents 844f03d + c94c373 commit 1aaa808

6 files changed

Lines changed: 133 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Manifest.toml

Project.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
name = "DyadBotComponents"
22
uuid = "6baa8624-4e17-4d27-96ac-5a32f577bc5c"
3-
version = "0.1.0"
43
authors = ["Fredrik Bagge Carlson"]
4+
version = "0.2.0"
55

66
[deps]
77
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"
88
ControlSystemsMTK = "687d7614-c7e5-45fc-bfc3-9ee385575c88"
99
DyadControlSystems = "6f9e59d0-2838-4fee-9bce-c163a6c9592b"
10+
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
1011
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
1112
ModelingToolkitStandardLibrary = "16a59e39-deab-5bd0-87e4-056b12336739"
1213
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
1314
OrdinaryDiffEqDefault = "50262376-6c5a-4cf5-baba-aaf4f84d72d7"
1415
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1516
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
16-
17+
WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
1718

1819
[compat]
1920
ControlSystemsMTK = "2.5.0"
21+
Makie = "0.24.8"
2022
ModelingToolkitStandardLibrary = "2.25.0"
2123
Plots = "1.41.2"
2224
StaticArrays = "1.9.15"
25+
WGLMakie = "0.13.8"
2326

2427
[extras]
2528
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

scripts/animation.jl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using DyadBotComponents
2+
using WGLMakie
3+
using ModelingToolkit
4+
using OrdinaryDiffEq
5+
6+
t_end = 100
7+
@mtkcompile bot = DyadBotComponents.CascadeControlledFlatDyadBot()
8+
prob = ODEProblem(bot, [bot.x_ref => 0.75], (0,t_end))
9+
sol = solve(prob)
10+
11+
plot(sol; idxs=[bot.ref.output.u, bot.plant.x])
12+
plot(sol; idxs=bot.plant.theta)
13+
14+
15+
function get_figure()
16+
17+
defs = ModelingToolkit.defaults(bot)
18+
19+
r = defs[bot.plant.R] #wheel radius
20+
y1 = r
21+
22+
L = defs[bot.plant.L] # body length
23+
y2 = y1 + L
24+
25+
w1 = r*0.5
26+
w2 = r*2
27+
28+
29+
f = Figure(size = (600, 600); aspect=DataAspect())
30+
ax = Axis(f[1, 1])
31+
32+
33+
# wheel
34+
base_transform = Transformation(origin = Vec3d(0.0, y1, 0))
35+
spoke_transform = Transformation(base_transform; origin = Vec3d(0.0, y1, 0))
36+
linesegments!(ax, [-r,+r], [y1,y1]; transformation=spoke_transform, color=:blue)
37+
linesegments!(ax, [0.0,0.0], [y1-r,y1+r]; transformation=spoke_transform, color=:blue)
38+
poly!(ax, Circle(Point2f(0.0,y1), r); color=:transparent, strokecolor=:blue, strokewidth=2, transformation=spoke_transform)
39+
40+
# body
41+
body_transform = Transformation(base_transform; origin = Vec3d(0.0, y1, 0))
42+
poly!(ax, Rect(0.0-w1/2, y1, w1, y2-y1); color=:transparent, strokecolor=:red, strokewidth=2, transformation=body_transform)
43+
poly!(ax, Rect(0.0-w2/2, y2, w2, w2); color=:transparent, strokecolor=:green, strokewidth=2, transformation=body_transform)
44+
45+
# frame
46+
poly!(ax, Rect(-3/2, 0 , 3, 3); color=:transparent)
47+
48+
return f, base_transform, spoke_transform, body_transform
49+
end
50+
51+
f, base_transform, spoke_transform, body_transform = get_figure()
52+
53+
function animate(;framerate = 30, filename="dyadbot.mp4")
54+
55+
nframes = 500
56+
times = range(0, t_end, length=nframes)
57+
58+
translate!(base_transform, 0.0)
59+
rotate!(body_transform, 0.0)
60+
rotate!(spoke_transform, 0.0)
61+
62+
record(f, filename, times;
63+
framerate) do t
64+
x = sol(t; idxs=bot.plant.x)
65+
theta = sol(t; idxs=bot.plant.theta)
66+
67+
# x = wheel*r
68+
69+
translate!(base_transform, x)
70+
rotate!(body_transform, -theta + π)
71+
rotate!(spoke_transform, -x/r)
72+
end
73+
74+
end
75+
76+
animate(; framerate=5, filename = "dyadbot_slow.mp4")
77+
animate(; framerate=30, filename = "dyadbot_fast.mp4")
78+

src/DyadBotComponents.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module DyadBotComponents
22

33
include("DiscreteKalmanFilter.jl")
4+
include("planar_flat.jl")
5+
include("cascade_planar_flat.jl")
46

57
# include("planar_multibody.jl")
68
# include("segway_3d.jl")

src/cascade_planar_flat.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
# Cascade control: outer velocity loop + inner angle loop
3+
@component function CascadeControlledFlatDyadBot(; name)
4+
pars = @parameters begin
5+
x_ref = 0.15 # Reference velocity
6+
end
7+
8+
systems = @named begin
9+
plant = FlatDyadBot()
10+
# Inner loop: angle controller
11+
inner_controller = Blocks.LimPID(k=15.6, Ti=Inf, Td=0.16, Nd=25, u_max=7)
12+
# Outer loop: velocity controller
13+
outer_controller = Blocks.LimPID(k=0.54, Ti=2.48, Td=0, Nd=600, wd=1, wp=0.5)
14+
neg_gain = Blocks.Gain(k=1)
15+
# ref = Blocks.Step(height=x_ref, start_time=5)
16+
ref = Blocks.Square(; frequency = 1/50, amplitude = x_ref, offset = 0.0, start_time = 0.0, smooth = true)
17+
# Add pi offset to inner loop reference
18+
pi_offset = Blocks.Constant(k=pi)
19+
add_pi = Blocks.Add(k1=1, k2=1)
20+
end
21+
22+
eqs = [
23+
# Outer loop: velocity reference -> angle reference
24+
connect(ref.output, :r2, outer_controller.reference)
25+
connect(plant.x_output, neg_gain.input)
26+
connect(neg_gain.output, :y2, outer_controller.measurement)
27+
28+
# Add pi to outer controller output for inner loop reference
29+
connect(outer_controller.ctr_output, :u2, add_pi.input1)
30+
connect(pi_offset.output, add_pi.input2)
31+
32+
# Inner loop: angle reference -> torque
33+
connect(add_pi.output, inner_controller.reference)
34+
connect(plant.theta_output, :y, inner_controller.measurement)
35+
connect(inner_controller.ctr_output, :u, plant.control_input)
36+
]
37+
38+
System(eqs, t, [], pars; systems, name)
39+
end

src/planar_flat.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
using ModelingToolkit
22
import ModelingToolkit: t_nounits as t, D_nounits as D
3-
import ModelingToolkitStandardLibrary.Mechanical.Rotational
3+
# import ModelingToolkitStandardLibrary.Mechanical.Rotational
44
import ModelingToolkitStandardLibrary.Blocks
5-
using OrdinaryDiffEq
6-
using DyadControlSystems, ControlSystemsBase, ControlSystemsMTK
7-
using Plots
8-
import DyadControlSystems as JSC
9-
using LinearAlgebra
5+
# using OrdinaryDiffEq
6+
# using DyadControlSystems, ControlSystemsBase, ControlSystemsMTK
7+
# # using Plots
8+
# import DyadControlSystems as JSC
9+
# # using LinearAlgebra
1010

1111

12-
Plots.default(size=(1200,1200))
13-
connect = ModelingToolkit.connect
12+
# # Plots.default(size=(1200,1200))
13+
# connect = ModelingToolkit.connect
1414

1515

1616
##

0 commit comments

Comments
 (0)