mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-24 01:33:46 +08:00
211 lines
6.1 KiB
Python
211 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import json
|
|
import time
|
|
from itertools import cycle
|
|
|
|
from cereal import log, messaging
|
|
from openpilot.common.params import Params, UnknownKeyName
|
|
|
|
|
|
ROUTE_COORDS = [
|
|
{"latitude": 0.0, "longitude": 0.0},
|
|
{"latitude": 0.0, "longitude": 0.01},
|
|
{"latitude": 0.01, "longitude": 0.02},
|
|
]
|
|
|
|
|
|
SCENARIOS = [
|
|
{
|
|
"primary": "Turn right onto Main St",
|
|
"secondary": "Then keep left",
|
|
"distance": 120.0,
|
|
"type": "turn",
|
|
"modifier": "right",
|
|
"next_type": "fork",
|
|
"next_modifier": "slightLeft",
|
|
},
|
|
{
|
|
"primary": "Turn left onto Pine Ave",
|
|
"secondary": "Then merge right",
|
|
"distance": 180.0,
|
|
"type": "turn",
|
|
"modifier": "left",
|
|
"next_type": "merge",
|
|
"next_modifier": "right",
|
|
},
|
|
{
|
|
"primary": "Keep right to stay on I-90",
|
|
"secondary": "Then continue straight",
|
|
"distance": 260.0,
|
|
"type": "fork",
|
|
"modifier": "slightRight",
|
|
"next_type": "continue",
|
|
"next_modifier": "straight",
|
|
},
|
|
{
|
|
"primary": "Keep left to stay on I-90",
|
|
"secondary": "Then take exit 14A",
|
|
"distance": 210.0,
|
|
"type": "fork",
|
|
"modifier": "slightLeft",
|
|
"next_type": "off ramp",
|
|
"next_modifier": "right",
|
|
},
|
|
{
|
|
"primary": "Take exit 14A",
|
|
"secondary": "Then turn sharp right",
|
|
"distance": 340.0,
|
|
"type": "off ramp",
|
|
"modifier": "right",
|
|
"next_type": "turn",
|
|
"next_modifier": "sharpRight",
|
|
},
|
|
{
|
|
"primary": "Continue straight for 1 mile",
|
|
"secondary": "Then enter the roundabout",
|
|
"distance": 1600.0,
|
|
"type": "continue",
|
|
"modifier": "straight",
|
|
"next_type": "roundabout",
|
|
"next_modifier": "right",
|
|
},
|
|
{
|
|
"primary": "Enter the roundabout",
|
|
"secondary": "Take the second exit",
|
|
"distance": 90.0,
|
|
"type": "roundabout",
|
|
"modifier": "right",
|
|
"next_type": "turn",
|
|
"next_modifier": "left",
|
|
},
|
|
{
|
|
"primary": "Turn sharp left onto Oak St",
|
|
"secondary": "Then make a U-turn",
|
|
"distance": 75.0,
|
|
"type": "turn",
|
|
"modifier": "sharpLeft",
|
|
"next_type": "continue",
|
|
"next_modifier": "uturn",
|
|
},
|
|
{
|
|
"primary": "Make a U-turn",
|
|
"secondary": "Then arrive at destination",
|
|
"distance": 60.0,
|
|
"type": "continue",
|
|
"modifier": "uturn",
|
|
"next_type": "arrive",
|
|
"next_modifier": "right",
|
|
},
|
|
{
|
|
"primary": "Arrive at destination",
|
|
"secondary": "Destination is on the right",
|
|
"distance": 25.0,
|
|
"type": "arrive",
|
|
"modifier": "right",
|
|
"next_type": "turn",
|
|
"next_modifier": "straight",
|
|
},
|
|
]
|
|
|
|
|
|
def build_nav_state(params_memory: Params, scenario: dict) -> None:
|
|
params_memory.put_nonblocking("NavInstructionState", {
|
|
"valid": True,
|
|
"maneuverModifier": str(scenario["modifier"]),
|
|
"maneuverType": str(scenario["type"]),
|
|
"maneuverPrimaryText": str(scenario["primary"]),
|
|
"maneuverSecondaryText": str(scenario["secondary"]),
|
|
"maneuverDistance": float(scenario["distance"]),
|
|
"nextManeuverType": str(scenario["next_type"]),
|
|
"nextManeuverModifier": str(scenario["next_modifier"]),
|
|
"nextManeuverDistance": float(scenario["distance"] + 220.0),
|
|
})
|
|
|
|
|
|
def build_instruction(pm: messaging.PubMaster, scenario: dict) -> None:
|
|
msg = messaging.new_message("navInstruction")
|
|
msg.valid = True
|
|
|
|
nav = msg.navInstruction
|
|
nav.maneuverPrimaryText = scenario["primary"]
|
|
nav.maneuverSecondaryText = scenario["secondary"]
|
|
nav.maneuverDistance = scenario["distance"]
|
|
nav.maneuverType = scenario["type"]
|
|
nav.maneuverModifier = scenario["modifier"]
|
|
nav.distanceRemaining = max(scenario["distance"] * 8, 400.0)
|
|
nav.timeRemaining = max(scenario["distance"] / 10.0, 20.0)
|
|
nav.timeRemainingTypical = nav.timeRemaining
|
|
nav.showFull = True
|
|
nav.speedLimit = 31.2928
|
|
nav.speedLimitSign = log.NavInstruction.SpeedLimitSign.mutcd
|
|
nav.allManeuvers = [
|
|
{"distance": scenario["distance"], "type": scenario["type"], "modifier": scenario["modifier"]},
|
|
{"distance": scenario["distance"] + 220.0, "type": scenario["next_type"], "modifier": scenario["next_modifier"]},
|
|
]
|
|
|
|
pm.send("navInstruction", msg)
|
|
|
|
|
|
def build_route(pm: messaging.PubMaster) -> None:
|
|
msg = messaging.new_message("navRoute")
|
|
msg.valid = True
|
|
msg.navRoute.coordinates = ROUTE_COORDS
|
|
pm.send("navRoute", msg)
|
|
|
|
|
|
def build_destination(scenario: dict) -> dict:
|
|
return {
|
|
"place_name": str(scenario["primary"]),
|
|
"latitude": float(ROUTE_COORDS[-1]["latitude"]),
|
|
"longitude": float(ROUTE_COORDS[-1]["longitude"]),
|
|
"routeId": "fake-nav-demo",
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Publish fake navigation instructions for desktop onroad replay.")
|
|
parser.add_argument("--hold-seconds", type=float, default=3.0, help="How long each maneuver stays active.")
|
|
parser.add_argument("--publish-interval", type=float, default=0.25, help="Seconds between navInstruction publishes.")
|
|
args = parser.parse_args()
|
|
|
|
pm = messaging.PubMaster(["navInstruction", "navRoute"])
|
|
params = Params()
|
|
params_memory = Params(memory=True)
|
|
try:
|
|
params_memory.put_bool("NavInstructionCollapsed", False)
|
|
except UnknownKeyName:
|
|
pass
|
|
|
|
scenario_cycle = cycle(SCENARIOS)
|
|
current = next(scenario_cycle)
|
|
params.put("NavDestination", json.dumps(build_destination(current)))
|
|
next_switch = time.monotonic() + args.hold_seconds
|
|
print(f"showing: {current['type']} / {current['modifier']} -> {current['next_type']} / {current['next_modifier']}", flush=True)
|
|
|
|
try:
|
|
while True:
|
|
now = time.monotonic()
|
|
if now >= next_switch:
|
|
current = next(scenario_cycle)
|
|
params.put("NavDestination", json.dumps(build_destination(current)))
|
|
next_switch = now + args.hold_seconds
|
|
print(f"showing: {current['type']} / {current['modifier']} -> {current['next_type']} / {current['next_modifier']}", flush=True)
|
|
|
|
build_nav_state(params_memory, current)
|
|
build_instruction(pm, current)
|
|
build_route(pm)
|
|
time.sleep(args.publish_interval)
|
|
finally:
|
|
params.remove("NavDestination")
|
|
params_memory.remove("NavInstructionState")
|
|
try:
|
|
params_memory.remove("NavInstructionCollapsed")
|
|
except UnknownKeyName:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|