Skip to content

Commit 6c593a6

Browse files
committed
Slightly increase the D value, add nomad3
1 parent b6edb46 commit 6c593a6

File tree

2 files changed

+174
-1
lines changed

2 files changed

+174
-1
lines changed

data/wc_settings.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ wc_settings:
2626
f_high: 3800 # upper force limit [N]
2727
pf_high: 0.0002304 # P constant of upper force controller
2828
if_high: 0.012 # I constant of upper force controller
29-
df_high: 2.04e-5 # D constant of upper force controller
29+
df_high: 2.4e-5 # D constant of upper force controller
3030
nf_high: 15.0 # filter constant n of upper force controller
3131
kbf_high: 1.0 # back calculation constant for the anti-windup loop of the upper force controller
3232
ktf_high: 10.0 # tracking constant of the upper force controller

scripts/autotune_nomad3.jl

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# this script tunes the controller parameters (well, seven of them)
2+
# TODO: add the RMS value of the derivative of acc to the damage
3+
using Pkg
4+
if ! ("ControlPlots" keys(Pkg.project().dependencies))
5+
using TestEnv; TestEnv.activate()
6+
using Test
7+
end
8+
using WinchControllers, KiteUtils, PRIMA, NOMAD, ControlPlots
9+
10+
TUNED::Bool = false
11+
load_settings("system.yaml")
12+
13+
function calc_force(v_wind, v_ro)
14+
(v_wind - v_ro)^2 * 4000.0 / 16.0
15+
end
16+
17+
function plot(lg::WCLogger)
18+
p1=plotx(lg.time, lg.v_wind, [lg.v_ro, lg.v_set_in], lg.f_err*0.001, lg.v_err, lg.acc, lg.force*0.001, lg.state,
19+
title="Winch controller test, all controllers active",
20+
ylabels=["v_wind [m/s]", "v_reel_out [m/s]", "f_err [kN]", "v_error [m/s]", "acc [m/s²]", "force [kN]", "state"],
21+
ysize=10,
22+
labels=["v_wind", ["v_reel_out", "v_set_in"]],
23+
fig="test_winchcontroller",)
24+
display(p1)
25+
end
26+
27+
function simulate(wcs::WCSettings; return_lg::Bool = false)
28+
if TUNED
29+
set = load_settings("system_tuned.yaml")
30+
else
31+
set = load_settings("system.yaml")
32+
end
33+
34+
# define the simulation parameters
35+
DURATION = 10.0
36+
V_WIND_MAX = 9.0 # max wind speed of test wind
37+
V_WIND_MIN = 0.0 # min wind speed of test wind
38+
FREQ_WIND = 0.25 # frequency of the triangle wind speed signal
39+
40+
# create the logger
41+
lg::WCLogger = WCLogger(DURATION, wcs.dt, set.max_force, wcs.max_acc, wcs.damage_factor)
42+
43+
STARTUP = get_startup(wcs, length(lg))
44+
V_WIND = STARTUP .* get_triangle_wind(wcs, V_WIND_MIN, V_WIND_MAX, FREQ_WIND, length(lg))
45+
46+
# create and initialize winch controller
47+
wc = WinchController(wcs)
48+
winch = WinchControllers.Winch(wcs, set)
49+
f_low = wcs.f_low
50+
51+
for i in 1:length(lg)
52+
# model
53+
v_wind = V_WIND[i]
54+
v_act = get_speed(winch)
55+
force = calc_force(v_wind, v_act)
56+
set_force(winch, force)
57+
58+
# controller
59+
v_set_out = calc_v_set(wc, v_act, force, f_low)
60+
61+
# update model input
62+
set_v_set(winch, v_set_out)
63+
64+
# run integration step
65+
on_timer(winch)
66+
on_timer(wc)
67+
68+
# get values for logging and log them
69+
status = get_status(wc)
70+
log(lg; v_wind, v_ro=v_act, acc=get_acc(winch), state=get_state(wc), reset=status[1], active=status[2], force=status[3],
71+
f_set=status[4], f_err=get_f_err(wc), v_err=get_v_err(wc), v_set=get_v_set(wc), v_set_out, v_set_in=get_v_set_in(wc))
72+
end
73+
if return_lg
74+
return wcs, lg
75+
end
76+
# calculate the performance metrics
77+
-gamma(lg; rms=true)
78+
end
79+
80+
function simulate_all(x::Vector; return_lg::Bool = false)
81+
wcs = WCSettings(dt=0.02)
82+
update(wcs)
83+
wcs.test = true
84+
wcs.i_speed = x[1] # set the speed controller gain
85+
wcs.p_speed = x[2] # set the speed controller proportional gain
86+
wcs.t_blend = x[3] # set the blending time for switching between controllers
87+
wcs.pf_low = x[4] # set the speed controller gain
88+
wcs.if_low = x[5] # set the speed controller proportional gain
89+
wcs.pf_high = x[6] # set the lower force controller gain
90+
wcs.if_high = x[7] # set the lower force controller integral gain
91+
wcs.df_high = x[8]
92+
simulate(wcs; return_lg)
93+
end
94+
95+
function eval_fct(x)
96+
bb_outputs = [simulate_all(x)]
97+
success = bb_outputs[1] < -0.7
98+
count_eval = true
99+
return (success, count_eval, bb_outputs)
100+
end
101+
102+
function autotune()
103+
global x, info, lg, TUNED, result
104+
if TUNED
105+
load_settings("system_tuned.yaml")
106+
else
107+
load_settings("system.yaml")
108+
end
109+
wcs = WCSettings(dt=0.02)
110+
update(wcs)
111+
wcs.test = true
112+
println("Autotuning all controllers...")
113+
x0 = [wcs.p_speed, wcs.i_speed, wcs.t_blend, wcs.pf_low, wcs.if_low, wcs.pf_high, wcs.if_high, maximum([1e-5, wcs.df_high])] # initial guess for the speed controller gain
114+
115+
pb = NomadProblem(8, # number of inputs of the blackbox
116+
1, # number of outputs of the blackbox
117+
["OBJ"], # type of outputs of the blackbox
118+
eval_fct;
119+
lower_bound = 0.75 .* x0,
120+
upper_bound = 1.5 .* x0)
121+
result = solve(pb, x0)
122+
x = result.x_best_feas
123+
124+
println("Autotuning results: $x")
125+
126+
if true
127+
println("Running simulation with tuned parameters...")
128+
TUNED = true
129+
wcs, lg = simulate_all(x; return_lg=true)
130+
131+
println("\nPerformance of force controllers: $(round(100*(1-f_err(lg)), digits=2)) %")
132+
println("Performance of speed controller: $(round(100*(1-v_err(lg)), digits=2)) %")
133+
println("Damage: $(round(100*(damage(lg)), digits=2)) %")
134+
println("Damage with rms: $(round(100*(damage(lg; rms=true)), digits=2)) %")
135+
println("Combined performance γ: $(round(-100*result.bbo_best_feas[1], digits=2)) %")
136+
return wcs
137+
else
138+
println("Autotuning failed: $(PRIMA.reason(info.status))")
139+
return nothing
140+
end
141+
end
142+
143+
function copy_settings()
144+
cp("data/wc_settings.yaml", "data/wc_settings_tuned.yaml"; force=true)
145+
end
146+
function change_value(lines, varname, value::Union{Integer, Float64})
147+
KiteUtils.change_value(lines, varname, repr(round(value, digits=5)))
148+
end
149+
function update_settings(wcs::WCSettings)
150+
lines = KiteUtils.readfile("data/wc_settings_tuned.yaml")
151+
lines = change_value(lines, "i_speed:", wcs.i_speed)
152+
lines = change_value(lines, "p_speed:", wcs.p_speed)
153+
lines = change_value(lines, "t_blend:", wcs.t_blend)
154+
lines = change_value(lines, "pf_low:", wcs.pf_low)
155+
lines = change_value(lines, "if_low:", wcs.if_low)
156+
lines = change_value(lines, "pf_high:", wcs.pf_high)
157+
lines = change_value(lines, "if_high:", wcs.if_high)
158+
lines = change_value(lines, "df_high:", wcs.df_high)
159+
KiteUtils.writefile(lines, "data/wc_settings_tuned.yaml")
160+
end
161+
162+
function tune_all()
163+
wcs = autotune()
164+
if ! isnothing(wcs)
165+
copy_settings()
166+
update_settings(wcs)
167+
println()
168+
@info "Tuned settings saved to data/wc_settings_tuned.yaml"
169+
end
170+
end
171+
172+
tune_all()
173+
tune_all()

0 commit comments

Comments
 (0)