77
88``_select_video_backend`` has three dispatch paths:
99
10- 1. ``"kit"`` visualizer present → Kit Replicator capture (IsaacsimKitPerspectiveVideo)
11- 2. ``"newton"`` visualizer present → Newton GL framebuffer (NewtonGLVisualizer.render_rgb_array)
12- 3. Neither above (any other visualizer or no visualizer)
10+ 1. ``"kit"`` visualizer present + PhysX → Kit Replicator capture (IsaacsimKitPerspectiveVideo)
11+ 2. ``"newton"`` visualizer present → Newton GL framebuffer (NewtonGLVisualizer.render_rgb_array)
12+ 3. Neither above, OR Kit visualizer with Newton physics
1313 → physics manager video_capture_backend():
1414 "kit" → standalone Kit capture
1515 "newton_gl" → standalone Newton GL capture
1616 None → RuntimeError (not tested here; covered by test_video_recorder.py)
1717
18+ When Newton is the physics backend, Kit Replicator recording is skipped
19+ (Newton Fabric writes do not notify RTX's scene delegate, producing black frames).
20+ _select_video_backend falls back to Newton GL standalone with a logged warning.
21+
1822Path 3 fallthrough (Rerun, Viser, NewtonRTX visualizer types) is covered at the
1923unit level by test_video_recorder.py::test_resolve_backend_unsupported_visualizer_falls_back.
20- NewtonRTXVisualizerCfg is not yet a factory-registered type and cannot be
21- instantiated as a visualizer, so it has no integration test here.
22-
23- Known limitation (xfail): Kit Replicator recording does not produce frames when
24- Newton is the physics backend. Kit recording relies on
25- ``ensure_isaac_rtx_render_update`` called by the PhysX manager's render
26- callback; when Newton is active that callback is absent, so the render product
27- buffer stays zeroed even though the Kit visualizer pumps ``app.update()``.
28- Tracked as a known gap — not a regression introduced by this re-arch.
2924
3025Setup:
3126 - AppLauncher(headless=True, enable_cameras=True)
3227 - CartpoleEnv (DirectRLEnv, 1 env) as the test vehicle.
3328Tests:
3429 - KitVisualizerCfg + PhysX + backend_source="visualizer"
35- -> Kit Replicator capture (path 1, PhysX physics ) [passes]
30+ -> Kit Replicator capture (path 1) [passes]
3631 - KitVisualizerCfg + Newton + backend_source="visualizer"
37- -> Kit Replicator capture (path 1, Newton physics) [xfail: see above ]
32+ -> Newton GL standalone (path 3 fallback: Kit skipped for Newton physics) [passes ]
3833 - NewtonGLVisualizerCfg + Newton + backend_source="visualizer"
3934 -> Newton GL framebuffer capture (path 2) [passes]
4035 - PhysX + backend_source="renderer"
@@ -130,17 +125,13 @@ def test_kit_visualizer_physx_source_records_rgb():
130125 _assert_valid_frame (frame , "kit-visualizer-physx" )
131126
132127
133- @pytest .mark .xfail (
134- strict = True ,
135- reason = (
136- "Kit Replicator recording produces a zero buffer when Newton is the physics backend. "
137- "The PhysX manager registers an ensure_isaac_rtx_render_update render callback that "
138- "primes the render product; Newton does not, so the buffer stays zeroed even though "
139- "the Kit visualizer pumps app.update(). Known gap — not a regression of this re-arch."
140- ),
141- )
142128def test_kit_visualizer_newton_source_records_rgb ():
143- """Kit visualizer + Newton physics → Kit Replicator capture stays all-black (known limitation)."""
129+ """Kit visualizer + Newton + backend_source='visualizer' → Newton GL standalone (Kit skipped for Newton).
130+
131+ Kit Replicator recording does not work with Newton physics because Newton Fabric
132+ writes do not notify RTX's scene delegate. _select_video_backend detects Newton
133+ and falls back to standalone Newton GL capture with a logged warning.
134+ """
144135 from isaaclab_newton .physics import MJWarpSolverCfg , NewtonCfg
145136 from isaaclab_visualizers .kit import KitVisualizerCfg
146137
@@ -158,13 +149,13 @@ def test_kit_visualizer_newton_source_records_rgb():
158149
159150
160151def test_newton_gl_visualizer_source_records_rgb ():
161- """NewtonGLVisualizerCfg + Newton + backend_source='visualizer' → Newton GL framebuffer capture."""
152+ """NewtonVisualizerCfg + Newton + backend_source='visualizer' → Newton GL framebuffer capture."""
162153 from isaaclab_newton .physics import MJWarpSolverCfg , NewtonCfg
163- from isaaclab_visualizers .newton import NewtonGLVisualizerCfg
154+ from isaaclab_visualizers .newton import NewtonVisualizerCfg
164155
165156 env_cfg = _cartpole_cfg (backend_source = "visualizer" )
166157 env_cfg .sim .physics = NewtonCfg (solver_cfg = MJWarpSolverCfg ())
167- env_cfg .sim .visualizer_cfgs = [NewtonGLVisualizerCfg (window_width = _W , window_height = _H )]
158+ env_cfg .sim .visualizer_cfgs = [NewtonVisualizerCfg (window_width = _W , window_height = _H )]
168159
169160 frame = _capture_frame (env_cfg )
170161 _assert_valid_frame (frame , "newton-gl-visualizer-source" )
0 commit comments