feat(calibration): add data-driven ground alignment with debug and fast iteration flags

This commit is contained in:
2026-02-07 03:20:16 +00:00
parent afc8e9034d
commit 446c02d42a
10 changed files with 1221 additions and 33 deletions
+40
View File
@@ -37,6 +37,46 @@ def load_marker_geometry(parquet_path: Union[str, Path]) -> dict[int, np.ndarray
return marker_geometry
def load_face_mapping(parquet_path: Union[str, Path]) -> dict[str, list[int]]:
"""
Reads face mapping from a parquet file.
The parquet file is expected to have 'name' and 'ids' columns.
'name' should be a string (face name), and 'ids' should be a list of integers.
Args:
parquet_path: Path to the parquet file.
Returns:
A dictionary mapping face names (lowercase) to lists of marker IDs.
"""
path = Path(parquet_path)
if not path.exists():
raise FileNotFoundError(f"Parquet file not found: {path}")
ops = ak.from_parquet(path)
# Check if required columns exist
if "name" not in ops.fields or "ids" not in ops.fields:
# Fallback or empty if columns missing (e.g. old format)
return {}
names = cast(np.ndarray, ak.to_numpy(ops["name"]))
# ids might be a jagged array if different faces have different marker counts
# ak.to_list() converts to python lists which is what we want for the dict values
ids_list = ak.to_list(ops["ids"])
face_map: dict[str, list[int]] = {}
for name, m_ids in zip(names, ids_list):
if name and m_ids:
# Normalize name to lowercase
key = str(name).lower()
# Ensure IDs are ints
face_map[key] = [int(mid) for mid in m_ids]
return face_map
def validate_marker_geometry(geometry: dict[int, np.ndarray]) -> None:
"""
Validates the marker geometry dictionary.