Skip to content

Commit c27ccb2

Browse files
committed
AP_Scripting: improved fan control
1 parent 5657b91 commit c27ccb2

File tree

1 file changed

+44
-21
lines changed

1 file changed

+44
-21
lines changed

libraries/AP_Scripting/applets/fan-control.lua

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ local RELAY_NUM = 0
2525

2626
-- add new param POI_DIST_MAX
2727
local PARAM_TABLE_KEY = 94
28-
assert(param:add_table(PARAM_TABLE_KEY, "FAN_", 1), "could not add param table")
28+
assert(param:add_table(PARAM_TABLE_KEY, "FAN_", 3), "could not add param table")
2929
assert(param:add_param(PARAM_TABLE_KEY, 1, "ENABLE", 1), "could not add FAN_ENABLE param")
30+
assert(param:add_param(PARAM_TABLE_KEY, 2, "FILT_TC", 0.1), "could not add FAN_FILT_TC param")
31+
assert(param:add_param(PARAM_TABLE_KEY, 3, "DEBUG", 0), "could not add FAN_DEBUG param")
3032

3133
--[[
3234
// @Param: FAN_ENABLE
@@ -37,11 +39,31 @@ assert(param:add_param(PARAM_TABLE_KEY, 1, "ENABLE", 1), "could not add FAN_ENAB
3739
--]]
3840
local FAN_ENABLE = Parameter("FAN_ENABLE")
3941

42+
--[[
43+
// @Param: FAN_FILT_TC
44+
// @DisplayName: Fan Control Filter Time Constant
45+
// @Description: Time constant for filtering fan control input (smaller = faster response, larger = smoother)
46+
// @Range: 0.01 2.0
47+
// @Units: s
48+
// @User: Standard
49+
--]]
50+
local FAN_FILT_TC = Parameter("FAN_FILT_TC")
51+
52+
--[[
53+
// @Param: FAN_DEBUG
54+
// @DisplayName: Fan Control Debug
55+
// @Description: Enable debug output for fan control
56+
// @Values: 0:Disable, 1:Enable
57+
// @User: Standard
58+
--]]
59+
local FAN_DEBUG = Parameter("FAN_DEBUG")
60+
4061
-- local variables and definitions
4162
local last_send_text_ms = 0 -- system time of last message to user (used to prevent spamming)
42-
local relay_output_total = 0 -- total number of relay outputs (including both low and high)
43-
local relay_output_high = 0 -- number of high relay outputs (never more than relay_output_total)
4463
local relay_output_last = 0 -- last output to relay (used to avoid unnecessarily changing relay output)
64+
local relay_output_filtered = 0 -- filtered output
65+
local pwm_accumulator = 0 -- accumulator for PWM generation
66+
local last_debug_text_ms = 0 -- system time of last debug output to user
4567

4668
-- send text message to user at no more than 1hz
4769
function send_text(priority, warning_msg)
@@ -81,14 +103,20 @@ function update()
81103
end
82104
rc_fan_control_norm = (rc_fan_control_norm + 1.0) / 2.0
83105

84-
-- determine if relay output should be moved high or low
85-
local relay_output_average = 0
86-
if relay_output_total > 0 then
87-
relay_output_average = relay_output_high / relay_output_total
88-
end
106+
-- apply low-pass filter to the desired output
107+
-- filter equation: filtered = filtered + (dt/tc) * (input - filtered)
108+
local dt = UPDATE_INTERVAL_MS / 1000.0 -- convert ms to seconds
109+
local filter_tc = FAN_FILT_TC:get() -- get time constant from parameter
110+
local alpha = dt / (filter_tc + dt)
111+
relay_output_filtered = relay_output_filtered + alpha * (rc_fan_control_norm - relay_output_filtered)
112+
113+
-- generate PWM output using filtered value
114+
-- accumulate the filtered value and output high when accumulator >= 1
115+
pwm_accumulator = pwm_accumulator + relay_output_filtered
89116
local relay_output_new = 0
90-
if relay_output_average < rc_fan_control_norm then
117+
if pwm_accumulator >= 1.0 then
91118
relay_output_new = 1
119+
pwm_accumulator = pwm_accumulator - 1.0 -- subtract 1 but keep remainder
92120
end
93121

94122
-- set relay to high or low
@@ -101,18 +129,13 @@ function update()
101129
end
102130
relay_output_last = relay_output_new
103131

104-
-- update totals
105-
relay_output_total = relay_output_total + 1
106-
if relay_output_new > 0 then
107-
relay_output_high = relay_output_high + 1
108-
end
109-
110-
-- reset totals each 1000 updates
111-
if relay_output_total >= 1000 then
112-
-- debug output to user
113-
gcs:send_text(MAV_SEVERITY.DEBUG, string.format("Fan control: %.2f outputs, %.2f high", rc_fan_control_norm, relay_output_average))
114-
relay_output_total = 0
115-
relay_output_high = 0
132+
-- debug output to user (every 1000 updates = 1 second)
133+
if FAN_DEBUG:get() == 1 then
134+
local now_ms = millis()
135+
if (now_ms - last_debug_text_ms) > 1000 then
136+
gcs:send_text(MAV_SEVERITY.DEBUG, string.format("Fan control: input=%.2f, filtered=%.2f, output=%d", rc_fan_control_norm, relay_output_filtered, relay_output_new))
137+
last_debug_text_ms = now_ms
138+
end
116139
end
117140

118141
return update, UPDATE_INTERVAL_MS

0 commit comments

Comments
 (0)