CARLA ? C-Shenron based Simualtor for Sensor data generation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

207 lines
6.1 KiB

"""
src/main.py
-----------
Entry point for the Fox CARLA ADAS simulation pipeline.
This file is now a thin CLI wrapper around the PipelineManager.
It parses arguments, builds a PipelineContext, and executes the
stage sequence: Simulation → Shenron → MCAP.
Usage
-----
python src/main.py --scenario braking
python src/main.py --scenario cutin --frames 120
python src/main.py --list-scenarios
python src/main.py --only-mcap --session data/braking_20260423_093000
python src/main.py --skip-shenron
This file never changes when new scenarios are added.
All scenario logic lives in scenarios/<name>.py.
"""
import sys
import os
from pathlib import Path
import argparse
# Add project root to sys.path
sys.path.append(str(Path(__file__).resolve().parents[1]))
import config
from scenario_loader import list_scenarios
# -----------------------------------------------------------------------
# CLI
# -----------------------------------------------------------------------
def parse_args():
parser = argparse.ArgumentParser(
description="CARLA ADAS Simulation — stage-based pipeline runner"
)
parser.add_argument(
"--scenario", "-s",
type=str,
default=getattr(config, "DEFAULT_SCENARIO", "braking"),
help="Scenario name to run (e.g. braking, cutin, obstacle)"
)
parser.add_argument(
"--frames", "-f",
type=int,
default=None,
help="Override config.MAX_FRAMES for this run"
)
parser.add_argument(
"--spawn-point", "-p",
type=int,
default=None,
help="Index of the spawn point to use for ego vehicle"
)
parser.add_argument(
"--no-record",
action="store_true",
help="Disable image and metadata recording for faster iteration"
)
parser.add_argument(
"--weather", "-w",
type=str,
default=None,
help="Weather preset (ClearNoon, Rain, etc.). "
"If omitted, scenario or config default is used."
)
parser.add_argument(
"--params",
type=str,
default=None,
help="Scenario parameters as key=val pairs, "
"e.g. 'BRAKE_FRAME=100,SPEED=50'"
)
parser.add_argument(
"--list-scenarios", "-l",
action="store_true",
help="Print available scenarios and exit"
)
# --- Pipeline Stage Control ---
parser.add_argument(
"--skip-sim",
action="store_true",
help="Skip the simulation stage (requires --session)"
)
parser.add_argument(
"--skip-shenron",
action="store_true",
help="Skip the Shenron radar synthesis stage"
)
parser.add_argument(
"--skip-mcap",
action="store_true",
help="Skip the MCAP conversion stage"
)
parser.add_argument(
"--only-mcap",
action="store_true",
help="Run only the MCAP stage (requires --session)"
)
parser.add_argument(
"--only-shenron",
action="store_true",
help="Run only the Shenron stage (requires --session)"
)
parser.add_argument(
"--session",
type=str,
default=None,
help="Path to an existing session folder. Required when "
"skipping the simulation stage."
)
return parser.parse_args()
# -----------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------
def main():
args = parse_args()
# ------------------------------------------------------------------
# 0. Clean up stale stop flags
# ------------------------------------------------------------------
flag_path = os.path.join(os.path.dirname(__file__), "..", "tmp", "stop.flag")
if os.path.exists(flag_path):
try:
os.remove(flag_path)
print("[INFO] Cleaned up stale stop.flag")
except Exception:
pass
if args.list_scenarios:
print("Available scenarios:")
for s in list_scenarios():
print(f" - {s}")
return
# ------------------------------------------------------------------
# 1. Build PipelineContext
# ------------------------------------------------------------------
from pipeline.base import PipelineContext
ctx = PipelineContext(
scenario_name=args.scenario,
args=args,
)
# Populate session_path if provided via CLI (for --skip-sim modes)
if args.session:
session = Path(args.session)
if session.exists():
ctx.session_path = session
print(f"[INFO] Using existing session: {session}")
else:
print(f"[ERROR] Session path does not exist: {args.session}")
return
# Determine which stages to skip
if args.only_mcap:
ctx.skip_stages = ["simulation", "shenron"]
elif args.only_shenron:
ctx.skip_stages = ["simulation", "mcap"]
else:
if args.skip_sim:
ctx.skip_stages.append("simulation")
if args.skip_shenron:
ctx.skip_stages.append("shenron")
if args.skip_mcap:
ctx.skip_stages.append("mcap")
# Validate: if sim is skipped, session_path must be provided
if "simulation" in ctx.skip_stages and ctx.session_path is None:
print("[ERROR] --session is required when skipping the simulation "
"stage (--skip-sim, --only-mcap, --only-shenron).")
return
# ------------------------------------------------------------------
# 2. Build & Execute Pipeline
# ------------------------------------------------------------------
from pipeline.manager import PipelineManager
from pipeline.stages.sim_stage import SimulationStage
from pipeline.stages.shenron_stage import ShenronStage
from pipeline.stages.mcap_stage import McapStage
from pipeline.stages.video_stage import VideoStage
manager = PipelineManager([
SimulationStage(),
ShenronStage(),
McapStage(),
VideoStage(),
])
manager.execute(ctx)
print("[INFO] Done")
if __name__ == "__main__":
main()