antioch-py 2.0.6__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 (99) hide show
  1. antioch/__init__.py +0 -0
  2. antioch/message.py +87 -0
  3. antioch/module/__init__.py +53 -0
  4. antioch/module/clock.py +62 -0
  5. antioch/module/execution.py +278 -0
  6. antioch/module/input.py +127 -0
  7. antioch/module/module.py +218 -0
  8. antioch/module/node.py +357 -0
  9. antioch/module/token.py +42 -0
  10. antioch/session/__init__.py +150 -0
  11. antioch/session/ark.py +504 -0
  12. antioch/session/asset.py +65 -0
  13. antioch/session/error.py +80 -0
  14. antioch/session/record.py +158 -0
  15. antioch/session/scene.py +1521 -0
  16. antioch/session/session.py +220 -0
  17. antioch/session/task.py +323 -0
  18. antioch/session/views/__init__.py +40 -0
  19. antioch/session/views/animation.py +189 -0
  20. antioch/session/views/articulation.py +245 -0
  21. antioch/session/views/basis_curve.py +186 -0
  22. antioch/session/views/camera.py +92 -0
  23. antioch/session/views/collision.py +75 -0
  24. antioch/session/views/geometry.py +74 -0
  25. antioch/session/views/ground_plane.py +63 -0
  26. antioch/session/views/imu.py +73 -0
  27. antioch/session/views/joint.py +64 -0
  28. antioch/session/views/light.py +175 -0
  29. antioch/session/views/pir_sensor.py +140 -0
  30. antioch/session/views/radar.py +73 -0
  31. antioch/session/views/rigid_body.py +282 -0
  32. antioch/session/views/xform.py +119 -0
  33. antioch_py-2.0.6.dist-info/METADATA +115 -0
  34. antioch_py-2.0.6.dist-info/RECORD +99 -0
  35. antioch_py-2.0.6.dist-info/WHEEL +5 -0
  36. antioch_py-2.0.6.dist-info/entry_points.txt +2 -0
  37. antioch_py-2.0.6.dist-info/top_level.txt +2 -0
  38. common/__init__.py +0 -0
  39. common/ark/__init__.py +60 -0
  40. common/ark/ark.py +128 -0
  41. common/ark/hardware.py +121 -0
  42. common/ark/kinematics.py +31 -0
  43. common/ark/module.py +85 -0
  44. common/ark/node.py +94 -0
  45. common/ark/scheduler.py +439 -0
  46. common/ark/sim.py +33 -0
  47. common/assets/__init__.py +3 -0
  48. common/constants.py +47 -0
  49. common/core/__init__.py +52 -0
  50. common/core/agent.py +296 -0
  51. common/core/auth.py +305 -0
  52. common/core/registry.py +331 -0
  53. common/core/task.py +36 -0
  54. common/message/__init__.py +59 -0
  55. common/message/annotation.py +89 -0
  56. common/message/array.py +500 -0
  57. common/message/base.py +517 -0
  58. common/message/camera.py +91 -0
  59. common/message/color.py +139 -0
  60. common/message/frame.py +50 -0
  61. common/message/image.py +171 -0
  62. common/message/imu.py +14 -0
  63. common/message/joint.py +47 -0
  64. common/message/log.py +31 -0
  65. common/message/pir.py +16 -0
  66. common/message/point.py +109 -0
  67. common/message/point_cloud.py +63 -0
  68. common/message/pose.py +148 -0
  69. common/message/quaternion.py +273 -0
  70. common/message/radar.py +58 -0
  71. common/message/types.py +37 -0
  72. common/message/vector.py +786 -0
  73. common/rome/__init__.py +9 -0
  74. common/rome/client.py +430 -0
  75. common/rome/error.py +16 -0
  76. common/session/__init__.py +54 -0
  77. common/session/environment.py +31 -0
  78. common/session/sim.py +240 -0
  79. common/session/views/__init__.py +263 -0
  80. common/session/views/animation.py +73 -0
  81. common/session/views/articulation.py +184 -0
  82. common/session/views/basis_curve.py +102 -0
  83. common/session/views/camera.py +147 -0
  84. common/session/views/collision.py +59 -0
  85. common/session/views/geometry.py +102 -0
  86. common/session/views/ground_plane.py +41 -0
  87. common/session/views/imu.py +66 -0
  88. common/session/views/joint.py +81 -0
  89. common/session/views/light.py +96 -0
  90. common/session/views/pir_sensor.py +115 -0
  91. common/session/views/radar.py +82 -0
  92. common/session/views/rigid_body.py +236 -0
  93. common/session/views/viewport.py +21 -0
  94. common/session/views/xform.py +39 -0
  95. common/utils/__init__.py +4 -0
  96. common/utils/comms.py +571 -0
  97. common/utils/logger.py +123 -0
  98. common/utils/time.py +42 -0
  99. common/utils/usd.py +12 -0
