antioch-py 2.0.7__py3-none-any.whl → 2.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of antioch-py might be problematic. Click here for more details.

Files changed (58) hide show
  1. antioch/session/__init__.py +15 -13
  2. antioch/session/ark.py +22 -26
  3. antioch/session/objects/__init__.py +40 -0
  4. antioch/session/{views → objects}/animation.py +25 -52
  5. antioch/session/{views → objects}/articulation.py +30 -95
  6. antioch/session/{views → objects}/basis_curve.py +48 -54
  7. antioch/session/{views → objects}/camera.py +12 -39
  8. antioch/session/objects/collision.py +46 -0
  9. antioch/session/{views → objects}/geometry.py +6 -22
  10. antioch/session/{views → objects}/ground_plane.py +5 -20
  11. antioch/session/{views → objects}/imu.py +10 -30
  12. antioch/session/{views → objects}/joint.py +5 -20
  13. antioch/session/{views → objects}/light.py +14 -66
  14. antioch/session/{views → objects}/pir_sensor.py +20 -62
  15. antioch/session/objects/radar.py +62 -0
  16. antioch/session/{views → objects}/rigid_body.py +25 -110
  17. antioch/session/{views → objects}/xform.py +24 -24
  18. antioch/session/scene.py +116 -134
  19. antioch/session/session.py +34 -43
  20. antioch/session/task.py +2 -16
  21. {antioch_py-2.0.7.dist-info → antioch_py-2.2.1.dist-info}/METADATA +1 -1
  22. antioch_py-2.2.1.dist-info/RECORD +85 -0
  23. common/ark/ark.py +2 -0
  24. common/ark/hardware.py +1 -5
  25. common/ark/kinematics.py +1 -1
  26. common/constants.py +16 -2
  27. common/core/agent.py +28 -0
  28. common/core/auth.py +1 -3
  29. common/message/__init__.py +2 -0
  30. common/message/velocity.py +11 -0
  31. common/session/__init__.py +1 -24
  32. common/session/config.py +390 -0
  33. common/session/sim.py +36 -147
  34. antioch/session/views/__init__.py +0 -42
  35. antioch/session/views/collision.py +0 -75
  36. antioch/session/views/material.py +0 -54
  37. antioch/session/views/radar.py +0 -131
  38. antioch_py-2.0.7.dist-info/RECORD +0 -101
  39. common/session/views/__init__.py +0 -263
  40. common/session/views/animation.py +0 -73
  41. common/session/views/articulation.py +0 -184
  42. common/session/views/basis_curve.py +0 -102
  43. common/session/views/camera.py +0 -147
  44. common/session/views/collision.py +0 -59
  45. common/session/views/geometry.py +0 -102
  46. common/session/views/ground_plane.py +0 -41
  47. common/session/views/imu.py +0 -66
  48. common/session/views/joint.py +0 -81
  49. common/session/views/light.py +0 -96
  50. common/session/views/material.py +0 -25
  51. common/session/views/pir_sensor.py +0 -119
  52. common/session/views/radar.py +0 -107
  53. common/session/views/rigid_body.py +0 -236
  54. common/session/views/viewport.py +0 -21
  55. common/session/views/xform.py +0 -39
  56. {antioch_py-2.0.7.dist-info → antioch_py-2.2.1.dist-info}/WHEEL +0 -0
  57. {antioch_py-2.0.7.dist-info → antioch_py-2.2.1.dist-info}/entry_points.txt +0 -0
  58. {antioch_py-2.0.7.dist-info → antioch_py-2.2.1.dist-info}/top_level.txt +0 -0
antioch/session/scene.py CHANGED
@@ -1,8 +1,7 @@
1
1
  from typing import Literal, overload
2
2
 
3
3
  from antioch.session.ark import Ark
