antioch-py 2.0.7__py3-none-any.whl → 2.1.0__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 (54) 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 +18 -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 +83 -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.1.0.dist-info}/METADATA +1 -1
  22. {antioch_py-2.0.7.dist-info → antioch_py-2.1.0.dist-info}/RECORD +33 -49
  23. common/ark/hardware.py +1 -5
  24. common/ark/kinematics.py +1 -1
  25. common/core/agent.py +28 -0
  26. common/message/__init__.py +2 -0
  27. common/message/velocity.py +11 -0
  28. common/session/__init__.py +1 -24
  29. common/session/config.py +390 -0
  30. common/session/sim.py +36 -147
  31. antioch/session/views/__init__.py +0 -42
  32. antioch/session/views/collision.py +0 -75
  33. antioch/session/views/material.py +0 -54
  34. antioch/session/views/radar.py +0 -131
  35. common/session/views/__init__.py +0 -263
  36. common/session/views/animation.py +0 -73
  37. common/session/views/articulation.py +0 -184
  38. common/session/views/basis_curve.py +0 -102
  39. common/session/views/camera.py +0 -147
  40. common/session/views/collision.py +0 -59
  41. common/session/views/geometry.py +0 -102
  42. common/session/views/ground_plane.py +0 -41
  43. common/session/views/imu.py +0 -66
  44. common/session/views/joint.py +0 -81
  45. common/session/views/light.py +0 -96
  46. common/session/views/material.py +0 -25
  47. common/session/views/pir_sensor.py +0 -119
  48. common/session/views/radar.py +0 -107
  49. common/session/views/rigid_body.py +0 -236
  50. common/session/views/viewport.py +0 -21
  51. common/session/views/xform.py +0 -39
  52. {antioch_py-2.0.7.dist-info → antioch_py-2.1.0.dist-info}/WHEEL +0 -0
  53. {antioch_py-2.0.7.dist-info → antioch_py-2.1.0.dist-info}/entry_points.txt +0 -0
  54. {antioch_py-2.0.7.dist-info → antioch_py-2.1.0.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,9 +410,9 @@ 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
 
434
418
  def add_asset(
@@ -485,18 +469,18 @@ class Scene(SessionContainer):
485
469
  if not asset_file_path:
486
470
  raise ValueError("Asset file path is required")
487
471
  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
- ),
472
+ endpoint="scene/add_asset",
473
+ payload={
474
+ "path": path,
475
+ "asset_file_path": asset_file_path,
476
+ "asset_prim_path": asset_prim_path,
477
+ "remove_articulation": remove_articulation,
478
+ "remove_rigid_body": remove_rigid_body,
479
+ "remove_sensors": remove_sensors,
480
+ "world_pose": Pose.from_any(world_pose) if world_pose is not None else None,
481
+ "local_pose": Pose.from_any(local_pose) if local_pose is not None else None,
482
+ "scale": Vector3.from_any(scale) if scale is not None else None,
483
+ },
500
484
  )
501
485
  return path
502
486
 
@@ -527,7 +511,6 @@ class Scene(SessionContainer):
527
511
 
528
512
  :param path: USD path for the geometry.
529
513
  :param geometry_type: Type of geometry (sphere, cube, cylinder, cone, capsule, mesh).
530
- :param name: Optional unique name for the view.
531
514
  :param radius: Radius for sphere/cylinder/cone/capsule.
532
515
  :param height: Height for cylinder/cone/capsule.
533
516
  :param size: Size for cube (uniform).
@@ -599,7 +582,6 @@ class Scene(SessionContainer):
599
582
  Add an articulation to the scene.
600
583
 
601
584
  :param path: USD path for the articulation.
602
- :param name: Optional unique name for the view.
603
585
  :param joint_configs: Per-joint configurations (stiffness, damping, limits, etc).
604
586
  :param solver_position_iterations: Number of position iterations for the solver.
605
587
  :param solver_velocity_iterations: Number of velocity iterations for the solver.
@@ -657,7 +639,6 @@ class Scene(SessionContainer):
657
639
  :param path: USD path for the joint.
658
640
  :param parent_path: USD path to parent body.
659
641
  :param child_path: USD path to child body.
660
- :param name: Optional unique name for the view.
661
642
  :param pose: Joint pose relative to parent (defaults to identity).
662
643
  :param joint_type: Type of joint motion (FIXED, REVOLUTE, PRISMATIC).
