ExplodingCB2's picture
drive-v5 and the checkpoints it came from, with a model card
ee68aa6 verified
Raw History Blame Contribute Delete
2.19 kB
"""The driving model behind the simulator's camera-model contract.
python -m mcq_sim evaluate --policy stack --perception driver:create
with ``PYTHONPATH=training/perception:src/mcq_sim``. Weights come from
``MCQ_DRIVER_WEIGHTS``, else ``runs/drive-latest/model.pt`` beside this file.
``predict(rgb)`` is the pavement probability, as for a segmenter, so the stack
can build its corridor. ``predict_drive(rgb)`` adds the racing line the model
intends to drive, as waypoints in base_link (x forward, y left), and the speed
it wants at each. The stack drives that line when it stays inside the corridor
and falls back to its own planner when it does not.
"""
from __future__ import annotations
import os
from pathlib import Path
import numpy as np
import torch
import torch.nn.functional as F
from model import DriveNet
HERE = Path(__file__).resolve().parent
class Driver:
def __init__(self, weights: str | Path, device="cpu"):
torch.set_num_threads(1) # many drivers run side by side in rollouts; one thread each
checkpoint = torch.load(weights, map_location=device, weights_only=True)
self.net = DriveNet(fine=bool(checkpoint.get("fine", False))).to(device).eval()
self.net.load_state_dict(checkpoint["state"])
self.device = device
self.weights = str(weights)
@torch.no_grad()
def predict_drive(self, rgb: np.ndarray):
"""uint8 HWC RGB (270 x 480) in; (pavement probability 270 x 480,
waypoints K x 2 in metres, speeds K in m/s) out."""
x = torch.from_numpy(np.ascontiguousarray(rgb)).to(self.device).permute(2, 0, 1)[None].float()
h, w = x.shape[-2:]
logits, points, speeds = self.net.forward_all(F.avg_pool2d(x, 2))
probability = torch.sigmoid(F.interpolate(logits[None], size=(h, w), mode="bilinear", align_corners=False))
out = probability[0, 0].cpu().numpy(), points[0].cpu().numpy(), speeds[0].cpu().numpy()
return out
def predict(self, rgb: np.ndarray) -> np.ndarray:
return self.predict_drive(rgb)[0]
def create():
path = os.environ.get("MCQ_DRIVER_WEIGHTS", HERE / "runs" / "drive-latest" / "model.pt")
return Driver(path)