4
- from antioch.session.session import SessionContainer
5
- from antioch.session.views import (
4
+ from antioch.session.objects import (
6
5
  Animation,
7
6
  Articulation,
8
7
  BasisCurve,
@@ -20,43 +19,40 @@ from antioch.session.views import (
20
19
  has_collision,
21
20
  remove_collision,
22
21
  set_collision,
23
- set_nonvisual_material,
24
22
  set_pir_material,
25
23
  )
24
+ from antioch.session.session import SessionContainer
26
25
  from common.core import ContainerSource, get_asset_path
27
26
  from common.core.agent import Agent
28
27
  from common.message import Pose, Vector3
29
- from common.session.environment import SessionEnvironment
30
- from common.session.sim import (
31
- AddAsset,
32
- GetPrimAttribute,
33
- PrimAttributeValue,
34
- QueryScene,
35
- SceneQueryResponse,
36
- SceneTarget,
37
- SetPrimAttribute,
38
- SetSimulationControls,
39
- SimulationInfo,
40
- SimulationTime,
41
- Step,
42
- ToggleUi,
28
+ from common.session.config import (
29
+ ArticulationConfig,
30
+ ArticulationJointConfig,
31
+ BodyType,
32
+ CameraConfig,
33
+ CameraMode,
34
+ DistortionModel,
35
+ GeometryConfig,
36
+ GeometryType,
37
+ GroundPlaneConfig,
38
+ ImuConfig,
39
+ JointAxis,
40
+ JointConfig,
41
+ JointType,
42
+ LightConfig,
43
+ LightType,
44
+ MeshApproximation,
45
+ PirSensorConfig,
46
+ RadarConfig,
47
+ RigidBodyConfig,
43
48
  )
44
- from common.session.views.articulation import ArticulationConfig, ArticulationJointConfig
45
- from common.session.views.camera import CameraConfig, CameraMode, DistortionModel
46
- from common.session.views.geometry import GeometryConfig, GeometryType, MeshApproximation # noqa: F401
47
- from common.session.views.ground_plane import GroundPlaneConfig
48
- from common.session.views.imu import ImuConfig
49
- from common.session.views.joint import JointAxis, JointConfig, JointType
50
- from common.session.views.light import LightConfig, LightType
51
- from common.session.views.pir_sensor import PirSensorConfig
52
- from common.session.views.radar import RadarConfig
53
- from common.session.views.rigid_body import BodyType, RigidBodyConfig
54
- from common.session.views.viewport import SetActiveViewportCamera, SetCameraView
49
+ from common.session.environment import SessionEnvironment
50
+ from common.session.sim import PrimAttributeValue, SceneQueryResponse, SceneTarget, SimulationInfo, SimulationTime
55
51
 
56
52
 
57
53
  class Scene(SessionContainer):
58
54
  """
59
- Singleton wrapper for scene-level operations and view factory.
55
+ Singleton wrapper for scene-level operations.
60
56
 
61
57
  Uses a lazy singleton pattern - the first instantiation or call to get_current()
62
58
  creates the instance, and all subsequent calls return the same instance.
@@ -68,9 +64,8 @@ class Scene(SessionContainer):
68
64
  scene = Scene() # or Scene.get_current()
69
65
  scene.clear()
70
66
  scene.toggle_ui(show_ui=False)
71
- scene.set_speed(1.0)
72
67
  scene.play()
73
- scene.step(dt=0.01)
68
+ scene.step(dt_us=1_000_000)
74
69
 
75
70
  # Add views
76
71
  geometry = scene.add_geometry(path="/World/box", ...)
@@ -278,34 +273,28 @@ class Scene(SessionContainer):
278
273
 
279
274
  self._session.query_sim_rpc(
280
275
  endpoint="set_simulation_controls",
281
- payload=SetSimulationControls(
282
- max_physics_dt_us=max_physics_dt_us,
283
- render_interval_us=render_interval_us,
284
- ),
276
+ payload={
277
+ "max_physics_dt_us": max_physics_dt_us,
278
+ "render_interval_us": render_interval_us,
279
+ },
285
280
  )
286
281
 
287
282
  def clear(self, timeout: float = 30.0) -> None:
288
283
  """
289
284
  Clear and completely reset the scene.
290
285
 
291
- Stops any running Ark before clearing the scene. If a task is active,
292
- restarts it to reset telemetry with the same configuration.
286
+ Stops any running Ark before clearing the scene.
293
287
 
294
288
  :param timeout: Timeout in seconds for stopping the Ark.
295
289
  """
296
290
 
297
- from antioch.session.task import Task
298
-
299
291
  # Always try to stop the Ark via the agent (idempotent)
300
292
  self._agent.stop_ark(timeout=timeout)
301
293
  self._ark = None
302
294
 
303
- # Clear the simulation scenne completely
295
+ # Clear the simulation scene completely
304
296
  self._session.query_sim_rpc(endpoint="clear")
305
297
 
306
- # Clear any existing task
307
- Task.get_current().clear()
308
-
309
298
  def restart(self) -> None:
310
299
  """
311
300
  Restart the simulation container.
@@ -317,8 +306,6 @@ class Scene(SessionContainer):
317
306
  Note: This function will not return as the process will be killed immediately.
318
307
  """
319
308
 
320
- from antioch.session.task import Task
321
-
322
309
  # Always try to stop the Ark via the agent (idempotent)
323
310
  self._agent.stop_ark()
324
311
  self._ark = None
@@ -326,9 +313,6 @@ class Scene(SessionContainer):
326
313
  # Restart the RPC container
327
314
  self._session.query_sim_rpc(endpoint="restart")
328
315
 
329
- # Clear any existing task
330
- Task.get_current().clear()
331
-
332
316
  def toggle_ui(self, show_ui: bool) -> None:
333
317
  """
334
318
  Toggle the Isaac Sim UI visibility.
@@ -338,7 +322,7 @@ class Scene(SessionContainer):
338
322
 
339
323
  self._session.query_sim_rpc(
340
324
  endpoint="toggle_ui",
341
- payload=ToggleUi(show_ui=show_ui),
325
+ payload={"show_ui": show_ui},
342
326
  )
343
327
 
344
328
  def set_camera_view(
@@ -357,11 +341,11 @@ class Scene(SessionContainer):
357
341
 
358
342
  self._session.query_sim_rpc(
359
343
  endpoint="set_camera_view",
360
- payload=SetCameraView(
361
- eye=Vector3.from_any(eye),
362
- target=Vector3.from_any(target),
363
- camera_prim_path=camera_prim_path,
364
- ),
344
+ payload={
345
+ "eye": Vector3.from_any(eye),
346
+ "target": Vector3.from_any(target),
347
+ "camera_prim_path": camera_prim_path,
348
+ },
365
349
  )
366
350
 
367
351
  def set_active_viewport_camera(self, camera_prim_path: str) -> None:
@@ -373,7 +357,7 @@ class Scene(SessionContainer):
373
357
 
374
358
  self._session.query_sim_rpc(
375
359
  endpoint="set_active_viewport_camera",
376
- payload=SetActiveViewportCamera(camera_prim_path=camera_prim_path),
360
+ payload={"camera_prim_path": camera_prim_path},
377
361
  )
378
362
 
379
363
  def get_prim_attribute(self, path: str, attribute_name: str) -> float | int | str | bool | list[float]:
@@ -389,9 +373,9 @@ class Scene(SessionContainer):
389
373
  """
390
374
 
391
375
  return self._session.query_sim_rpc(
392
- endpoint="get_prim_attribute_value",
376
+ endpoint="scene/get_prim_attribute_value",
393
377
  response_type=PrimAttributeValue,
394
- payload=GetPrimAttribute(path=path, attribute_name=attribute_name),
378
+ payload={"path": path, "attribute_name": attribute_name},
395
379
  ).value
396
380
 
397
381
  def set_prim_attribute(self, path: str, attribute_name: str, value: float | int | str | bool | list[float]) -> None:
@@ -408,8 +392,8 @@ class Scene(SessionContainer):
408
392
  """
409
393
 
410
394
  self._session.query_sim_rpc(
411
- endpoint="set_prim_attribute_value",
412
- payload=SetPrimAttribute(path=path, attribute_name=attribute_name, value=value),
395
+ endpoint="scene/set_prim_attribute_value",
396
+ payload={"path": path, "attribute_name": attribute_name, "value": value},
413
397
  )
414
398
 
415
399
  def query_scene(self, root_path: str = "/World", target: SceneTarget | None = None) -> SceneQueryResponse:
@@ -426,11 +410,20 @@ class Scene(SessionContainer):
426
410
  """
427
411
 
428
412
  return self._session.query_sim_rpc(
429
- endpoint="query_scene_hierarchy",
413
+ endpoint="scene/query_hierarchy",
430
414
  response_type=SceneQueryResponse,
431
- payload=QueryScene(root_path=root_path, target=target),
415
+ payload={"root_path": root_path, "target": target},
432
416
  )
433
417
 
418
+ def delete_prim(self, path: str) -> None:
419
+ """
420
+ Delete a prim from the scene.
421
+
422
+ :param path: USD path for the prim to delete.
423
+ """
424
+
425
+ self._session.query_sim_rpc(endpoint="scene/delete_prim", payload={"path": path})
426
+
434
427
  def add_asset(
435
428
  self,
436
429
  path: str,
@@ -485,18 +478,18 @@ class Scene(SessionContainer):
485
478
  if not asset_file_path:
486
479
  raise ValueError("Asset file path is required")
487
480
  self._session.query_sim_rpc(
488
- endpoint="add_asset",
489
- payload=AddAsset(
490
- path=path,
491
- asset_file_path=asset_file_path,
492
- asset_prim_path=asset_prim_path,
493
- remove_articulation=remove_articulation,
494
- remove_rigid_body=remove_rigid_body,
495
- remove_sensors=remove_sensors,
496
- world_pose=Pose.from_any(world_pose) if world_pose is not None else None,
497
- local_pose=Pose.from_any(local_pose) if local_pose is not None else None,
498
- scale=Vector3.from_any(scale) if scale is not None else None,
499
- ),
481
+ endpoint="scene/add_asset",
482
+ payload={
483
+ "path": path,
484
+ "asset_file_path": asset_file_path,
485
+ "asset_prim_path": asset_prim_path,
486
+ "remove_articulation": remove_articulation,
487
+ "remove_rigid_body": remove_rigid_body,
488
+ "remove_sensors": remove_sensors,
489
+ "world_pose": Pose.from_any(world_pose) if world_pose is not None else None,
490
+ "local_pose": Pose.from_any(local_pose) if local_pose is not None else None,
491
+ "scale": Vector3.from_any(scale) if scale is not None else None,
492
+ },
500
493
  )
501
494
  return path
502
495
 
@@ -527,7 +520,6 @@ class Scene(SessionContainer):
527
520
 
528
521
  :param path: USD path for the geometry.
529
522
  :param geometry_type: Type of geometry (sphere, cube, cylinder, cone, capsule, mesh).
530
- :param name: Optional unique name for the view.
531
523
  :param radius: Radius for sphere/cylinder/cone/capsule.
532
524
  :param height: Height for cylinder/cone/capsule.
533
525
  :param size: Size for cube (uniform).
@@ -599,7 +591,6 @@ class Scene(SessionContainer):
599
591
  Add an articulation to the scene.
600
592
 
601
593
  :param path: USD path for the articulation.
602
- :param name: Optional unique name for the view.
603
594
  :param joint_configs: Per-joint configurations (stiffness, damping, limits, etc).
604
595
  :param solver_position_iterations: Number of position iterations for the solver.
605
596
  :param solver_velocity_iterations: Number of velocity iterations for the solver.
@@ -657,7 +648,6 @@ class Scene(SessionContainer):
657
648
  :param path: USD path for the joint.
658
649
  :param parent_path: USD path to parent body.
659
650
  :param child_path: USD path to child body.
660
- :param name: Optional unique name for the view.
661
651
  :param pose: Joint pose relative to parent (defaults to identity).
662
652
  :param joint_type: Type of joint motion (FIXED, REVOLUTE, PRISMATIC).
663
653
  :param axis: Axis of motion for non-fixed joints.
@@ -715,7 +705,6 @@ class Scene(SessionContainer):
715
705
  Add rigid body physics to the scene.
716
706
 
717
707
  :param path: USD path for the rigid body.
718
- :param name: Optional unique name for the view.
719
708
  :param body_type: Body type (dynamic or kinematic).
720
709
  :param mass: Mass in kg.
721
710
  :param density: Density in kg/m³ (alternative to mass).
@@ -779,7 +768,6 @@ class Scene(SessionContainer):
779
768
  Add a light to the scene.
780
769
 
781
770
  :param path: USD path for the light.
782
- :param name: Optional unique name for the view.
783
771
  :param light_type: Type of light (sphere, rect, disk, cylinder, distant, dome).
784
772
  :param intensity: Light intensity.
785
773
  :param exposure: Light exposure value.
@@ -834,7 +822,6 @@ class Scene(SessionContainer):
834
822
  Add an xform to the scene.
835
823
 
836
824
  :param path: USD path for the xform.
837
- :param name: Optional unique name for the view.
838
825
  :param world_pose: Optional world pose as Pose (or dict with position/orientation lists).
839
826
  :param local_pose: Optional local pose as Pose (or dict with position/orientation lists).
840
827
  :param scale: Optional scale as Vector3 (or list/tuple of 3 floats).
@@ -945,8 +932,7 @@ class Scene(SessionContainer):
945
932
  """
946
933
  Add a ground plane to the scene.
947
934
 
948
- :param path: USD path for the ground plane (default: "/World/ground").
949
- :param name: Optional unique name for the view.
935
+ :param path: USD path for the ground plane.
950
936
  :param size: Size of the ground plane in meters.
951
937
  :param z_position: Z position of the ground plane.
952
938
  :param color: RGB color as Vector3 (or list/tuple of 3 floats) with values 0-1 (defaults to gray).
@@ -1004,7 +990,6 @@ class Scene(SessionContainer):
1004
990
  Add a camera to the scene.
1005
991
 
1006
992
  :param path: USD path for the camera.
1007
- :param name: Optional unique name for the camera.
1008
993
  :param config: Optional camera configuration (alternative to individual parameters).
1009
994
  :param mode: Camera capture mode (RGB or depth).
1010
995
  :param frequency: Camera update frequency in Hz.
@@ -1077,7 +1062,6 @@ class Scene(SessionContainer):
1077
1062
  Add an IMU to the scene.
1078
1063
 
1079
1064
  :param path: USD path for the IMU.
1080
- :param name: Optional unique name for the IMU.
1081
1065
  :param config: Optional IMU configuration (alternative to individual parameters).
1082
1066
  :param frequency: Sensor update frequency in Hz (optional, defaults to physics rate).
1083
1067
  :param linear_acceleration_filter_size: Filter window size for linear acceleration.
@@ -1133,7 +1117,6 @@ class Scene(SessionContainer):
1133
1117
  Add a radar to the scene.
1134
1118
 
1135
1119
  :param path: USD path for the radar.
1136
- :param name: Optional unique name for the radar.
1137
1120
  :param config: Optional radar configuration (alternative to individual parameters).
1138
1121
  :param frequency: Sensor update frequency in Hz.
1139
1122
  :param max_azimuth: Maximum azimuth angle in degrees (±FOV from center).
@@ -1176,6 +1159,9 @@ class Scene(SessionContainer):
1176
1159
  radius: float = 1.0,
1177
1160
  min_angle_deg: float = 0.0,
1178
1161
  max_angle_deg: float = 180.0,
1162
+ guide: bool = False,
1163
+ color: Vector3 | list[float] | tuple[float, float, float] | None = None,
1164
+ width: float = 0.005,
1179
1165
  ) -> BasisCurve:
1180
1166
  """
1181
1167
  Add a basis curve semi-circle to the scene.
@@ -1185,6 +1171,9 @@ class Scene(SessionContainer):
1185
1171
  :param radius: Radius of the basis curve.
1186
1172
  :param min_angle_deg: Minimum angle of the basis curve in degrees.
1187
1173
  :param max_angle_deg: Maximum angle of the basis curve in degrees.
1174
+ :param guide: If True, mark as guide purpose (invisible to cameras). If False, default purpose.
1175
+ :param color: Optional RGB color [0-1].
1176
+ :param width: Width of the curve.
1188
1177
  :return: The basis curve instance.
1189
1178
  """
1190
1179
 
@@ -1194,6 +1183,9 @@ class Scene(SessionContainer):
1194
1183
  radius=radius,
1195
1184
  min_angle_deg=min_angle_deg,
1196
1185
  max_angle_deg=max_angle_deg,
1186
+ guide=guide,
1187
+ color=Vector3.from_any(color) if color is not None else None,
1188
+ width=width,
1197
1189
  )
1198
1190
 
1199
1191
  @overload
@@ -1203,6 +1195,9 @@ class Scene(SessionContainer):
1203
1195
  *,
1204
1196
  start: Vector3 | list[float] | tuple[float, float, float],
1205
1197
  end: Vector3 | list[float] | tuple[float, float, float],
1198
+ guide: bool = False,
1199
+ color: Vector3 | list[float] | tuple[float, float, float] | None = None,
1200
+ width: float = 0.005,
1206
1201
  ) -> BasisCurve: ...
1207
1202
 
1208
1203
  @overload
@@ -1213,6 +1208,9 @@ class Scene(SessionContainer):
1213
1208
  start: Vector3 | list[float] | tuple[float, float, float],
1214
1209
  angle_deg: float,
1215
1210
  length: float,
1211
+ guide: bool = False,
1212
+ color: Vector3 | list[float] | tuple[float, float, float] | None = None,
1213
+ width: float = 0.005,
1216
1214
  ) -> BasisCurve: ...