663
644
  :param axis: Axis of motion for non-fixed joints.
@@ -715,7 +696,6 @@ class Scene(SessionContainer):
715
696
  Add rigid body physics to the scene.
716
697
 
717
698
  :param path: USD path for the rigid body.
718
- :param name: Optional unique name for the view.
719
699
  :param body_type: Body type (dynamic or kinematic).
720
700
  :param mass: Mass in kg.
721
701
  :param density: Density in kg/m³ (alternative to mass).
@@ -779,7 +759,6 @@ class Scene(SessionContainer):
779
759
  Add a light to the scene.
780
760
 
781
761
  :param path: USD path for the light.
782
- :param name: Optional unique name for the view.
783
762
  :param light_type: Type of light (sphere, rect, disk, cylinder, distant, dome).
784
763
  :param intensity: Light intensity.
785
764
  :param exposure: Light exposure value.
@@ -834,7 +813,6 @@ class Scene(SessionContainer):
834
813
  Add an xform to the scene.
835
814
 
836
815
  :param path: USD path for the xform.
837
- :param name: Optional unique name for the view.
838
816
  :param world_pose: Optional world pose as Pose (or dict with position/orientation lists).
839
817
  :param local_pose: Optional local pose as Pose (or dict with position/orientation lists).
840
818
  :param scale: Optional scale as Vector3 (or list/tuple of 3 floats).
@@ -945,8 +923,7 @@ class Scene(SessionContainer):
945
923
  """
946
924
  Add a ground plane to the scene.
947
925
 
948
- :param path: USD path for the ground plane (default: "/World/ground").
949
- :param name: Optional unique name for the view.
926
+ :param path: USD path for the ground plane.
950
927
  :param size: Size of the ground plane in meters.
951
928
  :param z_position: Z position of the ground plane.
952
929
  :param color: RGB color as Vector3 (or list/tuple of 3 floats) with values 0-1 (defaults to gray).
@@ -1004,7 +981,6 @@ class Scene(SessionContainer):
1004
981
  Add a camera to the scene.
1005
982
 
1006
983
  :param path: USD path for the camera.
1007
- :param name: Optional unique name for the camera.
1008
984
  :param config: Optional camera configuration (alternative to individual parameters).
1009
985
  :param mode: Camera capture mode (RGB or depth).
1010
986
  :param frequency: Camera update frequency in Hz.
@@ -1077,7 +1053,6 @@ class Scene(SessionContainer):
1077
1053
  Add an IMU to the scene.
1078
1054
 
1079
1055
  :param path: USD path for the IMU.
1080
- :param name: Optional unique name for the IMU.
1081
1056
  :param config: Optional IMU configuration (alternative to individual parameters).
1082
1057
  :param frequency: Sensor update frequency in Hz (optional, defaults to physics rate).
1083
1058
  :param linear_acceleration_filter_size: Filter window size for linear acceleration.
@@ -1133,7 +1108,6 @@ class Scene(SessionContainer):
1133
1108
  Add a radar to the scene.
1134
1109
 
1135
1110
  :param path: USD path for the radar.
1136
- :param name: Optional unique name for the radar.
1137
1111
  :param config: Optional radar configuration (alternative to individual parameters).
1138
1112
  :param frequency: Sensor update frequency in Hz.
1139
1113
  :param max_azimuth: Maximum azimuth angle in degrees (±FOV from center).
@@ -1282,41 +1256,6 @@ class Scene(SessionContainer):
1282
1256
 
1283
1257
  return BasisCurve(path)
1284
1258
 
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
1259
  def get_radar(self, path: str) -> Radar:
1321
1260
  """
1322
1261
  Get existing radar from the scene.
@@ -1500,12 +1439,7 @@ class Scene(SessionContainer):
1500
1439
 
1501
1440
  return get_mesh_approximation(path)
1502
1441
 
1503
- def set_pir_material(
1504
- self,
1505
- path: str,
1506
- emissivity: float = 0.9,
1507
- temperature_c: float | None = None,
1508
- ) -> None:
1442
+ def set_pir_material(self, path: str, emissivity: float = 0.9, temperature_c: float | None = None) -> None:
1509
1443
  """
1510
1444
  Set PIR-specific thermal properties on a prim.
1511
1445
 
@@ -1523,22 +1457,33 @@ class Scene(SessionContainer):
1523
1457
 
1524
1458
  set_pir_material(path, emissivity, temperature_c)
1525
1459
 
1526
- def set_nonvisual_material(
1527
- self,
1528
- path: str,
1529
- base: str,
1530
- coating: str = "none",
1531
- attribute: str = "none",
1532
- ) -> int:
1460
+ def set_nonvisual_material(self, path: str, base: str, coating: str = "none", attribute: str = "none") -> int:
1533
1461
  """
