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:
AdrianoandClaude Sonnet 4.6 committed 2026-06-03 12:20:04 +02:00
1 parent 77fb0f8fc0
commit 8b01ae123f
2 files changed
+174 -99

No files matched your search

+75
View File
@@ -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