闭环算法升级:分档在线辨识k+不对称EMA+过冲自惩罚+自适应激进系数,实测双向单调零过冲

This commit is contained in:
tonycao 2026-10-10 20:53:18 +08:00
parent ecf2702ede
commit d6a9c9e500
2 changed files with 25 additions and 8 deletions

Binary file not shown.

View File

@ -29,6 +29,7 @@ local DEADBAND = lux_deadband
local MIN_LEVEL = 0.05 local MIN_LEVEL = 0.05
local MAX_LEVEL = 1.0 local MAX_LEVEL = 1.0
local STEP_MAX = 0.20 local STEP_MAX = 0.20
local K_DEFAULT = 3000
local ok, grp = pcall(get_group, 0) local ok, grp = pcall(get_group, 0)
if not ok or grp == nil then if not ok or grp == nil then
@ -38,16 +39,20 @@ if not ok or grp == nil then return end
local err = TARGET_LUX - lux local err = TARGET_LUX - lux
if lux_prev_cmd ~= nil and lux_prev_cur ~= nil and lux_prev_lux ~= nil then if lux_prev_cmd ~= nil and lux_prev_cur ~= nil and lux_prev_lux ~= nil and lux_prev_band ~= nil then
local dl = lux_prev_cmd - lux_prev_cur local dl = lux_prev_cmd - lux_prev_cur
local clamped = (lux_prev_cmd <= MIN_LEVEL + 0.001) or (lux_prev_cmd >= MAX_LEVEL - 0.001) local clamped = (lux_prev_cmd <= MIN_LEVEL + 0.001) or (lux_prev_cmd >= MAX_LEVEL - 0.001)
if math.abs(dl) > 0.002 and not clamped then if math.abs(dl) > 0.005 and not clamped then
local ki = (lux - lux_prev_lux) / dl local ki = (lux - lux_prev_lux) / dl
if ki > 100 and ki < 10000 then if ki > 100 and ki < 10000 and math.abs(lux - lux_prev_lux) >= 3 then
if lux_k == nil then lux_kb = lux_kb or {}
lux_k = ki local kb = lux_kb[lux_prev_band]
if kb == nil then
lux_kb[lux_prev_band] = ki
elseif ki > kb then
lux_kb[lux_prev_band] = 0.5 * kb + 0.5 * ki
else else
lux_k = 0.7 * lux_k + 0.3 * ki lux_kb[lux_prev_band] = 0.9 * kb + 0.1 * ki
end end
end end
end end
@ -69,9 +74,20 @@ if cur == nil or (hw ~= nil and math.abs(hw - cur) > 0.05) then
cur = hw or 0.5 cur = hw or 0.5
end end
local k = lux_k or 500 local band = math.floor(cur * 4.999) + 1
local delta = err / k local k = (lux_kb ~= nil and lux_kb[band]) or K_DEFAULT
lux_agg = lux_agg or 0.7
local delta
if lux_last_err ~= nil and (err > 0) ~= (lux_last_err > 0) then if lux_last_err ~= nil and (err > 0) ~= (lux_last_err > 0) then
lux_agg = lux_agg * 0.5
if math.abs(err) > 3 and lux_kb ~= nil and lux_prev_band ~= nil and lux_kb[lux_prev_band] ~= nil then
lux_kb[lux_prev_band] = math.min(lux_kb[lux_prev_band] * 1.3, 10000)
end
else
lux_agg = math.min(lux_agg * 1.15, 0.9)
end
delta = err / k * lux_agg
if math.abs(err) < 30 then
delta = delta * 0.5 delta = delta * 0.5
end end
lux_last_err = err lux_last_err = err
@ -85,5 +101,6 @@ if new > MAX_LEVEL then new = MAX_LEVEL end
lux_prev_cur = cur lux_prev_cur = cur
lux_prev_cmd = new lux_prev_cmd = new
lux_prev_lux = lux lux_prev_lux = lux
lux_prev_band = band
lux_cur_level = new lux_cur_level = new
grp:set_master_intensity(new, lux_fade) grp:set_master_intensity(new, lux_fade)