Add env perf/timing config to teleop_replay_agent stats output#5716
Add env perf/timing config to teleop_replay_agent stats output#5716rwiltz wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
🤖 Isaac Lab Review Bot
PR: #5716 — Add env perf/timing config to teleop_replay_agent stats output
Commit: 74d5c3a8
Summary
This PR enhances teleop_replay_agent.py by embedding environment performance/timing configuration into the stats JSON output and printing a summary line to stdout. The changes are additive and non-breaking.
✅ Strengths
-
Well-designed defensive accessor: The
_safe()helper function properly handles missing attributes and None values with appropriate type casting, preventing crashes on non-standard env_cfg subclasses. -
Comprehensive documentation: Excellent docstring in
_extract_env_perf_cfg()explaining the rationale for capturing these fields and how derived values are computed. -
Self-documenting output: Precomputing derived values (
policy_dt_s,render_dt_s,renders_per_step,target_policy_hz,target_render_hz) eliminates manual calculation for cross-machine comparisons. -
Non-breaking schema: Maintaining
schema_version=1and allowing fields to degrade tonullensures backward compatibility. -
Good separation of concerns: Extracting the perf config into a dedicated function (
_extract_env_perf_cfg) keeps_build_reportclean.
💬 Suggestions (Non-blocking)
-
Division safety in
renders_per_step: The checkrender_interval not in (None, 0)is good, but consider unifying the pattern withtarget_policy_hz/target_render_hzfor consistency:# Current pattern mixes "not in (None, 0)" with checking separately renders_per_step = ( decimation / render_interval if decimation is not None and render_interval not in (None, 0) else None )
-
Type annotation opportunity:
_safe()could benefit from type hints for better IDE support:def _safe(obj: Any, attr: str, cast: Callable | None = None) -> Any:
-
Consider
antialiasing_modestringification: Unlike other fields that use explicit casts (str,int,float),antialiasing_modeis passed without a cast. If this is an enum, considerstr()wrapping for JSON serialization robustness:"antialiasing_mode": _safe(render, "antialiasing_mode", str),
-
Stdout formatting edge case: When
sim.dtisNone, the stdout output showsn/a, but otherNonevalues would print asNone. Consider consistent formatting for all nullable fields.
📝 Notes
- CI Status: Pre-commit and initial checks passing; some jobs still pending.
- Test coverage: The PR mentions tests were added per the checklist. Since
teleop_replay_agent.pyis a script without a dedicated test file visible in the test directory, consider documenting how the newenv_cfgextraction is validated (manual testing, integration test, etc.). - Changelog: Properly added in
changelog.d/rwiltz-replay-stats-env-cfg.rst✓
Verdict
Clean, well-thought-out enhancement that improves debugging and cross-machine comparisons without breaking existing consumers. The defensive coding patterns are appropriate for handling varying env_cfg implementations.
🔍 Reviewed by Isaac Lab Review Bot | 📋 Review Guidelines
Greptile SummaryThis PR extends
Confidence Score: 5/5Safe to merge; all new code paths are well-guarded and do not affect existing functionality when env config fields are absent. The per-render scaling in _RunStats.to_dict guards against None and zero for both decimation and render_interval before dividing, and _extract_env_perf_cfg uses a _safe helper for every attribute access so non-standard env configs degrade gracefully to None. The env_cfg block is additive to the JSON output and the schema_version is not bumped. No new code paths affect env lifecycle, CloudXR, or the replay control loop itself. The changelog fragment rwiltz-replay-stats-env-cfg.rst still uses Kit terminology inconsistent with the PR documentation goal, but this has no runtime impact. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[main] --> B[_prepare_env_cfg]
B --> C[env_cfg object]
A --> D[_run_single_replay loop]
D --> E[_RunStats with active_frame_times_ms]
A --> F[_build_report]
C --> F
E --> F
F --> G[_extract_env_perf_cfg]
G --> H[env_perf_cfg dict]
H --> I[Pull decimation and render_interval]
I --> J[_RunStats.to_dict]
J --> K{decimation and render_interval valid?}
K -- Yes --> L[scale samples by render_interval / decimation]
K -- No --> M[use raw per-env.step samples]
L --> N[_compute_frame_stats + _compute_fps_stats]
M --> N
N --> O[run_dict]
O --> P[_aggregate_runs]
F --> Q[report dict with env_cfg block]
Q --> R[_print_stdout_summary]
Q --> S[_write_json_report optional]
Reviews (2): Last reviewed commit: "Addressing feedback" | Re-trigger Greptile |
|
@greptile |
There was a problem hiding this comment.
🤖 Isaac Lab Review Bot
PR: #5716 — Add env perf/timing config to teleop_replay_agent stats output
Commit: ccc938f5 (updated from 74d5c3a8)
Summary
This PR enhances teleop_replay_agent.py with two significant improvements:
- Embeds environment performance/timing configuration into the stats JSON output
- Reports
cpu_frame_time_msandfpson a per-render basis instead of per-env.step, matching the simulator HUD
The new commit addresses feedback from the initial review with clean, well-documented fixes.
✅ Review Feedback Addressed
The author has addressed several points raised in the previous review:
-
✓ Stdout formatting consistency: Added
_or_na()helper function to normalizeNoneas"n/a"for integer fields (num_envs,decimation,render_interval), matching the behavior of_fmt()for floats. The Env timing line now displays consistently. -
✓ Dead code removal: Removed the misleading
env_cfg = Noneinit whose comment incorrectly described a finally-side report path that does not exist (since_build_reportruns after the try/finally). -
✓ Code efficiency:
_extract_env_perf_cfg()result is now stored once inenv_perf_cfgand reused for both the decimation/render_interval extraction and the report dict, avoiding a redundant function call.
✅ Strengths
-
Well-designed per-render conversion: The
to_dict()method now correctly converts env.step samples to per-render basis usingsamples_ms = [t / renders_per_env_step for t in samples_ms], with proper guards for None/zero values. -
Comprehensive docstrings: The extended comment block in
to_dict()clearly explains the math: per-render ms = env.step ms × render_interval / decimation. -
Defensive graceful degradation: Falls back to raw env.step units when decimation or render_interval is unavailable, rather than dropping the report entirely.
-
Brand-neutral documentation: Systematic replacement of "Kit" with "the simulator" throughout docstrings and comments maintains documentation quality while making it renderer-agnostic.
-
Complete changelog: The
.rstchangelog properly documents both the Added (env_cfgblock) and Changed (per-render basis) modifications.
💬 Remaining Minor Notes (Non-blocking)
-
Changelog still references "Kit": The changelog file (
rwiltz-replay-stats-env-cfg.rst) contains two remaining references to "Kit" ("the number of Kit renders" and "Kit's HUD shows") while the main script now uses "the simulator". Consider updating for consistency with the script's terminology changes. -
Type annotations:
_safe()and_or_na()helper functions could benefit from type hints for better IDE support, but this is stylistic and the functions work correctly as-is.
📋 CI Status
All pre-commit checks passed. Most CI jobs are still pending for the new commit.
Verdict
Clean iteration that addresses review feedback thoroughly. The per-render normalization is a meaningful improvement that makes the output match what users actually see in the simulator HUD. Ready for maintainer review.
🔍 Reviewed by Isaac Lab Review Bot | 📋 Review Guidelines
Description
env_cfgblock inteleop_replay_agent.py's stats JSON capturing the perf- and frame-timing-relevant env config inputs (sim.dt,sim.render_interval,decimation,episode_length_s,scene.num_envs,sim.device,sim.use_fabric,sim.render.antialiasing_mode) plus precomputedpolicy_dt_s/render_dt_s/renders_per_step/target_policy_hz/target_render_hzrates, so the measured numbers are self-interpreting across machines and configs without cross-referencing the env definition. Echoed in a compactEnv timing:line in the stdout summary.cpu_frame_time_msandfps(per-run and aggregate) on a per-render basis instead of per-env.step: each env.step CPU sample is divided bydecimation / render_interval(renders perenv.step) before stats are computed.cpu_frame_time_ms.meannow reads as the wall time between rendered frames andfps.meanreads as the render rate -- matching the simulator HUD and the rate the headset wearer / spectator actually perceives during real-time teleop. Falls back to raw per-env.stepunits whendecimationorrender_intervalare unavailable. Field shapes andschema_versionare unchanged (v1 unadopted; no bump needed).--kit_argsCLI flag andisaacsim.kit.xr.teleop.bridgeextension name) are preserved in the usage example.env_cfg = Noneinit whose comment misleadingly described afinally-side report (_build_reportactually runs after the try/finally), and normalizeNone-as-"n/a"rendering across theEnv timing:stdout fields.Fixes # (issue)
Type of change
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfileCONTRIBUTORS.mdor my name already exists there