* untested code

* add to manager

* whitespace

* only save on fix

* cleanup

* fix typo

* add to ignored processes

* import tici

* fix param name

* cleanup

* only run offroad

* use itertools

* wait for thermald

* simpler

* fall back to api call

* add param to override timezone

Co-authored-by: Comma Device <device@comma.ai>
albatross
Willem Melching 2021-02-06 11:07:37 +01:00 committed by GitHub
parent 3dc45554d7
commit 4c04e220a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 705 additions and 541 deletions

View File

@ -119,6 +119,7 @@ PyJWT = "*"
pyserial = "*"
onnx = "*"
onnxruntime = "*"
timezonefinder = "*"
[requires]
python_version = "3.8"

1144
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -44,8 +44,9 @@ keys = {
b"IsUpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
b"IsUploadRawEnabled": [TxType.PERSISTENT],
b"LastAthenaPingTime": [TxType.PERSISTENT],
b"LastUpdateTime": [TxType.PERSISTENT],
b"LastGPSPosition": [TxType.PERSISTENT],
b"LastUpdateException": [TxType.PERSISTENT],
b"LastUpdateTime": [TxType.PERSISTENT],
b"LiveParameters": [TxType.PERSISTENT],
b"OpenpilotEnabledToggle": [TxType.PERSISTENT],
b"LaneChangeEnabled": [TxType.PERSISTENT],
@ -58,6 +59,7 @@ keys = {
b"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
b"SubscriberInfo": [TxType.PERSISTENT],
b"TermsVersion": [TxType.PERSISTENT],
b"Timezone": [TxType.PERSISTENT],
b"TrainingVersion": [TxType.PERSISTENT],
b"UpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
b"UpdateFailedCount": [TxType.CLEAR_ON_MANAGER_START],

View File

@ -30,7 +30,7 @@ STEER_ANGLE_SATURATION_THRESHOLD = 2.5 # Degrees
SIMULATION = "SIMULATION" in os.environ
NOSENSOR = "NOSENSOR" in os.environ
IGNORE_PROCESSES = set(["rtshield", "uploader", "deleter", "loggerd", "logmessaged", "tombstoned", "logcatd", "proclogd", "clocksd", "gpsd", "updated"])
IGNORE_PROCESSES = set(["rtshield", "uploader", "deleter", "loggerd", "logmessaged", "tombstoned", "logcatd", "proclogd", "clocksd", "gpsd", "updated", "timezoned"])
ThermalStatus = log.ThermalData.ThermalStatus
State = log.ControlsState.OpenpilotState

View File

@ -1,8 +1,10 @@
#!/usr/bin/env python3
import json
import numpy as np
import sympy as sp
import cereal.messaging as messaging
from cereal import log
from common.params import Params
import common.transformations.coordinates as coord
from common.transformations.orientation import ecef_euler_from_ned, \
euler_from_quat, \
@ -295,6 +297,7 @@ def locationd_thread(sm, pm, disabled_logs=None):
if pm is None:
pm = messaging.PubMaster(['liveLocationKalman'])
params = Params()
localizer = Localizer(disabled_logs=disabled_logs)
while True:
@ -327,6 +330,14 @@ def locationd_thread(sm, pm, disabled_logs=None):
msg.liveLocationKalman.gpsOK = gps_age < 1.0
pm.send('liveLocationKalman', msg)
if sm.frame % 1200 == 0 and msg.liveLocationKalman.gpsOK: # once a minute
location = {
'latitude': msg.liveLocationKalman.positionGeodetic.value[0],
'longitude': msg.liveLocationKalman.positionGeodetic.value[1],
'altitude': msg.liveLocationKalman.positionGeodetic.value[2],
}
params.put("LastGPSPosition", json.dumps(location))
def main(sm=None, pm=None):
locationd_thread(sm, pm)

View File

@ -19,7 +19,7 @@ from common.basedir import BASEDIR
from common.spinner import Spinner
from common.text_window import TextWindow
import selfdrive.crash as crash
from selfdrive.hardware import HARDWARE, EON, PC
from selfdrive.hardware import HARDWARE, EON, PC, TICI
from selfdrive.hardware.eon.apk import update_apks, pm_apply_packages, start_offroad
from selfdrive.swaglog import cloudlog, add_logentries_handler
from selfdrive.version import version, dirty
@ -218,6 +218,10 @@ if EON:
'sensord',
]
if TICI:
managed_processes["timezoned"] = "selfdrive.timezoned"
persistent_processes += ['timezoned']
car_started_processes = [
'controlsd',
'plannerd',

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python3
import time
import json
import subprocess
import requests
from timezonefinder import TimezoneFinder
from common.params import Params
from selfdrive.swaglog import cloudlog
def set_timezone(valid_timezones, timezone):
if timezone not in valid_timezones:
cloudlog.error(f"Timezone not supported {timezone}")
return
cloudlog.info(f"Setting timezone to {timezone}")
try:
subprocess.check_call(f'sudo timedatectl set-timezone {timezone}', shell=True)
except subprocess.CalledProcessError:
cloudlog.exception(f"Error setting timezone to {timezone}")
def main():
params = Params()
tf = TimezoneFinder()
# Get allowed timezones
valid_timezones = subprocess.check_output('timedatectl list-timezones', shell=True, encoding='utf8').strip().split('\n')
while True:
time.sleep(60)
is_onroad = params.get("IsOffroad") != b"1"
if is_onroad:
continue
# Set based on param
timezone = params.get("Timezone", encoding='utf8')
if timezone is not None:
cloudlog.info("Setting timezone based on param")
set_timezone(valid_timezones, timezone)
continue
location = params.get("LastGPSPosition", encoding='utf8')
# Find timezone based on IP geolocation if no gps location is available
if location is None:
cloudlog.info("Setting timezone based on IP lookup")
try:
r = requests.get("https://ipapi.co/timezone", timeout=10)
if r.status_code == 200:
set_timezone(valid_timezones, r.text)
else:
cloudlog.error(f"Unexpected status code from api {r.status_code}")
except requests.exceptions.RequestException:
cloudlog.exception("Error getting timezone based on IP")
continue
# Find timezone by reverse geocoding the last known gps location
else:
cloudlog.info("Setting timezone based on GPS location")
try:
location = json.loads(location)
except Exception:
cloudlog.exception("Error parsing location")
continue
timezone = tf.timezone_at(lng=location['longitude'], lat=location['latitude'])
if timezone is None:
cloudlog.error(f"No timezone found based on location, {location}")
continue
set_timezone(valid_timezones, timezone)
if __name__ == "__main__":
main()