mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
feat(scenegraph): add depth-based 3D positioning via pinhole projection
- Add bbox_depth_center position strategy in SceneGraphBuilder using depth at bbox centre and configurable camera_hfov_degrees for pinhole projection. - Add optional depth_sensor_uuid to HabitatSimulatorConfig; create depth sensor spec alongside RGB sensor. - Add camera_position/camera_rotation fields to RoomView; capture pose from sensor_states when depth sensor is available. - Update flatten_room_views for backward compatibility with legacy tuple format. - Wired in depth sensor and bbox_depth_center strategy in verification notebook. - Add tests for depth sensor support and new position strategies.
This commit is contained in:
@@ -1,11 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
NOTEBOOK = Path(__file__).resolve().parents[1] / "notebooks" / "verification.py"
|
||||
|
||||
|
||||
def _find_calls(tree: ast.AST, func_name: str) -> list[ast.Call]:
|
||||
"""Find all Call nodes for a named function (simple name, not attribute)."""
|
||||
return [
|
||||
node
|
||||
for node in ast.walk(tree)
|
||||
if isinstance(node, ast.Call)
|
||||
and isinstance(node.func, ast.Name)
|
||||
and node.func.id == func_name
|
||||
]
|
||||
|
||||
|
||||
def test_verification_notebook_uses_scenegraph_query_api():
|
||||
source = NOTEBOOK.read_text()
|
||||
|
||||
@@ -20,7 +32,6 @@ def test_verification_notebook_uses_hash_codec_for_object_hashes():
|
||||
# the builder handles it internally.
|
||||
assert "bits_tensor_to_hash_bytes" not in source
|
||||
assert "np.packbits" not in source
|
||||
assert "scene_graph.objects[_obj_id] = ObjectNode" not in source
|
||||
|
||||
|
||||
def test_verification_notebook_uses_scene_graph_builder():
|
||||
@@ -30,4 +41,56 @@ def test_verification_notebook_uses_scene_graph_builder():
|
||||
assert "SceneGraphBuildConfig" in source
|
||||
assert "flatten_room_views" in source
|
||||
assert "scene_graph, build_artifacts = builder.build_from_room_views" in source
|
||||
assert "scene_graph.objects[_obj_id] = ObjectNode" not in source
|
||||
|
||||
# Verify no direct ObjectNode construction (builder handles it internally)
|
||||
tree = ast.parse(source)
|
||||
object_node_calls = _find_calls(tree, "ObjectNode")
|
||||
assert len(object_node_calls) == 0, (
|
||||
"Notebook should not construct ObjectNode() directly; "
|
||||
"the builder handles it"
|
||||
)
|
||||
|
||||
|
||||
def test_verification_notebook_uses_bbox_depth_center_positioning():
|
||||
source = NOTEBOOK.read_text()
|
||||
tree = ast.parse(source)
|
||||
|
||||
# --- SceneGraphBuildConfig must use position_strategy='bbox_depth_center' ---
|
||||
sg_config_calls = _find_calls(tree, "SceneGraphBuildConfig")
|
||||
assert len(sg_config_calls) >= 1, (
|
||||
"Notebook must instantiate SceneGraphBuildConfig"
|
||||
)
|
||||
config_kwargs = {
|
||||
kw.arg: kw.value for kw in sg_config_calls[0].keywords if kw.arg is not None
|
||||
}
|
||||
|
||||
assert "position_strategy" in config_kwargs
|
||||
pos_val = config_kwargs["position_strategy"]
|
||||
assert isinstance(pos_val, ast.Constant) and pos_val.value == "bbox_depth_center", (
|
||||
f"Expected position_strategy='bbox_depth_center', got {pos_val!r}"
|
||||
)
|
||||
|
||||
assert "camera_hfov_degrees" in config_kwargs, (
|
||||
"SceneGraphBuildConfig should include camera_hfov_degrees"
|
||||
)
|
||||
|
||||
# --- object_rows dict literals must include bbox_xyxy and position_confidence ---
|
||||
found_bbox = False
|
||||
found_pos_conf = False
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Dict):
|
||||
keys = {k.value for k in node.keys if isinstance(k, ast.Constant)}
|
||||
if "obj_id" in keys:
|
||||
if "bbox_xyxy" in keys:
|
||||
found_bbox = True
|
||||
if "position_confidence" in keys:
|
||||
found_pos_conf = True
|
||||
|
||||
assert found_bbox, "object_rows must include bbox_xyxy column"
|
||||
assert found_pos_conf, "object_rows must include position_confidence column"
|
||||
|
||||
# --- No direct ObjectNode( construction ---
|
||||
object_node_calls = _find_calls(tree, "ObjectNode")
|
||||
assert len(object_node_calls) == 0, (
|
||||
"Notebook should not construct ObjectNode() directly"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user