Skip to main content

place-camera-max-coverage

Greedy CameraPlacementManager that fills a navmesh or XY scope until a patch-coverage ratio is met. Use for facility surveillance layouts that minimize camera count.

Source facts

Repository
isaac-sim/IsaacSim
Last source activity
September 18, 2026 at 16:05
Detected SKILL.md language
English
Stars
4,169
Forks
560

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
5 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
place-camera-max-coverage
description
Greedy CameraPlacementManager that fills a navmesh or XY scope until a patch-coverage ratio is met. Use for facility surveillance layouts that minimize camera count.
license
Apache-2.0
metadata
{"author":"NVIDIA Isaac Sim <isaac-sim@nvidia.com>"}
# Place Cameras for Maximum Coverage ## Purpose Lay out infrastructure cameras across a floor area so a target fraction of it is observed, using the `CameraPlacementManager` API of `isaacsim.sensors.rtx.placement`. ## Prerequisites - Running Isaac Sim 6 / Kit 110 with python_server (port 8226); see `isaac-sim-remote`. - Extension `isaacsim.sensors.rtx.placement` enabled (action_and_event_data_generation app, or `--enable`). - Stage has the **facility/environment** loaded plus a baked navmesh **or** explicit `scope=xmin,xmax,ymin,ymax`. - Shell env: `$ISAAC_SIM_DIR`, `$ISAAC_LAB_DIR`, `$WORKSPACE_DIR` (`isaac-sim-orchestrator`). ## Limitations - Does not build `isaacsim.sensors.rtx.placement` — consume the pin from `source/apps/isaacsim.exp.action_and_event_data_generation.base.kit`. - Live Kit only; coverage uses a single focus plane at `focus_height` (no multi-level model). - Greedy solver stops at ratio / budget / `min_coverage_increase` — not a proven minimum set. - Cost scales with area / `patch_size`² (tens of seconds on large stages). - For single-object unoccluded views (not floor coverage), use `place-camera-aim-at`. ## Troubleshooting | Error / symptom | Cause | Solution | |---|---|---| | `MAX_COVERAGE_PREFLIGHT: ext=unavailable` | App does not resolve the extension | Launch `isaacsim.exp.action_and_event_data_generation.base.sh`, or add `--enable isaacsim.sensors.rtx.placement` | | `scope=none` in preflight | No navmesh baked and no explicit scope | Bake a navmesh, or pass `scope=xmin,xmax,ymin,ymax` | | Script raises "No cameras were authored" | Solver produced nothing | Check the console; usually a scope that misses the walkable floor, or `camera_on_navmesh` with no navmesh | | "input section distance … is too large" warning | `patch_size` exceeds `shorter_span / 10` | Harmless — the value is auto-shrunk; pass a smaller `patch_size` to control it | | Far fewer cameras than expected | Coverage target met early, or `min_coverage_increase` stopped the loop | Raise `target_coverage_ratio`, or raise `required_camera_per_patch` for redundancy | | Placement never finishes on a large stage | `patch_size` too small for the area | Raise `patch_size`; cost scales with area / `patch_size`² | | `camera_info_payload.json` not written | No output folder configured | Pass `output_dir`, which sets `camera_placement_output_folder_path` | ## When to use this skill | You want | Skill | |---|---| | Cover *this whole floor area* to a coverage ratio | **this skill** | | N unobstructed views of *this pallet / shelf / robot* | `place-camera-aim-at` | | Author a single camera's intrinsics, AOVs, distortion | `isaac-camera` | ## How the algorithm works 1. Resolve the target scope — either explicit `[(x_min, x_max), (y_min, y_max)]` bounds or the navmesh extents. 2. Split the scope into `patch_size` cells on a focus plane at `focus_height`, and mark which cells are accessible. 3. For each of four cardinal directions, estimate the ground-plane footprint of a candidate camera's frustum and greedily pick the pose that adds the most uncovered patches. 4. Stop when `target_coverage_ratio` is reached, the `num_cameras` budget is spent, or a new camera would add less than `min_coverage_increase` patches. Full parameter semantics and the carb-settings coupling live in [`references/coverage-api.md`](references/coverage-api.md); scope resolution, coverage visualisation, and the JSON payload are in [`references/coverage-runtime-notes.md`](references/coverage-runtime-notes.md). ## Available Scripts | Script | Purpose | Arguments | |---|---|---| | `scripts/place_camera_max_coverage.py` | Cover a floor area with cameras using isaacsim.sensors.rtx.placement | injected `key=value` args (see script docstring) | ## Running scripts The script is a python_server payload, not a standalone program. From agent runtimes that expose skill execution helpers, invoke it with `run_script()`: ```python run_script("scripts/place_camera_max_coverage.py", args=["action=preflight"]) ``` From a built tree, send it through the `isaac-sim-remote` client: ```bash python skills/isaac-sim-remote/scripts/isaacsim_send.py \ --file skills/place-camera-max-coverage/scripts/place_camera_max_coverage.py \ --arg action=place --arg num_cameras=5 --arg output_dir=/tmp/isp ``` ## Workflow 1. **Preflight.** `action=preflight` (the default) reports extension, stage, and scope state without touching the stage. It never raises, so it is safe first. ```python run_script("scripts/place_camera_max_coverage.py", args=["action=preflight"]) ``` Expect `MAX_COVERAGE_PREFLIGHT: ext=enabled stage=ok scope=navmesh` plus the resolved bounds. Resolve anything that is not `ok` before continuing. 2. **Confirm the scope.** `action=scope` prints the navmesh-derived bounds without placing anything. Compare them against the facility you expect — a navmesh that leaked outside the building silently wastes cameras. ```python run_script("scripts/place_camera_max_coverage.py", args=["action=scope"]) ``` 3. **Place.** Either give a camera budget or let coverage drive the count. ```python run_script( "scripts/place_camera_max_coverage.py", args=["action=place", "num_cameras=5", "height_range=5,7.5", "output_dir=/tmp/isp"], ) ``` `num_cameras=-1` (the default) places until `target_coverage_ratio` is met. Expect `MAX_COVERAGE_RESULT: placed=5 total=5 scope=... ratio=0.9 ...` plus one line per new camera. The script counts prims on the stage rather than trusting the API return value. 4. **Verify coverage.** `action=coverage` debug-draws the coverage frequency of the cameras currently under the parent prim and logs the achieved coverage and full-coverage ratios to the console. ```python run_script("scripts/place_camera_max_coverage.py", args=["action=coverage"]) ``` 5. **Iterate.** Vary `random_seed` for a different layout under the same constraints; raise `required_camera_per_patch` when downstream perception needs overlapping views. ## Calling the API directly ```python from isaacsim.sensors.rtx.placement import CameraPlacementManager manager = CameraPlacementManager.get_instance() cameras = manager.place_camera_in_target_scope_explicit( target_scope=[(-9.5, 9.5), (-19.0, 0.0)], camera_num=5, target_coverage_ratio=0.9, camera_height_range=(5.0, 7.5), camera_distance_range=(8.0, 16.0), camera_look_down_angle_range=(20.0, 60.0), spawn_camera=True, output_camera_data=True, ) for camera in cameras or []: print(camera["translate"], camera["rotation"]) ``` Two traps worth stating up front: - **`output_camera_data` defaults to `False`, and the call returns `None` in that case even on success.** Pass `True` when you want the poses back. - **Exceptions are swallowed into `carb.log_error`** and the call then returns a partially filled list. Verify against the stage, not the return value — which is what `scripts/place_camera_max_coverage.py` does. Use `place_camera_in_target_scope_explicit`, not `place_camera_in_target_scope`. The latter is the GUI path and reads every parameter from persistent carb settings. ## Related skills - `isaac-sim-remote` — the transport this skill's script rides on. - `place-camera-aim-at` — the single-target sibling. - `occupancy-map` — an alternative source of floor bounds when no navmesh exists. - `isaac-camera` — per-camera intrinsics, render products, AOVs, distortion. - `isaac-sim-sensor` — attaching annotators and writers once cameras exist.
View on GitHub