@@ -0,0 +1,220 @@
1
+ import os
2
+ import time
3
+ from typing import overload
4
+
5
+ from antioch.session.error import (
6
+ SessionSimRpcClientError,
7
+ SessionSimRpcInternalError,
8
+ SessionSimRpcInterruptedError,
9
+ SessionSimRpcNotConnectedError,
10
+ )
11
+ from common.core.auth import AuthHandler
12
+ from common.message import Message
13
+ from common.session.sim import RpcCall, RpcResponse, SimulationInfo
14
+ from common.utils.comms import CommsSession
15
+
16
+
17
+ class SessionContainer:
18
+ """
19
+ Base class for all session containers.
20
+
21
+ Provides common functionality for accessing the session client. Session containers
22
+ include Scene, Ark, and SessionContainer subclasses. This base class only manages the
23
+ session connection - path management is delegated to SessionContainer subclasses.
24
+ """
25
+
26
+ def __init__(self):
27
+ """
28
+ Initialize the session container.
29
+ """
30
+
31
+ self._session = Session.get_current()
32
+
33
+ @property
34
+ def connected(self) -> bool:
35
+ """
36
+ Check if the session is connected to the Sim RPC server.
37
+
38
+ :return: True if connected, False otherwise.
39
+ """
40
+
41
+ return self._session.connected
42
+
43
+
44
+ class Session:
45
+ """
46
+ Singleton client for interacting with the Sim RPC server.
47
+
48
+ Uses a lazy singleton pattern - the first call to get_current() creates the instance,
49
+ and all subsequent calls return the same instance.
50
+
51
+ Example:
52
+ session = Session.get_current()
53
+ state = session.query_sim_rpc(endpoint="get_state", response_type=SimulationState)
54
+ """
55
+
56
+ _current: "Session | None" = None
57
+
58
+ def __init__(self, timeout: float = 10.0, debug: bool = False):
59
+ """
60
+ Initialize the session client.
61
+
62
+ :param timeout: Default timeout for Sim RPC calls in seconds.
63
+ :param debug: Whether to enable debug mode.
64
+ """
65
+
66
+ self._comms = CommsSession()
67
+ self._timeout = timeout
68
+ self._debug = debug or os.environ.get("ANTIOCH_RPC_PROFILE", "0") == "1"
69
+ Session._current = self
70
+
71
+ def __del__(self):
72
+ """
73
+ Close the client connection.
74
+ """
75
+
76
+ self._comms.close()
77
+
78
+ @classmethod
79
+ def get_current(cls) -> "Session":
80
+ """
81
+ Get the current session client, creating it if it doesn't exist (lazy singleton).
82
+
83
+ :return: The current session client.
84
+ """
85
+
86
+ if cls._current is None:
87
+ cls._current = Session()
88
+ return cls._current
89
+
90
+ @property
91
+ def connected(self) -> bool:
92
+ """
93
+ Check if the simulation RPC server is reachable.
94
+
95
+ :return: True if connected, False otherwise.
96
+ """
97
+
98
+ try:
99
+ self.query_sim_rpc(
100
+ endpoint="get_info",
101
+ response_type=SimulationInfo,
102
+ timeout=1.0,
103
+ )
104
+ return True
105
+ except Exception:
106
+ return False
107
+
108
+ @property
109
+ def comms(self) -> CommsSession:
110
+ """
111
+ Get the comms session.
112
+
113
+ :return: The comms session.
114
+ """
115
+
116
+ return self._comms
117
+
118
+ @property
119
+ def authenticated(self) -> bool:
120
+ """
121
+ Check if user is authenticated.
122
+
123
+ :return: True if a valid access token exists, False otherwise.
124
+ """
125
+
126
+ return AuthHandler().get_token() is not None
127
+
128
+ def login(self) -> None:
129
+ """
130
+ Authenticate user and cache access token.
131
+
132
+ Initiates OAuth2 device code flow, prompting user to visit a URL and enter a code.
133
+ The access token is cached locally for subsequent requests.
134
+
135
+ :raises AuthError: If authentication fails.
136
+ """
137
+
138
+ AuthHandler().login()
139
+
140
+ @overload
141
+ def query_sim_rpc(
142
+ self,
143
+ endpoint: str,
144
+ response_type: None = None,
145
+ payload: Message | None = None,
146
+ timeout: float = 60.0,
147
+ ) -> None: ...
148
+
149
+ @overload
150
+ def query_sim_rpc[T: Message](
151
+ self,
152
+ endpoint: str,
153
+ response_type: type[T],
154
+ payload: Message | None = None,
155
+ timeout: float = 60.0,
156
+ ) -> T: ...
157
+
158
+ def query_sim_rpc[T: Message](
159
+ self,
160
+ endpoint: str,
161
+ response_type: type[T] | None = None,
162
+ payload: Message | None = None,
163
+ timeout: float = 60.0,
164
+ ) -> T | None:
165
+ """
166
+ Execute a sim RPC query.
167
+
168
+ :param endpoint: The sim RPC endpoint.
169
+ :param response_type: Expected response payload type.
170
+ :param payload: Optional request payload.
171
+ :param timeout: Query timeout in seconds.
172
+ :return: The response payload or None if no payload.
173
+ :raises SessionSimRpcNotConnectedError: If the Sim RPC server is not reachable.
174
+ :raises SessionSimRpcClientError: If the Sim RPC server returns a client error.
175
+ :raises SessionSimRpcInternalError: If the Sim RPC server returns an internal error.
176
+ """
177
+
178
+ try:
179
+ start_time = time.perf_counter() if self._debug else 0
180
+
181
+ # Normal RPC call
182
+ rpc_response = self._comms.query(
183
+ path=f"_sim/rpc/{endpoint}",
184
+ response_type=RpcResponse,
185
+ request=RpcCall(payload=payload.pack() if payload else None),
186
+ timeout=timeout or self._timeout,
187
+ )
188
+
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)
193
+ if self._debug:
194
+ elapsed_ms = (time.perf_counter() - start_time) * 1000
195
+ print(f"[SIM-RPC] {endpoint}: {elapsed_ms:.1f}ms", flush=True)
196
+
197
+ return result
198
+
199
+ except TimeoutError as e:
200
+ if not self.connected:
201
+ raise SessionSimRpcNotConnectedError("Sim RPC server is not connected") from e
202
+ raise
203
+ except KeyboardInterrupt as e:
204
+ 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)
@@ -0,0 +1,323 @@
1
+ import json
2
+ import tarfile
3
+ import tempfile
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+
7
+ from antioch.session.error import SessionTaskError
8
+ from antioch.session.scene import Scene
9
+ from antioch.session.session import SessionContainer
10
+ from common.constants import ANTIOCH_API_URL
11
+ from common.core import Agent, AuthHandler
12
+ from common.core.task import TaskOutcome
13
+ from common.rome import RomeClient
14
+ from common.utils.logger import Logger
15
+
16
+
17
+ class Task(SessionContainer):
18
+ """
19
+ Singleton for task management and telemetry recording.
20
+
21
+ Uses a lazy singleton pattern - the first instantiation or call to get_current()
22
+ creates the instance, and all subsequent calls return the same instance.
23
+
24
+ Provides logging with simulation time context and telemetry recording.
25
+ A task represents a single simulation run with defined outcomes.
26
+ Telemetry is always streamed to WebSocket on port 8765 when started.
27
+
28
+ Example:
29
+ scene = Scene()
30
+ task = Task() # or Task.get_current()
31
+
32
+ # Start task (streams to WebSocket on port 8765)
33
+ task.start()
34
+
35
+ # Or start task with MCAP recording
36
+ task.start(mcap_path="/tmp/task_telemetry.mcap")
37
+
38
+ # Run simulation
39
+ scene.step(dt=0.01)
40
+
41
+ # Log telemetry with sim time (automatically recorded when started)
42
+ task.logger.telemetry("velocity", VelocityMessage(...))
43
+
44
+ # Finish task with outcome (finalizes telemetry and uploads to cloud)
45
+ task.finish(TaskOutcome.SUCCESS)
46
+
47
+ # Or finish without uploading MCAP
48
+ task.finish(TaskOutcome.SUCCESS, upload_mcap=False)
49
+ """
50
+
51
+ _current: "Task | None" = None
52
+
53
+ def __init__(self):
54
+ """
55
+ Initialize the task.
56
+ """
57
+
58
+ super().__init__()
59
+ self._agent = Agent()
60
+ self._scene = Scene()
61
+
62
+ self._logger: Logger | None = None
63
+ self._started = False
64
+ self._mcap_path: str | None = None
65
+
66
+ # Task metadata for cloud storage
67
+ self._ark_name: str | None = None
68
+ self._ark_version: str | None = None
69
+ self._ark_hash: str | None = None
70
+ self._task_start_time: datetime | None = None
71
+
72
+ Task._current = self
73
+
74
+ @property
75
+ def logger(self) -> Logger:
76
+ """
77
+ Get the logger with current simulation time.
78
+
79
+ Sets the logger's logical execution time to match the current
80
+ simulation time before returning. We lazy load the scene to avoid
81
+ circular dependencies.
82
+
83
+ :return: The task logger.
84
+ :raises SessionTaskError: If task has not been started.
85
+ """
86
+
87
+ if self._logger is None:
88
+ raise SessionTaskError("Task not started")
89
+
90
+ self._logger.set_let(self._scene.time_us)
91
+ return self._logger
92
+
93
+ @classmethod
94
+ def get_current(cls) -> "Task":
95
+ """
96
+ Get the current task, creating it if it doesn't exist (lazy singleton).
97
+
98
+ :return: The current task.
99
+ """
100
+
101
+ if cls._current is None:
102
+ cls._current = Task()
103
+ return cls._current
104
+
105
+ @property
106
+ def started(self) -> bool:
107
+ """
108
+ Check if the task is currently started.
109
+
110
+ :return: True if task is started, False otherwise.
111
+ """
112
+
113
+ return self._started
114
+
115
+ def start(self, mcap_path: str | None = None) -> None:
116
+ """
117
+ Start the task and begin streaming telemetry to WebSocket (always active on port 8765).
118
+ Optionally records telemetry to an MCAP file.
119
+
120
+ This operation is idempotent - calling it multiple times will finish the previous
121
+ task and start a new one.
122
+
123
+ :param mcap_path: Optional path to save MCAP telemetry file (defaults to None for no MCAP recording).
124
+ :raises SessionTaskError: If no Ark is loaded in the scene or if user is not authenticated.
125
+ """
126
+
127
+ if self._started:
128
+ print("Task already started. Finish or clear the task before starting a new one")
129
+ return
130
+
131
+ # Check that an Ark is loaded
132
+ if self._scene.ark is None:
133
+ raise SessionTaskError("No Ark loaded. Please load an Ark before starting a task")
134
+
135
+ # Get auth token
136
+ auth = AuthHandler()
137
+ token = auth.get_token()
138
+ if not token:
139
+ raise SessionTaskError("User not authenticated. Please login first")
140
+
141
+ # Store task metadata
142
+ self._ark_name = self._scene.ark.definition.name
143
+ self._ark_version = self._scene.ark.definition.info.version
144
+ self._ark_hash = self._scene.ark.definition.metadata.digest
145
+ self._task_start_time = datetime.now(timezone.utc)
146
+
147
+ # Start recording telemetry
148
+ self._agent.record_telemetry(mcap_path)
149
+
150
+ # Update task state
151
+ self._logger = Logger(self._session.comms, base_channel="task", print_logs=True)
152
+ self._started = True
153
+ self._mcap_path = mcap_path
154
+
155
+ def finish(
156
+ self,
157
+ outcome: TaskOutcome,
158
+ result: dict | None = None,
159
+ bundle_paths: list[Path] | None = None,
160
+ upload_mcap: bool = True,
161
+ show_progress: bool = True,
162
+ ) -> None:
163
+ """
164
+ Finish the task with the specified outcome and optionally upload results to cloud storage.
165
+
166
+ Resets telemetry session (finalizes MCAP file if one was created and resets time tracking).
167
+ The WebSocket server remains active.
168
+
169
+ If result and/or bundle_paths are provided, uploads them to Antioch for cloud storage.
170
+
171
+ :param outcome: The task outcome (defaults to SUCCESS).
172
+ :param result: Optional dictionary of task results (must be JSON-serializable).
173
+ :param bundle_paths: Optional list of file paths to bundle and upload to cloud storage.
174
+ :param upload_mcap: Upload MCAP file to cloud storage if one was recorded (defaults to True).
175
+ :param show_progress: Show upload progress bars (defaults to True).
176
+ :raises SessionTaskError: If task not started or if result is not JSON-serializable.
177
+ """
178
+
179
+ if not self._started:
180
+ raise SessionTaskError("Task not started")
181
+
182
+ # Validate result is JSON-serializable if provided
183
+ if result is not None:
184
+ try:
185
+ json.dumps(result)
186
+ except (TypeError, ValueError) as e:
187
+ raise SessionTaskError(f"Task result must be JSON-serializable: {e}") from e
188
+
189
+ # Validate bundle paths exist and are accessible
190
+ bundle_tar_path = None
191
+ if bundle_paths is not None and len(bundle_paths) > 0:
192
+ for path in bundle_paths:
193
+ if not Path(path).exists():
194
+ raise SessionTaskError(f"Bundle path does not exist: {path}")
195
+ if not Path(path).is_file():
196
+ raise SessionTaskError(f"Bundle path is not a file: {path}")
197
+
198
+ # Create tar.gz bundle
199
+ try:
200
+ bundle_tar_path = self._create_bundle(bundle_paths)
201
+ except Exception as e:
202
+ raise SessionTaskError(f"Failed to create bundle: {e}") from e
203
+
204
+ # Reset telemetry and save the MCAP file to disk
205
+ self._agent.reset_telemetry()
206
+
207
+ # Upload task to Antioch Cloud
208
+ try:
209
+ task_complete_time = datetime.now(timezone.utc)
210
+ self._upload_task_to_antioch(outcome, result, bundle_tar_path, task_complete_time, upload_mcap, show_progress)
211
+ except Exception as e:
212
+ raise SessionTaskError(f"Failed to upload task to Antioch Cloud: {e}") from e
213
+
214
+ # Clean up temp bundle file
215
+ if bundle_tar_path and Path(bundle_tar_path).exists():
216
+ Path(bundle_tar_path).unlink()
217
+
218
+ # Reset task state
219
+ self._logger = None
220
+ self._started = False
221
+ self._mcap_path = None
222
+ self._ark_name = None
223
+ self._ark_version = None
224
+ self._ark_hash = None
225
+ self._task_start_time = None
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
+ def _create_bundle(self, bundle_paths: list[Path]) -> str:
242
+ """
243
+ Create a tar.gz archive from the provided file paths.
244
+
245
+ :param bundle_paths: List of file paths to include in the bundle.
246
+ :return: Path to the created tar.gz file.
247
+ """
248
+
249
+ # Create temp file for the bundle
250
+ with tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False) as temp_file:
251
+ temp_path = temp_file.name
252
+ with tarfile.open(temp_path, "w:gz") as tar:
253
+ for path in bundle_paths:
254
+ tar.add(str(path), arcname=Path(path).name)
255
+
256
+ return temp_path
257
+
258
+ def _upload_task_to_antioch(
259
+ self,
260
+ outcome: TaskOutcome,
261
+ result: dict | None,
262
+ bundle_tar_path: str | None,
263
+ task_complete_time: datetime,
264
+ upload_mcap: bool,
265
+ show_progress: bool,
266
+ ) -> None:
267
+ """
268
+ Upload task completion data to Antioch Cloud.
269
+
270
+ :param outcome: The task outcome.
271
+ :param result: Optional task result dictionary.
272
+ :param bundle_tar_path: Optional path to bundle tar.gz file.
273
+ :param task_complete_time: ISO 8601 timestamp of task completion.
274
+ :param upload_mcap: Upload MCAP file if one was recorded.
275
+ :param show_progress: Show upload progress bars.
276
+ :raises SessionTaskError: If upload operations fail.
277
+ """
278
+
279
+ # Get auth token
280
+ token = AuthHandler().get_token()
281
+ if token is None:
282
+ raise SessionTaskError("User not authenticated. Please login first")
283
+
284
+ # Create Rome client
285
+ rome_client = RomeClient(api_url=ANTIOCH_API_URL, token=token)
286
+
287
+ # Assert all required fields are set (should never be None at this point)
288
+ assert self._ark_name is not None, "Ark name should be set"
289
+ assert self._ark_version is not None, "Ark version should be set"
290
+ assert self._ark_hash is not None, "Ark hash should be set"
291
+ assert self._task_start_time is not None, "Task start time should be set"
292
+
293
+ # Complete the task (creates ES entry)
294
+ try:
295
+ task_id = rome_client.complete_task(
296
+ ark_name=self._ark_name,
297
+ ark_version=self._ark_version,
298
+ ark_hash=self._ark_hash,
299
+ task_start_time=self._task_start_time,
300
+ task_complete_time=task_complete_time,
301
+ outcome=outcome,
302
+ result=result,
303
+ )
304
+ except Exception as e:
305
+ raise SessionTaskError(f"Failed to complete task in Antioch: {e}") from e
306
+
307
+ # Upload MCAP if it exists and upload_mcap is True
308
+ if upload_mcap and self._mcap_path:
309
+ if not Path(self._mcap_path).exists():
310
+ raise SessionTaskError(f"MCAP file does not exist, or is inaccessible: {self._mcap_path}")
311
+ try:
312
+ rome_client.upload_mcap(task_id=task_id, mcap_path=self._mcap_path, show_progress=show_progress)
313
+ except Exception as e:
314
+ raise SessionTaskError(f"Failed to upload MCAP to Antioch: {e}") from e
315
+
316
+ # Upload bundle if it exists
317
+ if bundle_tar_path:
318
+ if not Path(bundle_tar_path).exists():
319
+ raise SessionTaskError(f"Bundle file does not exist, or is inaccessible: {bundle_tar_path}")
320
+ try:
321
+ rome_client.upload_bundle(task_id=task_id, bundle_path=bundle_tar_path, show_progress=show_progress)
322
+ except Exception as e:
323
+ raise SessionTaskError(f"Failed to upload bundle to Antioch: {e}") from e
@@ -0,0 +1,40 @@
1
+ from antioch.session.views.animation import Animation
2
+ from antioch.session.views.articulation import Articulation
3
+ from antioch.session.views.basis_curve import BasisCurve
4
+ from antioch.session.views.camera import Camera
5
+ from antioch.session.views.collision import (
6
+ get_mesh_approximation,
7
+ has_collision,
8
+ remove_collision,
9
+ set_collision,
10
+ )
11
+ from antioch.session.views.geometry import Geometry
12
+ from antioch.session.views.ground_plane import GroundPlane
13
+ from antioch.session.views.imu import Imu
14
+ from antioch.session.views.joint import Joint
15
+ from antioch.session.views.light import Light
16
+ from antioch.session.views.pir_sensor import PirSensor, set_pir_material
17
+ from antioch.session.views.radar import Radar
18
+ from antioch.session.views.rigid_body import RigidBody
19
+ from antioch.session.views.xform import XForm
20
+
21
+ __all__ = [
22
+ "Animation",
23
+ "Articulation",
24
+ "BasisCurve",
25
+ "Camera",
26
+ "Geometry",
27
+ "GroundPlane",
28
+ "Imu",
29
+ "Joint",
30
+ "Light",
31
+ "PirSensor",
32
+ "Radar",
33
+ "RigidBody",
34
+ "XForm",
35
+ "get_mesh_approximation",
36
+ "has_collision",
37
+ "remove_collision",
38
+ "set_collision",
39
+ "set_pir_material",
40
+ ]