Dos fan fix (#1335)

* hitl fan test

* enable cooldown on dos as well

* small cleanup

* get expected RPM from panda class

* fix

* overshoot test

* fix max RPM getting

* fix percentage

* revert cooldown fix

* add cooldown for dos fan as well

* remove feedforward from the fan controller to eliminate overshoot

* update clip

* cleanup

* add that back

---------

Co-authored-by: Comma Device <device@comma.ai>
Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
This commit is contained in:
Robbe Derks 2023-04-18 14:15:06 -07:00 committed by GitHub
parent 1f8b03666d
commit 237ffedcb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 8 deletions

View File

@ -217,7 +217,7 @@ const board board_dos = {
.fan_max_rpm = 6500U,
.adc_scale = 8862U,
.fan_stall_recovery = true,
.fan_enable_cooldown_time = 0U,
.fan_enable_cooldown_time = 3U,
.init = dos_init,
.enable_can_transceiver = dos_enable_can_transceiver,
.enable_can_transceivers = dos_enable_can_transceivers,

View File

@ -48,7 +48,7 @@ void fan_tick(void){
current_board->set_fan_enabled(false);
// clip integral, can't fully reset otherwise we may always be stuck in stall detection
fan_state.error_integral = MIN(50.0f, MAX(0.0f, fan_state.error_integral));
fan_state.error_integral = MIN(0.0f, fan_state.error_integral);
}
} else {
fan_state.stall_counter = 0U;
@ -57,13 +57,10 @@ void fan_tick(void){
}
// Update controller
float feedforward = (fan_state.target_rpm * 100.0f) / current_board->fan_max_rpm;
float error = fan_state.target_rpm - fan_rpm_fast;
fan_state.error_integral += FAN_I * (fan_state.target_rpm - fan_rpm_fast);
fan_state.error_integral = MIN(100.0f, MAX(0.0f, fan_state.error_integral));
fan_state.error_integral += FAN_I * error;
fan_state.error_integral = MIN(70.0f, MAX(-70.0f, fan_state.error_integral));
fan_state.power = MIN(100U, MAX(0U, feedforward + fan_state.error_integral));
fan_state.power = MIN(100U, MAX(0U, fan_state.error_integral));
pwm_set(TIM3, 3, fan_state.power);
// Cooldown counter

View File

@ -194,6 +194,12 @@ class Panda:
INTERNAL_DEVICES = (HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_TRES)
HAS_OBD = (HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES)
MAX_FAN_RPMs = {
HW_TYPE_UNO: 5100,
HW_TYPE_DOS: 6500,
HW_TYPE_TRES: 6600,
}
# first byte is for EPS scaling factor
FLAG_TOYOTA_ALT_BRAKE = (1 << 8)
FLAG_TOYOTA_STOCK_LONGITUDINAL = (2 << 8)

31
tests/fan_overshoot_test.py Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env python3
import time
from panda import Panda
def get_overshoot_rpm(p, power):
# make sure the fan is stopped completely
p.set_fan_power(0)
while p.get_fan_rpm() > 100:
time.sleep(0.1)
time.sleep(1)
# set it to 30% power to mimic going onroad
p.set_fan_power(power)
max_rpm = 0
for _ in range(70):
max_rpm = max(max_rpm, p.get_fan_rpm())
time.sleep(0.1)
# tolerate 10% overshoot
expected_rpm = Panda.MAX_FAN_RPMs[bytes(p.get_type())] * power / 100
overshoot = (max_rpm / expected_rpm) - 1
return overshoot, max_rpm
if __name__ == "__main__":
p = Panda()
for power in range(10, 101, 10):
overshoot, max_rpm = get_overshoot_rpm(p, power)
print(f"Fan power {power}% overshoot: {overshoot:.2f} Max RPM: {max_rpm}")