1217
1215
 
1218
1216
  def add_basis_curve_line(
@@ -1223,6 +1221,9 @@ class Scene(SessionContainer):
1223
1221
  end: Vector3 | list[float] | tuple[float, float, float] | None = None,
1224
1222
  angle_deg: float | None = None,
1225
1223
  length: float | None = None,
1224
+ guide: bool = False,
1225
+ color: Vector3 | list[float] | tuple[float, float, float] | None = None,
1226
+ width: float = 0.005,
1226
1227
  ) -> BasisCurve:
1227
1228
  """
1228
1229
  Add a basis curve line to the scene.
@@ -1252,6 +1253,9 @@ class Scene(SessionContainer):
1252
1253
  :param end: End point of the line (Cartesian mode).
1253
1254
  :param angle_deg: Angle in degrees from +X axis in XY plane (polar mode).
1254
1255
  :param length: Length of the line (polar mode).
1256
+ :param guide: If True, mark as guide purpose (invisible to cameras). If False, default purpose.
1257
+ :param color: Optional RGB color [0-1].
1258
+ :param width: Width of the curve.
1255
1259
  :return: The basis curve instance.
1256
1260
  :raises ValueError: If both modes are specified or neither mode is complete.
1257
1261
  """
@@ -1270,6 +1274,9 @@ class Scene(SessionContainer):
1270
1274
  end=Vector3.from_any(end) if end is not None else None,
