feat(pose_3d): GET /tags multi-camera, rimuovi /front_tags
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
77fb0f8fc0
commit
8b01ae123f
2 files changed
+174
-99
No files matched your search
@@ -0,0 +1,75 @@
|
||||
"""Test del nuovo endpoint multi-camera GET /api/pose_3d/tags."""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from presa_mano.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def _fake_camera(corner_depth_m=0.32):
|
||||
cam = MagicMock()
|
||||
cam.intrinsics.return_value = {
|
||||
"rgb": {"fx": 600.0, "fy": 600.0, "cx": 320.0, "cy": 240.0}
|
||||
}
|
||||
cam.rgb_url.return_value = "http://cam/rgb.png"
|
||||
|
||||
def _measure(u, v, radius=2):
|
||||
return {"point_m": {"x": u / 1000.0, "y": v / 1000.0, "z": corner_depth_m},
|
||||
"depth_mm": int(corner_depth_m * 1000)}
|
||||
cam.measure.side_effect = _measure
|
||||
return cam
|
||||
|
||||
|
||||
def _fake_marker(found_ids):
|
||||
mk = MagicMock()
|
||||
found = [{
|
||||
"id": i,
|
||||
"corners": [[100, 100], [140, 100], [140, 140], [100, 140]],
|
||||
} for i in found_ids]
|
||||
mk.detect_url.return_value = {"found": found, "not_found": []}
|
||||
return mk
|
||||
|
||||
|
||||
def test_tags_returns_both_cameras():
|
||||
with patch("presa_mano.api.pose_3d_routes._deps.nuwa") as nuwa_f, \
|
||||
patch("presa_mano.api.pose_3d_routes._deps.front_camera") as front_f, \
|
||||
patch("presa_mano.api.pose_3d_routes._deps.marker") as mk_f:
|
||||
nuwa_f.return_value = _fake_camera()
|
||||
front_f.return_value = _fake_camera()
|
||||
mk_f.return_value = _fake_marker([5])
|
||||
r = client.get("/api/pose_3d/tags?ids=0-9")
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert set(body["cameras"].keys()) == {"nuwa", "d435"}
|
||||
assert body["cameras"]["nuwa"]["frame"] == "nuwa_rgb_optical"
|
||||
assert body["cameras"]["d435"]["frame"] == "d435_rgb_optical"
|
||||
assert body["cameras"]["nuwa"]["tags"][0]["id"] == 5
|
||||
assert body["cameras"]["d435"]["tags"][0]["id"] == 5
|
||||
|
||||
tag = body["cameras"]["nuwa"]["tags"][0]
|
||||
assert tag["edge_mm"] is not None
|
||||
assert 35.0 < tag["edge_mm"] < 45.0 # ~40mm lato del quad
|
||||
assert tag["distance_m"] is not None
|
||||
assert abs(tag["distance_m"] - 0.362) < 0.02 # sqrt(.12^2+.12^2+.32^2)
|
||||
assert all(len(c) == 3 for c in tag["corners_3d_optical_m"])
|
||||
|
||||
|
||||
def test_tags_one_camera_offline_reports_error():
|
||||
with patch("presa_mano.api.pose_3d_routes._deps.nuwa") as nuwa_f, \
|
||||
patch("presa_mano.api.pose_3d_routes._deps.front_camera") as front_f, \
|
||||
patch("presa_mano.api.pose_3d_routes._deps.marker") as mk_f:
|
||||
nuwa = MagicMock()
|
||||
nuwa.intrinsics.side_effect = RuntimeError("nuwa down")
|
||||
nuwa_f.return_value = nuwa
|
||||
front_f.return_value = _fake_camera()
|
||||
mk_f.return_value = _fake_marker([5])
|
||||
r = client.get("/api/pose_3d/tags?ids=0-9")
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body["cameras"]["nuwa"]["tags"] == []
|
||||
assert "error" in body["cameras"]["nuwa"]
|
||||
assert body["cameras"]["d435"]["tags"][0]["id"] == 5
|
||||
Reference in new issue
Block a user