diff --git a/selfdrive/carrot/realtime/transports/raw_ws.py b/selfdrive/carrot/realtime/transports/raw_ws.py index 99961fbcf..ed7fb60b6 100644 --- a/selfdrive/carrot/realtime/transports/raw_ws.py +++ b/selfdrive/carrot/realtime/transports/raw_ws.py @@ -35,6 +35,13 @@ class RawWsHub: # 0 = no throttle (send every message) _THROTTLE_MAP = { "modelV2": 0, # camera-synced, don't throttle + "carState": 0, # plot 1,2,5,7,8 — needs full rate for dense graphs + "controlsState": 0, # plot 6 — needs full rate for dense graphs + "longitudinalPlan": 0, # plot 1,2,4 — needs full rate for dense graphs + "carControl": 0, # plot 1,6,7,8 — needs full rate for dense graphs + "radarState": 0, # plot 4,5 — needs full rate for dense graphs + "lateralPlan": 0, # overlay path rendering + "carrotMan": 0, # HUD status updates "roadCameraState": 0.25, # metadata/debug only on web HUD "deviceState": 0.5, # slow-changing HUD stats "peripheralState": 0.5, diff --git a/selfdrive/carrot/server/core.py b/selfdrive/carrot/server/core.py index 6504fbe11..7df1dc3ec 100644 --- a/selfdrive/carrot/server/core.py +++ b/selfdrive/carrot/server/core.py @@ -27,7 +27,7 @@ import traceback import numpy as np from typing import Dict, Any, Tuple, Optional, List -from aiohttp import web, ClientSession, WSMsgType +from aiohttp import web, ClientSession, ClientTimeout, WSMsgType from cereal import messaging from opendbc.car import structs import shlex @@ -204,14 +204,16 @@ async def proxy_stream(request: web.Request) -> web.StreamResponse: sess: ClientSession = request.app["http"] try: - async with sess.post(WEBRTCD_URL, data=body, headers={"Content-Type": ct}) as resp: + async with sess.post(WEBRTCD_URL, data=body, headers={"Content-Type": ct}, + timeout=ClientTimeout(total=15)) as resp: resp_body = await resp.read() - # 그대로 전달 out = web.Response(body=resp_body, status=resp.status) rct = resp.headers.get("Content-Type") if rct: out.headers["Content-Type"] = rct return out + except asyncio.TimeoutError: + return web.json_response({"ok": False, "error": "webrtcd timeout"}, status=504) except Exception as e: return web.json_response({"ok": False, "error": str(e)}, status=502) diff --git a/selfdrive/carrot/web/css/app.css b/selfdrive/carrot/web/css/app.css index 952ac5f73..60eeac418 100644 --- a/selfdrive/carrot/web/css/app.css +++ b/selfdrive/carrot/web/css/app.css @@ -2152,16 +2152,13 @@ body[data-page="carrot"] #driveHudCard.driveHudCard--loading { border-radius: calc(var(--r-2xl) + 2px); overflow: hidden; border: 1px solid color-mix(in srgb, var(--md-outline-var) 82%, rgba(255,255,255,0.12)); - background: - radial-gradient(circle at 16% 20%, rgba(255, 146, 77, 0.15), transparent 28%), - radial-gradient(circle at 80% 80%, rgba(104, 201, 255, 0.12), transparent 24%), - linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0)), - #04070c; + background: #0b0e12; box-shadow: 0 20px 48px rgba(0, 0, 0, 0.24); contain: layout style; } .carrot-stage__video, +.carrot-stage__videoHold, .carrot-stage__canvas, .carrot-stage__hud { position: absolute; @@ -2212,6 +2209,10 @@ body[data-page="carrot"] #driveHudCard.driveHudCard--loading { opacity: 1; } +.carrot-stage.is-video-held .carrot-stage__videoHold { + opacity: 1; +} + .carrot-stage.is-loading .carrot-stage__controls { opacity: 0; transform: translateY(8px); @@ -2225,6 +2226,14 @@ body[data-page="carrot"] #driveHudCard.driveHudCard--loading { pointer-events: none; } +.carrot-stage__videoHold { + transform-origin: 0 0; + will-change: transform; + background: #000; + pointer-events: none; + z-index: 1; +} + .carrot-stage__canvas { transform-origin: 0 0; will-change: transform; diff --git a/selfdrive/carrot/web/index.html b/selfdrive/carrot/web/index.html index d48adc45c..175e9c5e7 100644 --- a/selfdrive/carrot/web/index.html +++ b/selfdrive/carrot/web/index.html @@ -7,7 +7,7 @@ - +
@@ -243,6 +243,7 @@