1271
1275
  angle_deg=angle_deg,
1272
1276
  length=length,
1277
+ guide=guide,
1278
+ color=Vector3.from_any(color) if color is not None else None,
1279
+ width=width,
1273
1280
  )
1274
1281
 
1275
1282
  def get_basis_curve(self, path: str) -> BasisCurve:
@@ -1282,41 +1289,6 @@ class Scene(SessionContainer):
1282
1289
 
1283
1290
  return BasisCurve(path)
1284
1291
 
1285
- def get_basis_curve_extents(self, path: str) -> tuple[Vector3, Vector3]:
1286
- """
1287
- Get the extents of the basis curve.
1288
-
1289
- :param path: USD path for the basis curve.
1290
- :return: The extents of the basis curve.
1291
- """
1292
-
1293
- return BasisCurve(path).get_extents()
1294
-
1295
- def get_basis_curve_points(
1296
- self, path: str, samples_per_segment: int = 10, sort_by: Literal["X", "Y", "Z"] | None = None, ascending: bool = True
1297
- ) -> list[Vector3]:
1298
- """
1299
- Get the points of the basis curve.
1300
-
1301
- :param path: USD path for the basis curve.
1302
- :param samples_per_segment: The number of samples per segment.
1303
- :param sort_by: The axis to sort the points by.
1304
- :param ascending: Whether to sort the points in ascending order.
1305
- :return: The points of the basis curve.
1306
- """
1307
-
1308
- return BasisCurve(path).get_points(samples_per_segment=samples_per_segment, sort_by=sort_by, ascending=ascending)
1309
-
1310
- def set_basis_curve_visibility(self, path: str, visible: bool) -> None:
1311
- """
1312
- Set the visibility of the basis curve.
1313
-
1314
- :param path: USD path for the basis curve.
1315
- :param visible: True to make visible, False to hide.
1316
- """
1317
-
1318
- BasisCurve(path).set_visibility(visible)
1319
-
1320
1292
  def get_radar(self, path: str) -> Radar:
