antioch-py 2.0.6__py3-none-any.whl → 3.0.12__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.
- antioch/__init__.py +101 -0
- antioch/{module/execution.py → execution.py} +1 -1
- antioch/{module/input.py → input.py} +2 -4
- antioch/{module/module.py → module.py} +17 -34
- antioch/{module/node.py → node.py} +17 -16
- {antioch_py-2.0.6.dist-info → antioch_py-3.0.12.dist-info}/METADATA +8 -11
- antioch_py-3.0.12.dist-info/RECORD +61 -0
- {antioch_py-2.0.6.dist-info → antioch_py-3.0.12.dist-info}/WHEEL +1 -1
- antioch_py-3.0.12.dist-info/licenses/LICENSE +21 -0
- common/ark/__init__.py +6 -16
- common/ark/ark.py +23 -60
- common/ark/hardware.py +13 -37
- common/ark/kinematics.py +1 -1
- common/ark/module.py +22 -0
- common/ark/node.py +46 -3
- common/ark/scheduler.py +2 -29
- common/ark/sim.py +1 -1
- {antioch/module → common/ark}/token.py +17 -0
- common/assets/rigging.usd +0 -0
- common/constants.py +83 -4
- common/core/__init__.py +37 -24
- common/core/auth.py +87 -114
- common/core/container.py +261 -0
- common/core/registry.py +131 -152
- common/core/rome.py +251 -0
- common/core/telemetry.py +176 -0
- common/core/types.py +219 -0
- common/message/__init__.py +19 -3
- common/message/annotation.py +174 -23
- common/message/array.py +25 -1
- common/message/camera.py +23 -1
- common/message/color.py +32 -6
- common/message/detection.py +40 -0
- common/message/foxglove.py +20 -0
- common/message/frame.py +71 -7
- common/message/image.py +58 -9
- common/message/imu.py +24 -4
- common/message/joint.py +69 -10
- common/message/log.py +52 -7
- common/message/pir.py +22 -5
- common/message/plot.py +57 -0
- common/message/point.py +55 -6
- common/message/point_cloud.py +55 -19
- common/message/pose.py +59 -19
- common/message/quaternion.py +105 -92
- common/message/radar.py +195 -29
- common/message/twist.py +34 -0
- common/message/types.py +40 -5
- common/message/vector.py +180 -245
- common/sim/__init__.py +49 -0
- common/sim/objects.py +460 -0
- common/sim/state.py +11 -0
- common/utils/comms.py +30 -12
- common/utils/logger.py +26 -7
- antioch/message.py +0 -87
- antioch/module/__init__.py +0 -53
- antioch/session/__init__.py +0 -150
- antioch/session/ark.py +0 -504
- antioch/session/asset.py +0 -65
- antioch/session/error.py +0 -80
- antioch/session/record.py +0 -158
- antioch/session/scene.py +0 -1521
- antioch/session/session.py +0 -220
- antioch/session/task.py +0 -323
- antioch/session/views/__init__.py +0 -40
- antioch/session/views/animation.py +0 -189
- antioch/session/views/articulation.py +0 -245
- antioch/session/views/basis_curve.py +0 -186
- antioch/session/views/camera.py +0 -92
- antioch/session/views/collision.py +0 -75
- antioch/session/views/geometry.py +0 -74
- antioch/session/views/ground_plane.py +0 -63
- antioch/session/views/imu.py +0 -73
- antioch/session/views/joint.py +0 -64
- antioch/session/views/light.py +0 -175
- antioch/session/views/pir_sensor.py +0 -140
- antioch/session/views/radar.py +0 -73
- antioch/session/views/rigid_body.py +0 -282
- antioch/session/views/xform.py +0 -119
- antioch_py-2.0.6.dist-info/RECORD +0 -99
- antioch_py-2.0.6.dist-info/entry_points.txt +0 -2
- common/core/agent.py +0 -296
- common/core/task.py +0 -36
- common/rome/__init__.py +0 -9
- common/rome/client.py +0 -430
- common/rome/error.py +0 -16
- common/session/__init__.py +0 -54
- common/session/environment.py +0 -31
- common/session/sim.py +0 -240
- common/session/views/__init__.py +0 -263
- common/session/views/animation.py +0 -73
- common/session/views/articulation.py +0 -184
- common/session/views/basis_curve.py +0 -102
- common/session/views/camera.py +0 -147
- common/session/views/collision.py +0 -59
- common/session/views/geometry.py +0 -102
- common/session/views/ground_plane.py +0 -41
- common/session/views/imu.py +0 -66
- common/session/views/joint.py +0 -81
- common/session/views/light.py +0 -96
- common/session/views/pir_sensor.py +0 -115
- common/session/views/radar.py +0 -82
- common/session/views/rigid_body.py +0 -236
- common/session/views/viewport.py +0 -21
- common/session/views/xform.py +0 -39
- common/utils/usd.py +0 -12
- /antioch/{module/clock.py → clock.py} +0 -0
- {antioch_py-2.0.6.dist-info → antioch_py-3.0.12.dist-info}/top_level.txt +0 -0
- /common/message/{base.py → message.py} +0 -0
antioch/session/ark.py
DELETED
|
@@ -1,504 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import TYPE_CHECKING, cast
|
|
3
|
-
|
|
4
|
-
from antioch.module.token import TokenType
|
|
5
|
-
from antioch.session.error import SessionArkError, SessionAssetError
|
|
6
|
-
from antioch.session.record import NodeOutputRecorder
|
|
7
|
-
from antioch.session.session import SessionContainer
|
|
8
|
-
from antioch.session.views.articulation import Articulation
|
|
9
|
-
from antioch.session.views.camera import Camera
|
|
10
|
-
from antioch.session.views.imu import Imu
|
|
11
|
-
from antioch.session.views.pir_sensor import PirSensor
|
|
12
|
-
from antioch.session.views.radar import Radar
|
|
13
|
-
from common.ark import Ark as ArkDefinition, ArkReference, Environment, HardwareAccessMode
|
|
14
|
-
from common.ark.hardware import ActuatorGroupHardware, CameraHardware, HardwareType, ImuHardware, PirHardware, RadarHardware
|
|
15
|
-
from common.ark.scheduler import NodeCompleteEvent, NodeStartEvent, OnlineScheduler
|
|
16
|
-
from common.ark.sim import SimNodeComplete, SimNodeStart
|
|
17
|
-
from common.core import (
|
|
18
|
-
Agent,
|
|
19
|
-
ArkStateResponse,
|
|
20
|
-
ContainerSource,
|
|
21
|
-
get_ark_version_reference,
|
|
22
|
-
list_local_arks,
|
|
23
|
-
list_remote_arks,
|
|
24
|
-
load_local_ark,
|
|
25
|
-
pull_remote_ark,
|
|
26
|
-
)
|
|
27
|
-
from common.message import JointStates, JointTargets, Pose
|
|
28
|
-
from common.utils.comms import CommsAsyncSubscriber, CommsPublisher
|
|
29
|
-
from common.utils.time import now_us, us_to_s
|
|
30
|
-
from common.utils.usd import sanitize_usd_path
|
|
31
|
-
|
|
32
|
-
if TYPE_CHECKING:
|
|
33
|
-
from antioch.session.scene import Scene
|
|
34
|
-
|
|
35
|
-
NODE_START_PUBLISHER_PATH = "_ark/node_start/{module}/{node}"
|
|
36
|
-
NODE_COMPLETE_SUBSCRIBER_PATH = "_ark/node_complete/{module}/{node}"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class Ark(SessionContainer):
|
|
40
|
-
"""
|
|
41
|
-
Complete runtime for an Ark in simulation.
|
|
42
|
-
|
|
43
|
-
Manages entire Ark lifecycle from loading through execution. The runtime is designed to be
|
|
44
|
-
robust and deterministic:
|
|
45
|
-
- Events/time increase monotonically via the deterministic scheduler
|
|
46
|
-
- Each execution is processed exactly once via execution tracking
|
|
47
|
-
- Multiple nodes can execute at the same LET
|
|
48
|
-
|
|
49
|
-
Example:
|
|
50
|
-
scene = Scene()
|
|
51
|
-
|
|
52
|
-
# Build and start Ark
|
|
53
|
-
ark = scene.add_ark(
|
|
54
|
-
name="my_robot",
|
|
55
|
-
version="1.0.0",
|
|
56
|
-
debug=True
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
# Step simulation
|
|
60
|
-
scene.step(dt=0.01) # Delegates to ark.step()
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
def __init__(
|
|
64
|
-
self,
|
|
65
|
-
path: str,
|
|
66
|
-
scene: "Scene",
|
|
67
|
-
name: str,
|
|
68
|
-
version: str,
|
|
69
|
-
world_pose: Pose | None = None,
|
|
70
|
-
local_pose: Pose | None = None,
|
|
71
|
-
source: ContainerSource = ContainerSource.LOCAL,
|
|
72
|
-
debug: bool = False,
|
|
73
|
-
timeout: float = 30.0,
|
|
74
|
-
):
|
|
75
|
-
"""
|
|
76
|
-
Initialize and build complete Ark runtime.
|
|
77
|
-
|
|
78
|
-
:param path: USD path where the Ark will be built.
|
|
79
|
-
:param scene: Scene instance this Ark belongs to.
|
|
80
|
-
:param name: Name of the Ark.
|
|
81
|
-
:param version: Version of the Ark.
|
|
82
|
-
:param world_pose: Optional world pose.
|
|
83
|
-
:param local_pose: Optional local pose.
|
|
84
|
-
:param source: Container image source.
|
|
85
|
-
:param debug: Enable debug mode.
|
|
86
|
-
:param timeout: Timeout in seconds for the Ark to start.
|
|
87
|
-
"""
|
|
88
|
-
|
|
89
|
-
super().__init__()
|
|
90
|
-
self._path = path
|
|
91
|
-
self._scene = scene
|
|
92
|
-
self._agent = Agent()
|
|
93
|
-
|
|
94
|
-
# Load Ark definition
|
|
95
|
-
self._ark_def = load_local_ark(name, version)
|
|
96
|
-
self._ark_ref = get_ark_version_reference(name, version)
|
|
97
|
-
self._base_path = f"{path}/{sanitize_usd_path(self._ark_def.name)}"
|
|
98
|
-
|
|
99
|
-
# Start Ark via agent
|
|
100
|
-
self._agent.start_ark(
|
|
101
|
-
ark=self._ark_def,
|
|
102
|
-
source=source,
|
|
103
|
-
environment=Environment.SIM,
|
|
104
|
-
debug=debug,
|
|
105
|
-
timeout=timeout,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
# Initialize scheduler
|
|
109
|
-
self._scheduler = OnlineScheduler(self._ark_def.edges, self._ark_def.modules)
|
|
110
|
-
self._next_event = self._scheduler.next()
|
|
111
|
-
self._node_start_times_us: dict[tuple[str, str], int] = {}
|
|
112
|
-
|
|
113
|
-
# Create publishers and subscribers for node coordination
|
|
114
|
-
self._node_start_publishers: dict[tuple[str, str], CommsPublisher] = {}
|
|
115
|
-
self._node_complete_subscribers: dict[tuple[str, str], CommsAsyncSubscriber] = {}
|
|
116
|
-
for module in self._ark_def.modules:
|
|
117
|
-
for node_name in module.nodes:
|
|
118
|
-
start_path = NODE_START_PUBLISHER_PATH.format(module=module.name, node=node_name)
|
|
119
|
-
complete_path = NODE_COMPLETE_SUBSCRIBER_PATH.format(module=module.name, node=node_name)
|
|
120
|
-
self._node_start_publishers[(module.name, node_name)] = self._session.comms.declare_publisher(start_path)
|
|
121
|
-
self._node_complete_subscribers[(module.name, node_name)] = self._session.comms.declare_async_subscriber(complete_path)
|
|
122
|
-
|
|
123
|
-
# Build in scene
|
|
124
|
-
self._load_ark_asset(world_pose=world_pose, local_pose=local_pose)
|
|
125
|
-
self._build_hardware()
|
|
126
|
-
|
|
127
|
-
@property
|
|
128
|
-
def path(self) -> str:
|
|
129
|
-
"""
|
|
130
|
-
Get the USD path where this Ark is built.
|
|
131
|
-
|
|
132
|
-
:return: The USD path of this Ark.
|
|
133
|
-
"""
|
|
134
|
-
|
|
135
|
-
return self._path
|
|
136
|
-
|
|
137
|
-
@property
|
|
138
|
-
def definition(self) -> ArkDefinition:
|
|
139
|
-
"""
|
|
140
|
-
Get the Ark definition.
|
|
141
|
-
|
|
142
|
-
:return: The Ark definition.
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
return self._ark_def
|
|
146
|
-
|
|
147
|
-
@property
|
|
148
|
-
def name(self) -> str:
|
|
149
|
-
"""
|
|
150
|
-
Get the Ark name.
|
|
151
|
-
|
|
152
|
-
:return: The Ark name.
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
return self._ark_def.name
|
|
156
|
-
|
|
157
|
-
@property
|
|
158
|
-
def state(self) -> ArkStateResponse:
|
|
159
|
-
"""
|
|
160
|
-
Get current state of all modules.
|
|
161
|
-
|
|
162
|
-
:return: Ark state with module information.
|
|
163
|
-
"""
|
|
164
|
-
|
|
165
|
-
return self._agent.get_ark_state()
|
|
166
|
-
|
|
167
|
-
@staticmethod
|
|
168
|
-
def list_local() -> list[ArkReference]:
|
|
169
|
-
"""
|
|
170
|
-
List all locally available Arks.
|
|
171
|
-
|
|
172
|
-
:return: List of ArkReference objects from local storage.
|
|
173
|
-
"""
|
|
174
|
-
|
|
175
|
-
return list_local_arks()
|
|
176
|
-
|
|
177
|
-
@staticmethod
|
|
178
|
-
def list_remote() -> list[ArkReference]:
|
|
179
|
-
"""
|
|
180
|
-
List all Arks from remote registry.
|
|
181
|
-
|
|
182
|
-
Requires authentication. Call session.login() first if not authenticated.
|
|
183
|
-
|
|
184
|
-
:return: List of ArkReference objects from remote registry.
|
|
185
|
-
:raises SessionAuthError: If not authenticated.
|
|
186
|
-
"""
|
|
187
|
-
|
|
188
|
-
return list_remote_arks()
|
|
189
|
-
|
|
190
|
-
@staticmethod
|
|
191
|
-
def pull(name: str, version: str, overwrite: bool = False) -> ArkDefinition:
|
|
192
|
-
"""
|
|
193
|
-
Pull an Ark from remote registry to local storage.
|
|
194
|
-
|
|
195
|
-
Requires authentication. Call session.login() first if not authenticated.
|
|
196
|
-
If the Ark already exists locally, returns the existing Ark unless overwrite=True.
|
|
197
|
-
|
|
198
|
-
:param name: Name of the Ark.
|
|
199
|
-
:param version: Version of the Ark.
|
|
200
|
-
:param overwrite: Overwrite local Ark if it already exists.
|
|
201
|
-
:return: The loaded Ark definition.
|
|
202
|
-
:raises SessionAuthError: If not authenticated.
|
|
203
|
-
"""
|
|
204
|
-
|
|
205
|
-
return pull_remote_ark(name=name, version=version, overwrite=overwrite)
|
|
206
|
-
|
|
207
|
-
def step(self, dt_us: int = 1_000_000) -> None:
|
|
208
|
-
"""
|
|
209
|
-
Step the Ark simulation forward by exactly dt_us microseconds.
|
|
210
|
-
|
|
211
|
-
:param dt_us: Amount of time to step in microseconds (default 1 second).
|
|
212
|
-
"""
|
|
213
|
-
|
|
214
|
-
current_sim_time_us = self._scene.time_us
|
|
215
|
-
target_sim_time_us = current_sim_time_us + dt_us
|
|
216
|
-
while current_sim_time_us < target_sim_time_us:
|
|
217
|
-
event = self._next_event
|
|
218
|
-
|
|
219
|
-
# Step physics directly to target time and break
|
|
220
|
-
if event.let_us > target_sim_time_us:
|
|
221
|
-
self._scene._step_physics(target_sim_time_us - current_sim_time_us)
|
|
222
|
-
break
|
|
223
|
-
|
|
224
|
-
# Step physics to event time if needed
|
|
225
|
-
if event.let_us > current_sim_time_us:
|
|
226
|
-
self._scene._step_physics(event.let_us - current_sim_time_us)
|
|
227
|
-
current_sim_time_us = self._scene.time_us
|
|
228
|
-
|
|
229
|
-
# Node start: read hardware for node and send non-blocking start to nodes
|
|
230
|
-
if isinstance(event, NodeStartEvent):
|
|
231
|
-
hardware_reads = self._read_node_hardware(event.module, event.node)
|
|
232
|
-
self._node_start_times_us[(event.module, event.node)] = now_us()
|
|
233
|
-
self._node_start_publishers[(event.module, event.node)].publish(
|
|
234
|
-
SimNodeStart(
|
|
235
|
-
module_name=event.module,
|
|
236
|
-
node_name=event.node,
|
|
237
|
-
start_let_us=event.start_let_us,
|
|
238
|
-
start_timestamp_us=self._node_start_times_us[(event.module, event.node)],
|
|
239
|
-
input_tokens=event.input_tokens,
|
|
240
|
-
hardware_reads=hardware_reads,
|
|
241
|
-
)
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
# Node complete: wait for completion message or budget to elapse and write hardware for node
|
|
245
|
-
elif isinstance(event, NodeCompleteEvent):
|
|
246
|
-
node_config = next(m for m in self._ark_def.modules if m.name == event.module).nodes[event.node]
|
|
247
|
-
node_complete_subscriber = self._node_complete_subscribers[(event.module, event.node)]
|
|
248
|
-
target_time_us = self._node_start_times_us[(event.module, event.node)] + node_config.budget_us
|
|
249
|
-
while True:
|
|
250
|
-
remaining_time_s = us_to_s(max(0, target_time_us - now_us()))
|
|
251
|
-
complete = node_complete_subscriber.recv_timeout(SimNodeComplete, timeout=remaining_time_s)
|
|
252
|
-
if complete is None and now_us() > target_time_us:
|
|
253
|
-
break
|
|
254
|
-
if complete is not None and complete.completion_let_us == event.completion_let_us:
|
|
255
|
-
if complete.hardware_writes is not None:
|
|
256
|
-
self._write_node_hardware(event.module, event.node, complete.hardware_writes)
|
|
257
|
-
break
|
|
258
|
-
|
|
259
|
-
# Fetch next event
|
|
260
|
-
self._next_event = self._scheduler.next()
|
|
261
|
-
|
|
262
|
-
def get_articulation(self) -> Articulation:
|
|
263
|
-
"""
|
|
264
|
-
Get the articulation for the Ark.
|
|
265
|
-
|
|
266
|
-
:return: The articulation instance.
|
|
267
|
-
"""
|
|
268
|
-
|
|
269
|
-
return self._articulation
|
|
270
|
-
|
|
271
|
-
def get_camera(self, module_name: str, hardware_name: str) -> Camera:
|
|
272
|
-
"""
|
|
273
|
-
Get camera hardware view.
|
|
274
|
-
|
|
275
|
-
:param module_name: Module name.
|
|
276
|
-
:param hardware_name: Hardware name.
|
|
277
|
-
:return: Camera view.
|
|
278
|
-
"""
|
|
279
|
-
|
|
280
|
-
if (module_name, hardware_name) not in self._cameras:
|
|
281
|
-
raise SessionArkError(f"Camera '{hardware_name}' not found in module '{module_name}'")
|
|
282
|
-
return self._cameras[(module_name, hardware_name)]
|
|
283
|
-
|
|
284
|
-
def get_imu(self, module_name: str, hardware_name: str) -> Imu:
|
|
285
|
-
"""
|
|
286
|
-
Get IMU hardware view.
|
|
287
|
-
|
|
288
|
-
:param module_name: Module name.
|
|
289
|
-
:param hardware_name: Hardware name.
|
|
290
|
-
:return: IMU view.
|
|
291
|
-
"""
|
|
292
|
-
|
|
293
|
-
if (module_name, hardware_name) not in self._imus:
|
|
294
|
-
raise SessionArkError(f"IMU '{hardware_name}' not found in module '{module_name}'")
|
|
295
|
-
return self._imus[(module_name, hardware_name)]
|
|
296
|
-
|
|
297
|
-
def get_radar(self, module_name: str, hardware_name: str) -> Radar:
|
|
298
|
-
"""
|
|
299
|
-
Get radar hardware view.
|
|
300
|
-
|
|
301
|
-
:param module_name: Module name.
|
|
302
|
-
:param hardware_name: Hardware name.
|
|
303
|
-
:return: Radar view.
|
|
304
|
-
"""
|
|
305
|
-
|
|
306
|
-
if (module_name, hardware_name) not in self._radars:
|
|
307
|
-
raise SessionArkError(f"Radar '{hardware_name}' not found in module '{module_name}'")
|
|
308
|
-
return self._radars[(module_name, hardware_name)]
|
|
309
|
-
|
|
310
|
-
def get_pir(self, module_name: str, hardware_name: str) -> PirSensor:
|
|
311
|
-
"""
|
|
312
|
-
Get PIR sensor hardware view.
|
|
313
|
-
|
|
314
|
-
:param module_name: Module name.
|
|
315
|
-
:param hardware_name: Hardware name.
|
|
316
|
-
:return: PIR sensor view.
|
|
317
|
-
"""
|
|
318
|
-
|
|
319
|
-
if (module_name, hardware_name) not in self._pirs:
|
|
320
|
-
raise SessionArkError(f"PIR sensor '{hardware_name}' not found in module '{module_name}'")
|
|
321
|
-
return self._pirs[(module_name, hardware_name)]
|
|
322
|
-
|
|
323
|
-
def list_hardware(self) -> dict[str, list[tuple[str, str]]]:
|
|
324
|
-
"""
|
|
325
|
-
List all hardware in the Ark.
|
|
326
|
-
|
|
327
|
-
:return: Dictionary of hardware (module name, hardware name) keyed by hardware type.
|
|
328
|
-
"""
|
|
329
|
-
|
|
330
|
-
return {
|
|
331
|
-
"CAMERA": list(self._cameras.keys()),
|
|
332
|
-
"IMU": list(self._imus.keys()),
|
|
333
|
-
"PIR": list(self._pirs.keys()),
|
|
334
|
-
"RADAR": list(self._radars.keys()),
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
def record_node_output(
|
|
338
|
-
self,
|
|
339
|
-
module_name: str,
|
|
340
|
-
node_name: str,
|
|
341
|
-
output_name: str,
|
|
342
|
-
token_type: TokenType | None = TokenType.DATA,
|
|
343
|
-
last_n: int = 10,
|
|
344
|
-
) -> NodeOutputRecorder:
|
|
345
|
-
"""
|
|
346
|
-
Create a recorder for monitoring node output tokens.
|
|
347
|
-
|
|
348
|
-
:param module_name: Module name.
|
|
349
|
-
:param node_name: Node name within module.
|
|
350
|
-
:param output_name: Output name within node.
|
|
351
|
-
:param token_type: Token type to record (default: TokenType.DATA, None = all types).
|
|
352
|
-
:param last_n: Number of recent tokens to buffer.
|
|
353
|
-
:return: NodeOutputRecorder instance.
|
|
354
|
-
"""
|
|
355
|
-
|
|
356
|
-
return NodeOutputRecorder(
|
|
357
|
-
comms=self._session.comms,
|
|
358
|
-
ark_def=self._ark_def,
|
|
359
|
-
module_name=module_name,
|
|
360
|
-
node_name=node_name,
|
|
361
|
-
output_name=output_name,
|
|
362
|
-
token_type=token_type,
|
|
363
|
-
last_n=last_n,
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
def _read_node_hardware(self, module_name: str, node_name: str) -> dict[str, bytes]:
|
|
367
|
-
"""
|
|
368
|
-
Read hardware state for node execution.
|
|
369
|
-
|
|
370
|
-
:param module_name: Module name.
|
|
371
|
-
:param node_name: Node name.
|
|
372
|
-
:return: Hardware reads keyed by hardware name.
|
|
373
|
-
"""
|
|
374
|
-
|
|
375
|
-
hardware_reads = {}
|
|
376
|
-
node_def = next(m for m in self._ark_def.modules if m.name == module_name).nodes[node_name]
|
|
377
|
-
for hardware_name, access_mode in node_def.hardware_access.items():
|
|
378
|
-
if access_mode not in (HardwareAccessMode.READ, HardwareAccessMode.READ_WRITE):
|
|
379
|
-
continue
|
|
380
|
-
|
|
381
|
-
# Read from camera
|
|
382
|
-
if camera := self._cameras.get((module_name, hardware_name)):
|
|
383
|
-
camera_frame = camera.get_frame()
|
|
384
|
-
if camera_frame is not None:
|
|
385
|
-
hardware_reads[hardware_name] = camera_frame.pack()
|
|
386
|
-
|
|
387
|
-
# Read from IMU
|
|
388
|
-
elif imu := self._imus.get((module_name, hardware_name)):
|
|
389
|
-
imu_sample = imu.get_sample()
|
|
390
|
-
if imu_sample is not None:
|
|
391
|
-
hardware_reads[hardware_name] = imu_sample.pack()
|
|
392
|
-
|
|
393
|
-
# Read from radar
|
|
394
|
-
elif radar := self._radars.get((module_name, hardware_name)):
|
|
395
|
-
radar_scan = radar.get_scan()
|
|
396
|
-
if radar_scan is not None:
|
|
397
|
-
hardware_reads[hardware_name] = radar_scan.pack()
|
|
398
|
-
|
|
399
|
-
# Read from PIR sensor
|
|
400
|
-
elif pir := self._pirs.get((module_name, hardware_name)):
|
|
401
|
-
pir_status = pir.get_detection_status()
|
|
402
|
-
if pir_status is not None:
|
|
403
|
-
hardware_reads[hardware_name] = pir_status.pack()
|
|
404
|
-
|
|
405
|
-
# Read from actuator group
|
|
406
|
-
else:
|
|
407
|
-
joint_states = self._articulation.get_joint_states()
|
|
408
|
-
if joint_states is not None:
|
|
409
|
-
hardware_reads[hardware_name] = JointStates(states=joint_states).pack()
|
|
410
|
-
|
|
411
|
-
return hardware_reads
|
|
412
|
-
|
|
413
|
-
def _write_node_hardware(self, module_name: str, node_name: str, hardware_writes: dict[str, bytes]) -> None:
|
|
414
|
-
"""
|
|
415
|
-
Write hardware state from node execution.
|
|
416
|
-
|
|
417
|
-
:param module_name: Module name.
|
|
418
|
-
:param node_name: Node name.
|
|
419
|
-
:param hardware_writes: Hardware writes keyed by hardware name.
|
|
420
|
-
"""
|
|
421
|
-
|
|
422
|
-
node_def = next(m for m in self._ark_def.modules if m.name == module_name).nodes[node_name]
|
|
423
|
-
for hardware_name, write_data in hardware_writes.items():
|
|
424
|
-
access_mode = node_def.hardware_access.get(hardware_name)
|
|
425
|
-
if access_mode not in (HardwareAccessMode.WRITE, HardwareAccessMode.READ_WRITE):
|
|
426
|
-
continue
|
|
427
|
-
|
|
428
|
-
# Write to actuator group
|
|
429
|
-
targets = JointTargets.unpack(write_data)
|
|
430
|
-
self._articulation.set_joint_targets(joint_targets=targets.targets)
|
|
431
|
-
|
|
432
|
-
def _build_hardware(self) -> None:
|
|
433
|
-
"""
|
|
434
|
-
Create articulation and sensor views from hardware configs.
|
|
435
|
-
"""
|
|
436
|
-
|
|
437
|
-
actuator_group_configs = [
|
|
438
|
-
cast(ActuatorGroupHardware, hardware.config)
|
|
439
|
-
for hardware in self._ark_def.hardware
|
|
440
|
-
if hardware.type == HardwareType.ACTUATOR_GROUP
|
|
441
|
-
]
|
|
442
|
-
|
|
443
|
-
# Create single articulation view with all joint configs from actuator groups
|
|
444
|
-
self._articulation = self._scene.add_articulation(
|
|
445
|
-
path=self._base_path,
|
|
446
|
-
joint_configs=sum([config.config.joint_configs for config in actuator_group_configs], []),
|
|
447
|
-
)
|
|
448
|
-
|
|
449
|
-
# Create sensor views
|
|
450
|
-
self._cameras: dict[tuple[str, str], Camera] = {}
|
|
451
|
-
self._imus: dict[tuple[str, str], Imu] = {}
|
|
452
|
-
self._pirs: dict[tuple[str, str], PirSensor] = {}
|
|
453
|
-
self._radars: dict[tuple[str, str], Radar] = {}
|
|
454
|
-
for hardware in self._ark_def.hardware:
|
|
455
|
-
if hardware.type == HardwareType.CAMERA:
|
|
456
|
-
camera_hw = cast(CameraHardware, hardware.config)
|
|
457
|
-
self._cameras[(camera_hw.module, camera_hw.name)] = self._scene.add_camera(
|
|
458
|
-
path=f"{self._base_path}{camera_hw.path}",
|
|
459
|
-
config=camera_hw.config,
|
|
460
|
-
local_pose=camera_hw.pose,
|
|
461
|
-
)
|
|
462
|
-
|
|
463
|
-
elif hardware.type == HardwareType.IMU:
|
|
464
|
-
imu_hw = cast(ImuHardware, hardware.config)
|
|
465
|
-
self._imus[(imu_hw.module, imu_hw.name)] = self._scene.add_imu(
|
|
466
|
-
path=f"{self._base_path}{imu_hw.path}",
|
|
467
|
-
config=imu_hw.config,
|
|
468
|
-
local_pose=imu_hw.pose,
|
|
469
|
-
)
|
|
470
|
-
|
|
471
|
-
elif hardware.type == HardwareType.PIR:
|
|
472
|
-
pir_hw = cast(PirHardware, hardware.config)
|
|
473
|
-
self._pirs[(pir_hw.module, pir_hw.name)] = self._scene.add_pir_sensor(
|
|
474
|
-
path=f"{self._base_path}{pir_hw.path}",
|
|
475
|
-
config=pir_hw.config,
|
|
476
|
-
local_pose=pir_hw.pose,
|
|
477
|
-
)
|
|
478
|
-
|
|
479
|
-
elif hardware.type == HardwareType.RADAR:
|
|
480
|
-
radar_hw = cast(RadarHardware, hardware.config)
|
|
481
|
-
self._radars[(radar_hw.module, radar_hw.name)] = self._scene.add_radar(
|
|
482
|
-
path=f"{self._base_path}{radar_hw.path}",
|
|
483
|
-
config=radar_hw.config,
|
|
484
|
-
local_pose=radar_hw.pose,
|
|
485
|
-
)
|
|
486
|
-
|
|
487
|
-
def _load_ark_asset(self, world_pose: Pose | None = None, local_pose: Pose | None = None) -> None:
|
|
488
|
-
"""
|
|
489
|
-
Load the asset for the Ark.
|
|
490
|
-
|
|
491
|
-
:param world_pose: Optional world pose.
|
|
492
|
-
:param local_pose: Optional local pose.
|
|
493
|
-
:raises SessionAssetError: If the asset file is not found.
|
|
494
|
-
"""
|
|
495
|
-
|
|
496
|
-
if (asset_path := self._ark_ref.asset_path) is None or not os.path.exists(asset_path):
|
|
497
|
-
raise SessionAssetError(f"Asset file not found for Ark {self._ark_def.name}")
|
|
498
|
-
|
|
499
|
-
self._scene.add_asset(
|
|
500
|
-
path=self._base_path,
|
|
501
|
-
asset_file_path=asset_path,
|
|
502
|
-
world_pose=world_pose,
|
|
503
|
-
local_pose=local_pose,
|
|
504
|
-
)
|
antioch/session/asset.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from antioch.session.session import SessionContainer
|
|
4
|
-
from common.ark import AssetReference
|
|
5
|
-
from common.core import list_local_assets, list_remote_assets, pull_remote_asset
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Asset(SessionContainer):
|
|
9
|
-
"""
|
|
10
|
-
Provides methods for interacting with the asset registry.
|
|
11
|
-
|
|
12
|
-
All methods handle authentication automatically using the current session's auth context.
|
|
13
|
-
This is a lightweight wrapper around registry functions that manages auth token complexity.
|
|
14
|
-
|
|
15
|
-
Example:
|
|
16
|
-
# List local assets
|
|
17
|
-
local_assets = Asset.list_local()
|
|
18
|
-
|
|
19
|
-
# List remote assets (requires auth)
|
|
20
|
-
remote_assets = Asset.list_remote()
|
|
21
|
-
|
|
22
|
-
# Pull an asset from remote registry
|
|
23
|
-
asset_path = Asset.pull(name="my_asset", version="1.0.0")
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
@staticmethod
|
|
27
|
-
def list_local() -> list[AssetReference]:
|
|
28
|
-
"""
|
|
29
|
-
List all locally available assets.
|
|
30
|
-
|
|
31
|
-
:return: List of AssetReference objects from local storage.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
return list_local_assets()
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def list_remote() -> list[AssetReference]:
|
|
38
|
-
"""
|
|
39
|
-
List all assets from remote registry.
|
|
40
|
-
|
|
41
|
-
Requires authentication. Call session.login() first if not authenticated.
|
|
42
|
-
|
|
43
|
-
:return: List of AssetReference objects from remote registry.
|
|
44
|
-
:raises SessionAuthError: If not authenticated.
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
return list_remote_assets()
|
|
48
|
-
|
|
49
|
-
@staticmethod
|
|
50
|
-
def pull(name: str, version: str, overwrite: bool = False, show_progress: bool = True) -> Path:
|
|
51
|
-
"""
|
|
52
|
-
Pull an asset from remote registry to local storage.
|
|
53
|
-
|
|
54
|
-
Requires authentication. Call session.login() first if not authenticated.
|
|
55
|
-
If the asset already exists locally, returns the existing path unless overwrite=True.
|
|
56
|
-
|
|
57
|
-
:param name: Name of the asset.
|
|
58
|
-
:param version: Version of the asset.
|
|
59
|
-
:param overwrite: Overwrite local asset if it already exists.
|
|
60
|
-
:param show_progress: Show download progress bar.
|
|
61
|
-
:return: Path to the downloaded asset file.
|
|
62
|
-
:raises SessionAuthError: If not authenticated.
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
return pull_remote_asset(name=name, version=version, overwrite=overwrite, show_progress=show_progress)
|
antioch/session/error.py
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
class SessionError(Exception):
|
|
2
|
-
"""
|
|
3
|
-
Base exception for all session-related errors.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class SessionSimRpcNotConnectedError(SessionError):
|
|
8
|
-
"""
|
|
9
|
-
Raised when the Sim RPC server is not reachable.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class SessionSimRpcInterruptedError(SessionError):
|
|
14
|
-
"""
|
|
15
|
-
Raised when the Sim RPC is interrupted.
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class SessionSimRpcClientError(SessionError):
|
|
20
|
-
"""
|
|
21
|
-
Raised when the Sim RPC server returns a client error (user error).
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SessionSimRpcInternalError(SessionError):
|
|
26
|
-
"""
|
|
27
|
-
Raised when the Sim RPC server returns an internal error with traceback.
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
def __init__(self, message: str, traceback: str | None = None):
|
|
31
|
-
super().__init__(message)
|
|
32
|
-
self.traceback = traceback
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class SessionAuthError(SessionError):
|
|
36
|
-
"""
|
|
37
|
-
Raised when authentication fails.
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class SessionAgentError(SessionError):
|
|
42
|
-
"""
|
|
43
|
-
Raised when an agent operation fails (start/stop ark, telemetry, etc).
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class SessionTaskError(SessionError):
|
|
48
|
-
"""
|
|
49
|
-
Raised when a task operation fails (invalid lifecycle, etc).
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class SessionArkError(SessionError):
|
|
54
|
-
"""
|
|
55
|
-
Raised when an Ark operation fails (loading, stepping, hardware access, etc).
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class SessionHardwareError(SessionError):
|
|
60
|
-
"""
|
|
61
|
-
Raised when a hardware operation fails.
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class SessionAssetError(SessionError):
|
|
66
|
-
"""
|
|
67
|
-
Raised when an asset operation fails.
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class SessionRecordError(SessionError):
|
|
72
|
-
"""
|
|
73
|
-
Raised when a recording operation fails (node output recording, etc).
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class SessionValidationError(SessionError):
|
|
78
|
-
"""
|
|
79
|
-
Raised when input validation fails (user error).
|
|
80
|
-
"""
|