From 6aa919f836d14138e284893e3a8f908b445a5dac Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Fri, 24 Jul 2026 10:31:31 +0100 Subject: [PATCH] Inference server role: dedicated NVIDIA/Windows off-board compute (task 173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Productionize the ad-hoc off-board inference pattern into a first-class "inference server" role on a dedicated Windows gaming PC with an NVIDIA GPU, serving depth and detection today and future services as they land, with the robot degrading gracefully when the server is absent. Host decision (documented in docs/inference-server.md): native Windows, not WSL2. The win-64 CUDA torch wheel solves cleanly in a pixi feature (torch-2.11.0+cu128 win_amd64, verified in pixi.lock), native bind puts the socket straight on the LAN with no WSL NAT/portproxy, and Task Scheduler gives boot auto-start without a VM layer. - pixi: new `inference-cuda` env (feature platforms = ["win-64"], torch from the pytorch.org cu128 wheel index) as an isolated own-solve sibling of `inference`/`inference-rocm` — verified it never perturbs the aarch64 robot or any other env's solve. Tasks: inference-cuda, depth/detect-server-cuda, inference-prefetch[-cuda|-rocm], plus robot-side inference-health/inference-bench. - Health/version endpoint: HEALTH_MAGIC request in the shared wire protocol + WireClient.health(); servers reply with a JSON status blob (model, device, GPU, torch). tools/inference_health.py probes it from the robot (torch-free). - Cross-platform supervisor tools/inference_server.py replaces the bash launcher (no bash on Windows); its SERVICES list is the multi-service seam — a new tenant is one row and inherits binding, supervision, health, and reconnect. - detect_server gains --device auto|cpu|cuda so OWLv2 runs on the GPU too. - Windows deploy scripts (mote_perception/deploy/windows): setup.ps1 (pixi + env + model prefetch + GPU check), install/uninstall_service.ps1 (boot Scheduled Task), run_inference.ps1 (self-restarting runner + dated logs). - Measurement: tools/inference_bench.py (torch-free round-trip latency/fps -> committed JSON) and benchmarks/README.md with the #152 CPU/ROCm baselines and a template for the CUDA numbers Michael fills at the PC. - Fallback verified/documented: server-absent = warn-and-skip (topic goes quiet, publisher stays alive, reconnects automatically); nav keeps running on lidar. - Docs: docs/inference-server.md (role, host decision, setup guide, prod behaviors, multi-service pattern, fallback matrix, measurement); README + CLAUDE updated. New tests cover the health round-trip and interleaving with infer. Verified repo-side: 17 wire tests pass (incl. new health tests), ruff check/format clean, pixi.lock re-solves with per-env platform isolation intact. On-PC steps (CUDA latency numbers, reboot/auto-start, LAN e2e) need Michael's session at the gaming PC per the setup guide. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01LLcxTNpEiB29frknCDug2V --- CLAUDE.md | 2 +- docs/inference-server.md | 252 ++ mote_perception/README.md | 40 +- mote_perception/benchmarks/README.md | 65 + .../deploy/windows/install_service.ps1 | 44 + .../deploy/windows/run_inference.ps1 | 46 + mote_perception/deploy/windows/setup.ps1 | 38 + .../deploy/windows/uninstall_service.ps1 | 13 + mote_perception/mote_perception/depth_wire.py | 50 +- .../mote_perception/detect_wire.py | 22 +- mote_perception/test/test_depth_wire.py | 52 + mote_perception/test/test_detect_wire.py | 27 + mote_perception/tools/depth_server.py | 26 +- mote_perception/tools/detect_server.py | 61 +- mote_perception/tools/inference_bench.py | 150 + mote_perception/tools/inference_health.py | 89 + mote_perception/tools/inference_server.py | 79 + mote_perception/tools/inference_server.sh | 27 - mote_perception/tools/prefetch_models.py | 45 + pixi.lock | 3370 +++++++++++++++-- pixi.toml | 52 +- 21 files changed, 4192 insertions(+), 358 deletions(-) create mode 100644 docs/inference-server.md create mode 100644 mote_perception/benchmarks/README.md create mode 100644 mote_perception/deploy/windows/install_service.ps1 create mode 100644 mote_perception/deploy/windows/run_inference.ps1 create mode 100644 mote_perception/deploy/windows/setup.ps1 create mode 100644 mote_perception/deploy/windows/uninstall_service.ps1 create mode 100644 mote_perception/tools/inference_bench.py create mode 100644 mote_perception/tools/inference_health.py create mode 100644 mote_perception/tools/inference_server.py delete mode 100755 mote_perception/tools/inference_server.sh create mode 100644 mote_perception/tools/prefetch_models.py diff --git a/CLAUDE.md b/CLAUDE.md index efc9a3c..5933211 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,7 +114,7 @@ Workstation-only Gazebo simulation, kept separate from `mote_bringup` so it can ### `mote_perception` (Python/ament) Home for camera-derived perception. Runs on the robot (feeds Nav2), so unlike `mote_simulation` it is synced to the Pi. Contains: - `mote_perception/camera_monitor.py` — a dependency-light camera health monitor (rclpy + sensor_msgs only, no OpenCV). Subscribes to `image` and logs measured frame rate, resolution, and encoding on a timer, warning on dropouts. Registered as the `camera_monitor` console_script. -- **L1 depth-obstacle pipeline** — turns the mono camera into `/camera_obstacles` (PointCloud2) for Nav2's `camera_layer`. Split across: `depth_obstacle_node.py` (torch-free rclpy node: compressed image → server → rescale → back-project → level → z/range gates), `depth_wire.py` (the socket protocol spec + `DepthClient`, shared by node/server/tools), `lidar_rescale.py` (per-frame Theil-Sen affine-in-disparity metric rescale anchored to lidar), `ground_projection.py` (camera↔base geometry: `GroundProjector`, floor-plane fit, leveling, pixel→floor rays). Split by concern, not by machine: `depth_obstacle_node` runs on the robot (launched by `perception_launch.py`, in its DDS graph), reaching the torch server over TCP at `inference_host`. `tools/depth_server.py` runs in the `inference` pixi env (torch, no ROS) wherever the GPU is; `pixi run inference` starts it beside the detect server. `pixi run inference-rocm` is the GPU variant: the same servers in the `inference-rocm` env (torch from the pytorch.org ROCm wheel index, own solve; `HSA_OVERRIDE_GFX_VERSION` set for unsupported AMD iGPUs). The server takes `--device auto|cpu|cuda` (auto → GPU when available, else CPU) and optional `--fp16`. The iGPU doesn't beat the CPU at idle (small ViT, bandwidth-bound) but stays flat under CPU load where the CPU-only server degrades to ~1–2 s/frame; fp16 and larger models can crash/hang on unsupported iGPUs (gfx1103), so keep fp32 + V2-Small there. Needs `/dev/kfd` access (render/video groups). +- **L1 depth-obstacle pipeline** — turns the mono camera into `/camera_obstacles` (PointCloud2) for Nav2's `camera_layer`. Split across: `depth_obstacle_node.py` (torch-free rclpy node: compressed image → server → rescale → back-project → level → z/range gates), `depth_wire.py` (the socket protocol spec + `DepthClient`, shared by node/server/tools), `lidar_rescale.py` (per-frame Theil-Sen affine-in-disparity metric rescale anchored to lidar), `ground_projection.py` (camera↔base geometry: `GroundProjector`, floor-plane fit, leveling, pixel→floor rays). Split by concern, not by machine: `depth_obstacle_node` runs on the robot (launched by `perception_launch.py`, in its DDS graph), reaching the torch server over TCP at `inference_host`. `tools/depth_server.py` runs in the `inference` pixi env (torch, no ROS) wherever the GPU is; `pixi run inference` starts it beside the detect server. `pixi run inference-rocm` is the AMD GPU variant: the same servers in the `inference-rocm` env (torch from the pytorch.org ROCm wheel index, own solve; `HSA_OVERRIDE_GFX_VERSION` set for unsupported AMD iGPUs), and `pixi run inference-cuda` is the productionized NVIDIA variant for a dedicated Windows inference PC (`inference-cuda` env, `platforms = ["win-64"]`, torch from the pytorch.org CUDA wheel index — an isolated own-solve win-64 env that never touches the aarch64 robot solve). All three run the same servers via one cross-platform supervisor (`tools/inference_server.py` — add a tenant by adding a row to `SERVICES`). The full inference-server role (host decision, boot auto-start, `pixi run inference-health` probe, `pixi run inference-bench`, multi-service pattern, fallback matrix) is in `docs/inference-server.md`; wire modules carry a `HEALTH_MAGIC` request so `WireClient.health()` reports each server's model/device/version. The server takes `--device auto|cpu|cuda` (auto → GPU when available, else CPU) and optional `--fp16`. The iGPU doesn't beat the CPU at idle (small ViT, bandwidth-bound) but stays flat under CPU load where the CPU-only server degrades to ~1–2 s/frame; fp16 and larger models can crash/hang on unsupported iGPUs (gfx1103), so keep fp32 + V2-Small there. Needs `/dev/kfd` access (render/video groups). - **L2 open-vocabulary detection** — turns "fetch the red box" into a map pose for the task layer. Same node-on-robot / server-off-board split: `tools/detect_server.py` (OWLv2 in the `inference` pixi env; `pixi run detect-server`, or `pixi run inference` for both), `detect_wire.py` (protocol + `DetectClient`; the query labels ride in each request), `object_detector_node.py` (torch-free rclpy node: idles until labels arrive on `detect/labels` — String, comma-separated, transient_local, empty = idle — then grounds each bbox bottom-centre through the floor plane and publishes `detected_objects`, vision_msgs/Detection3DArray in the map frame at the capture stamp). Floor-ray grounding is metre-accurate only near the robot (camera is at ~0.10 m), gated by `range_max`. - `tools/` — offline bag harnesses (`depth_bag_replay`, `depth_bag_eval`, `depth_obstacles`, `detect_bag`, `bag_overlay`, shared `bag_utils`) and the live `measure_camera_pitch`; see `mote_perception/README.md` for the inventory. - `launch/perception_launch.py` — declares `use_sim_time` (applied via `SetParameter`) and starts `camera_monitor` (with `image` remapped to `/image_raw`) plus the depth/detect nodes. Which nodes run, their `server_port`s, and the shared `inference_host` come from `config/perception.yaml` (not launch args), so inference can move machines without editing launch. Not part of the mission bringup — run `pixi run perception` alongside `pixi run mapping`/`robot`. diff --git a/docs/inference-server.md b/docs/inference-server.md new file mode 100644 index 0000000..6fb57a3 --- /dev/null +++ b/docs/inference-server.md @@ -0,0 +1,252 @@ +# The inference server + +Mote keeps torch off the robot. The heavy vision models (monocular depth today, +open-vocabulary detection now, SfM/policy inference later) run in a separate +process reached over a plain TCP socket, so the robot's ROS environment stays +light and the compute can live wherever the GPU is. This document is about +running that process as a **first-class role on a dedicated machine** — a Windows +gaming PC with an NVIDIA GPU — that the whole robot talks to, and that the robot +degrades gracefully without. + +The mechanism (the two-process split, the `depth_wire`/`detect_wire` protocol, +the on-robot nodes) is described in [`mote_perception/README.md`](../mote_perception/README.md). +This document adds the *deployment*: host choice, the CUDA env, auto-start, +health, the multi-service pattern, the fallback matrix, and how to measure it. + +--- + +## Host decision: native Windows, not WSL2 + +The target is a Windows gaming PC with an NVIDIA GPU that also stays a gaming PC. +Two ways to host a Linux-flavoured torch stack there — native Windows or WSL2 — +were weighed against the things that actually matter for this role: + +| Criterion | Native Windows (chosen) | WSL2 | +|---|---|---| +| **CUDA torch in a pixi env** | ✅ `win-64` feature, torch `cu128` wheel from pytorch.org solves cleanly (verified: `torch-2.11.0+cu128-cp312-cp312-win_amd64.whl`) | ✅ `linux-64`, torch `cu128` linux wheel | +| **LAN reachability from the robot** | ✅ server binds `0.0.0.0` straight onto the PC's LAN IP; robot connects directly | ⚠️ WSL2 is NAT'd behind the host — needs `netsh interface portproxy` or mirrored-networking mode to expose the socket to the LAN | +| **Auto-start on boot** | ✅ Task Scheduler "at startup" runs the runner in session 0; CUDA compute needs no desktop | ⚠️ needs WSL auto-launch + systemd-in-WSL + the host waking the distro; more moving parts | +| **Stays a gaming PC** | ✅ a background scheduled task; no VM | ✅ but a running WSL VM alongside | +| **Operational simplicity** | ✅ one pixi env, one task, logs in `%LOCALAPPDATA%` | ⚠️ two OSes to reason about when something breaks | + +Native Windows wins on the two that bite in practice — the robot reaching the +socket, and the servers coming back after a reboot — without giving up the easy +CUDA torch path. WSL2's only real edge (matching the existing Linux tooling) is +outweighed by its NAT layer sitting between the robot and the server. Dual-boot +Linux was out of scope and unnecessary since both options solved. + +**So: the inference PC runs native Windows, pixi's `inference-cuda` env, torch +from the CUDA wheel index.** The pixi feature declares `platforms = ["win-64"]` +in its own environment, so this never perturbs the robot/dev/sim solves (the +aarch64 robot env is byte-for-byte unchanged — verified in `pixi.lock`). + +If the win-64 torch solve ever breaks (a torch release skips Windows wheels, say), +the fallback is WSL2 with the `inference-rocm`-style pattern retargeted to a linux +`cu128` index, plus a `portproxy` rule — but that is the contingency, not the plan. + +--- + +## Setup guide (run once at the PC) + +Everything below runs in PowerShell on the gaming PC. The scripts live in +[`mote_perception/deploy/windows/`](../mote_perception/deploy/windows) and are +parameterised, so a PC rebuild is: clone the repo, run these, done. + +1. **Get the repo.** Install git if needed, then clone Mote somewhere stable, + e.g. `C:\mote`. (Only the repo is needed; no ROS on this machine.) + +2. **Set up the env + models** — a normal (non-admin) PowerShell: + + ```powershell + cd C:\mote + .\mote_perception\deploy\windows\setup.ps1 + ``` + + This installs pixi if missing, solves and installs the `inference-cuda` env + (first run downloads the ~2–3 GB torch CUDA wheel — be patient), prints a GPU + check (`cuda_available True`, the device name), and pre-fetches the depth + + detect model weights into the HuggingFace cache so the first request doesn't + block on a download. + +3. **Smoke-test by hand** (optional but recommended): + + ```powershell + pixi run inference-cuda + ``` + + You should see `using GPU: ` for depth and detect, and both + "listening on 0.0.0.0:5601 / :5602". Leave it running and, from the robot: + + ```bash + pixi run inference-health --host + ``` + + Expect `depth UP ... on cuda ()` and `detect UP ... on cuda ()`. + Ctrl+C the server when satisfied. + +4. **Install boot auto-start** — an **elevated** (Administrator) PowerShell: + + ```powershell + .\mote_perception\deploy\windows\install_service.ps1 + ``` + + It registers a `MoteInference` scheduled task that runs the servers at every + boot (whether or not anyone logs in) and prompts for the account password so + Task Scheduler can run it unattended. Remove it later with + `uninstall_service.ps1`. + +5. **Point the robot at the PC** — see the next section. + +That's it. Reboot the PC and confirm `pixi run inference-health --host ` from +the robot answers with no manual step on the PC. + +--- + +## Pointing the robot at the server + +The single deployment knob is **`inference_host`** in +[`mote_perception/config/perception.yaml`](../mote_perception/config/perception.yaml). +Set it to the gaming PC's stable hostname (or LAN IP): + +```yaml +inference_host: mote-gpu # the gaming PC on the LAN +depth: { enabled: true, server_port: 5601 } +detect: { enabled: true, server_port: 5602 } +``` + +Override per-robot without editing the committed file by dropping the same keys in +`~/.mote/perception.yaml` (same precedence as the camera calibration). This config +lives here, **not** in `robot.yaml`: `robot.yaml` is hardware/description (wheels, +servos, sensor device paths) and `perception.yaml` is perception *runtime* — the +two are deliberately separate config surfaces. No discovery protocol is invented; +a stable hostname is the contract. Give the PC a DHCP reservation or a hosts entry +so its name is stable. + +Ports are per-service and fixed (depth 5601, detect 5602); the robot node for each +service carries its own port, so services are independent. + +--- + +## Production behaviors + +- **Auto-start on boot** — the `MoteInference` scheduled task (step 4) launches + [`run_inference.ps1`](../mote_perception/deploy/windows/run_inference.ps1), + which runs `pixi run inference-cuda` in a supervise loop and restarts it a few + seconds after any exit. So a server crash *or* a reboot both recover with no + human at the PC. + +- **Reconnect across restarts, both ends** — the robot nodes use a persistent + socket that reconnects lazily: any failure (server down, connection dropped, + server restarted) tears the socket down and the next frame reconnects, warning + once (throttled) meanwhile. Nothing on the robot needs restarting when the + server bounces. This is `WireClient` in `depth_wire.py` and is covered by + `test_depth_wire.py::test_depth_client_reconnects_after_server_drop` and the + health round-trip tests. On the server side, each connection is independent and + a bad frame never kills the server. + +- **Health / version check from the robot** — `pixi run inference-health [--host H]` + probes each service over the same socket (the `HEALTH_MAGIC` request in the wire + protocol) and prints the model, device, GPU, and torch version the server is + actually running, or `DOWN` if it can't be reached. Exit status is non-zero if + any service is down, so it doubles as a scriptable gate. `--json` for machine + output. + +- **Logs somewhere findable** — the runner tees everything (its own lifecycle + plus both servers' per-frame lines) to `%LOCALAPPDATA%\mote\logs\inference-.log` + on the PC. Each server also prints `health check` when probed, so you can see + the robot reaching it. + +--- + +## Multi-service pattern (adding the next tenant) + +Depth and detect are already two tenants of this role, and a third (SfM, a policy +server, …) is a config exercise, not a redesign. The seam is +[`inference_server.py`](../mote_perception/tools/inference_server.py), the +cross-platform supervisor the `inference*` tasks run: + +```python +SERVICES = [ + ("depth", "depth_server.py", []), + ("detect", "detect_server.py", []), +] +``` + +To add a tenant: + +1. **Write the server** in `mote_perception/tools/`, following `depth_server.py`: + load the model, `listen(1)`, and in the per-connection loop read the leading + `uint32` — if it equals `HEALTH_MAGIC`, `send_health(conn, info)` and continue; + otherwise read your request and reply. Reuse the framing helpers in a + `*_wire.py` module. +2. **Give it a wire module** (`mycompute_wire.py`) with a `DEFAULT_PORT` (next + free port, e.g. 5603), the request/reply framing, and a `Client(WireClient)` + subclass — it inherits `connect`/`close`/**`health`**/reconnect for free. +3. **Add one row to `SERVICES`** above. It now inherits `0.0.0.0` binding, + supervision (if it dies, the others are torn down so the failure is visible), + teardown, boot auto-start, and the health probe automatically. +4. **On the robot**, add its node to `perception_launch.py` and a + `mycompute: { enabled, server_port }` block to `perception.yaml`, exactly like + `depth`/`detect`. + +Port allocation is manual and documented here (5601 depth, 5602 detect, 5603+ for +new services) — a fixed small map beats a discovery protocol for a handful of +services on one box. Health and reconnect are free because they live in the shared +`WireClient`/`send_health`, not per-service. + +--- + +## Fallback matrix (server present / absent) + +The robot must keep working when the inference PC is off, asleep, or unreachable. +It does, because the depth/detect nodes are torch-free and treat "no server" as +"skip this frame", never as a fatal error. Navigation runs on lidar; the camera +obstacle layer is an *additive* near-band voxel layer, so losing it degrades +obstacle coverage but never stops nav. + +| Situation | What runs the depth model | `/camera_obstacles` | Navigation | +|---|---|---|---| +| **Gaming PC up** (`inference_host: mote-gpu`) | NVIDIA CUDA — the fast path | published normally | full: lidar + camera near-band | +| **Gaming PC down / unreachable** | nothing — node warns (throttled 2 s) and skips each frame; publisher stays alive, publishes nothing | silent (no points) | **unaffected** — runs on lidar alone | +| **No GPU box, fall back to the dev machine** (`inference_host: `, `pixi run inference-rocm` or `pixi run inference`) | AMD ROCm iGPU, or CPU | published (slower) | full, at reduced depth rate | + +The current code's behavior in the "down" case is **warn-and-skip, not disable**: +`DepthClient.infer` / `DetectClient.infer` return `None` on any socket failure and +the node returns early (`depth_obstacle_node._on_image`), so the topic simply goes +quiet and resumes automatically when the server returns — no relaunch. Verified by +`test_depth_client_unreachable_returns_none_and_warns` and the reconnect test. + +To *intentionally* disable a service (e.g. the PC is gone for a while and you want +the logs quiet), set `depth.enabled: false` / `detect.enabled: false` in +`perception.yaml` and relaunch `pixi run perception` — the node isn't created at +all. Leaving it enabled with no server is harmless (it idles, only working when a +subscriber is present). + +--- + +## Measuring it + +Two committed harnesses; results live under +[`mote_perception/benchmarks/`](../mote_perception/benchmarks) so they can be +compared across machines and over time. + +- **`pixi run inference-bench`** — client-side, torch-free, run from the robot (or + any LAN machine). Times the full round trip the node pays — compress → send → + server infer → receive — so the number includes GPU time *and* the network hop, + comparable to the on-robot pipeline. Example: + + ```bash + pixi run inference-bench --host mote-gpu --image sample.jpg --frames 200 \ + --out mote_perception/benchmarks/depth_cuda_lan.json + ``` + + It prints a percentile table (min/p50/mean/p90/p99/max ms + fps) and writes the + raw samples as JSON. Use `--service detect --labels "red box"` for the detector. + +- **The server's own per-frame log** (`served WxH in N ms`) isolates pure model + time on the GPU, so `inference-bench`'s round-trip minus the server's reported + time is the LAN + transport overhead. + +See [`benchmarks/README.md`](../mote_perception/benchmarks/README.md) for the +baseline numbers (#152 CPU / ROCm iGPU) and how to fill in the gaming-PC CUDA +results. diff --git a/mote_perception/README.md b/mote_perception/README.md index 5a196ad..61c11f7 100644 --- a/mote_perception/README.md +++ b/mote_perception/README.md @@ -36,8 +36,13 @@ concern, not by machine — which machine each half lands on is a deployment cho stream until it has labels), so it's safe to leave enabled without a server. - **The inference servers run wherever the compute is** — `pixi run inference` starts both (depth + detect) in the torch-only `inference` pixi env. That's a - GPU box, or the robot/dev machine itself. `pixi run inference-rocm` is the same - pair on an AMD ROCm GPU (see the L1 section below for the iGPU caveats). + GPU box, or the robot/dev machine itself. `pixi run inference-rocm` runs the + same pair on an AMD ROCm GPU (the Linux-dev fallback tier; see the L1 section + for the iGPU caveats), and **`pixi run inference-cuda`** runs them on a + dedicated NVIDIA Windows box — the productionized "inference server" role, with + boot auto-start, a health probe, and the multi-service pattern documented in + **[`docs/inference-server.md`](../../docs/inference-server.md)**. All three run + the same servers via one cross-platform supervisor (`tools/inference_server.py`). The only knob is **`inference_host`** in `config/perception.yaml` (with the same `~/.mote/perception.yaml` override as the camera calibration): leave it @@ -46,6 +51,13 @@ offload just inference. The same file's `depth.enabled` / `detect.enabled` toggl each node — turn one off if the Pi can't carry its per-frame CPU cost. Nothing is passed at launch time. +Check the server from the robot with **`pixi run inference-health [--host H]`** +(torch-free — prints each service's model/device/GPU/version, or `DOWN`), and +measure round-trip latency with **`pixi run inference-bench`** (see +[`benchmarks/`](benchmarks/README.md)). When the server is absent the nodes warn +and skip frames — nav keeps running on lidar alone; the full fallback matrix is +in the inference-server doc. + > Note: `perception_launch.py` is a separate process, not part of the mission > bringup — run `pixi run perception` alongside `pixi run mapping`/`robot`. @@ -197,7 +209,9 @@ request: - `tools/detect_server.py` — keeps OWLv2 resident in the torch-only `inference` pixi env, serving detections over a socket (`pixi run detect-server`, or `pixi run inference` to run it beside the depth server; protocol in - `mote_perception/detect_wire.py`). + `mote_perception/detect_wire.py`). Picks `cuda` when available (override with + `--device cpu|cuda`); on the CUDA inference PC it runs on the GPU, on CPU it + uses all cores. - `object_detector_node` — light rclpy node (no torch). Idles until a label set arrives on `detect/labels` (std_msgs/String, comma-separated, transient_local; empty string = idle) — the task layer's `AcquireObject` sets it while a @@ -254,3 +268,23 @@ server up (`pixi run depth-server`). Shared bag loading lives in the camera frames. - `measure_camera_pitch.py` — live checkerboard measurement of camera pitch/roll/height (mount calibration). + +### Inference-server tools + +Run the servers and operate them from the robot side. See +[`docs/inference-server.md`](../../docs/inference-server.md) for the deployment +role and [`benchmarks/`](benchmarks/README.md) for numbers. + +- `tools/inference_server.py` — cross-platform supervisor that runs every service + (the `SERVICES` list) bound to `0.0.0.0` and tears the rest down if one dies; the + `inference` / `inference-rocm` / `inference-cuda` tasks all run it. Add a tenant + by adding a row. +- `tools/inference_health.py` (`pixi run inference-health`) — torch-free probe of + each service's health/version over the wire; `DOWN` if unreachable, non-zero exit + if any service is down. +- `tools/inference_bench.py` (`pixi run inference-bench`) — torch-free round-trip + latency/fps benchmark against a server; writes JSON for the benchmarks dir. +- `tools/prefetch_models.py` (`pixi run inference-prefetch[-cuda|-rocm]`) — warm the + HuggingFace cache so the first request doesn't block on a download. +- `deploy/windows/` — PowerShell setup + boot auto-start for the NVIDIA Windows + inference PC (`setup.ps1`, `install_service.ps1`, `run_inference.ps1`). diff --git a/mote_perception/benchmarks/README.md b/mote_perception/benchmarks/README.md new file mode 100644 index 0000000..a0762b2 --- /dev/null +++ b/mote_perception/benchmarks/README.md @@ -0,0 +1,65 @@ +# Inference benchmarks + +Latency/throughput for the off-board inference servers, so the dedicated +gaming-PC (NVIDIA/CUDA) tier can be compared against the earlier CPU and +ROCm-iGPU tiers. Numbers here are the **full socket round trip** measured with +`pixi run inference-bench` unless noted (that is what the robot actually pays — +compress → send → infer → receive), plus the server's own per-frame model time +where it isolates GPU-only cost. + +Regenerate the CUDA numbers with, from the robot or a LAN machine: + +```bash +pixi run inference-bench --host mote-gpu --image sample.jpg --frames 200 \ + --out mote_perception/benchmarks/depth_cuda_lan.json +pixi run inference-bench --service detect --host mote-gpu --labels "red box" \ + --frames 50 --out mote_perception/benchmarks/detect_cuda_lan.json +``` + +Commit the resulting `*.json` alongside this file and fill the tables below. + +## Depth (Depth-Anything-V2-Small, 640×480) + +| Tier | Machine | Device | ~ms/frame | ~fps | Source | +|---|---|---|---:|---:|---| +| CPU (idle) | Linux dev | CPU (physical-core threads) | ~330 | ~3 | #152, `depth_server.py` comment (measured with `depth_bag_eval.py`) | +| CPU (oversubscribed) | Linux dev | CPU (SMT threads) | ~460 | ~2 | #152, same | +| CPU (under load) | Linux dev / Pi-class | CPU while RViz+ROS+node run | ~1000–2000 | ~0.5–1 | #152 prose baseline | +| ROCm iGPU | Linux dev | Radeon 780M (gfx1103, fp32) | ~330, **flat under load** | ~3 | #152 — ties idle CPU, stays flat where CPU degrades | +| **CUDA (LAN)** | **gaming PC** | **NVIDIA (fp32)** | _measure_ | _measure_ | **`inference-bench` → `depth_cuda_lan.json`** | +| CUDA (fp16) | gaming PC | NVIDIA (`--fp16`) | _optional_ | _optional_ | optional, if fp16 is stable on the card | + +The CUDA tier is expected to land well under the ROCm/CPU ~330 ms — a discrete +NVIDIA card runs this small ViT in tens of ms — so the depth rate is bounded by +the camera/publish rate, not the model. The point of the number is to *confirm* +that and to quantify the LAN overhead (round trip minus the server's reported +`served … in N ms`). + +## Detect (OWLv2-base, 640×480) + +OWLv2 is much heavier than depth and was CPU-only before this task; the +`inference-cuda` env plus the new `--device` support in `detect_server.py` let it +run on the GPU too. Measure once the gaming PC is up: + +| Tier | Machine | Device | ~ms/frame | ~fps | Source | +|---|---|---|---:|---:|---| +| CPU | Linux dev | CPU (all cores) | _prior_ | _prior_ | pre-CUDA baseline, if recorded | +| **CUDA (LAN)** | **gaming PC** | **NVIDIA** | _measure_ | _measure_ | **`inference-bench --service detect` → `detect_cuda_lan.json`** | + +Detection is a per-command burst (the task layer asks for a label, not a stream), +so its latency matters for fetch responsiveness, not sustained fps. + +## End-to-end (robot → server → `/camera_obstacles`) + +The socket round trip above is the dominant term, but the full pipeline also +includes JPEG capture on the Pi, lidar rescale, back-projection, and publish. To +capture the whole leg over the real LAN, with the robot running `pixi run +perception` pointed at the gaming PC: + +- read the depth node's cloud publish rate on `/camera_obstacles` + (`ros2 topic hz /camera_obstacles`), and +- compare against `inference-bench`'s server round trip to attribute the rest to + on-robot processing. + +Record the observed `/camera_obstacles` Hz and the `inference-bench` summary here +once measured on hardware. diff --git a/mote_perception/deploy/windows/install_service.ps1 b/mote_perception/deploy/windows/install_service.ps1 new file mode 100644 index 0000000..a57db02 --- /dev/null +++ b/mote_perception/deploy/windows/install_service.ps1 @@ -0,0 +1,44 @@ +# Register the Mote inference servers to start at boot (Windows Task Scheduler). +# +# Run in an ELEVATED (Administrator) PowerShell. Creates a scheduled task +# "MoteInference" that launches run_inference.ps1 at system startup, whether or +# not a user is logged in, and keeps it running (run_inference.ps1 self-restarts +# the servers; this task restarts the runner itself if it ever stops). CUDA +# compute does not need an interactive desktop, so session-0 startup is fine. +# +# You are prompted for the account to run as — use the machine's own user account +# so the HuggingFace cache and pixi install (both under that profile) are found. +# Task Scheduler stores the password; the servers then survive a reboot with no +# manual step, satisfying the reboot criterion. +# +# Alternative: to run the servers as a true Windows service instead, wrap +# run_inference.ps1 with NSSM (https://nssm.cc) — see docs/inference-server.md. + +param( + [string]$TaskName = "MoteInference", + [string]$RepoPath = (Resolve-Path (Join-Path $PSScriptRoot "..\..\..")).Path, + [string]$User = "$env:USERDOMAIN\$env:USERNAME" +) + +$ErrorActionPreference = "Stop" +$runner = Join-Path $RepoPath "mote_perception\deploy\windows\run_inference.ps1" +if (-not (Test-Path $runner)) { throw "runner not found: $runner" } + +$action = New-ScheduledTaskAction -Execute "powershell.exe" ` + -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$runner`" -RepoPath `"$RepoPath`"" +$trigger = New-ScheduledTaskTrigger -AtStartup +# Keep the runner alive: if it ever exits, restart it; no execution time limit. +$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries ` + -DontStopIfGoingOnBatteries -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) ` + -ExecutionTimeLimit (New-TimeSpan -Seconds 0) -StartWhenAvailable + +$cred = Get-Credential -UserName $User -Message "Password for the account that will run the inference servers" + +Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger ` + -Settings $settings -RunLevel Highest ` + -User $cred.UserName -Password $cred.GetNetworkCredential().Password -Force + +Start-ScheduledTask -TaskName $TaskName +Write-Host "Registered and started scheduled task '$TaskName'." +Write-Host "Logs: $env:LOCALAPPDATA\mote\logs\inference-.log" +Write-Host "Check from the robot with: pixi run inference-health --host " diff --git a/mote_perception/deploy/windows/run_inference.ps1 b/mote_perception/deploy/windows/run_inference.ps1 new file mode 100644 index 0000000..4f39d5e --- /dev/null +++ b/mote_perception/deploy/windows/run_inference.ps1 @@ -0,0 +1,46 @@ +# Boot-launched runner for the Mote inference servers on the Windows gaming PC. +# +# Runs `pixi run inference-cuda` (both depth + detect servers, bound to 0.0.0.0) +# in a supervise loop: if the pixi process exits — because a server crashed and +# the Python supervisor tore the rest down so the failure is visible — this waits +# a few seconds and starts it again, so the machine self-heals without waiting on +# Task Scheduler's restart policy. All output is tee'd to a dated log file. +# +# install_service.ps1 registers this to run at boot; you can also run it by hand +# in a terminal to watch the servers live. Ctrl+C stops the loop. +# +# Params let a PC rebuild point at a different checkout / pixi / log dir without +# editing the script. + +param( + [string]$RepoPath = (Resolve-Path (Join-Path $PSScriptRoot "..\..\..")).Path, + [string]$Pixi = (Join-Path $env:USERPROFILE ".pixi\bin\pixi.exe"), + [string]$LogDir = (Join-Path $env:LOCALAPPDATA "mote\logs"), + [int]$RestartDelaySeconds = 5 +) + +$ErrorActionPreference = "Stop" +New-Item -ItemType Directory -Force -Path $LogDir | Out-Null +$log = Join-Path $LogDir ("inference-{0}.log" -f (Get-Date -Format "yyyyMMdd")) + +function Write-Log($msg) { + $line = "{0} {1}" -f (Get-Date -Format "s"), $msg + $line | Tee-Object -FilePath $log -Append +} + +if (-not (Test-Path $Pixi)) { + Write-Log "pixi not found at $Pixi — run setup.ps1 first. Exiting." + exit 1 +} + +Write-Log "runner up: repo=$RepoPath pixi=$Pixi log=$log" +Set-Location $RepoPath + +while ($true) { + Write-Log "starting: pixi run inference-cuda" + # Stream the servers' stdout/stderr into the same log. + & $Pixi "run" "inference-cuda" 2>&1 | Tee-Object -FilePath $log -Append + $code = $LASTEXITCODE + Write-Log "inference-cuda exited ($code); restarting in ${RestartDelaySeconds}s" + Start-Sleep -Seconds $RestartDelaySeconds +} diff --git a/mote_perception/deploy/windows/setup.ps1 b/mote_perception/deploy/windows/setup.ps1 new file mode 100644 index 0000000..e862c5f --- /dev/null +++ b/mote_perception/deploy/windows/setup.ps1 @@ -0,0 +1,38 @@ +# One-shot setup for the Mote inference PC (Windows + NVIDIA GPU). +# +# Run once in a normal (non-admin) PowerShell from anywhere. It: +# 1. installs pixi if it isn't already on the machine, +# 2. solves + installs the win-64 CUDA inference env (torch cu128 wheel), +# 3. verifies the GPU is visible to torch, +# 4. pre-fetches the depth + detect model weights into the HF cache. +# +# After this, install_service.ps1 makes the servers start at boot. The whole +# thing is idempotent — safe to re-run after a repo update or a driver change. + +param( + [string]$RepoPath = (Resolve-Path (Join-Path $PSScriptRoot "..\..\..")).Path +) + +$ErrorActionPreference = "Stop" +$pixi = Join-Path $env:USERPROFILE ".pixi\bin\pixi.exe" + +if (-not (Test-Path $pixi)) { + Write-Host "Installing pixi ..." + powershell -ExecutionPolicy Bypass -Command "iwr -useb https://pixi.sh/install.ps1 | iex" +} +if (-not (Test-Path $pixi)) { + throw "pixi install did not produce $pixi — install manually from https://pixi.sh and re-run." +} + +Set-Location $RepoPath +Write-Host "Solving + installing the inference-cuda env (first run downloads torch; be patient) ..." +& $pixi install -e inference-cuda + +Write-Host "`nGPU check:" +& $pixi run -e inference-cuda python -c "import torch; print('torch', torch.__version__); print('cuda_available', torch.cuda.is_available()); print('device', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'NONE')" + +Write-Host "`nPre-fetching model weights ..." +& $pixi run inference-prefetch-cuda + +Write-Host "`nSetup complete. Start the servers now with: pixi run inference-cuda" +Write-Host "Install boot auto-start with: .\mote_perception\deploy\windows\install_service.ps1 (as Administrator)" diff --git a/mote_perception/deploy/windows/uninstall_service.ps1 b/mote_perception/deploy/windows/uninstall_service.ps1 new file mode 100644 index 0000000..f5210f6 --- /dev/null +++ b/mote_perception/deploy/windows/uninstall_service.ps1 @@ -0,0 +1,13 @@ +# Remove the MoteInference boot task (elevated PowerShell). Stops and unregisters +# it; leaves the pixi env, model cache, and logs in place. + +param([string]$TaskName = "MoteInference") + +$ErrorActionPreference = "Stop" +if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) { + Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue + Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false + Write-Host "Removed scheduled task '$TaskName'." +} else { + Write-Host "No scheduled task '$TaskName' found." +} diff --git a/mote_perception/mote_perception/depth_wire.py b/mote_perception/mote_perception/depth_wire.py index 7894242..75b7644 100644 --- a/mote_perception/mote_perception/depth_wire.py +++ b/mote_perception/mote_perception/depth_wire.py @@ -19,10 +19,17 @@ reply : uint32 H, uint32 W, then H*W float32 depth (row-major, metres) H == W == 0 means the frame was rejected; no payload follows. + health : uint32 n == HEALTH_MAGIC (0xFFFFFFFF, never a real image length), + no payload; the server replies uint32 L, then L bytes of UTF-8 + JSON describing the running service (model, device, versions). + A connection carries any number of request/reply cycles; either end closing the -socket ends the session. +socket ends the session. The health request shares this framing so the same +persistent socket and reconnect logic cover it — the robot can ask "who am I +talking to?" over the existing link (see WireClient.health). """ +import json import socket import struct @@ -30,6 +37,11 @@ DEFAULT_PORT = 5601 +# Leading uint32 sentinel marking a health request instead of an image length. +# 0xFFFFFFFF (4 GiB) can never be a real compressed-image length, so servers can +# branch on it before reading any payload. +HEALTH_MAGIC = 0xFFFFFFFF + def recvall(sock, n): """Read exactly n bytes, or None if the peer closed first.""" @@ -64,6 +76,16 @@ def send_rejection(conn): conn.sendall(struct.pack(">II", 0, 0)) +def send_health(conn, info): + """Server side: reply to a health request with a JSON status blob. + + `info` is any JSON-serialisable dict (service name, model, device, versions). + Shared by every server so the client's health probe is service-agnostic. + """ + body = json.dumps(info).encode("utf-8") + conn.sendall(struct.pack(">I", len(body)) + body) + + class WireClient: """Persistent connection to an inference server, reconnecting on demand. @@ -103,6 +125,32 @@ def close(self): pass self.sock = None + def health(self): + """The server's status dict, or None if unreachable or the check failed. + + Sends the health sentinel over the persistent socket and reads back the + JSON status blob. Works against any server (depth, detect, future + tenants) since the framing is shared. A failure tears the socket down so + the next call — health or infer — reconnects, exactly like `infer`. + """ + s = self.connect() + if s is None: + return None + try: + s.sendall(struct.pack(">I", HEALTH_MAGIC)) + hdr = recvall(s, 4) + if hdr is None: + raise ConnectionError("server closed") + (n,) = struct.unpack(">I", hdr) + body = recvall(s, n) + if body is None: + raise ConnectionError("server closed mid-health") + return json.loads(body.decode("utf-8")) + except (OSError, ConnectionError, ValueError) as e: + self.warn(f"{self.NAME} health check failed ({e}); will reconnect") + self.close() + return None + class DepthClient(WireClient): NAME = "depth" diff --git a/mote_perception/mote_perception/detect_wire.py b/mote_perception/mote_perception/detect_wire.py index adeabcc..f3b1477 100644 --- a/mote_perception/mote_perception/detect_wire.py +++ b/mote_perception/mote_perception/detect_wire.py @@ -16,13 +16,33 @@ float32 x0, y0, x1, y1 (pixel corners in the request image) k == 0xFFFFFFFF means the frame was rejected; no payload follows. + health : uint32 n == HEALTH_MAGIC, no payload; server replies with the + shared JSON status blob (see depth_wire). Same framing as depth so + WireClient.health works unchanged against this service too. + A connection carries any number of request/reply cycles; either end closing the socket ends the session. """ import struct -from mote_perception.depth_wire import WireClient, recvall +from mote_perception.depth_wire import ( + HEALTH_MAGIC, + WireClient, + recvall, + send_health, +) + +__all__ = [ + "HEALTH_MAGIC", + "send_health", + "recv_request", + "send_detections", + "send_rejection", + "DetectClient", + "DEFAULT_PORT", + "REJECTED", +] DEFAULT_PORT = 5602 REJECTED = 0xFFFFFFFF diff --git a/mote_perception/test/test_depth_wire.py b/mote_perception/test/test_depth_wire.py index 195362d..41c4ea8 100644 --- a/mote_perception/test/test_depth_wire.py +++ b/mote_perception/test/test_depth_wire.py @@ -13,10 +13,12 @@ import numpy as np from mote_perception.depth_wire import ( + HEALTH_MAGIC, DepthClient, recv_image, recvall, send_depth, + send_health, send_rejection, ) @@ -189,3 +191,53 @@ def handler(conn, blob): assert any("reconnect" in w for w in warnings) finally: server.close() + + +class _HealthServer: + """Server that mirrors the real loop: branch on the health sentinel, else echo.""" + + def __init__(self, info): + self.info = info + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.bind(("127.0.0.1", 0)) + self.sock.listen(1) + self.port = self.sock.getsockname()[1] + threading.Thread(target=self._serve, daemon=True).start() + + def _serve(self): + conn, _ = self.sock.accept() + with conn: + while True: + hdr = recvall(conn, 4) + if hdr is None: + return + (n,) = struct.unpack(">I", hdr) + if n == HEALTH_MAGIC: + send_health(conn, self.info) + continue + blob = recvall(conn, n) + if blob is None: + return + send_depth(conn, np.ones((2, 2), np.float32)) + + def close(self): + self.sock.close() + + +def test_health_round_trip_and_interleaves_with_infer(): + info = {"service": "depth", "model": "m", "device": "cuda", "torch": "2.11"} + server = _HealthServer(info) + try: + client = DepthClient("127.0.0.1", port=server.port, warn=lambda m: None) + assert client.health() == info + # health and infer share the one persistent socket, in any order. + np.testing.assert_array_equal(client.infer(b"img"), np.ones((2, 2), np.float32)) + assert client.health() == info + client.close() + finally: + server.close() + + +def test_health_returns_none_when_unreachable(): + client = DepthClient("127.0.0.1", port=1, timeout=0.5, warn=lambda m: None) + assert client.health() is None diff --git a/mote_perception/test/test_detect_wire.py b/mote_perception/test/test_detect_wire.py index faef87c..3160eb7 100644 --- a/mote_perception/test/test_detect_wire.py +++ b/mote_perception/test/test_detect_wire.py @@ -1,14 +1,18 @@ """Round-trip the detection wire protocol over a real socket, no torch/ROS.""" import socket +import struct import threading import pytest +from mote_perception.depth_wire import recvall from mote_perception.detect_wire import ( + HEALTH_MAGIC, DetectClient, recv_request, send_detections, + send_health, send_rejection, ) @@ -78,3 +82,26 @@ def handler(conn, blob, labels): def test_unreachable_server(): client = DetectClient("127.0.0.1", 1, timeout=0.2, warn=lambda m: None) assert client.infer(b"x", ["thing"]) is None + + +def test_health_round_trip(): + info = {"service": "detect", "model": "owlv2", "device": "cuda"} + + srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + srv.bind(("127.0.0.1", 0)) + srv.listen(1) + port = srv.getsockname()[1] + + def run(): + conn, _ = srv.accept() + with conn: + hdr = recvall(conn, 4) + (n,) = struct.unpack(">I", hdr) + if n == HEALTH_MAGIC: + send_health(conn, info) + srv.close() + + threading.Thread(target=run, daemon=True).start() + client = DetectClient("127.0.0.1", port, warn=lambda m: None) + assert client.health() == info + client.close() diff --git a/mote_perception/tools/depth_server.py b/mote_perception/tools/depth_server.py index 126f837..8a8e962 100644 --- a/mote_perception/tools/depth_server.py +++ b/mote_perception/tools/depth_server.py @@ -19,6 +19,7 @@ import argparse import io import socket +import struct import sys import time from pathlib import Path @@ -32,8 +33,10 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from mote_perception.depth_wire import ( # noqa: E402 DEFAULT_PORT, - recv_image, + HEALTH_MAGIC, + recvall, send_depth, + send_health, send_rejection, ) @@ -76,6 +79,17 @@ def main(): # os.cpu_count() counts SMT siblings, and oversubscribing them thrashes the # CPU (~460 ms vs ~330 ms per frame here — measured with depth_bag_eval.py). + health_info = { + "service": "depth", + "model": args.model, + "device": device, + "gpu": torch.cuda.get_device_name(0) if device != "cpu" else None, + "fp16": use_fp16, + "metric": args.metric, + "torch": torch.__version__, + "cuda_available": torch.cuda.is_available(), + } + srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind((args.host, args.port)) @@ -87,7 +101,15 @@ def main(): print("client", addr) try: while True: - blob = recv_image(conn) + hdr = recvall(conn, 4) + if hdr is None: + break + (n,) = struct.unpack(">I", hdr) + if n == HEALTH_MAGIC: + send_health(conn, health_info) + print("health check") + continue + blob = recvall(conn, n) if blob is None: break depth = None diff --git a/mote_perception/tools/detect_server.py b/mote_perception/tools/detect_server.py index 653f455..ca78268 100644 --- a/mote_perception/tools/detect_server.py +++ b/mote_perception/tools/detect_server.py @@ -15,6 +15,7 @@ import io import os import socket +import struct import sys import time from pathlib import Path @@ -26,15 +27,17 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from mote_perception.detect_wire import ( # noqa: E402 DEFAULT_PORT, - recv_request, + HEALTH_MAGIC, + recvall, send_detections, + send_health, send_rejection, ) MODEL = "google/owlv2-base-patch16-ensemble" -def detect(proc, model, img, labels, threshold): +def detect(proc, model, img, labels, threshold, device): """Run OWLv2 on one image: [(label_index, score, (x0, y0, x1, y1)), ...]. The processor pads the image bottom-right to a square before resizing, and @@ -45,11 +48,13 @@ def detect(proc, model, img, labels, threshold): """ W, H = img.size side = max(W, H) - inputs = proc(text=[labels], images=img, return_tensors="pt") + inputs = proc(text=[labels], images=img, return_tensors="pt").to(device) with torch.no_grad(): outputs = model(**inputs) res = proc.post_process_object_detection( - outputs, threshold=threshold, target_sizes=torch.tensor([(side, side)]) + outputs, + threshold=threshold, + target_sizes=torch.tensor([(side, side)], device=device), )[0] out = [] for idx, score, box in zip(res["labels"], res["scores"], res["boxes"]): @@ -77,12 +82,34 @@ def main(): # Low floor so score policy stays client-side (the node's min_score param); # this only trims the wire traffic of clear noise. ap.add_argument("--threshold", type=float, default=0.1) + ap.add_argument("--device", default="auto", choices=["auto", "cpu", "cuda"]) args = ap.parse_args() + if args.device == "auto": + device = "cuda" if torch.cuda.is_available() else "cpu" + else: + device = args.device + print("loading", args.model) proc = Owlv2Processor.from_pretrained(args.model) - model = Owlv2ForObjectDetection.from_pretrained(args.model).eval() - torch.set_num_threads(os.cpu_count()) + model = Owlv2ForObjectDetection.from_pretrained(args.model).eval().to(device) + if device == "cpu": + # OWLv2 is CPU-bound here; use all cores. On GPU, leave torch's threading + # alone — the heavy work runs on the device. + torch.set_num_threads(os.cpu_count()) + print("using CPU") + else: + print("using GPU:", torch.cuda.get_device_name(0)) + + health_info = { + "service": "detect", + "model": args.model, + "device": device, + "gpu": torch.cuda.get_device_name(0) if device != "cpu" else None, + "threshold": args.threshold, + "torch": torch.__version__, + "cuda_available": torch.cuda.is_available(), + } srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -95,15 +122,29 @@ def main(): print("client", addr) try: while True: - req = recv_request(conn) - if req is None: + hdr = recvall(conn, 4) + if hdr is None: + break + (n,) = struct.unpack(">I", hdr) + if n == HEALTH_MAGIC: + send_health(conn, health_info) + print("health check") + continue + blob = recvall(conn, n) + if blob is None: + break + hdr = recvall(conn, 4) + if hdr is None: + break + text = recvall(conn, struct.unpack(">I", hdr)[0]) + if text is None: break - blob, labels = req + labels = text.decode("utf-8").splitlines() dets = None try: img = Image.open(io.BytesIO(blob)).convert("RGB") t0 = time.perf_counter() - dets = detect(proc, model, img, labels, args.threshold) + dets = detect(proc, model, img, labels, args.threshold, device) dt = (time.perf_counter() - t0) * 1000 log = f"served {labels} -> {len(dets)} in {dt:.0f} ms" except OSError as e: diff --git a/mote_perception/tools/inference_bench.py b/mote_perception/tools/inference_bench.py new file mode 100644 index 0000000..70bab1e --- /dev/null +++ b/mote_perception/tools/inference_bench.py @@ -0,0 +1,150 @@ +"""Measure end-to-end inference latency/throughput over the socket (torch-free). + +Runs on the robot side (or any machine on the LAN) and times the full round +trip the depth/detect nodes actually pay: compress -> send -> server infer -> +receive. That captures GPU time *and* the network hop, so the numbers are +comparable to the on-robot pipeline, not just raw model speed. + + # depth, 200 frames of a real image, over the LAN, results to a file + pixi run inference-bench --host mote-gpu --image frame.jpg --frames 200 \ + --out mote_perception/benchmarks/depth_cuda_lan.json + + # synthetic frames if you have no sample image handy + pixi run inference-bench --host mote-gpu --frames 100 + + # the detect service + pixi run inference-bench --service detect --host mote-gpu --labels "red box,shoe" + +Prints a percentile table and, with --out, writes the raw samples + summary as +JSON so results can be committed and compared across machines. +""" + +import argparse +import json +import statistics +import sys +import time +from pathlib import Path + +import cv2 +import numpy as np + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +from mote_perception.depth_wire import DEFAULT_PORT as DEPTH_PORT # noqa: E402 +from mote_perception.depth_wire import DepthClient # noqa: E402 +from mote_perception.detect_wire import DEFAULT_PORT as DETECT_PORT # noqa: E402 +from mote_perception.detect_wire import DetectClient # noqa: E402 + + +def _frame(image, size): + """A JPEG blob: the given image (resized to `size`), or synthetic noise.""" + w, h = size + if image: + img = cv2.imread(image, cv2.IMREAD_COLOR) + if img is None: + raise SystemExit(f"cannot read image: {image}") + img = cv2.resize(img, (w, h)) + else: + rng = np.random.default_rng(0) + img = rng.integers(0, 256, (h, w, 3), dtype=np.uint8) + ok, buf = cv2.imencode(".jpg", img) + if not ok: + raise SystemExit("jpeg encode failed") + return buf.tobytes() + + +def _pct(xs, q): + return statistics.quantiles(xs, n=100, method="inclusive")[q - 1] + + +def main(): + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--service", choices=["depth", "detect"], default="depth") + ap.add_argument("--host", default="127.0.0.1") + ap.add_argument("--port", type=int, default=None, help="default: service port") + ap.add_argument( + "--image", default=None, help="sample JPEG to send (else synthetic)" + ) + ap.add_argument("--width", type=int, default=640) + ap.add_argument("--height", type=int, default=480) + ap.add_argument("--frames", type=int, default=100) + ap.add_argument("--warmup", type=int, default=5, help="untimed frames first") + ap.add_argument("--labels", default="box", help="detect only, comma-separated") + ap.add_argument("--timeout", type=float, default=30.0) + ap.add_argument("--out", default=None, help="write JSON results here") + args = ap.parse_args() + + blob = _frame(args.image, (args.width, args.height)) + if args.service == "depth": + port = args.port or DEPTH_PORT + client = DepthClient(args.host, port, args.timeout, warn=print) + call = lambda: client.infer(blob) # noqa: E731 + else: + port = args.port or DETECT_PORT + labels = [s.strip() for s in args.labels.split(",") if s.strip()] + client = DetectClient(args.host, port, args.timeout, warn=print) + call = lambda: client.infer(blob, labels) # noqa: E731 + + health = client.health() + print(f"{args.service} server @ {args.host}:{port} -> {health}") + if health is None: + raise SystemExit("server did not answer health check; aborting") + + for _ in range(args.warmup): + call() + + samples = [] + for i in range(args.frames): + t0 = time.perf_counter() + r = call() + dt = (time.perf_counter() - t0) * 1000.0 + if r is None: + print(f"frame {i}: no result (server rejected or dropped)") + continue + samples.append(dt) + client.close() + + if not samples: + raise SystemExit("no successful frames") + + summary = { + "service": args.service, + "host": args.host, + "port": port, + "server": health, + "image": args.image or "synthetic", + "resolution": [args.width, args.height], + "payload_bytes": len(blob), + "frames": len(samples), + "latency_ms": { + "min": round(min(samples), 1), + "mean": round(statistics.fmean(samples), 1), + "p50": round(_pct(samples, 50), 1), + "p90": round(_pct(samples, 90), 1), + "p99": round(_pct(samples, 99), 1), + "max": round(max(samples), 1), + }, + "fps": round(1000.0 / statistics.fmean(samples), 2), + } + + lm = summary["latency_ms"] + print( + f"\n{args.service} over {len(samples)} frames ({len(blob) / 1024:.0f} KiB/frame)" + ) + print( + f" latency ms min {lm['min']} p50 {lm['p50']} mean {lm['mean']} " + f"p90 {lm['p90']} p99 {lm['p99']} max {lm['max']}" + ) + print(f" throughput {summary['fps']} fps") + + if args.out: + Path(args.out).parent.mkdir(parents=True, exist_ok=True) + with open(args.out, "w") as f: + json.dump( + {**summary, "samples_ms": [round(s, 2) for s in samples]}, f, indent=2 + ) + print(f" wrote {args.out}") + + +if __name__ == "__main__": + main() diff --git a/mote_perception/tools/inference_health.py b/mote_perception/tools/inference_health.py new file mode 100644 index 0000000..ce5468b --- /dev/null +++ b/mote_perception/tools/inference_health.py @@ -0,0 +1,89 @@ +"""Probe the off-board inference servers from the robot side (torch-free). + +Answers "is the inference machine up, and what is it running?" over the same +socket the depth/detect nodes use — no ROS, no torch, so it runs anywhere the +robot env does. It sends the health sentinel (see depth_wire) to each service +and prints the JSON status the server reports (model, device, GPU, versions). + + pixi run inference-health # probe the configured inference_host + pixi run inference-health --host mote-gpu # or a specific host + pixi run inference-health --json # machine-readable + +Exit status is 0 only if every probed service answered, so it doubles as a +health gate in scripts. +""" + +import argparse +import json +import os +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +from mote_perception.depth_wire import DepthClient # noqa: E402 +from mote_perception.detect_wire import DetectClient # noqa: E402 + + +def _default_host(): + """The inference_host from perception.yaml (user override, then packaged).""" + user = os.path.expanduser("~/.mote/perception.yaml") + packaged = Path(__file__).resolve().parents[1] / "config" / "perception.yaml" + path = user if os.path.exists(user) else packaged + try: + import yaml + + with open(path) as f: + return yaml.safe_load(f).get("inference_host", "127.0.0.1") + except Exception: + return "127.0.0.1" + + +def main(): + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument( + "--host", default=None, help="inference host (default: perception.yaml)" + ) + ap.add_argument("--depth-port", type=int, default=5601) + ap.add_argument("--detect-port", type=int, default=5602) + ap.add_argument("--timeout", type=float, default=3.0) + ap.add_argument("--json", action="store_true", help="emit raw JSON, no table") + args = ap.parse_args() + + host = args.host or _default_host() + services = [ + ( + "depth", + DepthClient(host, args.depth_port, args.timeout, warn=lambda m: None), + ), + ( + "detect", + DetectClient(host, args.detect_port, args.timeout, warn=lambda m: None), + ), + ] + + results = {} + for name, client in services: + results[name] = client.health() + client.close() + + if args.json: + print(json.dumps({"host": host, "services": results}, indent=2)) + else: + print(f"inference host: {host}") + for name, info in results.items(): + if info is None: + print(f" {name:7} DOWN (no response)") + else: + dev = info.get("device", "?") + gpu = info.get("gpu") + where = f"{dev} ({gpu})" if gpu else dev + print( + f" {name:7} UP {info.get('model', '?')} on {where}" + f" torch {info.get('torch', '?')}" + ) + + return 0 if all(v is not None for v in results.values()) else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/mote_perception/tools/inference_server.py b/mote_perception/tools/inference_server.py new file mode 100644 index 0000000..7b7b91f --- /dev/null +++ b/mote_perception/tools/inference_server.py @@ -0,0 +1,79 @@ +"""Supervise every inference service as one process (cross-platform). + +Runs each server (depth, detect, ...) as a child bound to 0.0.0.0 so the robot +reaches them over the LAN at `inference_host` (see perception.yaml). Replaces the +old bash launcher so the same command works on the Linux dev box *and* the +Windows gaming PC — pixi provides `python` on every platform, but not `bash`. + +If any child exits, the rest are torn down so a partial failure is visible rather +than half-served (a supervisor that keeps a dead tenant's siblings alive just +hides the outage). SIGINT/SIGTERM (or the Windows equivalent) stops everything. + +This is the seam for the multi-service pattern: a new inference tenant is one row +in SERVICES — it inherits binding, supervision, teardown, and (via the shared +wire) health and reconnect for free. Per-service flags go in the row's args; the +robot-side node already carries its own port. See docs/inference-server.md. + + pixi run inference # CPU env + pixi run inference-rocm # AMD ROCm env + pixi run inference-cuda # Windows/NVIDIA env + # extra args pass through to every server, e.g. a shared device override: + pixi run inference-cuda -- --device cuda +""" + +import signal +import subprocess +import sys +import time +from pathlib import Path + +HERE = Path(__file__).resolve().parent + +# (name, script, per-service args). Add a tenant here — nothing else changes. +SERVICES = [ + ("depth", "depth_server.py", []), + ("detect", "detect_server.py", []), +] + + +def main(): + passthrough = sys.argv[1:] + procs = [] + for name, script, extra in SERVICES: + cmd = [ + sys.executable, + "-u", + str(HERE / script), + "--host", + "0.0.0.0", + *extra, + *passthrough, + ] + print(f"[supervisor] starting {name}: {' '.join(cmd)}", flush=True) + procs.append((name, subprocess.Popen(cmd))) + + def shutdown(*_): + for name, p in procs: + if p.poll() is None: + p.terminate() + for _, p in procs: + try: + p.wait(timeout=10) + except subprocess.TimeoutExpired: + p.kill() + sys.exit(0) + + signal.signal(signal.SIGINT, shutdown) + signal.signal(signal.SIGTERM, shutdown) + + while True: + for name, p in procs: + code = p.poll() + if code is not None: + print(f"[supervisor] {name} exited ({code}); stopping all", flush=True) + shutdown() + time.sleep(0.5) + + +if __name__ == "__main__": + main() diff --git a/mote_perception/tools/inference_server.sh b/mote_perception/tools/inference_server.sh deleted file mode 100755 index 2dc67bd..0000000 --- a/mote_perception/tools/inference_server.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Runs both inference servers together on the "inference" machine (the pixi -# inference env: torch, no ROS). The ROS depth/detect nodes run on the robot and -# reach these over TCP at inference_host (see perception.yaml). This runs directly -# in the torch env, so — unlike the old per-model launchers that shelled out from -# the ROS env — there is no PYTHONPATH to drop. If either server dies, tear both -# down so the failure is visible rather than half-served. -# -# --host 0.0.0.0: this launcher's whole purpose is a dedicated inference machine, -# so bind all interfaces — the robot connects over the LAN at inference_host. (The -# standalone depth-server/detect-server tasks keep the 127.0.0.1 default for the -# single-machine dev case.) The wire protocol is unauthenticated: run it on a -# trusted network. -python -u mote_perception/tools/depth_server.py --host 0.0.0.0 & -depth_pid=$! -python -u mote_perception/tools/detect_server.py --host 0.0.0.0 & -detect_pid=$! - -cleanup() { - kill "$depth_pid" "$detect_pid" 2>/dev/null || true - wait "$depth_pid" "$detect_pid" 2>/dev/null || true -} -trap cleanup EXIT INT TERM - -wait -n diff --git a/mote_perception/tools/prefetch_models.py b/mote_perception/tools/prefetch_models.py new file mode 100644 index 0000000..a7f5617 --- /dev/null +++ b/mote_perception/tools/prefetch_models.py @@ -0,0 +1,45 @@ +r"""Download the inference models into the local HuggingFace cache ahead of time. + +The servers pull their weights via `from_pretrained` on first use, which means +the very first depth/detect request after a fresh install blocks on a multi- +hundred-MB download. Running this once at setup time (part of the inference-PC +guide) makes the servers start serving immediately and confirms the machine can +reach the HF hub before you rely on it. + + pixi run inference-prefetch # CPU/dev env + pixi run inference-prefetch-cuda # the gaming-PC CUDA env + +Weights land in the standard HF cache (~/.cache/huggingface, or %USERPROFILE%\ +.cache\huggingface on Windows); set HF_HOME to relocate it. Safe to re-run — +already-cached files are skipped. +""" + +import sys + +DEPTH_MODEL = "depth-anything/Depth-Anything-V2-Small-hf" +DETECT_MODEL = "google/owlv2-base-patch16-ensemble" + + +def main(): + models = sys.argv[1:] or [DEPTH_MODEL, DETECT_MODEL] + from transformers import ( + AutoImageProcessor, + AutoModelForDepthEstimation, + Owlv2ForObjectDetection, + Owlv2Processor, + ) + + for model in models: + print(f"fetching {model} ...", flush=True) + if "owlv2" in model.lower(): + Owlv2Processor.from_pretrained(model) + Owlv2ForObjectDetection.from_pretrained(model) + else: + AutoImageProcessor.from_pretrained(model) + AutoModelForDepthEstimation.from_pretrained(model) + print(f" done: {model}", flush=True) + print("all models cached") + + +if __name__ == "__main__": + main() diff --git a/pixi.lock b/pixi.lock index ea059d7..9d7e2fc 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2,6 +2,7 @@ version: 7 platforms: - name: linux-64 - name: linux-aarch64 +- name: win-64 environments: default: channels: @@ -3798,6 +3799,188 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda + inference-cuda: + channels: + - url: https://prefix.dev/mote/ + - url: https://conda.anaconda.org/robostack-jazzy/ + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + win-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.13-py312hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.12.13-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.4.2-h11686cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.14.1-pl5321h06fc181_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.10.4-hc6e9107_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.14-h032d170_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.14.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.2-h1da161f_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.11.0-h667fc28_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.27.3-hbdc738f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.12.8-hd7ee1a1_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.7-h1da161f_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.10-h1da161f_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-8.1.2-gpl_he504192_904.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.2-hd47e2ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gdk-pixbuf-2.44.7-h1f5b9c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.88.2-h395db07_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.88.2-h74ecf4c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glslang-16.3.0-h294ba9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.2.1-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-2.1.0-nompi_h0d3e4b2_110.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/imath-3.2.2-h1608b31_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/khronos-opencl-icd-loader-2024.10.24-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lame-4.0-h4a41cd3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20260526.0-cxx17_h0eb2380_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.5-haf901d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.4.2-hdefa946_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-8_h8455456_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-8_h2a3cdd5_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.21.0-h51a1c48_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_19.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.2-h7ce1215_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_19.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.2.1-h03b5201_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-devel-14.2.1-h03b5201_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwy-1.4.0-h2419aca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-devel-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjxl-0.12.0-h932607e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-8_hf9ab0e9_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-8_h3ae206f_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.5-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopencv-4.13.0-qt6_hfadb9d5_614.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-2026.2.1-h2f25fdd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-auto-batch-plugin-2026.2.1-hd74cc32_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-auto-plugin-2026.2.1-hd74cc32_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-hetero-plugin-2026.2.1-hc39e7c6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-intel-cpu-plugin-2026.2.1-h2f25fdd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-intel-gpu-plugin-2026.2.1-h2f25fdd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-ir-frontend-2026.2.1-hc39e7c6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-onnx-frontend-2026.2.1-hb13cd65_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-paddle-frontend-2026.2.1-hb13cd65_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-pytorch-frontend-2026.2.1-hac47afa_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-tensorflow-frontend-2026.2.1-ha992cae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-tensorflow-lite-frontend-2026.2.1-hac47afa_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.6.1-h6a83c73_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-h7351971_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-7.35.1-h1a71995_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpsl-0.22.0-h25e0afd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/librsvg-2.62.3-h15cfe45_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.3-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libusb-1.0.29-h1839187_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h5112557_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.350.1-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.8-h4fa8253_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_233.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mpg123-1.32.9-h01009b0_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.1-py312ha3f287d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/onemkl-license-2026.1.0-h57928b3_233.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/opencl-headers-2025.06.13-h826ebb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/opencv-4.13.0-qt6_he7afa43_614.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.4.13-hd20f895_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.6.0-h1eab103_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjph-0.30.1-hf13a347_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.3-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py312h31f0997_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pugixml-1.15-h372dad0_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/py-opencv-4.13.0-qt6_hd26e59d_614.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.13-h0159041_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.1-pl5321hfcac499_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.8.1-h007690e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.18.0-py312h9b3c559_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sdl2-2.32.56-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sdl3-3.4.12-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/shaderc-2026.3-hbcac29b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/spirv-tools-2026.2-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.2.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-h1b7c187_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.51.36231-h84cd919_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://download-r2.pytorch.org/whl/cu128/torch-2.11.0%2Bcu128-cp312-cp312-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/03/b8/e484ef633af3887baeeb4b6ad12743363af7cce68ae51e938e00aaa0529d/transformers-4.57.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/79/b4c714bef36bc4ec2beeae1e0c124f0223888cd8c6feb1cdc56038116920/filelock-3.32.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/8e/c780c131f79b42ed22d1bd7da4096c2c35f813e835acd02ef0f018bd892c/regex-2026.7.19-cp312-cp312-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/af/48ac8483240de756d2438c380746e7130d1c6f75802ef22f3c6d49982787/huggingface_hub-0.36.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/22/4222d7ddf3da30f363edaa98e329c2bce6c65497c9cb2810931c8b2c0fbc/fsspec-2026.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/21/99a0cdaf54eb35e77623c41b5a2c9472ee4404bba687052791fe2aba6773/tqdm-4.69.0-py3-none-any.whl inference-rocm: channels: - url: https://prefix.dev/mote/ @@ -23513,6 +23696,7 @@ packages: - python-gil license: MIT license_family: MIT + purls: [] run_exports: {} size: 8144 timestamp: 1784221492234 @@ -23602,6 +23786,16 @@ packages: purls: [] size: 129868 timestamp: 1779289852439 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda + sha256: 95e8e74062a5fe5f870ac8c90302b6e89945165fdaed7810606e84ddee6aac12 + md5: e27d2ac27b096dc51fedfcf775a53f9b + depends: + - __win + license: ISC + purls: [] + run_exports: {} + size: 132136 + timestamp: 1784754918886 - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda sha256: 0a0544cf95f64394fe4959286f5c71f5444ad58feb0602e53becb27448d24da6 md5: 0f51e2391ade309db462a55611263e9c @@ -23964,6 +24158,18 @@ packages: - pkg:pypi/coloredlogs?source=hash-mapping size: 43758 timestamp: 1733928076798 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.13-py312hd8ed1ab_0.conda + noarch: generic + sha256: d3e9bbd7340199527f28bbacf947702368f31de60c433a16446767d3c6aaf6fe + md5: f54c1ffb8ecedb85a8b7fcde3a187212 + depends: + - python >=3.12,<3.13.0a0 + - python_abi * *_cp312 + license: Python-2.0 + purls: [] + run_exports: {} + size: 46463 + timestamp: 1772728929620 - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda noarch: generic sha256: 7a548856ef5307890a8cadfc196655117658f8c24589ce175caa4c1c2ded9d13 @@ -24199,6 +24405,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] + run_exports: {} size: 397370 timestamp: 1566932522327 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 @@ -24207,6 +24414,7 @@ packages: license: OFL-1.1 license_family: Other purls: [] + run_exports: {} size: 96530 timestamp: 1620479909603 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 @@ -24215,6 +24423,7 @@ packages: license: OFL-1.1 license_family: Other purls: [] + run_exports: {} size: 700814 timestamp: 1620479612257 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda @@ -24223,6 +24432,7 @@ packages: license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 license_family: Other purls: [] + run_exports: {} size: 1620504 timestamp: 1727511233259 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 @@ -24233,6 +24443,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] + run_exports: {} size: 3667 timestamp: 1566974674465 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda @@ -24246,6 +24457,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] + run_exports: {} size: 4059 timestamp: 1762351264405 - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.6.0-pyhd8ed1ab_0.conda @@ -24925,6 +25137,17 @@ packages: license_family: MIT size: 35514 timestamp: 1781257630962 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.12.13-hd8ed1ab_0.conda + sha256: 97327b9509ae3aae28d27217a5d7bd31aff0ab61a02041e9c6f98c11d8a53b29 + md5: 32780d6794b8056b78602103a04e90ef + depends: + - cpython 3.12.13.* + - python_abi * *_cp312 + license: Python-2.0 + purls: [] + run_exports: {} + size: 46449 + timestamp: 1772728979370 - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda sha256: 84c129bdd6abcecac42a948f2670d17fe735d02d3a5a483a9b1f1bc33ba38c28 md5: 224f69f177eb5aae6c9a6052846bf609 @@ -25313,333 +25536,2699 @@ packages: - pkg:pypi/zipp?source=compressed-mapping size: 24190 timestamp: 1779159948016 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ackermann-msgs-2.0.2-np2py312h2ed9cc7_16.conda - sha256: 24c3be282ad6e801ccd25d93f14ab2584a756174c8d5b1f97d4e66acbdfa677e - md5: ee033082fda524a2116438ce5335d8f4 +- conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.4.2-h11686cb_3.conda + sha256: 699636321392c880feaa54162b15edd786927bf614396c571eae6d43b3b3415b + md5: 3ead269c6af33e75b5bfb8cca7d4e249 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: {} + size: 10138 + timestamp: 1784120074651 +- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 + md5: 1626967b574d1784b578b52eaeb071e7 depends: - - python - - ros-jazzy-ros-workspace - - ros-jazzy-rosidl-default-runtime - - ros-jazzy-std-msgs - - ros2-distro-mutex 0.14.* jazzy_* - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - numpy >=1.23,<3 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - python_abi 3.12.* *_cp312 + - libgomp >=7.5.0 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - openmp_impl <0.0a0 + - msys2-conda-epoch <0.0a0 license: BSD-3-Clause - size: 90133 - timestamp: 1771184649784 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ackermann-steering-controller-4.37.0-np2py312h2ed9cc7_16.conda - sha256: 148b3a42e3f423c55507c1c042b3550c347e60c535fda2a7996e60f9be198545 - md5: 28f1023702bc12c02178af5242e94bb2 - depends: - - python - - ros-jazzy-backward-ros - - ros-jazzy-control-msgs - - ros-jazzy-controller-interface - - ros-jazzy-hardware-interface - - ros-jazzy-pluginlib - - ros-jazzy-rclcpp - - ros-jazzy-rclcpp-lifecycle - - ros-jazzy-ros-workspace - - ros-jazzy-std-srvs - - ros-jazzy-steering-controllers-library - - ros2-distro-mutex 0.14.* jazzy_* - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - numpy >=1.23,<3 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - python_abi 3.12.* *_cp312 - license: Apache-2.0 - size: 107200 - timestamp: 1771190428063 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-msgs-2.0.3-np2py312h2ed9cc7_16.conda - sha256: de90c354f2833719b868748f8683cce0788fcb33fc950c65d98fbc33653466d0 - md5: ee92167b7ec28fdbc23388c7a8c74936 - depends: - - python - - ros-jazzy-builtin-interfaces - - ros-jazzy-ros-workspace - - ros-jazzy-rosidl-core-runtime - - ros-jazzy-service-msgs - - ros-jazzy-unique-identifier-msgs - - ros2-distro-mutex 0.14.* jazzy_* - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license_family: BSD + purls: [] + run_exports: + strong: + - _openmp_mutex >=4.5 + size: 52252 + timestamp: 1770943776666 +- conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.14.1-pl5321h06fc181_1.conda + sha256: 3033fa8953f7f0c1bb5b89b5af77253badc14a89ba94d743dde3c9159e10fd5e + md5: 7a8ace8100a48355a34d87386012c57b + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - aom >=3.14.1,<3.15.0a0 + size: 2214571 + timestamp: 1780752497150 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.10.4-hc6e9107_1.conda + sha256: cf7ab8abaac6b462463310412cc37d087a767a95920809cbe6dc0a08fe4bcfbd + md5: f7069cdc81f7a5e781f1faf6aab6c171 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-sdkutils >=0.2.7,<0.2.8.0a0 + - aws-c-cal >=0.9.14,<0.9.15.0a0 + - aws-c-http >=0.11.0,<0.11.1.0a0 + - aws-c-io >=0.27.3,<0.27.4.0a0 + - aws-c-common >=0.14.2,<0.14.3.0a0 license: Apache-2.0 - size: 152219 - timestamp: 1771184279030 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-cpp-0.33.9-np2py312h2ed9cc7_16.conda - sha256: 76e5bbb0e325371c3377dfec3699b57b9828d7860073e23a1f25b5be5ad02b1e - md5: 9c1f60b118635f9b442be44f3da0649d - depends: - - python - - ros-jazzy-action-tutorials-interfaces - - ros-jazzy-rclcpp - - ros-jazzy-rclcpp-action - - ros-jazzy-rclcpp-components - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-auth >=0.10.4,<0.10.5.0a0 + size: 127842 + timestamp: 1784086873207 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.14-h032d170_4.conda + sha256: cda33360c71ab9a4b4e269004a5672d712fa1ae581ecca0404181805ce6762ce + md5: fda8fa85ef5d8570d5a0aadea688bb82 + depends: + - aws-c-common >=0.14.2,<0.14.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 - size: 132598 - timestamp: 1771187103592 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-interfaces-0.33.9-np2py312h2ed9cc7_16.conda - sha256: 148e56b13ed1d1465bcae67e255562a758c722f3e697bbaa592cbe99e4321b94 - md5: 17823b83b20caad37d6a90c1c577cbde + license_family: Apache + purls: [] + run_exports: + weak: + - aws-c-cal >=0.9.14,<0.9.15.0a0 + size: 54285 + timestamp: 1784043506729 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.14.2-hfd05255_0.conda + sha256: 63fc3f34a3b3d21d5f6527ba5136e132f3ad50541d4d16e385d03f4e47e1db2b + md5: 75b4445fec6477b271920f87830d22a3 depends: - - python - - ros-jazzy-ros-workspace - - ros-jazzy-rosidl-default-runtime - - ros2-distro-mutex 0.14.* jazzy_* - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 - size: 185188 - timestamp: 1771184400148 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-py-0.33.9-np2py312h2ed9cc7_16.conda - sha256: 91b65725bd864a3ad4e18ec756d8a25e221459567d73e7b5f4fffc5e0ce15cfa - md5: dbec62941731e2358f8adf3f56cb7f6d - depends: - - python - - ros-jazzy-action-tutorials-interfaces - - ros-jazzy-rclpy - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - python_abi 3.12.* *_cp312 - - numpy >=1.23,<3 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license_family: Apache + purls: [] + run_exports: + weak: + - aws-c-common >=0.14.2,<0.14.3.0a0 + size: 241190 + timestamp: 1783637351552 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.2-h1da161f_4.conda + sha256: 97eaf03572b61d118616e8ee8459823c7b0f5dc26295bbab3ac3f6d671f1547a + md5: 996e5c7da8f9e255eac094d2413b40c3 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-common >=0.14.2,<0.14.3.0a0 license: Apache-2.0 - size: 30774 - timestamp: 1771186792870 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-actionlib-msgs-5.3.6-np2py312h2ed9cc7_16.conda - sha256: 4cfbbd610ecf55c5f6b22c9972a9271a33d0b385caee9e747a3721b5d6d70d69 - md5: cf00ccaa7ddf4586dee2363a736bab77 - depends: - - python - - ros-jazzy-builtin-interfaces - - ros-jazzy-ros-workspace - - ros-jazzy-rosidl-default-runtime - - ros-jazzy-std-msgs - - ros2-distro-mutex 0.14.* jazzy_* - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - python_abi 3.12.* *_cp312 - - numpy >=1.23,<3 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-compression >=0.3.2,<0.3.3.0a0 + size: 23355 + timestamp: 1784042894276 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.11.0-h667fc28_4.conda + sha256: 304587d77daccde630fbdbb8ae2f3994cf583427f710c60d62e88bc97c4ff013 + md5: c17a284b159959a8639298ed7da8ad0b + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-compression >=0.3.2,<0.3.3.0a0 + - aws-c-common >=0.14.2,<0.14.3.0a0 + - aws-c-cal >=0.9.14,<0.9.15.0a0 + - aws-c-io >=0.27.3,<0.27.4.0a0 license: Apache-2.0 - size: 112790 - timestamp: 1771184720660 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-actuator-msgs-0.0.1-np2py312h2ed9cc7_16.conda - sha256: 4713d100cf5065a3fde754db44485ff1469311d8e94bc50b1d15eb8a49ff3959 - md5: f9b3251409c4f85b044c148166299872 - depends: - - python - - ros-jazzy-ros-workspace - - ros-jazzy-rosidl-default-runtime - - ros-jazzy-std-msgs - - ros2-distro-mutex 0.14.* jazzy_* - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - numpy >=1.23,<3 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-http >=0.11.0,<0.11.1.0a0 + size: 213342 + timestamp: 1784075730337 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.27.3-hbdc738f_1.conda + sha256: 36816ff394ee736fcf705db5b1c1491c98f6f77ef84791d73b71e78154df402d + md5: 579600368b15fb523d69e2a3f8a9bc55 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-cal >=0.9.14,<0.9.15.0a0 + - aws-c-common >=0.14.2,<0.14.3.0a0 license: Apache-2.0 - size: 161558 - timestamp: 1771184683438 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-admittance-controller-4.37.0-np2py312h2ed9cc7_16.conda - sha256: 8ffd5ecd3ffbdef53181cc2f342bb4791dc959456d7e1f0314184348c3eb7978 - md5: 4c5d20f2c6053e5858894a490458e5a6 - depends: - - python - - ros-jazzy-angles - - ros-jazzy-backward-ros - - ros-jazzy-control-msgs - - ros-jazzy-control-toolbox - - ros-jazzy-controller-interface - - ros-jazzy-generate-parameter-library - - ros-jazzy-geometry-msgs - - ros-jazzy-hardware-interface - - ros-jazzy-kinematics-interface - - ros-jazzy-pluginlib - - ros-jazzy-rclcpp - - ros-jazzy-rclcpp-lifecycle - - ros-jazzy-realtime-tools - - ros-jazzy-ros-workspace - - ros-jazzy-tf2 - - ros-jazzy-tf2-eigen - - ros-jazzy-tf2-geometry-msgs - - ros-jazzy-tf2-kdl - - ros-jazzy-tf2-ros - - ros-jazzy-trajectory-msgs - - ros2-distro-mutex 0.14.* jazzy_* - - tinyxml2 - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - numpy >=1.23,<3 - - tinyxml2 >=11.0.0,<11.1.0a0 - - python_abi 3.12.* *_cp312 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-io >=0.27.3,<0.27.4.0a0 + size: 183828 + timestamp: 1784054860660 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.12.8-hd7ee1a1_1.conda + sha256: c79e62931e163b65a01786d5ed7156ecca2ab748b7c7835756d34e438035706a + md5: 4ac02fa15bf3809101e2eeb340b6078c + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-http >=0.11.0,<0.11.1.0a0 + - aws-checksums >=0.2.10,<0.2.11.0a0 + - aws-c-common >=0.14.2,<0.14.3.0a0 + - aws-c-cal >=0.9.14,<0.9.15.0a0 + - aws-c-auth >=0.10.4,<0.10.5.0a0 + - aws-c-io >=0.27.3,<0.27.4.0a0 license: Apache-2.0 - size: 425869 - timestamp: 1771189941612 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-2.5.5-np2py312h2ed9cc7_16.conda - sha256: 86d39bcd77b513620b09c20f7312dc70fbc9330d68e4c2faf6e4063f2cb4ff91 - md5: 33ef0274dc2e7f9a5df9071a4e415dd8 - depends: - - python - - ros-jazzy-ament-cmake-core - - ros-jazzy-ament-cmake-export-definitions - - ros-jazzy-ament-cmake-export-dependencies - - ros-jazzy-ament-cmake-export-include-directories - - ros-jazzy-ament-cmake-export-interfaces - - ros-jazzy-ament-cmake-export-libraries - - ros-jazzy-ament-cmake-export-link-flags - - ros-jazzy-ament-cmake-export-targets - - ros-jazzy-ament-cmake-gen-version-h - - ros-jazzy-ament-cmake-libraries - - ros-jazzy-ament-cmake-python - - ros-jazzy-ament-cmake-target-dependencies - - ros-jazzy-ament-cmake-test - - ros-jazzy-ament-cmake-version - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - cmake - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - numpy >=1.23,<3 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-s3 >=0.12.8,<0.12.9.0a0 + size: 146292 + timestamp: 1784101024241 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.7-h1da161f_2.conda + sha256: d5da00123d9ceb082e61fd5bf82fff9cd5bec0b8e1ae91454f29155a59499bf5 + md5: 882d834f12e0abf4c7a0e9bb0c72e281 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-common >=0.14.2,<0.14.3.0a0 license: Apache-2.0 - size: 23070 - timestamp: 1771181803403 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-auto-2.5.5-np2py312h2ed9cc7_16.conda - sha256: ca62d269434b7a45cc5f77d4c43c20c4528d7c4d682512aaeef0a6b054247083 - md5: 33d729a5e385fa4beadc4b8c739ca142 - depends: - - python - - ros-jazzy-ament-cmake - - ros-jazzy-ament-cmake-gmock - - ros-jazzy-ament-cmake-gtest - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-c-sdkutils >=0.2.7,<0.2.8.0a0 + size: 64723 + timestamp: 1784044301184 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.10-h1da161f_4.conda + sha256: 2227fa77f395f1b4699533709e7ef140a8292fccb31376ec5498565c7ad33225 + md5: a3c81085892f2983979836f2937291ce + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aws-c-common >=0.14.2,<0.14.3.0a0 license: Apache-2.0 - size: 27193 - timestamp: 1771181891347 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-copyright-0.17.4-np2py312h2ed9cc7_16.conda - sha256: 8e675aa31012e495edc5d384fc60706808d3c61ed3ed38d96bc3e46601e036a3 - md5: c93e829e07be2b722ee1ac9de30e1b44 + license_family: APACHE + purls: [] + run_exports: + weak: + - aws-checksums >=0.2.10,<0.2.11.0a0 + size: 117110 + timestamp: 1784044282001 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + run_exports: + weak: + - bzip2 >=1.0.8,<2.0a0 + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda + sha256: 9ee4ad706c5d3e1c6c469785d60e3c2b263eec569be0eac7be33fbaef978bccc + md5: 52ea1beba35b69852d210242dd20f97d depends: - - python - - ros-jazzy-ament-cmake-test - - ros-jazzy-ament-copyright - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - license: Apache-2.0 - size: 22507 - timestamp: 1771182141337 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-core-2.5.5-np2py312h2ed9cc7_16.conda - sha256: 1ba0ba9e288f0631ccfdece200cdf8784e38834b5074529ca8f330613b58875d - md5: e60e1669ce01c53eb9ebfabb0264ed84 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libglib >=2.86.3,<3.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.46.4,<1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only or MPL-1.1 + purls: [] + run_exports: + weak: + - cairo >=1.18.4,<2.0a0 + size: 1537783 + timestamp: 1766416059188 +- conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda + sha256: 2aa2083c9c186da7d6f975ccfbef654ed54fff27f4bc321dbcd12cee932ec2c4 + md5: ed2c27bda330e3f0ab41577cf8b9b585 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - dav1d >=1.2.1,<1.2.2.0a0 + size: 618643 + timestamp: 1685696352968 +- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda + sha256: 09e30a170e0da3e9847d449b594b5e55e6ae2852edd3a3680e05753a5e015605 + md5: 3d3caf4ccc6415023640af4b1b33060a depends: - - catkin_pkg - - python - - ros-jazzy-ament-package - - ros2-distro-mutex 0.14.* jazzy_* - - cmake - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - numpy >=1.23,<3 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - license: Apache-2.0 - size: 44761 - timestamp: 1771181255713 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-cppcheck-0.17.4-np2py312h2ed9cc7_16.conda - sha256: f2145fea7ff195212971388295cdd8b4cbb706da3c580e95b5f3b06cc2055e02 - md5: 03ace4f94dc129213d05e768553967ca + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - double-conversion >=3.4.0,<3.5.0a0 + size: 70943 + timestamp: 1765193243911 +- conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-8.1.2-gpl_he504192_904.conda + sha256: a31772d389fa14ca3eec690a4f07b8308116302392a48f6affab01cbcaa97e23 + md5: 9a9e4bdb63c2a32c82f97c168c9602a3 + depends: + - aom >=3.14.1,<3.15.0a0 + - bzip2 >=1.0.8,<2.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - fontconfig >=2.18.1,<3.0a0 + - fonts-conda-ecosystem + - lame >=4.0,<4.1.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libharfbuzz >=14.2.1 + - libiconv >=1.18,<2.0a0 + - libjxl >=0.12.0,<0.13.0a0 + - liblzma >=5.8.3,<6.0a0 + - libopus >=1.6.1,<2.0a0 + - librsvg >=2.62.3,<3.0a0 + - libvorbis >=1.3.7,<1.4.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - openh264 >=2.6.0,<2.6.1.0a0 + - openssl >=3.5.7,<4.0a0 + - sdl2 >=2.32.56,<3.0a0 + - shaderc >=2026.3,<2026.4.0a0 + - svt-av1 >=4.2.0,<4.2.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - x264 >=1!164.3095,<1!165 + - x265 >=3.5,<3.6.0a0 + constrains: + - __cuda >=12.8 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + run_exports: + weak: + - ffmpeg >=8.1.2,<9.0a0 + size: 11022986 + timestamp: 1784315529510 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.2-hd47e2ca_0.conda + sha256: 3263ba9ad9e78a927964c76e0b2b4c745d279394928f4d381272b771ec816235 + md5: 8a2cb80ec7f2a366dd53b48403844154 depends: - - python - - ros-jazzy-ament-cmake-core - - ros-jazzy-ament-cmake-test - - ros-jazzy-ament-cppcheck - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.12.* *_cp312 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - - numpy >=1.23,<3 - license: Apache-2.0 - size: 24257 - timestamp: 1771182320712 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-cpplint-0.17.4-np2py312h2ed9cc7_16.conda - sha256: f297fde71fad587e24b9ac919fd3078727826b3b81807f728b1a01d1642dc523 - md5: 31af3ac064c79441b3867deb76bb63a7 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - fontconfig >=2.18.2,<3.0a0 + - fonts-conda-ecosystem + size: 216273 + timestamp: 1784754573317 +- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_1.conda + sha256: a0e419e96146159f12344c870dca608d11bca36841f228092b986ffc2e1e0f02 + md5: e77293b32225b136a8be300f93d0e89f + depends: + - libfreetype 2.14.3 h57928b3_1 + - libfreetype6 2.14.3 hdbac1cb_1 + - zlib + license: GPL-2.0-only OR FTL + purls: [] + run_exports: + weak: + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + size: 185584 + timestamp: 1780934817461 +- conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda + sha256: 15011071ee56c216ffe276c8d734427f1f893f275ef733f728d13f610ed89e6e + md5: c27bd87e70f970010c1c6db104b88b18 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - fribidi >=1.0.16,<2.0a0 + size: 64394 + timestamp: 1757438741305 +- conda: https://conda.anaconda.org/conda-forge/win-64/gdk-pixbuf-2.44.7-h1f5b9c4_0.conda + sha256: 4965bf7c84c9b7c970f1f7bc475962e43441018cf9551682a4a22960c5090588 + md5: 5daba86dbe8072c7e49f74013ef308cd + depends: + - libglib >=2.88.2,<3.0a0 + - libintl >=0.22.5,<1.0a0 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - liblzma >=5.8.3,<6.0a0 + - libpng >=1.6.58,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + run_exports: + weak: + - gdk-pixbuf >=2.44.7,<3.0a0 + size: 579329 + timestamp: 1782591520147 +- conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.88.2-h395db07_0.conda + sha256: b67107959a71dbf9f5c2e95511f18095d9ac6f0001f0de4a1b6e14282162989e + md5: 7d203837b88a2255b32dca555d37ca50 depends: - - python - - ros-jazzy-ament-cmake-test - - ros-jazzy-ament-cpplint - - ros-jazzy-ros-workspace - - ros2-distro-mutex 0.14.* jazzy_* - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.12.* *_cp312 - - numpy >=1.23,<3 - - ros2-distro-mutex >=0.14.0,<0.15.0a0 - license: Apache-2.0 - size: 23122 - timestamp: 1771182344919 -- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-export-definitions-2.5.5-np2py312h2ed9cc7_16.conda - sha256: b82ea4e717ed6ef6832a5f3d5bb3a68142ca3f3ccba8800ccbdc43d07ab395a0 - md5: 376993cd9c67f43f31841d8fe0b31362 + - python * + - packaging + - libglib ==2.88.2 h7ce1215_0 + - glib-tools ==2.88.2 h74ecf4c_0 + - libintl-devel + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libintl >=0.22.5,<1.0a0 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - libglib >=2.88.2,<3.0a0 + size: 75973 + timestamp: 1782463965040 +- conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.88.2-h74ecf4c_0.conda + sha256: c604b6ca42c6271f281b1c0616e0d50bd800f8fc913a91a2753c2551b3b6b16c + md5: 63c615f0c525ee64f72e557e583b6257 + depends: + - libglib ==2.88.2 h7ce1215_0 + - libffi + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libintl >=0.22.5,<1.0a0 + license: LGPL-2.1-or-later + purls: [] + run_exports: {} + size: 251644 + timestamp: 1782463965040 +- conda: https://conda.anaconda.org/conda-forge/win-64/glslang-16.3.0-h294ba9c_0.conda + sha256: d80276b89d8aeab6ff0d8d7d4b9af336b368fc0b8fa28ea8cde6f6f2aa07bacf + md5: 7d6fed8a6ebeeebd6362790e22e56bb3 + depends: + - spirv-tools >=2026,<2027.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - glslang >=16,<17.0a0 + size: 5074630 + timestamp: 1777747167205 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-hac47afa_0.conda + sha256: 88b6601f8edae59834b59b521e293ff3b58361dc1603240f5a8328c24e6936ad + md5: ff9a9bfe791f56b0227597a7651a6af0 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + run_exports: + weak: + - graphite2 >=1.3.15,<2.0a0 + size: 97308 + timestamp: 1780454389458 +- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.2.1-h57928b3_1.conda + sha256: c8bf564f2c415b82f056eff98b8967fb75c86821398998f20289397b5acf1ef7 + md5: e706de885f817f9832c56f1c9ad7ce71 + depends: + - libharfbuzz-devel 14.2.1 h03b5201_1 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libharfbuzz >=14.2.1 + size: 11542 + timestamp: 1782801047786 +- conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-2.1.0-nompi_h0d3e4b2_110.conda + sha256: f6c79581d03d2e2e0cbbb0391d21a149a1f9c311159a9f74c6be8a79e2f696d9 + md5: 146134e4db96613ecdc63cf44bec847d + depends: + - aws-c-auth >=0.10.4,<0.10.5.0a0 + - aws-c-common >=0.14.2,<0.14.3.0a0 + - aws-c-http >=0.11.0,<0.11.1.0a0 + - aws-c-io >=0.27.3,<0.27.4.0a0 + - aws-c-s3 >=0.12.8,<0.12.9.0a0 + - aws-c-sdkutils >=0.2.7,<0.2.8.0a0 + - libaec >=1.1.5,<2.0a0 + - libcurl >=8.21.0,<9.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - hdf5 >=2.1.0,<3.0a0 + size: 2609470 + timestamp: 1784118471522 +- conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_1.conda + sha256: 61f16ae57ee8956d5c1f69e703f7abaebb972d0def1edc5704d7198430398295 + md5: e3232ea6dafd9f12663f860a3194d6dc + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - icu >=78.3,<79.0a0 + size: 14346784 + timestamp: 1784588850918 +- conda: https://conda.anaconda.org/conda-forge/win-64/imath-3.2.2-h1608b31_0.conda + sha256: 2aa57a5ed668ab34cc061b61082e3cee893d2e45ebc33f9432d13f7f292a990e + md5: 297d73cfad37a288459cf18286bb0e1f + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - imath >=3.2.2,<3.2.3.0a0 + size: 162099 + timestamp: 1759983547586 +- conda: https://conda.anaconda.org/conda-forge/win-64/khronos-opencl-icd-loader-2024.10.24-h2466b09_1.conda + sha256: 881f92399f706df1185ec4372e59c5c9832f2dbb8e7587c6030a2a9a6e8ce7f8 + md5: 71a72eb0eed16a4a76fd88359be48fec + depends: + - opencl-headers >=2024.10.24 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - khronos-opencl-icd-loader >=2024.10.24 + size: 46768 + timestamp: 1732916943523 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h719d79b_1.conda + sha256: c55745796e762ba9e817ab1fc0f21f1a049e202f90fa762df39578f37923f6c2 + md5: 00335c2c4a98656554771aaf6f1a7400 + depends: + - openssl >=3.5.7,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - krb5 >=1.22.2,<1.23.0a0 + size: 750320 + timestamp: 1781859644591 +- conda: https://conda.anaconda.org/conda-forge/win-64/lame-4.0-h4a41cd3_0.conda + sha256: ed10e660e52e7180cef2e2e90d912c21b8e84fed4f0bccf03dfd42a79b113846 + md5: fe5aa7c5c8c387db5fadce4d814a8d04 + depends: + - mpg123 >=1.32.9,<1.33.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.0-only + license_family: LGPL + purls: [] + run_exports: + weak: + - lame >=4.0,<4.1.0a0 + size: 357834 + timestamp: 1783769697203 +- conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_1.conda + sha256: 5ed63a32639a130564a870becb679fd52dfb816666a61ed3c023917389010480 + md5: 1df4012c8a2478699d07bc26af66d41e + depends: + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - lcms2 >=2.19.1,<3.0a0 + size: 523194 + timestamp: 1780211799997 +- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda + sha256: 45df58fca800b552b17c3914cc9ab0d55a82c5172d72b5c44a59c710c06c5473 + md5: 54b231d595bc1ff9bff668dd443ee012 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: + weak: + - lerc >=4.1.0,<5.0a0 + size: 172395 + timestamp: 1773113455582 +- conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20260526.0-cxx17_h0eb2380_1.conda + sha256: 103c3c49368204d26c1c4ac82cd29b6c39adf0492501b0145f6a853f0c600b3f + md5: 50a46018a50bb1feeb4496dc98deae5b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libabseil-static =20260526.0=cxx17* + - abseil-cpp =20260526.0 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: + weak: + - libabseil >=20260526.0,<20260527.0a0 + - libabseil =*=cxx17* + size: 2007071 + timestamp: 1780524734178 +- conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.5-haf901d7_0.conda + sha256: e54c08964262c73671d9e80e400333e59c617e0b454476ad68933c0c458156c8 + md5: 43b6385cfad52a7083f2c41984eb4e91 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libaec >=1.1.5,<2.0a0 + size: 34463 + timestamp: 1769221960556 +- conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.4.2-hdefa946_3.conda + sha256: 90ff61d555a4ebbd7ceff56ce02b727186a8f191741a2641814b0c3124a097c3 + md5: 90f8f8ee85e98e5867945cf009432714 + depends: + - _libavif_api >=1.4.2,<1.4.3.0a0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - aom >=3.14.1,<3.15.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - svt-av1 >=4.2.0,<4.2.1.0a0 + - rav1e >=0.8.1,<0.9.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libavif16 >=1.4.2,<2.0a0 + size: 124532 + timestamp: 1784120074651 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-8_h8455456_mkl.conda + build_number: 8 + sha256: 43a87b59e6d4c68d80b2e4de487b1b54d66fe1f9a06636909b5a5ab9eae27269 + md5: 4a0ce24b1a946ff77ae9eaa7ef015a33 + depends: + - mkl >=2026.0.0,<2027.0a0 + constrains: + - libcblas 3.11.0 8*_mkl + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + - liblapack 3.11.0 8*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libblas >=3.11.0,<4.0a0 + size: 68103 + timestamp: 1779859688049 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda + sha256: 5097303c2fc8ebf9f9ea9731520aa5ce4847d0be41764edd7f6dee2100b82986 + md5: 444b0a45bbd1cb24f82eedb56721b9c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libbrotlicommon >=1.2.0,<1.3.0a0 + size: 82042 + timestamp: 1764017799966 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda + sha256: 3239ce545cf1c32af6fffb7fc7c75cb1ef5b6ea8221c66c85416bb2d46f5cccb + md5: 450e3ae947fc46b60f1d8f8f318b40d4 + depends: + - libbrotlicommon 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libbrotlidec >=1.2.0,<1.3.0a0 + size: 34449 + timestamp: 1764017851337 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda + sha256: 3226df6b7df98734440739f75527d585d42ca2bfe912fbe8d1954c512f75341a + md5: ccd93cfa8e54fd9df4e83dbe55ff6e8c + depends: + - libbrotlicommon 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libbrotlienc >=1.2.0,<1.3.0a0 + size: 252903 + timestamp: 1764017901735 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-8_h2a3cdd5_mkl.conda + build_number: 8 + sha256: 2a5b6555b481df4603e44cba49a6ef727584fd2f3c5235dd4bcb3028fffbdfb5 + md5: 09f1d8e4d2675d34ad2acb115211d10c + depends: + - libblas 3.11.0 8_h8455456_mkl + constrains: + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + - liblapack 3.11.0 8*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libcblas >=3.11.0,<4.0a0 + size: 68443 + timestamp: 1779859701498 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.21.0-h51a1c48_2.conda + sha256: e9a9231e6c04b82979a6a1a4f90b8a697dc3a42884e709dee8ba5d0355b45296 + md5: 88c875a8f34785d6f6185ceb646154fa + depends: + - krb5 >=1.22.2,<1.23.0a0 + - libpsl >=0.22.0,<0.23.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + purls: [] + run_exports: + weak: + - libcurl >=8.21.0,<9.0a0 + size: 404786 + timestamp: 1782911887650 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + sha256: 834e4881a18b690d5ec36f44852facd38e13afe599e369be62d29bd675f107ee + md5: e77030e67343e28b084fabd7db0ce43e + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libdeflate >=1.25,<1.26.0a0 + size: 156818 + timestamp: 1761979842440 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + sha256: 1a54d874addda73b6f7164d5f3905821277a1831bcc05edd74b3085391688571 + md5: ccc490c81ffe14181861beac0e8f3169 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + purls: [] + run_exports: {} + size: 71631 + timestamp: 1781203724164 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libffi >=3.5.2,<3.6.0a0 + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_1.conda + sha256: 035d0c67bf9f7a16f4a1764f420c120f1a995d071bb265fcc66ef688ef709d7b + md5: e45b52fb9a81c9e2708465a706e05952 + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + run_exports: {} + size: 8711 + timestamp: 1780934891782 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_1.conda + sha256: 0bbd19c9f7c4d0232b31892e6a4d1f82b8d19d1b84d89725f1f491b336447758 + md5: 4e4d54f9f98383d977ba56ef39ebf46d + depends: + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + run_exports: {} + size: 340411 + timestamp: 1780934813224 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_19.conda + sha256: 80e80ef5e31b00b12539db3c5aaecde60dab91381abfc1060e323d5c3b016dce + md5: cc5d690fc1c629038f13c68e88e65f44 + depends: + - _openmp_mutex >=4.5 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + - libgcc-ng ==15.2.0=*_19 + - libgomp 15.2.0 h8ee18e1_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + run_exports: {} + size: 821854 + timestamp: 1778273037795 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.2-h7ce1215_0.conda + sha256: 20d4a182b8aa1d71b331579fae281bb3ccb1a199257ce15fadc53786031a7408 + md5: 5be116480ef34a5646894d7f7cd7ae41 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.2,<2.0a0 + - libiconv >=1.18,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libffi >=3.5.2,<3.6.0a0 + constrains: + - glib >2.66 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - libglib >=2.88.2,<3.0a0 + size: 4518265 + timestamp: 1782463965040 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_19.conda + sha256: 4dc958ced2fc7f42bc675b07e2c9abe3e150875ffdf62ca551d94fc6facf1fd7 + md5: f1147651e3fdd585e2f442c0c2fc8f2d + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + run_exports: + strong: + - _openmp_mutex >=4.5 + - libgomp >=15.2.0 + size: 664640 + timestamp: 1778272979661 +- conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-14.2.1-h03b5201_1.conda + sha256: 634a64cf43f1ce5a4139334bcdbde54d6854ae33d881ae1774377965e21051a5 + md5: 005469a341088900ca235892d3154c24 + depends: + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.15,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libglib >=2.88.2,<3.0a0 + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: {} + size: 1008194 + timestamp: 1782801000396 +- conda: https://conda.anaconda.org/conda-forge/win-64/libharfbuzz-devel-14.2.1-h03b5201_1.conda + sha256: d04bac65245bf76ae23a18148b941d8215085d38a6d391971966ccda8a996b99 + md5: de077ebf9cbc0c1da6510fdf1bbc6baa + depends: + - cairo >=1.18.4,<2.0a0 + - freetype + - glib + - graphite2 >=1.3.15,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libglib >=2.88.2,<3.0a0 + - libharfbuzz 14.2.1 h03b5201_1 + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libharfbuzz >=14.2.1 + size: 321750 + timestamp: 1782801035822 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + sha256: 2ee12e37223dfcd0acd050c80a91150c482b6e2899198521e1800dce66662467 + md5: 6a01c986e30292c715038d2788aa1385 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - libxml2 + - libxml2-16 >=2.14.6 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libhwloc >=2.13.0,<2.13.1.0a0 + size: 2396128 + timestamp: 1770954127918 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwy-1.4.0-h2419aca_0.conda + sha256: ade3e4e8e09051bad9c75ea9e96b09e3c635216c409c87c369e6f8566a528cb1 + md5: 430378e206cf5a148fc8da7603b2466e + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 OR BSD-3-Clause + purls: [] + run_exports: + weak: + - libhwy >=1.4.0,<1.5.0a0 + size: 564121 + timestamp: 1784325614001 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 + md5: 64571d1dd6cdcfa25d0664a5950fdaa2 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only + purls: [] + run_exports: + weak: + - libiconv >=1.18,<2.0a0 + size: 696926 + timestamp: 1754909290005 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + sha256: c7e4600f28bcada8ea81456a6530c2329312519efcf0c886030ada38976b0511 + md5: 2cf0cf76cc15d360dfa2f17fd6cf9772 + depends: + - libiconv >=1.17,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - libintl >=0.22.5,<1.0a0 + size: 95568 + timestamp: 1723629479451 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-devel-0.22.5-h5728263_3.conda + sha256: be1f3c48bc750bca7e68955d57180dfd826d6f9fa7eb32994f6cb61b813f9a6a + md5: 7537784e9e35399234d4007f45cdb744 + depends: + - libiconv >=1.17,<2.0a0 + - libintl 0.22.5 h5728263_3 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - libintl >=0.22.5,<1.0a0 + size: 40746 + timestamp: 1723629745649 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.2.0-hfd05255_0.conda + sha256: 3d6635efa9497b9c5ba7957df8067c0a980d5cb10a6ea136931809eb410f8a99 + md5: cf219146d5bf2fee5907409ff9f5ac89 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + run_exports: + weak: + - libjpeg-turbo >=3.2.0,<4.0a0 + size: 991057 + timestamp: 1783731990693 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjxl-0.12.0-h932607e_1.conda + sha256: 141310ec747808be57ba9e7501fcfab75b260803233dd9ba818fb85f6080aad9 + md5: adb20d060513fe9655d28a780bafafaa + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libhwy >=1.4.0,<1.5.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libjxl >=0.12.0,<0.13.0a0 + size: 1199695 + timestamp: 1783146089449 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-8_hf9ab0e9_mkl.conda + build_number: 8 + sha256: 44999ed04bc0a56de44ee0ac8bd5b3702efd411a8b29491c0e3d3deb8619c94e + md5: d584799b920ecae9b75a2b70743a3de7 + depends: + - libblas 3.11.0 8_h8455456_mkl + constrains: + - libcblas 3.11.0 8*_mkl + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - liblapack >=3.11.0,<3.12.0a0 + size: 81027 + timestamp: 1779859714698 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-8_h3ae206f_mkl.conda + build_number: 8 + sha256: bfe3d2f84bb17de0543a505b054e993c607cdf5508e1b47f88fb38e42b0426aa + md5: e4039fcb8a1690441bb7f63fb50b7b9a + depends: + - libblas 3.11.0 8_h8455456_mkl + - libcblas 3.11.0 8_h2a3cdd5_mkl + - liblapack 3.11.0 8_hf9ab0e9_mkl + constrains: + - blas 2.308 mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - liblapacke >=3.11.0,<3.12.0a0 + size: 85017 + timestamp: 1779859728005 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 + md5: 8f83619ab1588b98dd99c90b0bfc5c6d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + run_exports: + weak: + - liblzma >=5.8.3,<6.0a0 + size: 106486 + timestamp: 1775825663227 +- conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.5-h2466b09_1.conda + sha256: c63e5fb169dbd192aacdcee6e37235407f106b8ca9c9036942a25e0366cbc73c + md5: b67ed8c9ca072695ff482e50d888a523 + depends: + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - ucrt >=10.0.20348.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libogg >=1.3.5,<1.4.0a0 + size: 35040 + timestamp: 1745826086628 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopencv-4.13.0-qt6_hfadb9d5_614.conda + sha256: d555ce690c29957f10e1a767fa8f43b4c4af9c1bf1e7c67230b85701f73c08f6 + md5: 31a0f6b84fcccbdb132b452b932f436d + depends: + - ffmpeg >=8.1.2,<9.0a0 + - hdf5 >=2.1.0,<3.0a0 + - imath >=3.2.2,<3.2.3.0a0 + - libavif16 >=1.4.2,<2.0a0 + - libcblas >=3.9.0,<4.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libharfbuzz >=14.2.1 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - libjxl >=0.12,<0.13.0a0 + - liblapack >=3.9.0,<4.0a0 + - liblapacke >=3.9.0,<4.0a0 + - libopenvino >=2026.2.1,<2026.2.2.0a0 + - libopenvino-auto-batch-plugin >=2026.2.1,<2026.2.2.0a0 + - libopenvino-auto-plugin >=2026.2.1,<2026.2.2.0a0 + - libopenvino-hetero-plugin >=2026.2.1,<2026.2.2.0a0 + - libopenvino-intel-cpu-plugin >=2026.2.1,<2026.2.2.0a0 + - libopenvino-intel-gpu-plugin >=2026.2.1,<2026.2.2.0a0 + - libopenvino-ir-frontend >=2026.2.1,<2026.2.2.0a0 + - libopenvino-onnx-frontend >=2026.2.1,<2026.2.2.0a0 + - libopenvino-paddle-frontend >=2026.2.1,<2026.2.2.0a0 + - libopenvino-pytorch-frontend >=2026.2.1,<2026.2.2.0a0 + - libopenvino-tensorflow-frontend >=2026.2.1,<2026.2.2.0a0 + - libopenvino-tensorflow-lite-frontend >=2026.2.1,<2026.2.2.0a0 + - libpng >=1.6.58,<1.7.0a0 + - libprotobuf >=7.35.1,<7.35.2.0a0 + - libtiff >=4.7.2,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openexr >=3.4.13,<3.5.0a0 + - openjpeg >=2.5.4,<3.0a0 + - qt6-main >=6.11.1,<7.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: + weak: + - libopencv >=4.13.0,<4.13.1.0a0 + size: 33332328 + timestamp: 1783116309049 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-2026.2.1-h2f25fdd_1.conda + sha256: 586252ae61818837803eb82f628014bdf497a56abe0133b5e9ecb4eb2c88cdf9 + md5: eaade10e055e55ba7095fc623adcf699 + depends: + - pugixml >=1.15,<1.16.0a0 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino >=2026.2.1,<2026.2.2.0a0 + size: 3935555 + timestamp: 1782213197990 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-auto-batch-plugin-2026.2.1-hd74cc32_1.conda + sha256: fe66608a9f0d6dd420fe7b91c8bd39f01325fef0025c43d400377c698f06cdb5 + md5: 8db2fd70d1d72c02d481226d873b70a4 + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 103555 + timestamp: 1782213215380 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-auto-plugin-2026.2.1-hd74cc32_1.conda + sha256: 2175dfd4626b875cc88bde976adf4f3a20793bab40501fdbcaf2fee45810b492 + md5: f155c46d777888acccabc16b964876ff + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 204472 + timestamp: 1782213226912 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-hetero-plugin-2026.2.1-hc39e7c6_1.conda + sha256: cc6f6a65e726b00ea083bc2af6cec9460ff802f13adf01d80ad72fc9c9030f44 + md5: 6af1627b2bd941e21f8cf32c11c74b4a + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - pugixml >=1.15,<1.16.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 175241 + timestamp: 1782213239501 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-intel-cpu-plugin-2026.2.1-h2f25fdd_1.conda + sha256: 9ca7c0df99374c9c6903e154f29d22d95d6015d92f5cb8d61b721c5696484113 + md5: 6e3ef8c568471e83dfc598cff9456a37 + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 8524394 + timestamp: 1782213252510 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-intel-gpu-plugin-2026.2.1-h2f25fdd_1.conda + sha256: e4bd931ef1d3f5ce9722a89f782dd41569e42c8d14d2f4c139e0cba329301333 + md5: a7075689ede1d7ea5d7bb8e6e6560191 + depends: + - khronos-opencl-icd-loader >=2024.10.24 + - libopenvino 2026.2.1 h2f25fdd_1 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 9014907 + timestamp: 1782213282076 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-ir-frontend-2026.2.1-hc39e7c6_1.conda + sha256: 75fc2f30281256106e5b0dd15857f264b7aa16eb516826111ee4924c3342750c + md5: 5a6c6faa1972aad71712ec1d3edce829 + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - pugixml >=1.15,<1.16.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-ir-frontend >=2026.2.1,<2026.2.2.0a0 + size: 174784 + timestamp: 1782213308377 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-onnx-frontend-2026.2.1-hb13cd65_1.conda + sha256: ef41e5e82cf8724babc4900db024c4f2d2a2c24845a0cc3d422304d9b413b116 + md5: f35aaa38fbe2478e44106ba1e2f1da64 + depends: + - libabseil * cxx17* + - libabseil >=20260526.0,<20260527.0a0 + - libopenvino 2026.2.1 h2f25fdd_1 + - libprotobuf >=7.35.1,<7.35.2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-onnx-frontend >=2026.2.1,<2026.2.2.0a0 + size: 1231814 + timestamp: 1782213320811 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-paddle-frontend-2026.2.1-hb13cd65_1.conda + sha256: fc20e15b77ee191bba53d7ede5a802f827a152f5f91214b9d909cc8c247b8bba + md5: fabb1a5bcc8271743ae9d1e77c2c35e4 + depends: + - libabseil * cxx17* + - libabseil >=20260526.0,<20260527.0a0 + - libopenvino 2026.2.1 h2f25fdd_1 + - libprotobuf >=7.35.1,<7.35.2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-paddle-frontend >=2026.2.1,<2026.2.2.0a0 + size: 426081 + timestamp: 1782213333773 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-pytorch-frontend-2026.2.1-hac47afa_1.conda + sha256: 44fb6a76eddafcef8cfe1298e74ba6a1afee268ed3e70d0ab24a77060623effe + md5: 07fe27c3e82be1c64ae9c1ed3c5e5eeb + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-pytorch-frontend >=2026.2.1,<2026.2.2.0a0 + size: 726880 + timestamp: 1782213345854 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-tensorflow-frontend-2026.2.1-ha992cae_1.conda + sha256: 8cae679a9a330ddfc197eeea16a524b648e7fb470d52ee2a63dc9a392f785826 + md5: 79de3c7fbf2e17a2f638eca0e19697bd + depends: + - libabseil * cxx17* + - libabseil >=20260526.0,<20260527.0a0 + - libopenvino 2026.2.1 h2f25fdd_1 + - libprotobuf >=7.35.1,<7.35.2.0a0 + - snappy >=1.2.2,<1.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-tensorflow-frontend >=2026.2.1,<2026.2.2.0a0 + size: 867198 + timestamp: 1782213359873 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopenvino-tensorflow-lite-frontend-2026.2.1-hac47afa_1.conda + sha256: e13a390f51f82c4d78875807e6b8eed21670e5db910cc4f08fd0c7d7798762e6 + md5: 015c77ae26c3578103a21140c2ed2f5a + depends: + - libopenvino 2026.2.1 h2f25fdd_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - libopenvino-tensorflow-lite-frontend >=2026.2.1,<2026.2.2.0a0 + size: 348751 + timestamp: 1782213370892 +- conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.6.1-h6a83c73_0.conda + sha256: c3678f111866235b44fa65265966abae7d90b6387178f1459afaedcee8b4a997 + md5: 0ed21da5b6e3a0393e05762b3cce2878 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libopus >=1.6.1,<2.0a0 + size: 307373 + timestamp: 1768497136248 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-h7351971_0.conda + sha256: 218913aeee391460bd0e341b834dbd9c6fa6ae0a4276c0c300266cc99a816a28 + md5: 52f1280563f3b48b5f75414cd2d15dd1 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + purls: [] + run_exports: + weak: + - libpng >=1.6.58,<1.7.0a0 + size: 385227 + timestamp: 1776315248638 +- conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-7.35.1-h1a71995_2.conda + sha256: 0901c04727c76556a0afb1bf3f32e4ba9f4f8b50e8a6f96d02085f47875b70e0 + md5: 86341febfb82a8beb84058167f41c3d5 + depends: + - libabseil * cxx17* + - libabseil >=20260526.0,<20260527.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libprotobuf >=7.35.1,<7.35.2.0a0 + size: 7373575 + timestamp: 1783170105520 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpsl-0.22.0-h25e0afd_1.conda + sha256: 040d4adabae2634b13183203e383c21f74ed98028b5d50bf9bae4968dd05aaa5 + md5: ba200e33e10ccf0d730c4ce87badbdf1 + depends: + - icu >=78.3,<79.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libpsl >=0.22.0,<0.23.0a0 + size: 72405 + timestamp: 1783937048984 +- conda: https://conda.anaconda.org/conda-forge/win-64/librsvg-2.62.3-h15cfe45_0.conda + sha256: 6f678be6074b79fe754660d16857a6edba73dd197ad92086250dc38c11b179ab + md5: 3fffc63af7b943cde57aa72f5ffe6048 + depends: + - cairo >=1.18.4,<2.0a0 + - gdk-pixbuf >=2.44.6,<3.0a0 + - harfbuzz >=14.2.0 + - libglib >=2.88.1,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - librsvg >=2.62.3,<3.0a0 + size: 3361405 + timestamp: 1780451179155 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.3-hf5d6505_0.conda + sha256: 692dfb73a22c873656d5e393b8f1e2b019a3c8a6486c97cb6900552e64e38c25 + md5: 051f1b2228e7517a2ef8cca5146c8967 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + run_exports: + weak: + - libsqlite >=3.53.3,<4.0a0 + size: 1315909 + timestamp: 1782519131898 +- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 + md5: 9dce2f112bfd3400f4f432b3d0ac07b2 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libssh2 >=1.11.1,<2.0a0 + size: 292785 + timestamp: 1745608759342 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.2-h8f73337_0.conda + sha256: ec6d66308a6d6abaf3225f2f185113e6172e77eb0fa8622af982d7a5d6d47a2c + md5: e83f459471905a04ebe15e21d063c49d + depends: + - lerc >=4.1.0,<5.0a0 + - libdeflate >=1.25,<1.26.0a0 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + purls: [] + run_exports: + weak: + - libtiff >=4.7.2,<4.8.0a0 + size: 1014598 + timestamp: 1783085017197 +- conda: https://conda.anaconda.org/conda-forge/win-64/libusb-1.0.29-h1839187_0.conda + sha256: 9837f8e8de20b6c9c033561cd33b4554cd551b217e3b8d2862b353ed2c23d8b8 + md5: a656b2c367405cd24988cf67ff2675aa + depends: + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - ucrt >=10.0.20348.0 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - libusb >=1.0.29,<2.0a0 + size: 118204 + timestamp: 1748856290542 +- conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h5112557_2.conda + sha256: 429124709c73b2e8fae5570bdc6b42f5418a7551ba72e591bb960b752e87b365 + md5: 42a8a56c60882da5d451aa95b8455111 + depends: + - libogg + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libogg >=1.3.5,<1.4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libvorbis >=1.3.7,<1.4.0a0 + size: 243401 + timestamp: 1753879416570 +- conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.350.1-h477610d_0.conda + sha256: c367888506e54422fd1f703fcdaa96d0a033a5a19699e044ffdc36bf93dcde7e + md5: 9cacbf81324479c89f59afcbf93043ee + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + constrains: + - libvulkan-headers 1.4.350.1.* + license: Apache-2.0 + purls: [] + run_exports: + weak: + - libvulkan-loader >=1.4.350.1,<2.0a0 + size: 284503 + timestamp: 1784860741032 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + sha256: 7b6316abfea1007e100922760e9b8c820d6fc19df3f42fb5aca684cfacb31843 + md5: f9bbae5e2537e3b06e0f7310ba76c893 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - libwebp-base >=1.6.0,<2.0a0 + size: 279176 + timestamp: 1752159543911 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0 + md5: 8a86073cf3b343b87d03f41790d8b4e5 + depends: + - ucrt + constrains: + - pthreads-win32 <0.0a0 + - msys2-conda-epoch <0.0a0 + license: MIT AND BSD-3-Clause-Clear + purls: [] + run_exports: {} + size: 36621 + timestamp: 1759768399557 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + sha256: 08dec73df0e161c96765468847298a420933a36bc4f09b50e062df8793290737 + md5: a69bbf778a462da324489976c84cfc8c + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - pthread-stubs + - ucrt >=10.0.20348.0 + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libxcb >=1.17.0,<2.0a0 + size: 1208687 + timestamp: 1727279378819 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_0.conda + sha256: 3b61ee3caba702d2ff432fa3920835db963026e5c99c4e6fdca0c6114f59e7ce + md5: 9e8dd0d90ed830107b2c36801035b7db + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libxml2 2.15.3 + license: MIT + license_family: MIT + purls: [] + run_exports: {} + size: 519871 + timestamp: 1776376969852 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda + sha256: a4599c6bbbbdd7db570896e520c557eec8e66d94e839a59d17dc1f24a3d5f82b + md5: 95591ca5671d2213f5b2d5aa7818420d + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h3cfd58e_0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - libxml2 + - libxml2-16 >=2.15.3 + size: 43684 + timestamp: 1776376992865 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 + md5: dbabbd6234dea34040e631f87676292f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 58347 + timestamp: 1774072851498 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.8-h4fa8253_0.conda + sha256: 50c02902bb516eeb56680358f052be38b5bf74b40e78ea4b2a675e84957e7307 + md5: de3551bf6508d45ca46b714639e52823 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - openmp 22.1.8|22.1.8.* + - intel-openmp <0.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + run_exports: + strong: + - llvm-openmp >=22.1.8 + size: 348002 + timestamp: 1781737042070 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.1.0-hac47afa_233.conda + sha256: ff355522fb0b6e33841167d9ca749147c8734d8be07b63b2ce25b0db043f42ed + md5: 5afbf28c4ca3e05b5469dbbd78c8e704 + depends: + - llvm-openmp >=22.1.8 + - onemkl-license 2026.1.0 h57928b3_233 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + run_exports: {} + size: 114592547 + timestamp: 1783700769546 +- conda: https://conda.anaconda.org/conda-forge/win-64/mpg123-1.32.9-h01009b0_0.conda + sha256: a1d7d25f2c448f5c47d1678cca1f6ae5deadb38e176ea0c76ea5c688589dfd7a + md5: 1ed1580d4211223b285787eff05560f9 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-only + license_family: LGPL + purls: [] + run_exports: + weak: + - mpg123 >=1.32.9,<1.33.0a0 + size: 274386 + timestamp: 1730581654395 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.5.1-py312ha3f287d_0.conda + sha256: e9df7b016c6910a9d4b1894e53499de79a871292e2f88f338070f0fa0080fcaa + md5: 8ae08a63662c4b2d46af3f2917e749b4 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - liblapack >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - python_abi 3.12.* *_cp312 + - libblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=compressed-mapping + run_exports: + weak: + - numpy >=1.25,<3 + size: 7301536 + timestamp: 1783206237609 +- conda: https://conda.anaconda.org/conda-forge/win-64/onemkl-license-2026.1.0-h57928b3_233.conda + sha256: 96dec1c878d6e6f835be8ed57152a37be9a5104ac79c2425815d71c64cf13ee4 + md5: 1566e2ce8c3bc23a2feb866c4d9e91e3 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + run_exports: {} + size: 53362 + timestamp: 1783700628723 +- conda: https://conda.anaconda.org/conda-forge/win-64/opencl-headers-2025.06.13-h826ebb9_0.conda + sha256: 3acfdfe4b914a9fd8c950da6c13cfe563896744709eb5c4c7a926919c3e0b630 + md5: 77af5a2fabd1c8c3eb9e0a7b3d5afc22 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 56082 + timestamp: 1773844547434 +- conda: https://conda.anaconda.org/conda-forge/win-64/opencv-4.13.0-qt6_he7afa43_614.conda + noarch: python + sha256: 96c97469f9db7982c70fa4867330a55a2da6896fdde7910e4d2f784b4e0aec6d + md5: 156f966086f9d8f319e739d93ad0c3df + depends: + - libopencv 4.13.0 qt6_hfadb9d5_614 + - py-opencv 4.13.0 qt6_hd26e59d_614 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: {} + size: 31395 + timestamp: 1783116448993 +- conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.4.13-hd20f895_1.conda + sha256: a00088687b2eb0c22041be2e74fa3222c44b42667415e10e8312365a245d061c + md5: cb83fa215048c5da5dc8a14c7fe37485 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - imath >=3.2.2,<3.2.3.0a0 + - libdeflate >=1.25,<1.26.0a0 + - openjph >=0.30.1,<0.31.0a0 + - libzlib >=1.3.2,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - openexr >=3.4.13,<3.5.0a0 + size: 949849 + timestamp: 1782198449274 +- conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.6.0-h1eab103_1.conda + sha256: 8d7e4a2dcd68afcc87c1e875a19600d980ca8f792f00105a622efd5faed6b05a + md5: 91c186a483e5491170156399b2850804 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - openh264 >=2.6.0,<2.6.1.0a0 + size: 422904 + timestamp: 1782686043511 +- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda + sha256: 24342dee891a49a9ba92e2018ec0bde56cc07fdaec95275f7a55b96f03ea4252 + md5: e723ab7cc2794c954e1b22fde51c16e4 + depends: + - libpng >=1.6.55,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - openjpeg >=2.5.4,<3.0a0 + size: 245594 + timestamp: 1772624841727 +- conda: https://conda.anaconda.org/conda-forge/win-64/openjph-0.30.1-hf13a347_0.conda + sha256: 5deaf995e476e6928dedced3254025b568a70a905f04ad23fd150d9abe558b91 + md5: 47ed976bdc702ab527737d6dc0d7e6d7 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libtiff >=4.7.1,<4.8.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - openjph >=0.30.1,<0.31.0a0 + size: 226246 + timestamp: 1782091209917 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.3-hf411b9b_0.conda + sha256: cb6e7ba0d010ee0d3249ce9886de3d7613d26d9965d4c95666fa66b9c4c31001 + md5: e99f95734a326c0fd4d02bbd995150d4 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: + weak: + - openssl >=3.6.3,<4.0a0 + size: 9414790 + timestamp: 1781071745579 +- conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + sha256: 3d4e6e541e633f6fd22fc2c1d79ad5ec39503dea3ba04fc3e01d5be904ec7cea + md5: 1f1cf3772ba7d4eef989e4679ddf97f7 + depends: + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-or-later + purls: [] + run_exports: + weak: + - pango >=1.56.4,<2.0a0 + size: 454919 + timestamp: 1774282149607 +- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda + sha256: 3e9e02174edf02cb4bcdd75668ad7b74b8061791a3bc8bdb8a52ae336761ba3e + md5: 77eaf2336f3ae749e712f63e36b0f0a1 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 + size: 995992 + timestamp: 1763655708300 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.3.0-py312h31f0997_0.conda + sha256: 19e982ab2e3e43ca1506bd34ce516fd309d78068692e4770a1bb59cbda2d2710 + md5: 7e163dfd8d118658c0ca0ebffe80ad7d + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - openjpeg >=2.5.4,<3.0a0 + - python_abi 3.12.* *_cp312 + - libxcb >=1.17.0,<2.0a0 + - lcms2 >=2.19.1,<3.0a0 + - zlib-ng >=2.3.3,<2.4.0a0 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + license: HPND + purls: + - pkg:pypi/pillow?source=compressed-mapping + run_exports: {} + size: 949403 + timestamp: 1782912129930 +- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_2.conda + sha256: f37fb21952bd4297f8c7d78e2f256647da2b4ad4e1df097d49ebff8a40275cab + md5: df8da7fe89bdc91b880df69a8eb1c37b + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - pixman >=0.46.4,<1.0a0 + size: 257105 + timestamp: 1784286884376 +- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + sha256: 7e446bafb4d692792310ed022fe284e848c6a868c861655a92435af7368bae7b + md5: 3c8f2573569bb816483e5cf57efbbe29 + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + run_exports: {} + size: 9389 + timestamp: 1726802555076 +- conda: https://conda.anaconda.org/conda-forge/win-64/pugixml-1.15-h372dad0_0.conda + sha256: 97b34ed73b6f559fcf5e706d4c8435923ba95cfed478d3fd50b475f94f60dc6e + md5: cadea4c6edb512e979edbf793bf979ac + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - pugixml >=1.15,<1.16.0a0 + size: 113967 + timestamp: 1736601565527 +- conda: https://conda.anaconda.org/conda-forge/win-64/py-opencv-4.13.0-qt6_hd26e59d_614.conda + noarch: python + sha256: 509b1cb54d808ac4bdd26feffdc7f686e7f0c0d3e20bf4e9efc482f9c542937d + md5: d11e95631daddf0be23fc431828f7cf8 + depends: + - _python_abi3_support 1.* + - cpython >=3.10 + - libopencv 4.13.0 qt6_hfadb9d5_614 + - numpy >=1.21,<3 + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/opencv-python?source=hash-mapping + - pkg:pypi/opencv-python-headless?source=hash-mapping + run_exports: + weak: + - py-opencv >=4.13.0,<5.0a0 + size: 2980515 + timestamp: 1783116442646 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.13-h0159041_0_cpython.conda + sha256: a02b446d8b7b167b61733a3de3be5de1342250403e72a63b18dac89e99e6180e + md5: 2956dff38eb9f8332ad4caeba941cfe7 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - python_abi 3.12.* *_cp312 + license: Python-2.0 + purls: [] + run_exports: + weak: + - python_abi 3.12.* *_cp312 + noarch: + - python + size: 15840187 + timestamp: 1772728877265 +- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.1-pl5321hfcac499_1.conda + sha256: c0f0552a879e18282799431c7d2769b269839ac3b3735082e754df3c6fa0728d + md5: a8d735f3faf356a24acf9eea0a940a0f + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - krb5 >=1.22.2,<1.23.0a0 + - libglib >=2.88.1,<3.0a0 + - libpng >=1.6.58,<1.7.0a0 + - double-conversion >=3.4.0,<3.5.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - icu >=78.3,<79.0a0 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libsqlite >=3.53.1,<4.0a0 + - harfbuzz >=14.2.0 + constrains: + - qt ==6.11.1 + license: LGPL-3.0-only + license_family: LGPL + purls: [] + run_exports: + weak: + - qt6-main >=6.11.1,<7.0a0 + size: 89576886 + timestamp: 1780400596481 +- conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.8.1-h007690e_0.conda + sha256: 4ee3caf1260c946e756f2be4cadf720592391b24fce652a67255e4386880249b + md5: b0ab2fc43381024f5a694e6f5f54c973 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - rav1e >=0.8.1,<0.9.0a0 + size: 4386341 + timestamp: 1772541112444 +- conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.18.0-py312h9b3c559_0.conda + sha256: 68e7c49be1e409ed2ac44f2977581d58a9a4d12e6724a4a5c5470348e5e40f34 + md5: e1fee578f6c533ff532693143919afde + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.7 + - numpy >=1.23,<3 + - numpy >=2.0.0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: {} + size: 15077907 + timestamp: 1781914327034 +- conda: https://conda.anaconda.org/conda-forge/win-64/sdl2-2.32.56-h5112557_0.conda + sha256: d17da21386bdbf32bce5daba5142916feb95eed63ef92b285808c765705bbfd2 + md5: 4cffbfebb6614a1bff3fc666527c25c7 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - sdl3 >=3.2.22,<4.0a0 + license: Zlib + purls: [] + run_exports: + weak: + - sdl2 >=2.32.56,<3.0a0 + size: 572101 + timestamp: 1757842925694 +- conda: https://conda.anaconda.org/conda-forge/win-64/sdl3-3.4.12-h5112557_0.conda + sha256: cd70a95559fdcaa9809d7c697b1d2e283c2d61eb184f91f7b03f8c2291e206a8 + md5: 5f80121d90de6623ae8e0eee34da16ff + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libusb >=1.0.29,<2.0a0 + license: Zlib + purls: [] + run_exports: + weak: + - sdl3 >=3.4.12,<4.0a0 + size: 1680362 + timestamp: 1782948074728 +- conda: https://conda.anaconda.org/conda-forge/win-64/shaderc-2026.3-hbcac29b_0.conda + sha256: ae69be2f9a0828e35397b4c0d25bad3eb9b395535bc635154e872a6fd5b440aa + md5: 77b44ad4a137a273aeff5962764cfa58 + depends: + - glslang >=16,<17.0a0 + - spirv-tools >=2026,<2027.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + run_exports: + weak: + - shaderc >=2026.3,<2026.4.0a0 + size: 1600332 + timestamp: 1784251308130 +- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + sha256: d2deda1350abf8c05978b73cf7fe9147dd5c7f2f9b312692d1b98e52efad53c3 + md5: 3075846de68f942150069d4289aaad63 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - snappy >=1.2.2,<1.3.0a0 + size: 67417 + timestamp: 1762948090450 +- conda: https://conda.anaconda.org/conda-forge/win-64/spirv-tools-2026.2-h49e36cd_1.conda + sha256: 30a87a710c1deed93371e6ff365ebd3b578aeefad68cc89bedff85ffb2fea9d2 + md5: 5a929a4b1f6c82d05f0a1283d4a14e45 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - spirv-headers >=1.4.350.1,<1.4.350.2.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: + weak: + - spirv-tools >=2026,<2027.0a0 + size: 14643364 + timestamp: 1784384374991 +- conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.2.0-hac47afa_0.conda + sha256: 6dc6ed0e651e99d03ae25b6a358064247c96b1cb436fdbf973ab25c1c6aedcd4 + md5: c49fb5bcbd2f2537875e4b2f62c0de3b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - svt-av1 >=4.2.0,<4.2.1.0a0 + size: 1833926 + timestamp: 1784070033860 +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + sha256: 8a4053839b8e997a5965e2dff7d6cf3c77be62d82c0e48c8a04a5ed2d2e73035 + md5: 8ee01a693aecff5432069eaaf1183c45 + depends: + - libhwloc >=2.13.0,<2.13.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + run_exports: {} + size: 156515 + timestamp: 1778673901757 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_3.conda + sha256: 13fa29257d43f8e630a1e591ed77fae9bbbb236b011432f01e2034cf36e6bf03 + md5: aaf79e2af50a151fb5b5a3e3f38b7a69 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: TCL + purls: [] + run_exports: + weak: + - tk >=8.6.13,<8.7.0a0 + size: 3782314 + timestamp: 1784229072899 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + purls: [] + run_exports: {} + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-h1b7c187_39.conda + sha256: 17693b60cb54f80c60275f003f3bfc1b128af56dbfd65c4fae37c64eeb755ce1 + md5: 2eacea63f545b97342da520df6854276 + depends: + - vc14_runtime >=14.51.36231 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: {} + size: 20362 + timestamp: 1781320968457 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_39.conda + sha256: 8153ed849c92e891eacac0f2f8d7ecb79f9b5fd7f7917fbb896f252a60a40390 + md5: 06a5bf5a1ca16cce0df6eaa91fc42bc2 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.51.36231 h1b9f54f_39 + constrains: + - vs2015_runtime 14.51.36231.* *_39 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + run_exports: {} + size: 737434 + timestamp: 1781320964561 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_39.conda + sha256: 07fb14713c4bc62e2533a2e23a363abfb0e65650681fba0ae4c840e2219350f3 + md5: 8b53a83fda40ec679e4d63fa32fae989 + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.51.36231.* *_39 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + run_exports: + strong: + - vcomp14 >=14.51.36231 + size: 120684 + timestamp: 1781320948530 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.51.36231-h84cd919_39.conda + sha256: 6de6c2cf008fc2dce61060b583f2d8494c83883106952b201381b6b0505f03d7 + md5: 2ccc63d7b7d066a814ed9f99072832d7 + depends: + - vc14_runtime >=14.51.36231 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: {} + size: 20355 + timestamp: 1781320968804 +- conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 + sha256: 97166b318f8c68ffe4d50b2f4bd36e415219eeaef233e7d41c54244dc6108249 + md5: 19e39905184459760ccb8cf5c75f148b + depends: + - vc >=14.1,<15 + - vs2015_runtime >=14.16.27033 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + run_exports: + weak: + - x264 >=1!164.3095,<1!165 + size: 1041889 + timestamp: 1660323726084 +- conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 + sha256: 02b9874049112f2b7335c9a3e880ac05d99a08d9a98160c5a98898b2b3ac42b2 + md5: ca7129a334198f08347fb19ac98a2de9 + depends: + - vc >=14.1,<15 + - vs2015_runtime >=14.16.27033 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + run_exports: + weak: + - x265 >=3.5,<3.6.0a0 + size: 5517425 + timestamp: 1646611941216 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + sha256: 156a583fa43609507146de1c4926172286d92458c307bb90871579601f6bc568 + md5: 8436cab9a76015dfe7208d3c9f97c156 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - xorg-libxau >=1.0.12,<2.0a0 + size: 109246 + timestamp: 1762977105140 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + sha256: 366b8ae202c3b48958f0b8784bbfdc37243d3ee1b1cd4b8e76c10abe41fa258b + md5: a7c03e38aa9c0e84d41881b9236eacfb + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + run_exports: + weak: + - xorg-libxdmcp >=1.1.5,<2.0a0 + size: 70691 + timestamp: 1762977015220 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + sha256: ef408f85f664a4b9c9dac3cb2e36154d9baa15a88984ea800e11060e0f2394a1 + md5: 5187ecf958be3c39110fe691cbd6873e + depends: + - libzlib 1.3.2 hfd05255_2 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 850351 + timestamp: 1774072891049 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda + sha256: 71332532332d13b5dbe57074ddcf82ae711bdc132affa5a2982a29ffa06dc234 + md5: 46a21c0a4e65f1a135251fc7c8663f83 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + run_exports: + weak: + - zlib-ng >=2.3.3,<2.4.0a0 + size: 124542 + timestamp: 1770167984883 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: + weak: + - zstd >=1.5.7,<1.6.0a0 + size: 388453 + timestamp: 1764777142545 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ackermann-msgs-2.0.2-np2py312h2ed9cc7_16.conda + sha256: 24c3be282ad6e801ccd25d93f14ab2584a756174c8d5b1f97d4e66acbdfa677e + md5: ee033082fda524a2116438ce5335d8f4 + depends: + - python + - ros-jazzy-ros-workspace + - ros-jazzy-rosidl-default-runtime + - ros-jazzy-std-msgs + - ros2-distro-mutex 0.14.* jazzy_* + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - numpy >=1.23,<3 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - python_abi 3.12.* *_cp312 + license: BSD-3-Clause + size: 90133 + timestamp: 1771184649784 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ackermann-steering-controller-4.37.0-np2py312h2ed9cc7_16.conda + sha256: 148b3a42e3f423c55507c1c042b3550c347e60c535fda2a7996e60f9be198545 + md5: 28f1023702bc12c02178af5242e94bb2 + depends: + - python + - ros-jazzy-backward-ros + - ros-jazzy-control-msgs + - ros-jazzy-controller-interface + - ros-jazzy-hardware-interface + - ros-jazzy-pluginlib + - ros-jazzy-rclcpp + - ros-jazzy-rclcpp-lifecycle + - ros-jazzy-ros-workspace + - ros-jazzy-std-srvs + - ros-jazzy-steering-controllers-library + - ros2-distro-mutex 0.14.* jazzy_* + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - numpy >=1.23,<3 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + size: 107200 + timestamp: 1771190428063 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-msgs-2.0.3-np2py312h2ed9cc7_16.conda + sha256: de90c354f2833719b868748f8683cce0788fcb33fc950c65d98fbc33653466d0 + md5: ee92167b7ec28fdbc23388c7a8c74936 + depends: + - python + - ros-jazzy-builtin-interfaces + - ros-jazzy-ros-workspace + - ros-jazzy-rosidl-core-runtime + - ros-jazzy-service-msgs + - ros-jazzy-unique-identifier-msgs + - ros2-distro-mutex 0.14.* jazzy_* + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 152219 + timestamp: 1771184279030 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-cpp-0.33.9-np2py312h2ed9cc7_16.conda + sha256: 76e5bbb0e325371c3377dfec3699b57b9828d7860073e23a1f25b5be5ad02b1e + md5: 9c1f60b118635f9b442be44f3da0649d + depends: + - python + - ros-jazzy-action-tutorials-interfaces + - ros-jazzy-rclcpp + - ros-jazzy-rclcpp-action + - ros-jazzy-rclcpp-components + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + size: 132598 + timestamp: 1771187103592 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-interfaces-0.33.9-np2py312h2ed9cc7_16.conda + sha256: 148e56b13ed1d1465bcae67e255562a758c722f3e697bbaa592cbe99e4321b94 + md5: 17823b83b20caad37d6a90c1c577cbde + depends: + - python + - ros-jazzy-ros-workspace + - ros-jazzy-rosidl-default-runtime + - ros2-distro-mutex 0.14.* jazzy_* + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 185188 + timestamp: 1771184400148 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-action-tutorials-py-0.33.9-np2py312h2ed9cc7_16.conda + sha256: 91b65725bd864a3ad4e18ec756d8a25e221459567d73e7b5f4fffc5e0ce15cfa + md5: dbec62941731e2358f8adf3f56cb7f6d + depends: + - python + - ros-jazzy-action-tutorials-interfaces + - ros-jazzy-rclpy + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - python_abi 3.12.* *_cp312 + - numpy >=1.23,<3 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 30774 + timestamp: 1771186792870 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-actionlib-msgs-5.3.6-np2py312h2ed9cc7_16.conda + sha256: 4cfbbd610ecf55c5f6b22c9972a9271a33d0b385caee9e747a3721b5d6d70d69 + md5: cf00ccaa7ddf4586dee2363a736bab77 + depends: + - python + - ros-jazzy-builtin-interfaces + - ros-jazzy-ros-workspace + - ros-jazzy-rosidl-default-runtime + - ros-jazzy-std-msgs + - ros2-distro-mutex 0.14.* jazzy_* + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - python_abi 3.12.* *_cp312 + - numpy >=1.23,<3 + license: Apache-2.0 + size: 112790 + timestamp: 1771184720660 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-actuator-msgs-0.0.1-np2py312h2ed9cc7_16.conda + sha256: 4713d100cf5065a3fde754db44485ff1469311d8e94bc50b1d15eb8a49ff3959 + md5: f9b3251409c4f85b044c148166299872 + depends: + - python + - ros-jazzy-ros-workspace + - ros-jazzy-rosidl-default-runtime + - ros-jazzy-std-msgs + - ros2-distro-mutex 0.14.* jazzy_* + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - numpy >=1.23,<3 + license: Apache-2.0 + size: 161558 + timestamp: 1771184683438 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-admittance-controller-4.37.0-np2py312h2ed9cc7_16.conda + sha256: 8ffd5ecd3ffbdef53181cc2f342bb4791dc959456d7e1f0314184348c3eb7978 + md5: 4c5d20f2c6053e5858894a490458e5a6 + depends: + - python + - ros-jazzy-angles + - ros-jazzy-backward-ros + - ros-jazzy-control-msgs + - ros-jazzy-control-toolbox + - ros-jazzy-controller-interface + - ros-jazzy-generate-parameter-library + - ros-jazzy-geometry-msgs + - ros-jazzy-hardware-interface + - ros-jazzy-kinematics-interface + - ros-jazzy-pluginlib + - ros-jazzy-rclcpp + - ros-jazzy-rclcpp-lifecycle + - ros-jazzy-realtime-tools + - ros-jazzy-ros-workspace + - ros-jazzy-tf2 + - ros-jazzy-tf2-eigen + - ros-jazzy-tf2-geometry-msgs + - ros-jazzy-tf2-kdl + - ros-jazzy-tf2-ros + - ros-jazzy-trajectory-msgs + - ros2-distro-mutex 0.14.* jazzy_* + - tinyxml2 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - numpy >=1.23,<3 + - tinyxml2 >=11.0.0,<11.1.0a0 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + size: 425869 + timestamp: 1771189941612 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-2.5.5-np2py312h2ed9cc7_16.conda + sha256: 86d39bcd77b513620b09c20f7312dc70fbc9330d68e4c2faf6e4063f2cb4ff91 + md5: 33ef0274dc2e7f9a5df9071a4e415dd8 + depends: + - python + - ros-jazzy-ament-cmake-core + - ros-jazzy-ament-cmake-export-definitions + - ros-jazzy-ament-cmake-export-dependencies + - ros-jazzy-ament-cmake-export-include-directories + - ros-jazzy-ament-cmake-export-interfaces + - ros-jazzy-ament-cmake-export-libraries + - ros-jazzy-ament-cmake-export-link-flags + - ros-jazzy-ament-cmake-export-targets + - ros-jazzy-ament-cmake-gen-version-h + - ros-jazzy-ament-cmake-libraries + - ros-jazzy-ament-cmake-python + - ros-jazzy-ament-cmake-target-dependencies + - ros-jazzy-ament-cmake-test + - ros-jazzy-ament-cmake-version + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - cmake + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - numpy >=1.23,<3 + license: Apache-2.0 + size: 23070 + timestamp: 1771181803403 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-auto-2.5.5-np2py312h2ed9cc7_16.conda + sha256: ca62d269434b7a45cc5f77d4c43c20c4528d7c4d682512aaeef0a6b054247083 + md5: 33d729a5e385fa4beadc4b8c739ca142 + depends: + - python + - ros-jazzy-ament-cmake + - ros-jazzy-ament-cmake-gmock + - ros-jazzy-ament-cmake-gtest + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 27193 + timestamp: 1771181891347 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-copyright-0.17.4-np2py312h2ed9cc7_16.conda + sha256: 8e675aa31012e495edc5d384fc60706808d3c61ed3ed38d96bc3e46601e036a3 + md5: c93e829e07be2b722ee1ac9de30e1b44 + depends: + - python + - ros-jazzy-ament-cmake-test + - ros-jazzy-ament-copyright + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 22507 + timestamp: 1771182141337 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-core-2.5.5-np2py312h2ed9cc7_16.conda + sha256: 1ba0ba9e288f0631ccfdece200cdf8784e38834b5074529ca8f330613b58875d + md5: e60e1669ce01c53eb9ebfabb0264ed84 + depends: + - catkin_pkg + - python + - ros-jazzy-ament-package + - ros2-distro-mutex 0.14.* jazzy_* + - cmake + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - numpy >=1.23,<3 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 44761 + timestamp: 1771181255713 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-cppcheck-0.17.4-np2py312h2ed9cc7_16.conda + sha256: f2145fea7ff195212971388295cdd8b4cbb706da3c580e95b5f3b06cc2055e02 + md5: 03ace4f94dc129213d05e768553967ca + depends: + - python + - ros-jazzy-ament-cmake-core + - ros-jazzy-ament-cmake-test + - ros-jazzy-ament-cppcheck + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.12.* *_cp312 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + - numpy >=1.23,<3 + license: Apache-2.0 + size: 24257 + timestamp: 1771182320712 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-cpplint-0.17.4-np2py312h2ed9cc7_16.conda + sha256: f297fde71fad587e24b9ac919fd3078727826b3b81807f728b1a01d1642dc523 + md5: 31af3ac064c79441b3867deb76bb63a7 + depends: + - python + - ros-jazzy-ament-cmake-test + - ros-jazzy-ament-cpplint + - ros-jazzy-ros-workspace + - ros2-distro-mutex 0.14.* jazzy_* + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.12.* *_cp312 + - numpy >=1.23,<3 + - ros2-distro-mutex >=0.14.0,<0.15.0a0 + license: Apache-2.0 + size: 23122 + timestamp: 1771182344919 +- conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ament-cmake-export-definitions-2.5.5-np2py312h2ed9cc7_16.conda + sha256: b82ea4e717ed6ef6832a5f3d5bb3a68142ca3f3ccba8800ccbdc43d07ab395a0 + md5: 376993cd9c67f43f31841d8fe0b31362 depends: - python - ros-jazzy-ament-cmake-core @@ -45638,6 +48227,23 @@ packages: run_exports: {} size: 32970 timestamp: 1779704204089 +- pypi: https://download-r2.pytorch.org/whl/cu128/torch-2.11.0%2Bcu128-cp312-cp312-win_amd64.whl + name: torch + version: 2.11.0+cu128 + sha256: 7c78215c3af4f62e63f2b2e360f1722fc719b0853c7ac22666483d9810613a4c + index: https://download.pytorch.org/whl/cu128 + requires_dist: + - filelock + - typing-extensions>=4.10.0 + - setuptools<82 + - sympy>=1.13.3 + - networkx>=2.5.1 + - jinja2 + - fsspec>=0.8.5 + - opt-einsum>=3.3 ; extra == 'opt-einsum' + - optree>=0.13.0 ; extra == 'optree' + - pyyaml ; extra == 'pyyaml' + requires_python: '>=3.10' - pypi: https://download-r2.pytorch.org/whl/pytorch_triton_rocm-3.5.1-cp312-cp312-linux_x86_64.whl name: pytorch-triton-rocm version: 3.5.1 @@ -46149,11 +48755,58 @@ packages: version: 3.32.0 sha256: d396bea984af47333ef05e50eae7eff88c84256de6112aea0ec48a233c064fe3 requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/08/8e/c780c131f79b42ed22d1bd7da4096c2c35f813e835acd02ef0f018bd892c/regex-2026.7.19-cp312-cp312-win_amd64.whl + name: regex + version: 2026.7.19 + sha256: e30d40268a28d54ce0437031750497004c22602b8e3ab891f759b795a003b312 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl name: certifi version: 2026.7.22 sha256: 62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775 requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl + name: safetensors + version: 0.8.0 + sha256: 096ec1a98435df7beb08853bb5aa9081a84f23d0adc67ed1a0a10550f608373f + requires_dist: + - safetensors[torch] ; extra == 'all' + - safetensors[numpy] ; extra == 'all' + - safetensors[jax] ; extra == 'all' + - safetensors[paddlepaddle] ; extra == 'all' + - safetensors[convert] ; extra == 'all' + - safetensors[quality] ; extra == 'all' + - safetensors[testing] ; extra == 'all' + - safetensors[torch] ; extra == 'convert' + - huggingface-hub>=1.4 ; extra == 'convert' + - safetensors[all] ; extra == 'dev' + - safetensors[pinned-tf] ; extra == 'dev' + - safetensors[numpy] ; extra == 'jax' + - flax>=0.6.3 ; extra == 'jax' + - jax>=0.3.25 ; extra == 'jax' + - jaxlib>=0.3.25 ; extra == 'jax' + - mlx>=0.0.9 ; extra == 'mlx' + - numpy>=1.24.6 ; extra == 'numpy' + - safetensors[numpy] ; extra == 'paddlepaddle' + - paddlepaddle>=2.4.1 ; extra == 'paddlepaddle' + - safetensors[numpy] ; extra == 'pinned-tf' + - tensorflow==2.18.0 ; extra == 'pinned-tf' + - ruff ; extra == 'quality' + - safetensors[numpy] ; extra == 'tensorflow' + - tensorflow>=2.11.0 ; extra == 'tensorflow' + - safetensors[numpy] ; extra == 'testing' + - h5py>=3.7.0 ; extra == 'testing' + - setuptools-rust>=1.12.0 ; extra == 'testing' + - pytest>=9.0 ; extra == 'testing' + - pytest-benchmark>=5.2 ; extra == 'testing' + - hypothesis>=6.70.2 ; extra == 'testing' + - fsspec>=2024.6.0 ; extra == 'testing' + - s3fs>=2024.6.0 ; extra == 'testing' + - safetensors[numpy] ; extra == 'tf-nightly' + - tf-nightly ; extra == 'tf-nightly' + - safetensors[numpy] ; extra == 'torch' + - torch>=2.4 ; extra == 'torch' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl name: idna version: '3.18' @@ -46315,6 +48968,24 @@ packages: - markupsafe>=2.0 - babel>=2.7 ; extra == 'i18n' requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl + name: tokenizers + version: 0.22.2 + sha256: c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48 + requires_dist: + - huggingface-hub>=0.16.4,<2.0 + - pytest ; extra == 'testing' + - pytest-asyncio ; extra == 'testing' + - requests ; extra == 'testing' + - numpy ; extra == 'testing' + - datasets ; extra == 'testing' + - ruff ; extra == 'testing' + - ty ; extra == 'testing' + - sphinx ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - setuptools-rust ; extra == 'docs' + - tokenizers[testing] ; extra == 'dev' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/7d/0a/2e0c30342586dabb0b4b7946393a7aeb725fca7b4549fb02e128a1a0fe87/py_trees-2.4.0-py3-none-any.whl name: py-trees version: 2.4.0 @@ -46352,6 +49023,16 @@ packages: - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl + name: charset-normalizer + version: 3.4.9 + sha256: 4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl + name: pyyaml + version: 6.0.3 + sha256: 5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: pyyaml version: 6.0.3 @@ -46558,6 +49239,16 @@ packages: - types-tqdm ; extra == 'dev' - types-urllib3 ; extra == 'dev' requires_python: '>=3.8.0' +- pypi: https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl + name: markupsafe + version: 3.0.3 + sha256: 26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + name: colorama + version: 0.4.6 + sha256: 4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' - pypi: https://files.pythonhosted.org/packages/d3/35/db860aa3a0780660324a506ad4b3d322ddc6ecbba4b9340aed0942cbf21c/hf_xet-1.5.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: hf-xet version: 1.5.2 @@ -46570,6 +49261,63 @@ packages: version: '26.2' sha256: 5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl + name: setuptools + version: 81.0.0 + sha256: fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6 + requires_dist: + - pytest>=6,!=8.1.* ; extra == 'test' + - virtualenv>=13.0.0 ; extra == 'test' + - wheel>=0.44.0 ; extra == 'test' + - pip>=19.1 ; extra == 'test' + - packaging>=24.2 ; extra == 'test' + - jaraco-envs>=2.2 ; extra == 'test' + - pytest-xdist>=3 ; extra == 'test' + - jaraco-path>=3.7.2 ; extra == 'test' + - build[virtualenv]>=1.0.3 ; extra == 'test' + - filelock>=3.4.0 ; extra == 'test' + - ini2toml[lite]>=0.14 ; extra == 'test' + - tomli-w>=1.0.0 ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-perf ; sys_platform != 'cygwin' and extra == 'test' + - jaraco-develop>=7.21 ; python_full_version >= '3.9' and sys_platform != 'cygwin' and extra == 'test' + - pytest-home>=0.5 ; extra == 'test' + - pytest-subprocess ; extra == 'test' + - pyproject-hooks!=1.1 ; extra == 'test' + - jaraco-test>=5.5 ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pygments-github-lexers==0.0.5 ; extra == 'doc' + - sphinx-favicon ; extra == 'doc' + - sphinx-inline-tabs ; extra == 'doc' + - sphinx-reredirects ; extra == 'doc' + - sphinxcontrib-towncrier ; extra == 'doc' + - sphinx-notfound-page>=1,<2 ; extra == 'doc' + - pyproject-hooks!=1.1 ; extra == 'doc' + - towncrier<24.7 ; extra == 'doc' + - packaging>=24.2 ; extra == 'core' + - more-itertools>=8.8 ; extra == 'core' + - jaraco-text>=3.7 ; extra == 'core' + - importlib-metadata>=6 ; python_full_version < '3.10' and extra == 'core' + - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'core' + - wheel>=0.43.0 ; extra == 'core' + - platformdirs>=4.2.2 ; extra == 'core' + - jaraco-functools>=4 ; extra == 'core' + - more-itertools ; extra == 'core' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - ruff>=0.13.0 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest-mypy ; extra == 'type' + - mypy==1.18.* ; extra == 'type' + - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' + - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/e5/22/4222d7ddf3da30f363edaa98e329c2bce6c65497c9cb2810931c8b2c0fbc/fsspec-2026.6.0-py3-none-any.whl name: fsspec version: 2026.6.0 diff --git a/pixi.toml b/pixi.toml index 31f645e..2280ef1 100644 --- a/pixi.toml +++ b/pixi.toml @@ -39,6 +39,10 @@ teleop = "ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -p sta perception = "ros2 launch mote_perception perception_launch.py" record = "ros2 launch mote_bringup record_launch.py" tasks = "ros2 launch mote_tasks tasks_launch.py" +# Robot-side inference diagnostics (torch-free — run in the default/robot env): +# probe the inference machine's health/version, or benchmark round-trip latency. +inference-health = "python -u mote_perception/tools/inference_health.py" +inference-bench = "python -u mote_perception/tools/inference_bench.py" #### The below tasks are tied to specific features and environments however they #### can be run like any other task. @@ -169,10 +173,12 @@ transformers = ">=4,<5" # redirection to a file (block buffering otherwise holds them indefinitely) [feature.inference.tasks] # Both servers together — the usual way to run a dedicated inference machine. -inference = "bash mote_perception/tools/inference_server.sh" +inference = "python -u mote_perception/tools/inference_server.py" # Or one model at a time (e.g. depth-server --metric, or to save VRAM). depth-server = "python -u mote_perception/tools/depth_server.py" detect-server = "python -u mote_perception/tools/detect_server.py" +# Warm the HuggingFace cache so the first request doesn't block on a download. +inference-prefetch = "python -u mote_perception/tools/prefetch_models.py" # GPU-accelerated sibling of the `inference` feature (env `inference-rocm`). Same # depth/detect servers, but torch comes from the pytorch.org ROCm wheel index @@ -209,9 +215,48 @@ HSA_OVERRIDE_GFX_VERSION = "11.0.0" # stay unambiguous; `inference-rocm` runs both servers on the GPU (the servers' # --device auto picks the GPU when present), the single-server variants save VRAM. [feature.inference-rocm.tasks] -inference-rocm = "bash mote_perception/tools/inference_server.sh" +inference-rocm = "python -u mote_perception/tools/inference_server.py" depth-server-rocm = "python -u mote_perception/tools/depth_server.py" detect-server-rocm = "python -u mote_perception/tools/detect_server.py" +inference-prefetch-rocm = "python -u mote_perception/tools/prefetch_models.py" + +# CUDA sibling of the `inference` feature (env `inference-cuda`), for the dedicated +# off-board inference machine: a Windows gaming PC with an NVIDIA GPU. Same +# depth/detect servers, but torch comes from the pytorch.org CUDA wheel index +# (win_amd64 cu128 build) instead of conda-forge's CPU pytorch. This is the +# destination tier — the ROCm iGPU path stays the Linux-dev fallback. +# +# win-64 only, and note the *feature* declares win-64 even though the workspace +# platforms are linux only: pixi resolves this feature's environment for win-64 +# alone and leaves every other env (the aarch64 robot, linux dev, sim) untouched, +# so a Windows torch wheel can never perturb the robot solve. python is pinned to +# 3.12 (the pytorch.org wheels only publish cp3.x up to 3.12); numpy/pillow/scipy +# stay on conda and only torch + transformers come from PyPI so pip resolves torch +# against the CUDA index. No triton — it has no Windows wheels and torch on Windows +# doesn't need it. Native Windows (not WSL2) is the chosen host: it binds the +# socket straight onto the LAN and auto-starts via a Scheduled Task, with no WSL +# NAT/port-proxy layer between the robot and the server (see +# docs/inference-server.md for the host decision and setup guide). +[feature.inference-cuda] +platforms = ["win-64"] + +[feature.inference-cuda.dependencies] +python = "3.12.*" +numpy = ">=1.26,<3" +pillow = ">=10,<13" +# scipy: undeclared requirement of transformers' Owlv2ImageProcessor +scipy = ">=1,<2" +opencv = ">=4,<5" + +[feature.inference-cuda.pypi-dependencies] +torch = { version = ">=2.8,<3", index = "https://download.pytorch.org/whl/cu128" } +transformers = ">=4,<5" + +[feature.inference-cuda.tasks] +inference-cuda = "python -u mote_perception/tools/inference_server.py" +depth-server-cuda = "python -u mote_perception/tools/depth_server.py" +detect-server-cuda = "python -u mote_perception/tools/detect_server.py" +inference-prefetch-cuda = "python -u mote_perception/tools/prefetch_models.py" [feature.lint.dependencies] pre-commit = ">=4,<5" @@ -228,5 +273,8 @@ inference = { features = ["inference"], no-default-feature = true } inference-rocm = { features = ["inference-rocm"], no-default-feature = true } # ^ GPU sibling of `inference`; own solve (no solve-group) so the ROCm torch wheel # can never perturb any other env. +inference-cuda = { features = ["inference-cuda"], no-default-feature = true } +# ^ win-64/NVIDIA sibling for the dedicated gaming-PC inference machine; own solve, +# win-64 only, so its CUDA torch wheel never touches the robot/dev/sim envs. # Minimal env (no ROS) so 'pixi run lint' is fast to solve and install lint = { features = ["lint"], no-default-feature = true }