1321
1293
  """
1322
1294
  Get existing radar from the scene.
@@ -1500,12 +1472,7 @@ class Scene(SessionContainer):
1500
1472
 
1501
1473
  return get_mesh_approximation(path)
1502
1474
 
1503
- def set_pir_material(
1504
- self,
1505
- path: str,
1506
- emissivity: float = 0.9,
1507
- temperature_c: float | None = None,
1508
- ) -> None:
1475
+ def set_pir_material(self, path: str, emissivity: float = 0.9, temperature_c: float | None = None) -> None:
1509
1476
  """
1510
1477
  Set PIR-specific thermal properties on a prim.
1511
1478
 
@@ -1523,22 +1490,33 @@ class Scene(SessionContainer):
1523
1490
 
1524
1491
  set_pir_material(path, emissivity, temperature_c)
1525
1492
 
1526
- def set_nonvisual_material(
1527
- self,
1528
- path: str,
1529
- base: str,
1530
- coating: str = "none",
1531
- attribute: str = "none",
1532
- ) -> int:
1493
+ def set_nonvisual_material(self, path: str, base: str, coating: str = "none", attribute: str = "none") -> int:
1533
1494
  """
1534
1495
  Set non-visual material properties on all Material prims in a subtree.
1535
1496
 
1536
1497
  These properties define how objects appear to RTX sensors (LiDAR and Radar).
1537
1498
 
1499
+ Valid base materials:
1500
+ Metals: aluminum, steel, oxidized_steel, iron, oxidized_iron, silver, brass,
1501
+ bronze, oxidized_bronze_patina, tin
1502
+ Polymers: plastic, fiberglass, carbon_fiber, vinyl, plexiglass, pvc, nylon, polyester
1503
+ Glass: clear_glass, frosted_glass, one_way_mirror, mirror, ceramic_glass
1504
+ Other: asphalt, concrete, leaf_grass, dead_leaf_grass, rubber, wood, bark,
1505
+ cardboard, paper, fabric, skin, fur_hair, leather, marble, brick,
1506
+ stone, gravel, dirt, mud, water, salt_water, snow, ice, calibration_lambertion
1507
+ Default: none
1508
+
1509
+ Valid coatings: none, paint, clearcoat, paint_clearcoat
1510
+
1511
+ Valid attributes: none, emissive, retroreflective, single_sided, visually_transparent
1512
+
1538
1513
  Example:
1539
1514
  # Make a person visible to radar/lidar with skin material
1540
1515
  scene.set_nonvisual_material("/World/person", base="skin")
1541
1516
 
1517
+ # Make a car with aluminum body and paint coating
1518
+ scene.set_nonvisual_material("/World/car", base="aluminum", coating="paint")
1519
+
1542
1520
  :param path: USD path of the root prim to configure.
1543
1521
  :param base: Base material type.
1544
1522
  :param coating: Coating type.
@@ -1546,7 +1524,11 @@ class Scene(SessionContainer):
1546
1524
  :return: Number of Material prims modified.
1547
1525
  """
