Compare commits
5 Commits
5738920c9c
...
V3.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dd4b0a20c | |||
| 271ce73d09 | |||
| 1bd6c6b011 | |||
| d8bca535ac | |||
| 14257304f8 |
@@ -289,7 +289,7 @@ Nginx (dev): gzip abilitato, `client_max_body_size 50M`, `proxy_read_timeout 120
|
||||
|
||||
Il runner di visione (`src/vision/`) e il suo worker FastAPI (`src/vision_worker/`) dipendono da `vendor/visionsuite`, un **submodule** che punta al repo TieVision-Core (`ssh://git@git.tielogic.xyz:222/Adriano/TieVision-Core.git`, ex visionsuite, rinominato il 15/10/2026; `vs-gui` e `vs-assistant` sono ora in TieVision-Studio e TieVision-Assistant, che TieMeasureFlow non usa; il path resta `vendor/visionsuite`): un `git clone` senza `--recurse-submodules` lascia la cartella vuota (chi ha già clonato: `git submodule update --init`). Le librerie di VisionSuite richiedono **Python 3.13**, mentre backend e frontend restano su Python 3.11 — è un albero a parte nel monorepo, isolato con il proprio extra `uv`.
|
||||
|
||||
Regola (Adriano, 07/10/2026): il submodule `vendor/visionsuite` segue `origin/main`: a ogni integrazione si porta all'ultimo commit (`git -C vendor/visionsuite fetch origin && git -C vendor/visionsuite checkout origin/main`) e si rilanciano i test della visione. La regola vale ora per `origin/main` di TieVision-Core. Pin attuale: 2e73691.
|
||||
Regola (Adriano, 07/10/2026): il submodule `vendor/visionsuite` segue `origin/main`: a ogni integrazione si porta all'ultimo commit (`git -C vendor/visionsuite fetch origin && git -C vendor/visionsuite checkout origin/main`) e si rilanciano i test della visione. La regola vale ora per `origin/main` di TieVision-Core. Pin attuale: 9eb6f4c.
|
||||
|
||||
Il worker gira in un container separato (`Dockerfile.vision`), non pubblica porte verso l'esterno ed è raggiungibile solo dal server all'indirizzo interno `http://vision:8100`. Il container non ha accesso al repository Git del progetto principale, quindi il commit di VisionSuite in uso (`engine_version`) non può essere scoperto dentro l'immagine: va stampato al momento del build leggendo il commit dalla macchina che esegue `docker compose build`, con la variabile `VISION_ENGINE_VERSION`. Una build senza questa variabile fallisce subito, invece di produrre un worker che risponde con una versione indovinata:
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ def _graph(dxf_sha: str, cal_sha: str, band_mm: float, min_points_pct: float, po
|
||||
"band_plus": float(band_mm),
|
||||
"band_minus": float(band_mm),
|
||||
"nominal_unit": "mm",
|
||||
# #127 (Adriano, 06/11/2026): LocateBlob normalizza l'angolo in (-90, 90], il pezzo a 180 o +-120 gradi
|
||||
# verrebbe capovolto; "quarter" prova le pose ruotate (Core#343). Lo specchiato resta fuori.
|
||||
"pose_search": "quarter",
|
||||
# tolleranza di points_in_pct: nominale = limite, plus = 100 - limite
|
||||
"points_in_pct_nominal": float(min_points_pct),
|
||||
"points_in_pct_plus": float(100.0 - min_points_pct),
|
||||
|
||||
@@ -22,6 +22,7 @@ from src.vision.costruttori import (
|
||||
DXF_FILE,
|
||||
CostruttoreError,
|
||||
_candidate_anchors,
|
||||
_graph,
|
||||
_maschera_pezzo,
|
||||
build_dxf_compare,
|
||||
)
|
||||
@@ -94,6 +95,74 @@ def test_ricetta_dxf_con_riferimento_gia_ruotato(tmp_path):
|
||||
assert risultato["outputs"]["dxf.points_in_pct"] > 95.0
|
||||
|
||||
|
||||
# #127: pezzo a L (asimmetrico a 180 gradi: sample.dxf e' simmetrico e non distingue il
|
||||
# capovolgimento). Un rettangolo con foro fuori centro NON basta: l'ICP di Core non lo risolve.
|
||||
L_PROFILE_MM = [(-100, -50), (100, -50), (100, 50), (-20, 50), (-20, 10), (-100, 10)]
|
||||
|
||||
|
||||
def _l_dxf(path: Path) -> bytes:
|
||||
import ezdxf
|
||||
|
||||
doc = ezdxf.new()
|
||||
doc.modelspace().add_lwpolyline(L_PROFILE_MM, close=True)
|
||||
doc.saveas(str(path))
|
||||
return path.read_bytes()
|
||||
|
||||
|
||||
def _l_scene(angle_deg: float = 0.0) -> np.ndarray:
|
||||
"""Il pezzo a L (scuro su bianco) a 4 px/mm; l'asse y del DXF e' verso l'alto."""
|
||||
w, h = int(320 * PX_PER_MM), int(220 * PX_PER_MM)
|
||||
cx, cy = w // 2, h // 2
|
||||
img = np.full((h, w), 255, np.uint8)
|
||||
pts = np.array([(cx + x * PX_PER_MM, cy - y * PX_PER_MM) for x, y in L_PROFILE_MM], np.int32)
|
||||
cv2.fillPoly(img, [pts], 0)
|
||||
if angle_deg:
|
||||
m = cv2.getRotationMatrix2D((cx, cy), angle_deg, 1.0)
|
||||
img = cv2.warpAffine(img, m, (w, h), flags=cv2.INTER_LINEAR, borderValue=255)
|
||||
return img
|
||||
|
||||
|
||||
def _pct_a_180(tmp_path, togli_quarter: bool) -> tuple[float, float]:
|
||||
"""points_in_pct della ricetta costruita a 0 gradi: (sulla scena dritta, a 180 gradi)."""
|
||||
risultato = build_dxf_compare(_l_scene(0.0), _l_dxf(tmp_path / "l.dxf"), PX_PER_MM, band_mm=2.0)
|
||||
graph = risultato["graph"]
|
||||
if togli_quarter: # misura di controllo: senza pose_search il pezzo a 180 va capovolto
|
||||
for tool in graph["tools"]:
|
||||
tool["values"].pop("pose_search", None)
|
||||
for nome, b64 in risultato["files"].items():
|
||||
(tmp_path / nome).write_bytes(base64.b64decode(b64))
|
||||
|
||||
def pct(img):
|
||||
esito = run_graph(img, graph, calibration={"px_per_mm": PX_PER_MM}, recipe_dir=tmp_path)
|
||||
assert not esito.failures, esito.failures
|
||||
return esito.outputs["dxf.points_in_pct"]
|
||||
return pct(_l_scene(0.0)), pct(_l_scene(180.0))
|
||||
|
||||
|
||||
def test_ricetta_dxf_su_pezzo_capovolto_di_180(tmp_path):
|
||||
# #127: con pose_search=quarter il pezzo a 180 gradi vale quanto quello dritto
|
||||
pct_0, pct_180 = _pct_a_180(tmp_path, togli_quarter=False)
|
||||
assert pct_0 >= 95.0
|
||||
assert pct_180 >= 95.0 and abs(pct_180 - pct_0) <= 2.0
|
||||
|
||||
|
||||
def test_ricetta_dxf_senza_quarter_il_pezzo_a_180_e_capovolto(tmp_path):
|
||||
# #127: controllo del test sopra - senza pose_search il disegno finisce capovolto
|
||||
_, pct_180 = _pct_a_180(tmp_path, togli_quarter=True)
|
||||
assert pct_180 < 20.0 # misurato ~2,8% (Core#343 riporta 3,3% su PR165)
|
||||
|
||||
|
||||
def test_graph_scrive_pose_search_quarter_nel_compare_dxf():
|
||||
# #127: il CompareDxf porta pose_search=quarter solo se c'e' l'ancora
|
||||
con = _graph("a" * 64, "b" * 64, 1.0, 95.0, "dark",
|
||||
{"row": 0.0, "col": 0.0, "angle_deg": 0.0}, (1.0, 2.0, 3.0))
|
||||
dxf_tool = next(t for t in con["tools"] if t["kind"] == "CompareDxf")
|
||||
assert dxf_tool["values"]["pose_search"] == "quarter"
|
||||
senza = _graph("a" * 64, "b" * 64, 1.0, 95.0, "dark",
|
||||
{"row": 0.0, "col": 0.0, "angle_deg": 0.0}, None)
|
||||
assert [t["kind"] for t in senza["tools"]] == ["LocateBlob"]
|
||||
|
||||
|
||||
def test_immagine_senza_pezzo_solleva():
|
||||
bianca = np.full((600, 800), 255, np.uint8)
|
||||
with pytest.raises(CostruttoreError, match="pezzo"):
|
||||
|
||||
@@ -2464,6 +2464,7 @@ dependencies = [
|
||||
{ name = "visionsuite" },
|
||||
{ name = "vs-measure" },
|
||||
{ name = "vs-task" },
|
||||
{ name = "zxing-cpp" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -2485,6 +2486,7 @@ requires-dist = [
|
||||
{ name = "vs-pm2d", marker = "extra == 'locate'", editable = "vendor/visionsuite/packages/vs-pm2d" },
|
||||
{ name = "vs-task", editable = "vendor/visionsuite/packages/vs-task" },
|
||||
{ name = "vs-tools", extras = ["locate", "dxf"], marker = "extra == 'dev'", editable = "vendor/visionsuite/packages/vs-tools" },
|
||||
{ name = "zxing-cpp", specifier = ">=3.1,<4" },
|
||||
]
|
||||
provides-extras = ["locate", "dxf", "dev"]
|
||||
|
||||
@@ -2787,3 +2789,35 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zxing-cpp"
|
||||
version = "3.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/30/ad0e0352c593712ebb47143571ff11b130812e2852d7540e7c80cdf23340/zxing_cpp-3.1.1.tar.gz", hash = "sha256:1051a521b21a9fe206702ad4186aeb195154e3e1badcd99576d030723f36382b", size = 1437030, upload-time = "2026-07-29T08:50:59.019Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/c4/d64c1b751561eee75706def600041e4c72642403864ac6c52588fdb54bb3/zxing_cpp-3.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:9e558cf4d6d0dd0ae1199541bc8fd01e8fb67e18673faa7ca96e50440fdd6f93", size = 912350, upload-time = "2026-07-29T08:50:23.952Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/1b/94067d5a5d324a30cd9862296171ec50cda58c9e31317eca53286aeab832/zxing_cpp-3.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec41a833dc1697e5360b5d9e2620fab1f3e92892b890c31fe85b50a10ca05217", size = 865032, upload-time = "2026-07-29T08:50:25.304Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/ee/4ab8cf9594959e1dc8f3c0e234d225fd1080cecc349c99cac4850005055a/zxing_cpp-3.1.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:07ac611267b7220b769c182ae33473ee95aca1cc6c57e597755288b557848935", size = 1028402, upload-time = "2026-07-29T08:50:26.935Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/83/5af471c7ad3fbb11d3efba64b41aba9f209d5dcc2945ca6b0afb29a9fed0/zxing_cpp-3.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a5b32d719a5448f1b2f474e04d2db6ce41cc6973fb5c705d47dbe899361e5f9", size = 1102966, upload-time = "2026-07-29T08:50:28.428Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/f4/8b75505b3b2110146769006a0087e1517675af057bb1eaa7709ef8dd507a/zxing_cpp-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:0343458a0fdf3f99c9dcff74dd09be6bae5d0d87a2f99de7876014317b939996", size = 1005571, upload-time = "2026-07-29T08:50:29.806Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/e8/05b134e41abda4bb3aca00ea2bc16898c9c3641afce5ad4637fd4b1166f0/zxing_cpp-3.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:73a26e6e7c5fa411bfd690c374e3d4a7fdcb41ca57a047839365b0c985e325ad", size = 933099, upload-time = "2026-07-29T08:50:31.309Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/57/ac717270db6888973eba83e9832fe800808b555df0ebe34e37b6a6e07545/zxing_cpp-3.1.1-cp312-abi3-macosx_10_13_x86_64.whl", hash = "sha256:09dea611a7c9dc7c713a82303b15b733dc71abb1a77454b26b779e33671cef05", size = 911430, upload-time = "2026-07-29T08:50:32.625Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/70/f14831dd92d5c844a39c03ebe9ba185e073d4467d50b48dcf2a816cae0c5/zxing_cpp-3.1.1-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:037cbcaeb0cb12497fc15ced23f6b778fce8a6a1d1bbffddbffd004c6225744d", size = 863740, upload-time = "2026-07-29T08:50:34.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/f3/3fb2c6c48e6f58382fbbd31965c7caafd81f75b7e6707b011bdb940adb5f/zxing_cpp-3.1.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4dae01111f323f46736fc21f05c14dcaaac06cea5fdc8fd994ba19f6f918c6e", size = 1024253, upload-time = "2026-07-29T08:50:35.599Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/30/79683cf7139ee5325fbc68169eb8dc1cb2033ec43339b5f39de990f909a7/zxing_cpp-3.1.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9cf67341949946307d086b302cefd453fb47bc6d6ddc7d088839e9481982757b", size = 1096795, upload-time = "2026-07-29T08:50:36.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/14/055c5a68a50bdde8378ced94e63f9ce340311e51c87b947f9b95fe69f51a/zxing_cpp-3.1.1-cp312-abi3-win_amd64.whl", hash = "sha256:29f98a91148171460b47a942d137ecc90c4b8097636f23cca65263a56bb025d3", size = 1003677, upload-time = "2026-07-29T08:50:38.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/32/a827a99fa5e0aee382b5d464cbd2075e1911a69500116705f6695a6accd8/zxing_cpp-3.1.1-cp312-abi3-win_arm64.whl", hash = "sha256:04a8f8b78779ab9b637853a0329770791cfc3095d232c768dc4824b63901ebd0", size = 931324, upload-time = "2026-07-29T08:50:39.632Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/30/e98ce9c56bd1f1fe0a1fd0e5c39202da49baa3620031cb80ac7a04759ffb/zxing_cpp-3.1.1-cp313-cp313t-macosx_10_15_x86_64.whl", hash = "sha256:9d291fd958c26066aca97c4a416a9f15475a99c97b253cd4d2c6754a485b01e6", size = 915582, upload-time = "2026-07-29T08:50:41.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/d8/ab1db4571348e8756c2019425c72b3cb936f72c4a7c2af35687396381c36/zxing_cpp-3.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:670e2946232128b1ebba5b1f623e016ac8f8ad743ae3a0fb2e50b33180f216a2", size = 867699, upload-time = "2026-07-29T08:50:42.815Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/09/78a038367fd3d4fc00fa1f696672bfff002b4771814c3b20b1c392872043/zxing_cpp-3.1.1-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9efc7ed301846a8c060720f09bed8a29fefccef54b5106c291e4136ffe87d089", size = 1030204, upload-time = "2026-07-29T08:50:44.356Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/7b/0fc91d2d0463164268d06dd3e9b97520f9fe5c79dc6a954c92cd9ac92fbf/zxing_cpp-3.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f37e714ad4fd0ae4dd759b19fef25bd524a2865bc3ca8730b4e318c0cc7800e", size = 1104920, upload-time = "2026-07-29T08:50:45.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/9d/2adb3c88894b1e018739aae9bd2725733b55c14e3df090a0e01b2bffff14/zxing_cpp-3.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:93918148c1ed7ec60ff172b183ddc9dddfcb59e40867b0e98d79cc2d62a2b41d", size = 1009395, upload-time = "2026-07-29T08:50:47.118Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/f1/c7c93c2123701c12cda01ef02662ff010a79d31e86f67e9080d10d19013b/zxing_cpp-3.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:68b8cbd6797228eb983ab616b876cc744db319c64a9491a4806324afd04a8c48", size = 934267, upload-time = "2026-07-29T08:50:48.463Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/a8/8c005a5251734f57a30f1e85fa2a8965d53cd0df99d1abf642956153410e/zxing_cpp-3.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b4bd34f71868af0e34b000da4fc885c85a7f0ef37eecc0ec433ff27b263a5b7", size = 915637, upload-time = "2026-07-29T08:50:50.129Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/31/a2e693c9771b88e45dd7e52b56c85c169649123cf0eebfb32151efdfb356/zxing_cpp-3.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94e342d390933b9678f71bf6005cf2125cdb27c2355c21fa194e3a672502aac6", size = 867750, upload-time = "2026-07-29T08:50:51.788Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/30/d2f7e626b4216bbb47783d7431cd27b151cfe5abeb22aa06f0b130095841/zxing_cpp-3.1.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71df8523deb2fb40b834238e6fa739e210e3a6e27c5b94a99b4106c08e339b9b", size = 1030274, upload-time = "2026-07-29T08:50:53.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/b9/c4b6db45a3a9f7e34a3faadcce78c2084f0bc2ce0ee8344d61f1149d2318/zxing_cpp-3.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:388626ac8df24f63c2bb17dcd42fd21daeeea6fd6759bd9b1c064b71142da07e", size = 1104873, upload-time = "2026-07-29T08:50:54.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/8e/8dbf8fcf4d466c7d9b5023ae4cf17da22f328efabd4d7107109ac7737155/zxing_cpp-3.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:fe8172f3c9b17f8fd40fba2ae0ba9728228caeff3587eabf5d99888891d02e62", size = 1032030, upload-time = "2026-07-29T08:50:56.169Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/38/e547ea4f9a7c8c24a1d3a59869540029e4bad467f9544084c3cee94eb6e0/zxing_cpp-3.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:1992231c161c3eaf5857f7bc35193b8ca621eba0debc51e752403657b88d542a", size = 956213, upload-time = "2026-07-29T08:50:57.524Z" },
|
||||
]
|
||||
|
||||
Vendored
+1
-1
Submodule vendor/visionsuite updated: 06b549a25d...9eb6f4cbce
Reference in New Issue
Block a user