Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Power monitoring fix (#1269) #51

Merged
merged 1 commit into from
Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions selfdrive/thermald/power_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ def panda_current_to_actual_current(panda_current):


class PowerMonitoring:
def __init__(self):
def __init__(self, is_uno):
self.last_measurement_time = None # Used for integration delta
self.power_used_uWh = 0 # Integrated power usage in uWh since going into offroad
self.next_pulsed_measurement_time = None
self.integration_lock = threading.Lock()
self.is_uno = is_uno

# Calculation tick
def calculate(self, health):
Expand All @@ -76,14 +77,17 @@ def calculate(self, health):
# Only integrate when there is no ignition
# If health is None, we're probably not in a car, so we don't care
if health is None or (health.health.ignitionLine or health.health.ignitionCan):
self.last_measurement_time = None
self.power_used_uWh = 0
with self.integration_lock:
self.last_measurement_time = None
self.next_pulsed_measurement_time = None
self.power_used_uWh = 0
return

# First measurement, set integration time
if self.last_measurement_time is None:
self.last_measurement_time = now
return
with self.integration_lock:
if self.last_measurement_time is None:
self.last_measurement_time = now
return

# Get current power draw somehow
current_power = 0
Expand Down Expand Up @@ -114,6 +118,7 @@ def perform_pulse_measurement(now):
currents.append(get_battery_current())
time.sleep(1)
current_power = ((mean(voltages) / 1000000) * (mean(currents) / 1000000))

self._perform_integration(now, current_power * FUDGE_FACTOR)

# Enable charging again
Expand All @@ -126,7 +131,7 @@ def perform_pulse_measurement(now):
self.next_pulsed_measurement_time = None
return

elif self.next_pulsed_measurement_time is None:
elif self.next_pulsed_measurement_time is None and not self.is_uno:
# On a charging EON with black panda, or drawing more than 400mA out of a white/grey one
# Only way to get the power draw is to turn off charging for a few sec and check what the discharging rate is
# We shouldn't do this very often, so make sure it has been some long-ish random time interval
Expand All @@ -139,14 +144,17 @@ def perform_pulse_measurement(now):
# Do the integration
self._perform_integration(now, current_power)
except Exception:
cloudlog.exception("Power monitoring calculation failed:")
cloudlog.exception("Power monitoring calculation failed")

def _perform_integration(self, t, current_power):
self.integration_lock.acquire()
integration_time_h = (t - self.last_measurement_time) / 3600
self.power_used_uWh += (current_power * 1000000) * integration_time_h
self.last_measurement_time = t
self.integration_lock.release()
with self.integration_lock:
try:
if self.last_measurement_time:
integration_time_h = (t - self.last_measurement_time) / 3600
self.power_used_uWh += (current_power * 1000000) * integration_time_h
self.last_measurement_time = t
except Exception:
cloudlog.exception("Integration failed")

# Get the power usage
def get_power_used(self):
Expand Down
2 changes: 1 addition & 1 deletion selfdrive/thermald/thermald.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def thermald_thread():
handle_fan = handle_fan_eon

params = Params()
pm = PowerMonitoring()
pm = PowerMonitoring(is_uno)

while 1:
health = messaging.recv_sock(health_sock, wait=True)
Expand Down