1534
1462
  Set non-visual material properties on all Material prims in a subtree.
1535
1463
 
1536
1464
  These properties define how objects appear to RTX sensors (LiDAR and Radar).
1537
1465
 
1466
+ Valid base materials:
1467
+ Metals: aluminum, steel, oxidized_steel, iron, oxidized_iron, silver, brass,
1468
+ bronze, oxidized_bronze_patina, tin
1469
+ Polymers: plastic, fiberglass, carbon_fiber, vinyl, plexiglass, pvc, nylon, polyester
1470
+ Glass: clear_glass, frosted_glass, one_way_mirror, mirror, ceramic_glass
1471
+ Other: asphalt, concrete, leaf_grass, dead_leaf_grass, rubber, wood, bark,
1472
+ cardboard, paper, fabric, skin, fur_hair, leather, marble, brick,
1473
+ stone, gravel, dirt, mud, water, salt_water, snow, ice, calibration_lambertion
1474
+ Default: none
1475
+
1476
+ Valid coatings: none, paint, clearcoat, paint_clearcoat
1477
+
1478
+ Valid attributes: none, emissive, retroreflective, single_sided, visually_transparent
1479
+
1538
1480
  Example:
1539
1481
  # Make a person visible to radar/lidar with skin material
1540
1482
  scene.set_nonvisual_material("/World/person", base="skin")
1541
1483
 
1484
+ # Make a car with aluminum body and paint coating
1485
+ scene.set_nonvisual_material("/World/car", base="aluminum", coating="paint")
1486
+
1542
1487
  :param path: USD path of the root prim to configure.
1543
1488
  :param base: Base material type.
1544
1489
  :param coating: Coating type.
@@ -1546,7 +1491,11 @@ class Scene(SessionContainer):
1546
1491
  :return: Number of Material prims modified.
1547
1492
  """
1548
1493
 
1549
- return set_nonvisual_material(path, base, coating, attribute)
1494
+ return self._session.query_sim_rpc(
1495
+ endpoint="material/set_nonvisual",
1496
+ payload={"path": path, "base": base, "coating": coating, "attribute": attribute},
1497
+ response_type=int,
1498
+ )
1550
1499
 
1551
1500
  def _step_physics(self, dt_us: int) -> None:
1552
1501
  """
@@ -1558,5 +1507,5 @@ class Scene(SessionContainer):
1558
1507
  if dt_us > 0:
1559
1508
  self._session.query_sim_rpc(
1560
1509
  endpoint="step",
1561
- payload=Step(dt_us=dt_us),
1510
+ payload={"dt_us": dt_us},
1562
1511
  )
@@ -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)
antioch/session/task.py CHANGED
@@ -201,8 +201,8 @@ class Task(SessionContainer):
201
201
  except Exception as e:
202
202
  raise SessionTaskError(f"Failed to create bundle: {e}") from e
203
203
 
204
- # Reset telemetry and save the MCAP file to disk
205
- self._agent.reset_telemetry()
204
+ # Save the MCAP file to disk (does not reset websocket session)
205
+ self._agent.save_telemetry()
206
206
 
207
207
  # Upload task to Antioch Cloud
208
208
  try:
@@ -224,20 +224,6 @@ class Task(SessionContainer):
224
224
  self._ark_hash = None
225
225
  self._task_start_time = None
226
226
 
227
- def clear(self) -> None:
228
- """
229
- Clear the task and reset the task state.
230
- """
231
-
232
- self._agent.reset_telemetry()
233
- self._logger = None
234
- self._started = False
235
- self._mcap_path = None
236
- self._ark_name = None
237
- self._ark_version = None
238
- self._ark_hash = None
239
- self._task_start_time = None
240
-
241
227
  def _create_bundle(self, bundle_paths: list[Path]) -> str:
242
228
  """
243
229
  Create a tar.gz archive from the provided file paths.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: antioch-py
3
- Version: 2.0.7
3
+ Version: 2.1.0
4
4
  Summary: The Antioch Python SDK
5
5
  Author-email: Antioch Robotics <support@antioch.dev>
6
6
  License-Expression: MIT