mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
109 lines
4.1 KiB
Python
Executable File
109 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Wired Android Auto test: project to the car over USB instead of Wi-Fi.
|
|
|
|
Runs on the comma with the car's USB port connected to the comma's USB-C
|
|
device port. It runs one attempt of the supervisor's own wired session
|
|
(``Supervisor._attempt_usb``): an accessory-only USB gadget (comma's ADB gadget
|
|
steps aside if bound), the car's accessory handshake -- or, when it never comes,
|
|
presenting as Google's accessory directly -- then the real streaming path over
|
|
the USB link, printing every event. The ADB gadget is rebound on exit.
|
|
|
|
cd /data/openpilot
|
|
PYTHONPATH=/data/openpilot /usr/local/venv/bin/python tools/starport/usb_device.py [--mode direct]
|
|
|
|
Stop wireless Android Auto in settings first. Start this, then plug the cable
|
|
into the car (or unplug and replug it: the car sends the handshake on connect).
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import signal
|
|
import threading
|
|
from typing import cast
|
|
|
|
from openpilot.starpilot.system.starport import identity as identity_store
|
|
from openpilot.starpilot.system.starport.supervisor import Cancelled, EventLog, Supervisor
|
|
|
|
|
|
class EchoLog:
|
|
"""The supervisor's session log, also printed as it is written."""
|
|
|
|
def __init__(self, log):
|
|
self._log = log
|
|
|
|
def __call__(self, name: str, **values) -> None:
|
|
self._log(name, **values)
|
|
print(json.dumps({"event": name, **values}, default=str), flush=True)
|
|
|
|
def __getattr__(self, name):
|
|
return getattr(self._log, name)
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
parser.add_argument("--view", choices=("car", "mirror"), help="default: the configured view")
|
|
parser.add_argument("--encoder", choices=("auto", "hardware", "software"), help="default: the configured encoder")
|
|
parser.add_argument("--mode", choices=("auto", "handshake", "direct"),
|
|
help="default: the configured usb_mode (auto: handshake, then direct if the car sends none)")
|
|
parser.add_argument("--wait", type=float, default=600.0, help="seconds to wait for the car before giving up")
|
|
args = parser.parse_args()
|
|
|
|
supervisor = Supervisor()
|
|
supervisor.config["connection"] = "wired"
|
|
for key, config_key in (("view", "view"), ("encoder", "encoder"), ("mode", "usb_mode")):
|
|
if getattr(args, key) is not None:
|
|
supervisor.config[config_key] = getattr(args, key)
|
|
ident = identity_store.load_identity()
|
|
print(f"identity ok, expires {ident.expires} ({ident.days_left} days)", flush=True)
|
|
supervisor.log = cast(EventLog, EchoLog(supervisor.log))
|
|
|
|
def stop(*_):
|
|
supervisor._stop.set()
|
|
supervisor._close_sockets()
|
|
signal.signal(signal.SIGINT, stop)
|
|
signal.signal(signal.SIGTERM, stop)
|
|
|
|
timed_out = threading.Event()
|
|
|
|
def give_up():
|
|
if supervisor.status()["state"] == "waiting_for_usb":
|
|
print("the car never started Android Auto over USB", flush=True)
|
|
timed_out.set()
|
|
stop()
|
|
timer = threading.Timer(args.wait, give_up)
|
|
timer.daemon = True
|
|
timer.start()
|
|
|
|
def report():
|
|
while not supervisor._stop.wait(5.0):
|
|
status = supervisor.status()
|
|
print(json.dumps({key: status[key] for key in ("state", "view", "encoder", "target_fps", "mode", "stats")}), flush=True)
|
|
threading.Thread(target=report, daemon=True).start()
|
|
|
|
supervisor.log.open()
|
|
supervisor.log("session_start", receiver="usb", generation=0, trigger="usb_device")
|
|
result = 0
|
|
try:
|
|
print("plug in (or replug) the USB cable", flush=True)
|
|
supervisor._attempt_usb()
|
|
print("session ended", flush=True)
|
|
except Cancelled:
|
|
print("stopped", flush=True)
|
|
except Exception as error:
|
|
if not supervisor._stop.is_set():
|
|
print(json.dumps({"result": "fail", "error": f"{type(error).__name__}: {error}",
|
|
"recent": list(supervisor.log.recent)[-8:]}, default=str))
|
|
result = 1
|
|
finally:
|
|
timer.cancel()
|
|
supervisor._stop.set()
|
|
supervisor._close_sockets()
|
|
supervisor.log("session_stop")
|
|
supervisor.log.close()
|
|
print(f"log: {identity_store.LOG_DIR}", flush=True)
|
|
return 1 if timed_out.is_set() else result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|