Files
MoreTore/selfdrive/frogpilot/frogpilot_process.py
T
2024-09-10 19:52:56 -07:00

208 lines
7.4 KiB
Python

import datetime
import os
import threading
from cereal import log, messaging
from openpilot.common.params import Params
from openpilot.common.realtime import Priority, config_realtime_process
from openpilot.common.time import system_time_valid
from openpilot.system.hardware import HARDWARE
from openpilot.selfdrive.frogpilot.controls.frogpilot_planner import FrogPilotPlanner
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import backup_toggles, is_url_pingable
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_tracking import FrogPilotTracking
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_variables import FrogPilotVariables
from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, DEFAULT_MODEL_NAME, ModelManager
from openpilot.selfdrive.frogpilot.controls.lib.theme_manager import ThemeManager
WIFI = log.DeviceState.NetworkType.wifi
locks = {
"backup_toggles": threading.Lock(),
"download_all_models": threading.Lock(),
"download_model": threading.Lock(),
"download_theme": threading.Lock(),
"time_checks": threading.Lock(),
"toggle_updates": threading.Lock(),
"update_active_theme": threading.Lock(),
"update_models": threading.Lock(),
"update_themes": threading.Lock()
}
running_threads = {}
def run_thread_with_lock(name, target, args=()):
if not running_threads.get(name, threading.Thread()).is_alive():
with locks[name]:
thread = threading.Thread(target=target, args=args)
thread.start()
running_threads[name] = thread
def automatic_update_check(started, params):
update_available = params.get_bool("UpdaterFetchAvailable")
update_ready = params.get_bool("UpdateAvailable")
update_state_idle = params.get("UpdaterState", encoding='utf8') == "idle"
if update_ready and not started:
HARDWARE.reboot()
elif update_available:
os.system("pkill -SIGHUP -f system.updated.updated")
elif update_state_idle:
os.system("pkill -SIGUSR1 -f system.updated.updated")
def download_assets(model_manager, theme_manager, params, params_memory):
model_to_download = params_memory.get("ModelToDownload", encoding='utf-8')
if model_to_download:
run_thread_with_lock("download_model", model_manager.download_model, (model_to_download,))
if params_memory.get_bool("DownloadAllModels"):
run_thread_with_lock("download_all_models", model_manager.download_all_models)
assets = [
("ColorToDownload", "colors"),
("DistanceIconToDownload", "distance_icons"),
("IconToDownload", "icons"),
("SignalToDownload", "signals"),
("SoundToDownload", "sounds"),
("WheelToDownload", "steering_wheels")
]
for param, asset_type in assets:
asset_to_download = params_memory.get(param, encoding='utf-8')
if asset_to_download:
run_thread_with_lock("download_theme", theme_manager.download_theme, (asset_type, asset_to_download, param))
def time_checks(automatic_updates, deviceState, model_manager, now, started, theme_manager, params, params_memory):
if deviceState.networkType != WIFI:
return
if not is_url_pingable("https://github.com"):
return
screen_off = deviceState.screenBrightnessPercent == 0
if automatic_updates and screen_off:
automatic_update_check(started, params)
update_maps(now, params, params_memory)
with locks["update_models"]:
model_manager.update_models()
with locks["update_themes"]:
theme_manager.update_themes()
def toggle_updates(frogpilot_toggles, started, time_validated, params, params_storage):
FrogPilotVariables.update_frogpilot_params(started)
if not frogpilot_toggles.model_manager:
params.put_nonblocking("Model", DEFAULT_MODEL)
params.put_nonblocking("ModelName", DEFAULT_MODEL_NAME)
if time_validated and not started:
run_thread_with_lock("backup_toggles", backup_toggles, (params, params_storage))
def update_maps(now, params, params_memory):
maps_selected = params.get("MapsSelected", encoding='utf8')
if not maps_selected:
return
day = now.day
is_first = day == 1
is_Sunday = now.weekday() == 6
schedule = params.get_int("PreferredSchedule")
maps_downloaded = os.path.exists('/data/media/0/osm/offline')
if maps_downloaded and (schedule == 0 or (schedule == 1 and not is_Sunday) or (schedule == 2 and not is_first)):
return
suffix = "th" if 4 <= day <= 20 or 24 <= day <= 30 else ["st", "nd", "rd"][day % 10 - 1]
todays_date = now.strftime(f"%B {day}{suffix}, %Y")
if params.get("LastMapsUpdate", encoding='utf-8') == todays_date:
return
if params.get("OSMDownloadProgress", encoding='utf-8') is None:
params_memory.put_nonblocking("OSMDownloadLocations", maps_selected)
params.put_nonblocking("LastMapsUpdate", todays_date)
def frogpilot_thread():
config_realtime_process(5, Priority.CTRL_LOW)
frogpilot_toggles = FrogPilotVariables.toggles
FrogPilotVariables.update_frogpilot_params()
params = Params()
params_memory = Params("/dev/shm/params")
params_storage = Params("/persist/params")
frogpilot_planner = FrogPilotPlanner()
frogpilot_tracking = FrogPilotTracking()
model_manager = ModelManager()
theme_manager = ThemeManager()
theme_manager.update_active_theme()
run_time_checks = False
started_previously = False
time_validated = False
update_toggles = False
pm = messaging.PubMaster(['frogpilotPlan'])
sm = messaging.SubMaster(['carState', 'controlsState', 'deviceState', 'frogpilotCarControl',
'frogpilotCarState', 'frogpilotNavigation', 'modelV2', 'radarState'],
poll='modelV2', ignore_avg_freq=['radarState'])
while True:
sm.update()
now = datetime.datetime.now()
deviceState = sm['deviceState']
started = deviceState.started
if not started and started_previously:
frogpilot_planner = FrogPilotPlanner()
frogpilot_tracking = FrogPilotTracking()
if started and sm.updated['modelV2']:
frogpilot_planner.update(sm['carState'], sm['controlsState'], sm['frogpilotCarControl'], sm['frogpilotCarState'],
sm['frogpilotNavigation'], sm['modelV2'], sm['radarState'], frogpilot_toggles)
frogpilot_planner.publish(sm, pm, frogpilot_toggles)
frogpilot_tracking.update(sm['carState'])
if params_memory.get_bool("UpdateTheme"):
run_thread_with_lock("update_active_theme", theme_manager.update_active_theme)
if FrogPilotVariables.toggles_updated:
update_toggles = True
elif update_toggles:
run_thread_with_lock("toggle_updates", toggle_updates, (frogpilot_toggles, started, time_validated, params, params_storage))
update_toggles = False
started_previously = started
download_assets(model_manager, theme_manager, params, params_memory)
if now.second == 0:
run_time_checks = True
elif run_time_checks or not time_validated:
run_thread_with_lock("time_checks", time_checks, (frogpilot_toggles.automatic_updates, deviceState, model_manager, now, started, theme_manager, params, params_memory))
run_time_checks = False
if not time_validated:
time_validated = system_time_valid()
if not time_validated:
continue
if deviceState.networkType == WIFI:
run_thread_with_lock("update_models", model_manager.update_models, (True,))
run_thread_with_lock("update_themes", theme_manager.update_themes, (True,))
theme_manager.update_holiday()
def main():
frogpilot_thread()
if __name__ == "__main__":
main()