1548
1526
 
1549
- return set_nonvisual_material(path, base, coating, attribute)
1527
+ return self._session.query_sim_rpc(
1528
+ endpoint="material/set_nonvisual",
1529
+ payload={"path": path, "base": base, "coating": coating, "attribute": attribute},
1530
+ response_type=int,
1531
+ )
1550
1532
 
1551
1533
  def _step_physics(self, dt_us: int) -> None:
1552
1534
  """
@@ -1558,5 +1540,5 @@ class Scene(SessionContainer):
1558
1540
  if dt_us > 0:
1559
1541
  self._session.query_sim_rpc(
1560
1542
  endpoint="step",
1561
- payload=Step(dt_us=dt_us),
1543
+ payload={"dt_us": dt_us},
1562
1544
  )
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import time
3
- from typing import overload
3
+ from typing import Any, overload
4
4
 
5
5
  from antioch.session.error import (
6
6
  SessionSimRpcClientError,
@@ -50,7 +50,7 @@ class Session:
50
50
 
51
51
  Example:
52
52
  session = Session.get_current()
53
- state = session.query_sim_rpc(endpoint="get_state", response_type=SimulationState)
53
+ result = session.query_sim_rpc("get_state")
54
54
  """
55
55
 
56
56
  _current: "Session | None" = None
