Files
wehub-resource-sync eec33d25b2
pre-commit / pre-commit (push) Failing after 1s
Build Wheel / build (3.11) (push) Failing after 1s
Build Wheel / build (3.12) (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:29:08 +08:00

130 lines
4.1 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
"""DreamZero AR client frame schedule aligned with upstream ``test_client_AR.py``."""
from __future__ import annotations
import logging
from typing import Any
import numpy as np
# Frame schedule constants (matching upstream debug_inference.py / test_client_AR.py).
ACTION_HORIZON = 24
DEFAULT_ACTION_DIM = 8
RELATIVE_OFFSETS = [-23, -16, -8, 0]
DEFAULT_NUM_AR_CHUNKS = 15
CAMERA_FILES = {
"observation/exterior_image_0_left": "exterior_image_1_left.mp4",
"observation/exterior_image_1_left": "exterior_image_2_left.mp4",
"observation/wrist_image_left": "wrist_image_left.mp4",
}
def build_frame_schedule(
total_frames: int,
num_chunks: int,
*,
logger: logging.Logger | None = None,
) -> list[list[int]]:
"""Build the frame index schedule for multi-frame chunks.
Args:
total_frames: Number of frames available in each camera video.
num_chunks: Number of 4-frame chunks to schedule after the initial frame.
Returns:
A list of frame-index lists. Each inner list has four indices. The
returned list may be shorter than ``num_chunks`` when the videos run
out of frames (upstream stops early instead of erroring).
"""
chunks: list[list[int]] = []
current_frame = 23
for _ in range(num_chunks):
indices = [max(current_frame + offset, 0) for offset in RELATIVE_OFFSETS]
if indices[-1] >= total_frames:
if logger is not None:
logger.info(
"Frame %s >= %s, stopping at %s chunks",
indices[-1],
total_frames,
len(chunks),
)
break
chunks.append(indices)
current_frame += ACTION_HORIZON
return chunks
def make_obs_from_video(
camera_frames: dict[str, np.ndarray],
frame_indices: list[int],
*,
prompt: str,
session_id: str,
) -> dict[str, Any]:
"""Build an observation dict from real video frames.
For one frame each image key is ``(H, W, 3)``. For four frames each key is
``(4, H, W, 3)``.
"""
obs: dict[str, Any] = {}
for camera_key, all_frames in camera_frames.items():
selected = all_frames[frame_indices]
obs[camera_key] = selected[0] if len(frame_indices) == 1 else selected
obs["observation/joint_position"] = np.zeros(7, dtype=np.float32)
obs["observation/cartesian_position"] = np.zeros(6, dtype=np.float32)
obs["observation/gripper_position"] = np.zeros(1, dtype=np.float32)
obs["prompt"] = prompt
obs["session_id"] = session_id
return obs
def build_ar_observations(
camera_frames: dict[str, np.ndarray],
*,
prompt: str,
session_id: str,
num_chunks: int = DEFAULT_NUM_AR_CHUNKS,
repeat_chunk_observations: bool = False,
logger: logging.Logger | None = None,
) -> list[dict[str, Any]]:
"""Build the AR observation sequence used by upstream ``test_client_AR.py``.
Step 0 sends frame ``[0]``. Each subsequent step sends one 4-frame chunk.
``num_chunks`` counts only the 4-frame chunks after the initial frame, not
the total number of inferences.
"""
if num_chunks < 0:
raise ValueError("num_chunks must be non-negative")
total_frames = min(frames.shape[0] for frames in camera_frames.values())
observations = [
make_obs_from_video(
camera_frames,
[0],
prompt=prompt,
session_id=session_id,
)
]
chunk_schedule = build_frame_schedule(total_frames, num_chunks, logger=logger)
if repeat_chunk_observations and chunk_schedule and len(chunk_schedule) < num_chunks:
while len(chunk_schedule) < num_chunks:
chunk_schedule.append(chunk_schedule[-1])
for frame_indices in chunk_schedule:
observations.append(
make_obs_from_video(
camera_frames,
frame_indices,
prompt=prompt,
session_id=session_id,
)
)
return observations