You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					89 lines
				
				2.1 KiB
			
		
		
			
		
	
	
					89 lines
				
				2.1 KiB
			| 
								 
											1 year ago
										 
									 | 
							
								#!/usr/bin/env python3
							 | 
						||
| 
								 | 
							
								import json
							 | 
						||
| 
								 | 
							
								import time
							 | 
						||
| 
								 | 
							
								import threading
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from panda import Panda
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def drain_serial(p):
							 | 
						||
| 
								 | 
							
								  ret = []
							 | 
						||
| 
								 | 
							
								  while True:
							 | 
						||
| 
								 | 
							
								    d = p.serial_read(0)
							 | 
						||
| 
								 | 
							
								    if len(d) == 0:
							 | 
						||
| 
								 | 
							
								      break
							 | 
						||
| 
								 | 
							
								    ret.append(d)
							 | 
						||
| 
								 | 
							
								  return ret
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fan_cmd = 0.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def logger(event):
							 | 
						||
| 
								 | 
							
								  # requires a build with DEBUG_FAN
							 | 
						||
| 
								 | 
							
								  with Panda(claim=False) as p, open('/tmp/fan_log', 'w') as f:
							 | 
						||
| 
								 | 
							
								    power = None
							 | 
						||
| 
								 | 
							
								    target_rpm = None
							 | 
						||
| 
								 | 
							
								    stall_count = None
							 | 
						||
| 
								 | 
							
								    rpm_fast = None
							 | 
						||
| 
								 | 
							
								    t = time.monotonic()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    drain_serial(p)
							 | 
						||
| 
								 | 
							
								    while not event.is_set():
							 | 
						||
| 
								 | 
							
								      p.set_fan_power(fan_cmd)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      for l in drain_serial(p)[::-1]:
							 | 
						||
| 
								 | 
							
								        ns = l.decode('utf8').strip().split(' ')
							 | 
						||
| 
								 | 
							
								        if len(ns) == 4:
							 | 
						||
| 
								 | 
							
								          target_rpm, rpm_fast, power, stall_count = (int(n, 16) for n in ns)
							 | 
						||
| 
								 | 
							
								          break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      dat = {
							 | 
						||
| 
								 | 
							
								        't': time.monotonic() - t,
							 | 
						||
| 
								 | 
							
								        'cmd_power': fan_cmd,
							 | 
						||
| 
								 | 
							
								        'pwm_power': power,
							 | 
						||
| 
								 | 
							
								        'target_rpm': target_rpm,
							 | 
						||
| 
								 | 
							
								        'rpm_fast': rpm_fast,
							 | 
						||
| 
								 | 
							
								        'rpm': p.get_fan_rpm(),
							 | 
						||
| 
								 | 
							
								        'stall_counter': stall_count,
							 | 
						||
| 
								 | 
							
								        'total_stall_count': p.health()['fan_stall_count'],
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      f.write(json.dumps(dat) + '\n')
							 | 
						||
| 
								 | 
							
								      time.sleep(1/16.)
							 | 
						||
| 
								 | 
							
								    p.set_fan_power(0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def get_overshoot_rpm(p, power):
							 | 
						||
| 
								 | 
							
								  global fan_cmd
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # make sure the fan is stopped completely
							 | 
						||
| 
								 | 
							
								  fan_cmd = 0.
							 | 
						||
| 
								 | 
							
								  while p.get_fan_rpm() > 100:
							 | 
						||
| 
								 | 
							
								    time.sleep(0.1)
							 | 
						||
| 
								 | 
							
								  time.sleep(3)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # set it to 30% power to mimic going onroad
							 | 
						||
| 
								 | 
							
								  fan_cmd = power
							 | 
						||
| 
								 | 
							
								  max_rpm = 0
							 | 
						||
| 
								 | 
							
								  max_power = 0
							 | 
						||
| 
								 | 
							
								  for _ in range(70):
							 | 
						||
| 
								 | 
							
								    max_rpm = max(max_rpm, p.get_fan_rpm())
							 | 
						||
| 
								 | 
							
								    max_power = max(max_power, p.health()['fan_power'])
							 | 
						||
| 
								 | 
							
								    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, max_power
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if __name__ == "__main__":
							 | 
						||
| 
								 | 
							
								  event = threading.Event()
							 | 
						||
| 
								 | 
							
								  threading.Thread(target=logger, args=(event, )).start()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  try:
							 | 
						||
| 
								 | 
							
								    p = Panda()
							 | 
						||
| 
								 | 
							
								    for power in range(10, 101, 10):
							 | 
						||
| 
								 | 
							
								      overshoot, max_rpm, max_power = get_overshoot_rpm(p, power)
							 | 
						||
| 
								 | 
							
								      print(f"Fan power {power}%: overshoot {overshoot:.2%}, Max RPM {max_rpm}, Max power {max_power}%")
							 | 
						||
| 
								 | 
							
								  finally:
							 | 
						||
| 
								 | 
							
								    event.set()
							 |