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.
- antioch/__init__.py +0 -0
- antioch/message.py +87 -0
- antioch/module/__init__.py +53 -0
- antioch/module/clock.py +62 -0
- antioch/module/execution.py +278 -0
- antioch/module/input.py +127 -0
- antioch/module/module.py +218 -0
- antioch/module/node.py +357 -0
- antioch/module/token.py +42 -0
- antioch/session/__init__.py +150 -0
- antioch/session/ark.py +504 -0
- antioch/session/asset.py +65 -0
- antioch/session/error.py +80 -0
- antioch/session/record.py +158 -0
- antioch/session/scene.py +1521 -0
- antioch/session/session.py +220 -0
- antioch/session/task.py +323 -0
- antioch/session/views/__init__.py +40 -0
- antioch/session/views/animation.py +189 -0
- antioch/session/views/articulation.py +245 -0
- antioch/session/views/basis_curve.py +186 -0
- antioch/session/views/camera.py +92 -0
- antioch/session/views/collision.py +75 -0
- antioch/session/views/geometry.py +74 -0
- antioch/session/views/ground_plane.py +63 -0
- antioch/session/views/imu.py +73 -0
- antioch/session/views/joint.py +64 -0
- antioch/session/views/light.py +175 -0
- antioch/session/views/pir_sensor.py +140 -0
- antioch/session/views/radar.py +73 -0
- antioch/session/views/rigid_body.py +282 -0
- antioch/session/views/xform.py +119 -0
- antioch_py-2.0.6.dist-info/METADATA +115 -0
- antioch_py-2.0.6.dist-info/RECORD +99 -0
- antioch_py-2.0.6.dist-info/WHEEL +5 -0
- antioch_py-2.0.6.dist-info/entry_points.txt +2 -0
- antioch_py-2.0.6.dist-info/top_level.txt +2 -0
- common/__init__.py +0 -0
- common/ark/__init__.py +60 -0
- common/ark/ark.py +128 -0
- common/ark/hardware.py +121 -0
- common/ark/kinematics.py +31 -0
- common/ark/module.py +85 -0
- common/ark/node.py +94 -0
- common/ark/scheduler.py +439 -0
- common/ark/sim.py +33 -0
- common/assets/__init__.py +3 -0
- common/constants.py +47 -0
- common/core/__init__.py +52 -0
- common/core/agent.py +296 -0
- common/core/auth.py +305 -0
- common/core/registry.py +331 -0
- common/core/task.py +36 -0
- common/message/__init__.py +59 -0
- common/message/annotation.py +89 -0
- common/message/array.py +500 -0
- common/message/base.py +517 -0
- common/message/camera.py +91 -0
- common/message/color.py +139 -0
- common/message/frame.py +50 -0
- common/message/image.py +171 -0
- common/message/imu.py +14 -0
- common/message/joint.py +47 -0
- common/message/log.py +31 -0
- common/message/pir.py +16 -0
- common/message/point.py +109 -0
- common/message/point_cloud.py +63 -0
- common/message/pose.py +148 -0
- common/message/quaternion.py +273 -0
- common/message/radar.py +58 -0
- common/message/types.py +37 -0
- common/message/vector.py +786 -0
- common/rome/__init__.py +9 -0
- common/rome/client.py +430 -0
- common/rome/error.py +16 -0
- common/session/__init__.py +54 -0
- common/session/environment.py +31 -0
- common/session/sim.py +240 -0
- common/session/views/__init__.py +263 -0
- common/session/views/animation.py +73 -0
- common/session/views/articulation.py +184 -0
- common/session/views/basis_curve.py +102 -0
- common/session/views/camera.py +147 -0
- common/session/views/collision.py +59 -0
- common/session/views/geometry.py +102 -0
- common/session/views/ground_plane.py +41 -0
- common/session/views/imu.py +66 -0
- common/session/views/joint.py +81 -0
- common/session/views/light.py +96 -0
- common/session/views/pir_sensor.py +115 -0
- common/session/views/radar.py +82 -0
- common/session/views/rigid_body.py +236 -0
- common/session/views/viewport.py +21 -0
- common/session/views/xform.py +39 -0
- common/utils/__init__.py +4 -0
- common/utils/comms.py +571 -0
- common/utils/logger.py +123 -0
- common/utils/time.py +42 -0
- common/utils/usd.py +12 -0
common/core/registry.py
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from common.ark import Ark as ArkDefinition, ArkReference, ArkVersionReference, AssetReference, AssetVersionReference
|
|
7
|
+
from common.constants import ANTIOCH_API_URL, get_ark_dir, get_asset_dir
|
|
8
|
+
from common.core.auth import AuthError, AuthHandler
|
|
9
|
+
from common.rome import RomeClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def list_local_arks() -> list[ArkReference]:
|
|
13
|
+
"""
|
|
14
|
+
List all locally available Arks.
|
|
15
|
+
|
|
16
|
+
:return: List of ArkReference objects from local storage.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
arks_dir = get_ark_dir()
|
|
20
|
+
files_by_name = defaultdict(list)
|
|
21
|
+
for file_path in arks_dir.iterdir():
|
|
22
|
+
if file_path.is_file() and (file_path.name.endswith(":ark.json") or file_path.name.endswith(":asset.usdz")):
|
|
23
|
+
name = file_path.name.split(":")[0]
|
|
24
|
+
files_by_name[name].append(file_path)
|
|
25
|
+
|
|
26
|
+
results = []
|
|
27
|
+
for name, files in files_by_name.items():
|
|
28
|
+
ref = _build_ark_reference(name, files)
|
|
29
|
+
if ref is not None:
|
|
30
|
+
results.append(ref)
|
|
31
|
+
|
|
32
|
+
return results
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def load_local_ark(name: str, version: str) -> ArkDefinition:
|
|
36
|
+
"""
|
|
37
|
+
Load Ark definition from local storage.
|
|
38
|
+
|
|
39
|
+
:param name: Name of the Ark.
|
|
40
|
+
:param version: Version of the Ark.
|
|
41
|
+
:return: The loaded Ark definition.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
with open(get_ark_version_reference(name, version).full_path) as f:
|
|
45
|
+
return ArkDefinition(**json.load(f))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_ark_version_reference(name: str, version: str) -> ArkVersionReference:
|
|
49
|
+
"""
|
|
50
|
+
Get version reference for an Ark.
|
|
51
|
+
|
|
52
|
+
:param name: Name of the Ark.
|
|
53
|
+
:param version: Version of the Ark.
|
|
54
|
+
:return: Version reference for the Ark.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
available_arks = list_local_arks()
|
|
58
|
+
for ark_ref in available_arks:
|
|
59
|
+
if ark_ref.name == name:
|
|
60
|
+
for version_ref in ark_ref.versions:
|
|
61
|
+
if version_ref.version == version:
|
|
62
|
+
return version_ref
|
|
63
|
+
raise FileNotFoundError(f"Version {version} of Ark {name} not found in local storage")
|
|
64
|
+
raise FileNotFoundError(f"No versions of Ark {name} found in local storage")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_asset_path(name: str, version: str, extension: str = "usdz", assert_exists: bool = True) -> Path:
|
|
68
|
+
"""
|
|
69
|
+
Get the local file path for a specific asset version.
|
|
70
|
+
|
|
71
|
+
:param name: Name of the asset.
|
|
72
|
+
:param version: Version of the asset.
|
|
73
|
+
:param extension: File extension (without dot), defaults to 'usdz'.
|
|
74
|
+
:param assert_exists: If True, raises error if asset file doesn't exist.
|
|
75
|
+
:return: Path to the asset file.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
assets_dir = get_asset_dir()
|
|
79
|
+
asset_file = assets_dir / f"{name}:{version}:file.{extension}"
|
|
80
|
+
if assert_exists and not asset_file.exists():
|
|
81
|
+
raise FileNotFoundError(f"Asset {name}:{version} with extension .{extension} does not exist")
|
|
82
|
+
|
|
83
|
+
return asset_file
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def list_local_assets() -> list[AssetReference]:
|
|
87
|
+
"""
|
|
88
|
+
List all locally cached assets.
|
|
89
|
+
|
|
90
|
+
:return: List of AssetReference objects from local storage.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
assets_dir = get_asset_dir()
|
|
94
|
+
if not assets_dir.exists():
|
|
95
|
+
return []
|
|
96
|
+
|
|
97
|
+
files_by_name: dict[str, list[Path]] = defaultdict(list)
|
|
98
|
+
for file_path in assets_dir.iterdir():
|
|
99
|
+
if file_path.is_file():
|
|
100
|
+
# Parse filename format: {name}:{version}:file.{extension}
|
|
101
|
+
parts = file_path.stem.split(":")
|
|
102
|
+
if len(parts) == 3 and parts[-1] == "file":
|
|
103
|
+
files_by_name[parts[0]].append(file_path)
|
|
104
|
+
|
|
105
|
+
results = []
|
|
106
|
+
for name, files in files_by_name.items():
|
|
107
|
+
ref = _build_asset_reference(name, files)
|
|
108
|
+
if ref is not None:
|
|
109
|
+
results.append(ref)
|
|
110
|
+
|
|
111
|
+
return results
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def list_remote_arks() -> list[ArkReference]:
|
|
115
|
+
"""
|
|
116
|
+
List all Arks from remote registry.
|
|
117
|
+
|
|
118
|
+
Requires authentication.
|
|
119
|
+
|
|
120
|
+
:return: List of ArkReference objects from remote registry.
|
|
121
|
+
:raises AuthError: If not authenticated.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
# Get auth token
|
|
125
|
+
auth = AuthHandler()
|
|
126
|
+
token = auth.get_token()
|
|
127
|
+
if token is None:
|
|
128
|
+
raise AuthError("User not authenticated. Please login first")
|
|
129
|
+
|
|
130
|
+
# Create Rome client and list arks
|
|
131
|
+
rome_client = RomeClient(api_url=ANTIOCH_API_URL, token=token)
|
|
132
|
+
return rome_client.list_arks()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def pull_remote_ark(name: str, version: str, overwrite: bool = False) -> ArkDefinition:
|
|
136
|
+
"""
|
|
137
|
+
Pull an Ark from remote registry to local storage.
|
|
138
|
+
|
|
139
|
+
Requires authentication.
|
|
140
|
+
|
|
141
|
+
:param name: Name of the Ark.
|
|
142
|
+
:param version: Version of the Ark.
|
|
143
|
+
:param overwrite: Overwrite local Ark if it already exists.
|
|
144
|
+
:return: The loaded Ark definition.
|
|
145
|
+
:raises AuthError: If not authenticated.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
# Check if Ark already exists locally
|
|
149
|
+
arks_dir = get_ark_dir()
|
|
150
|
+
ark_json_path = arks_dir / f"{name}:{version}:ark.json"
|
|
151
|
+
if ark_json_path.exists() and not overwrite:
|
|
152
|
+
return load_local_ark(name, version)
|
|
153
|
+
|
|
154
|
+
# Get auth token
|
|
155
|
+
auth = AuthHandler()
|
|
156
|
+
token = auth.get_token()
|
|
157
|
+
if not token:
|
|
158
|
+
raise AuthError("User not authenticated. Please login first")
|
|
159
|
+
|
|
160
|
+
# Create Rome client and fetch Ark definition and save to local storage
|
|
161
|
+
rome_client = RomeClient(api_url=ANTIOCH_API_URL, token=token)
|
|
162
|
+
ark = rome_client.get_ark(name=name, version=version)
|
|
163
|
+
|
|
164
|
+
# Save Ark JSON
|
|
165
|
+
with open(ark_json_path, "wb") as f:
|
|
166
|
+
f.write(json.dumps(ark).encode("utf-8"))
|
|
167
|
+
|
|
168
|
+
# Download asset usdz only if ark has asset_hash (hardware modules exist)
|
|
169
|
+
if ark.get("metadata", {}).get("asset_hash") is not None:
|
|
170
|
+
asset_content = rome_client.download_ark_assets(name=name, version=version)
|
|
171
|
+
with open(arks_dir / f"{name}:{version}:asset.usdz", "wb") as f:
|
|
172
|
+
f.write(asset_content)
|
|
173
|
+
|
|
174
|
+
return ArkDefinition(**ark)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def list_remote_assets() -> list[AssetReference]:
|
|
178
|
+
"""
|
|
179
|
+
List all assets from remote registry.
|
|
180
|
+
|
|
181
|
+
Requires authentication.
|
|
182
|
+
|
|
183
|
+
:return: List of AssetReference objects from remote registry.
|
|
184
|
+
:raises AuthError: If not authenticated.
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
# Get auth token
|
|
188
|
+
token = AuthHandler().get_token()
|
|
189
|
+
if token is None:
|
|
190
|
+
raise AuthError("User not authenticated. Please login first")
|
|
191
|
+
|
|
192
|
+
# Create Rome client and list assets
|
|
193
|
+
rome_client = RomeClient(api_url=ANTIOCH_API_URL, token=token)
|
|
194
|
+
return rome_client.list_assets()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def pull_remote_asset(name: str, version: str, overwrite: bool = False, show_progress: bool = True) -> Path:
|
|
198
|
+
"""
|
|
199
|
+
Pull an asset from remote registry to local storage.
|
|
200
|
+
|
|
201
|
+
Requires authentication.
|
|
202
|
+
|
|
203
|
+
:param name: Name of the asset.
|
|
204
|
+
:param version: Version of the asset.
|
|
205
|
+
:param overwrite: Overwrite local asset if it already exists.
|
|
206
|
+
:param show_progress: Show download progress bar.
|
|
207
|
+
:return: Path to the downloaded asset file.
|
|
208
|
+
:raises AuthError: If not authenticated.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
# Get auth token
|
|
212
|
+
token = AuthHandler().get_token()
|
|
213
|
+
if token is None:
|
|
214
|
+
raise AuthError("User not authenticated. Please login first")
|
|
215
|
+
|
|
216
|
+
# Create Rome client and get asset metadata to determine extension
|
|
217
|
+
rome_client = RomeClient(api_url=ANTIOCH_API_URL, token=token)
|
|
218
|
+
metadata = rome_client.get_asset_metadata(name=name, version=version)
|
|
219
|
+
extension = metadata.get("extension", "usdz")
|
|
220
|
+
|
|
221
|
+
# Check if asset already exists locally
|
|
222
|
+
asset_file_path = get_asset_path(name=name, version=version, extension=extension, assert_exists=False)
|
|
223
|
+
if asset_file_path.exists() and not overwrite:
|
|
224
|
+
print(f"Asset {name}:{version} already exists locally, skipping download")
|
|
225
|
+
return asset_file_path
|
|
226
|
+
|
|
227
|
+
# Download the asset file
|
|
228
|
+
rome_client.download_asset(name=name, version=version, output_path=str(asset_file_path), show_progress=show_progress)
|
|
229
|
+
return asset_file_path
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _build_ark_reference(name: str, files: list[Path]) -> ArkReference | None:
|
|
233
|
+
"""
|
|
234
|
+
Create an ArkReference from a list of files for a given ark.
|
|
235
|
+
|
|
236
|
+
:param name: The name of the ark.
|
|
237
|
+
:param files: List of file paths (ark JSON and asset USDZ files).
|
|
238
|
+
:return: ArkReference object or None if no valid versions found.
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
file_stats = [f.stat() for f in files]
|
|
242
|
+
created_at = min(datetime.fromtimestamp(stat.st_ctime) for stat in file_stats).isoformat()
|
|
243
|
+
updated_at = max(datetime.fromtimestamp(stat.st_mtime) for stat in file_stats).isoformat()
|
|
244
|
+
|
|
245
|
+
# Group files by version - parse from {name}:{version}:ark.json or {name}:{version}:asset.usdz
|
|
246
|
+
files_by_version: dict[str, list[Path]] = defaultdict(list)
|
|
247
|
+
for file_path in files:
|
|
248
|
+
files_by_version[file_path.name.split(":")[1]].append(file_path)
|
|
249
|
+
|
|
250
|
+
# Create an ArkVersionReference for each version
|
|
251
|
+
version_refs = []
|
|
252
|
+
for version, version_files in files_by_version.items():
|
|
253
|
+
ark_file = None
|
|
254
|
+
asset_file = None
|
|
255
|
+
for file_path in version_files:
|
|
256
|
+
if file_path.name.endswith(":ark.json"):
|
|
257
|
+
ark_file = file_path
|
|
258
|
+
elif file_path.name.endswith(":asset.usdz"):
|
|
259
|
+
asset_file = file_path
|
|
260
|
+
if ark_file is None:
|
|
261
|
+
continue
|
|
262
|
+
|
|
263
|
+
ark_stat = ark_file.stat()
|
|
264
|
+
version_refs.append(
|
|
265
|
+
ArkVersionReference(
|
|
266
|
+
version=version,
|
|
267
|
+
full_path=str(ark_file),
|
|
268
|
+
asset_path=str(asset_file) if asset_file else None,
|
|
269
|
+
size_bytes=ark_stat.st_size,
|
|
270
|
+
created_at=datetime.fromtimestamp(ark_stat.st_ctime).isoformat(),
|
|
271
|
+
updated_at=datetime.fromtimestamp(ark_stat.st_mtime).isoformat(),
|
|
272
|
+
asset_size_bytes=asset_file.stat().st_size if asset_file else None,
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
if not version_refs:
|
|
277
|
+
return None
|
|
278
|
+
|
|
279
|
+
return ArkReference(
|
|
280
|
+
name=name,
|
|
281
|
+
versions=version_refs,
|
|
282
|
+
created_at=created_at,
|
|
283
|
+
updated_at=updated_at,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _build_asset_reference(name: str, files: list[Path]) -> AssetReference | None:
|
|
288
|
+
"""
|
|
289
|
+
Create an AssetReference from a list of files for a given asset.
|
|
290
|
+
|
|
291
|
+
:param name: The name of the asset.
|
|
292
|
+
:param files: List of file paths (.usdz files).
|
|
293
|
+
:return: AssetReference object or None if no valid versions found.
|
|
294
|
+
"""
|
|
295
|
+
|
|
296
|
+
file_stats = [f.stat() for f in files]
|
|
297
|
+
created_at = min(datetime.fromtimestamp(stat.st_ctime) for stat in file_stats).isoformat()
|
|
298
|
+
updated_at = max(datetime.fromtimestamp(stat.st_mtime) for stat in file_stats).isoformat()
|
|
299
|
+
|
|
300
|
+
# Group files by version
|
|
301
|
+
files_by_version: dict[str, list[Path]] = defaultdict(list)
|
|
302
|
+
for file_path in files:
|
|
303
|
+
# Parse filename format: {name}:{version}:file.usdz
|
|
304
|
+
version = file_path.name.split(":")[1]
|
|
305
|
+
files_by_version[version].append(file_path)
|
|
306
|
+
|
|
307
|
+
# Create an AssetVersionReference for each version
|
|
308
|
+
version_refs = []
|
|
309
|
+
for version, version_files in files_by_version.items():
|
|
310
|
+
# Should only be one file per version, but take first if multiple
|
|
311
|
+
asset_file = version_files[0]
|
|
312
|
+
asset_stat = asset_file.stat()
|
|
313
|
+
version_refs.append(
|
|
314
|
+
AssetVersionReference(
|
|
315
|
+
version=version,
|
|
316
|
+
full_path=str(asset_file),
|
|
317
|
+
size_bytes=asset_stat.st_size,
|
|
318
|
+
created_at=datetime.fromtimestamp(asset_stat.st_ctime).isoformat(),
|
|
319
|
+
updated_at=datetime.fromtimestamp(asset_stat.st_mtime).isoformat(),
|
|
320
|
+
)
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
if not version_refs:
|
|
324
|
+
return None
|
|
325
|
+
|
|
326
|
+
return AssetReference(
|
|
327
|
+
name=name,
|
|
328
|
+
versions=version_refs,
|
|
329
|
+
created_at=created_at,
|
|
330
|
+
updated_at=updated_at,
|
|
331
|
+
)
|
common/core/task.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
from common.message import Message
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TaskOutcome(str, Enum):
|
|
8
|
+
"""
|
|
9
|
+
Task outcome status.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
SUCCESS = "success"
|
|
13
|
+
FAILURE = "failure"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TaskCompletion(Message):
|
|
17
|
+
"""
|
|
18
|
+
Task completion message (does not include task ID, as that is the lookup key).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
ark_name: str
|
|
22
|
+
ark_version: str
|
|
23
|
+
ark_hash: str
|
|
24
|
+
task_start_time: datetime
|
|
25
|
+
task_complete_time: datetime
|
|
26
|
+
outcome: TaskOutcome
|
|
27
|
+
result: dict | None = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class TaskFileType(str, Enum):
|
|
31
|
+
"""
|
|
32
|
+
Task file type.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
MCAP = "mcap"
|
|
36
|
+
BUNDLE = "bundle"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from common.message.annotation import CircleAnnotation, ImageAnnotations, PointsAnnotation, PointsAnnotationType, TextAnnotation
|
|
2
|
+
from common.message.array import Array
|
|
3
|
+
from common.message.base import DeserializationError, Message, MessageError, MismatchError, SerializationError
|
|
4
|
+
from common.message.camera import CameraInfo
|
|
5
|
+
from common.message.color import Color
|
|
6
|
+
from common.message.frame import FrameTransform, FrameTransforms
|
|
7
|
+
from common.message.image import Image, ImageEncoding
|
|
8
|
+
from common.message.imu import ImuSample
|
|
9
|
+
from common.message.joint import JointState, JointStates, JointTarget, JointTargets
|
|
10
|
+
from common.message.log import Log, LogLevel
|
|
11
|
+
from common.message.pir import PirStatus
|
|
12
|
+
from common.message.point import Point2, Point3
|
|
13
|
+
from common.message.point_cloud import PointCloud
|
|
14
|
+
from common.message.pose import Pose
|
|
15
|
+
from common.message.quaternion import Quaternion
|
|
16
|
+
from common.message.radar import RadarDetection, RadarScan
|
|
17
|
+
from common.message.types import Bool, Float, Int, String
|
|
18
|
+
from common.message.vector import Vector2, Vector3
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"Array",
|
|
22
|
+
"Bool",
|
|
23
|
+
"CameraInfo",
|
|
24
|
+
"CircleAnnotation",
|
|
25
|
+
"Color",
|
|
26
|
+
"DeserializationError",
|
|
27
|
+
"Float",
|
|
28
|
+
"FrameTransform",
|
|
29
|
+
"FrameTransforms",
|
|
30
|
+
"Image",
|
|
31
|
+
"ImageAnnotations",
|
|
32
|
+
"ImageEncoding",
|
|
33
|
+
"ImuSample",
|
|
34
|
+
"Int",
|
|
35
|
+
"JointState",
|
|
36
|
+
"JointStates",
|
|
37
|
+
"JointTarget",
|
|
38
|
+
"JointTargets",
|
|
39
|
+
"Log",
|
|
40
|
+
"LogLevel",
|
|
41
|
+
"Message",
|
|
42
|
+
"MessageError",
|
|
43
|
+
"MismatchError",
|
|
44
|
+
"PirStatus",
|
|
45
|
+
"Point2",
|
|
46
|
+
"Point3",
|
|
47
|
+
"PointCloud",
|
|
48
|
+
"PointsAnnotation",
|
|
49
|
+
"PointsAnnotationType",
|
|
50
|
+
"Pose",
|
|
51
|
+
"Quaternion",
|
|
52
|
+
"RadarDetection",
|
|
53
|
+
"RadarScan",
|
|
54
|
+
"SerializationError",
|
|
55
|
+
"String",
|
|
56
|
+
"TextAnnotation",
|
|
57
|
+
"Vector2",
|
|
58
|
+
"Vector3",
|
|
59
|
+
]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import IntEnum
|
|
4
|
+
|
|
5
|
+
from common.message.base import Message
|
|
6
|
+
from common.message.color import Color
|
|
7
|
+
from common.message.point import Point2
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PointsAnnotationType(IntEnum):
|
|
11
|
+
"""
|
|
12
|
+
Type of points annotation.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
UNKNOWN = 0
|
|
16
|
+
POINTS = 1
|
|
17
|
+
LINE_LOOP = 2
|
|
18
|
+
LINE_STRIP = 3
|
|
19
|
+
LINE_LIST = 4
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CircleAnnotation(Message):
|
|
23
|
+
"""
|
|
24
|
+
A circle annotation on a 2D image.
|
|
25
|
+
|
|
26
|
+
Coordinates use the top-left corner of the top-left pixel as the origin.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
timestamp_us: int
|
|
30
|
+
position: Point2
|
|
31
|
+
diameter: float
|
|
32
|
+
thickness: float
|
|
33
|
+
fill_color: Color
|
|
34
|
+
outline_color: Color
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class PointsAnnotation(Message):
|
|
38
|
+
"""
|
|
39
|
+
An array of points on a 2D image.
|
|
40
|
+
|
|
41
|
+
Coordinates use the top-left corner of the top-left pixel as the origin.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
timestamp_us: int
|
|
45
|
+
type: PointsAnnotationType
|
|
46
|
+
points: list[Point2]
|
|
47
|
+
outline_color: Color
|
|
48
|
+
outline_colors: list[Color] | None = None
|
|
49
|
+
fill_color: Color | None = None
|
|
50
|
+
thickness: float
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TextAnnotation(Message):
|
|
54
|
+
"""
|
|
55
|
+
A text label on a 2D image.
|
|
56
|
+
|
|
57
|
+
Position uses the bottom-left origin of the text label.
|
|
58
|
+
Coordinates use the top-left corner of the top-left pixel as the origin.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
timestamp_us: int
|
|
62
|
+
position: Point2
|
|
63
|
+
text: str
|
|
64
|
+
font_size: float
|
|
65
|
+
text_color: Color
|
|
66
|
+
background_color: Color
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ImageAnnotations(Message):
|
|
70
|
+
"""
|
|
71
|
+
Array of annotations for a 2D image.
|
|
72
|
+
|
|
73
|
+
Used in the Foxglove Image panel for visualization.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
_type = "antioch/image_annotations"
|
|
77
|
+
circles: list[CircleAnnotation]
|
|
78
|
+
points: list[PointsAnnotation]
|
|
79
|
+
texts: list[TextAnnotation]
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def empty(cls) -> ImageAnnotations:
|
|
83
|
+
"""
|
|
84
|
+
Create an empty ImageAnnotations instance.
|
|
85
|
+
|
|
86
|
+
:return: ImageAnnotations with no annotations.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
return cls(circles=[], points=[], texts=[])
|