@@ -96,11 +96,7 @@ class Session:
96
96
  """
97
97
 
98
98
  try:
99
- self.query_sim_rpc(
100
- endpoint="get_info",
101
- response_type=SimulationInfo,
102
- timeout=1.0,
103
- )
99
+ self.query_sim_rpc("get_info", response_type=SimulationInfo, timeout=1.0)
104
100
  return True
105
101
  except Exception:
106
102
  return False
@@ -141,35 +137,37 @@ class Session:
141
137
  def query_sim_rpc(
142
138
  self,
143
139
  endpoint: str,
144
- response_type: None = None,
145
- payload: Message | None = None,
140
+ payload: dict[str, Any] | None = None,
141
+ *,
146
142
  timeout: float = 60.0,
147
- ) -> None: ...
143
+ ) -> Any | None: ...
148
144
 
149
145
  @overload
150
- def query_sim_rpc[T: Message](
146
+ def query_sim_rpc[T](
151
147
  self,
152
148
  endpoint: str,
149
+ payload: dict[str, Any] | None = None,
150
+ *,
153
151
  response_type: type[T],
154
- payload: Message | None = None,
155
152
  timeout: float = 60.0,
156
153
  ) -> T: ...
157
154
 
158
- def query_sim_rpc[T: Message](
155
+ def query_sim_rpc[T](
159
156
  self,
160
157
  endpoint: str,
158
+ payload: dict[str, Any] | None = None,
159
+ *,
161
160
  response_type: type[T] | None = None,
162
- payload: Message | None = None,
163
161
  timeout: float = 60.0,
164
- ) -> T | None:
162
+ ) -> T | Any | None:
165
163
  """
