arena_planners¶
Subprocess-isolated DRL planner bridge for Arena-Rosnav. Each planner runs in its own venv (own torch/gym/numpy versions), communicates with Arena over msgpack-on-ZMQ, and is driven by a single step(features) -> [v, omega] contract (or a discrete forward/left/right command, or a chunk of waypoints or twists).
Layout¶
arena_planners/
├── arena_planners/ # SDK: bridge, observations pipeline, resolver
├── planners/ # submodules, one per planner (drlvo, crowdnav, ...)
└── pyproject.toml
- The SDK lives in
arena_planners/arena_planners/. Install withpip install git+https://github.com/arena-planners/arena_planners.git. - Each planner is its own submodule under
planners/, registered in this repo's.gitmodules. See planners/README.md for the per-planner contract.
Use from Arena¶
arena launch robot.mobile:=drl robot.mobile.planner:=drlvo
The robot.mobile:=drl adapter (in Arena's task_generator) spawns the planner subprocess, pipes observations to it via the bridge, and routes the returned action to cmd_vel. Optional global plan via robot.mobile.global_planner:=nav2/navfn (or any registered <family>/<kind>). Planners that declare goal_inputs in planner.yaml are VLA planners: they run under robot.mobile:=vla, which robot.planner:=<name> selects automatically, and robot.mobile.goal:=pose|instruction|pose+instruction sets which goal inputs a run reveals. A planner that lists signals: [arrived] can end goto phases that set signal: arrived (the VLN convention): the phase ends when the planner signals, judged against the phase's tolerance at that moment. robot.mobile.config.<key>:=<value> overrides a key of the manifest's config block. robot.mobile.rate:=<hz> sets the planner tick (else drl.rate in the robot's caps/mobile.yaml, else the manifest's rate_hz, else 10), snapped to whole physics steps under lockstep. Planner subprocesses get OMP_NUM_THREADS/MKL_NUM_THREADS/OPENBLAS_NUM_THREADS=4 and OMP_WAIT_POLICY=PASSIVE unless already set in the environment. robot.mobile.deadline:=<s> caps how long the bridge waits for the planner to connect, ack a cancel or reset, or answer an observation before declaring it dead. The default 0 waits forever with periodic warnings, so a planner is only dead once its process exits. The quick checks (arena planners test --preflight, the quicktest_map_empty suite) set 30.
Adding a planner¶
- Create a submodule under
planners/<name>/matching the contract in planners/README.md. - Register it in this repo's
.gitmoduleswith aplanner = <name>tag. - From Arena:
arena feature planners add <name>initializes the submodule and fetches and verifies the weights declared inweights.yaml, if present. For a gated Hugging Face repo the fetch names the page where the terms are accepted and stops for that planner. Accept them, log in withhf auth login(or setHF_TOKEN) and run the command again.
MCP domain¶
arena_planners/arena_planners/mcp.py contributes the planners domain to the Arena MCP server (python3 -m arena_mcp ls planners lists its tools). It reads the same registry and resolver as the CLI: every registry planner with its kind, submodule status, planner.yaml summary and weights presence, the full manifest with its resolution, and the structured arena feature planners check verdict plus sha256 verification of weights.yaml. The rosnav_rl agents and nav2 controllers the resolver accepts come with the listing. Adding, installing, updating and removing planner submodules and fetching weights run the real CLI verbs as jobs, polled with jobs_status and stopped with jobs_cancel. The preflight soak belongs to the evaluation domain.
License¶
MIT. Per-planner submodules carry their own upstream licenses (drlvo: GPL-3.0, crowdnav: MIT).