166
164
  Execute a sim RPC query.
167
165
 
168
166
  :param endpoint: The sim RPC endpoint.
169
- :param response_type: Expected response payload type.
170
- :param payload: Optional request payload.
167
+ :param payload: Optional request payload dict.
168
+ :param response_type: Expected response type (Message subclass or primitive like int, str, bool).
171
169
  :param timeout: Query timeout in seconds.
172
- :return: The response payload or None if no payload.
170
+ :return: Response as typed object, arbitrary data, or None.
173
171
  :raises SessionSimRpcNotConnectedError: If the Sim RPC server is not reachable.
174
172
  :raises SessionSimRpcClientError: If the Sim RPC server returns a client error.
175
173
  :raises SessionSimRpcInternalError: If the Sim RPC server returns an internal error.
@@ -177,24 +175,33 @@ class Session:
177
175
 
178
176
  try:
179
177
  start_time = time.perf_counter() if self._debug else 0
180
-
181
- # Normal RPC call
182
- rpc_response = self._comms.query(
178
+ response = self._comms.query(
183
179
  path=f"_sim/rpc/{endpoint}",
184
180
  response_type=RpcResponse,
185
- request=RpcCall(payload=payload.pack() if payload else None),
181
+ request=RpcCall(data=payload),
186
182
  timeout=timeout or self._timeout,
187
183
  )
188
184
 
189
- result = None
190
- self._check_rpc_error(rpc_response)
191
- if response_type is not None and rpc_response.payload is not None:
192
- result = response_type.unpack(rpc_response.payload)
185
+ # Check for errors in RPC response
186
+ if response.error is not None:
187
+ if response.error.internal:
188
+ raise SessionSimRpcInternalError(message=response.error.message, traceback=response.error.traceback)
189
+ else:
190
+ raise SessionSimRpcClientError(response.error.message)
191
+
192
+ # Print elapsed time in debug mode
193
193
  if self._debug:
194
194
  elapsed_ms = (time.perf_counter() - start_time) * 1000
195
195
  print(f"[SIM-RPC] {endpoint}: {elapsed_ms:.1f}ms", flush=True)
196
196
 
197
- return result
197
+ # Return response data or None if no data
198
+ if response.data is None:
199
+ return None
200
+ if response_type is not None:
201
+ if issubclass(response_type, Message):
202
+ return response_type.model_validate(response.data)
203
+ return response.data
204
+ return response.data
198
205
 
199
206
  except TimeoutError as e:
200
207
  if not self.connected:
@@ -202,19 +209,3 @@ class Session:
202
209
  raise
203
210
  except KeyboardInterrupt as e:
204
211
  raise SessionSimRpcInterruptedError("Sim RPC interrupted") from e
205
-
206
- @staticmethod
207
- def _check_rpc_error(response: RpcResponse) -> None:
208
- """
209
- Check for errors in Sim RPC response and raise appropriate exceptions.
210
-
211
- :param response: The Sim RPC response to check.
212
- :raises SessionSimRpcInternalError: If response contains an internal error.
213
- :raises SessionSimRpcClientError: If response contains a client error.
214
- """
215
-
216
- if response.error is not None:
217
- if response.error.internal:
218
- raise SessionSimRpcInternalError(message=response.error.message, traceback=response.error.traceback)
219
- else:
220
- raise SessionSimRpcClientError(response.error.message)