Files
massive-cloud/server/plugins/adapters/underframe_deflection_run.py

177 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""underframe-deflection 算法适配器 (v1.2.1)。
调用 alg/delivery_v1.2.1/underframe_deflection 的 run_both_beams:
- 输入:整车配准点云 + 左梁 ROI JSON + 右梁 ROI JSON + CAD STP(溯源用)
- 输出:left/ right/ 各一份 report.xlsx + report.json + deflection_curve.csv/png
- measurements 展示左右梁最大挠度及检验结论
v1.2.1 变更:
- 改用 run_both_beams 双梁并行入口,与算法方命令行一致
- leftRoiPath / rightRoiPath 参数默认指向 test_data ROI
- skipRegistration 默认 True(点云已配准)
"""
from __future__ import annotations
import os
import sys
import traceback
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from _plugin_io import (
emit_progress,
first_pointcloud,
load_input,
write_error_result,
write_result,
)
def _status_for(value: float | None, tolerance: float | None) -> str:
if value is None or tolerance is None:
return "info"
abs_val = abs(value)
if abs_val <= tolerance:
return "pass"
if abs_val <= tolerance * 1.5:
return "warning"
return "fail"
def main() -> int:
payload = load_input(sys.argv)
inputs = payload.get("inputs") or {}
config = inputs.get("config") or {}
out_dir = Path(payload["outDir"])
out_dir.mkdir(parents=True, exist_ok=True)
try:
emit_progress(0.05, "加载挠度算法包 v1.2.1")
# ── 输入文件 ────────────────────────────────────────────────────────
pointcloud_path = first_pointcloud(payload)
if not pointcloud_path:
write_error_result(out_dir, "未提供点云文件")
return 1
cad_path = inputs.get("cadPath") or None
left_roi = config.get("leftRoiPath") or \
"/alg/delivery_v1.2.1/underframe_deflection/test_data/roi_left_beam.json"
right_roi = config.get("rightRoiPath") or \
"/alg/delivery_v1.2.1/underframe_deflection/test_data/roi_right_beam.json"
for p, label in [(left_roi, "左梁 ROI"), (right_roi, "右梁 ROI")]:
if not os.path.isfile(p):
write_error_result(out_dir, f"{label} 文件不存在:{p}")
return 1
tolerance_mm = float(config.get("toleranceMm") or 3.0)
left_tolerance_mm = float(config.get("leftToleranceMm") or tolerance_mm or 7.0)
right_tolerance_mm = float(config.get("rightToleranceMm") or tolerance_mm or 12.0)
skip_registration = bool(config.get("skipRegistration", True))
enable_bilateral = bool(config.get("enableBilateral", True))
emit_progress(0.10, f"开始左梁挠度测量(容差 {left_tolerance_mm} mm)")
from underframe_deflection import run_single_beam_pipeline # type: ignore
left_out = out_dir / "left"
left_out.mkdir(exist_ok=True)
left_report = run_single_beam_pipeline(
input_cloud = pointcloud_path,
roi_path = left_roi,
out_dir = str(left_out),
side = "left",
tolerance_mm = left_tolerance_mm,
cad_path = cad_path,
enable_registration= not skip_registration,
config = {"enable_bilateral": enable_bilateral},
)
emit_progress(0.55, f"左梁完成,开始右梁挠度测量(容差 {right_tolerance_mm} mm)")
right_out = out_dir / "right"
right_out.mkdir(exist_ok=True)
right_report = run_single_beam_pipeline(
input_cloud = pointcloud_path,
roi_path = right_roi,
out_dir = str(right_out),
side = "right",
tolerance_mm = right_tolerance_mm,
cad_path = cad_path,
enable_registration= not skip_registration,
config = {"enable_bilateral": enable_bilateral},
)
result = {"left": left_report, "right": right_report}
emit_progress(0.95, "整理结果")
def _beam_measurements(report: dict, label: str) -> list:
insp = report.get("inspection") or {}
item_name = insp.get("item_name") or "纵向梁到直线的垂直偏差(挠度)"
measured = insp.get("measured_mm")
tol = insp.get("tolerance_mm")
verdict = insp.get("verdict") or ""
return [{
"name" : f"{label} · {item_name}",
"value" : round(float(measured), 4) if measured is not None else 0.0,
"unit" : "mm",
"tolerance": float(tol) if tol is not None else None,
"status" : "pass" if verdict == "合格"
else "fail" if verdict == "不合格"
else "info",
}]
measurements = (
_beam_measurements(left_report, "左梁") +
_beam_measurements(right_report, "右梁")
)
# 收集产物文件(xlsx/csv/png)- write_result 会自动扫 xlsx,
# 这里额外加 csv/png 让前端也能下载
extra_files: list[str] = []
for subdir in ("left", "right"):
sub = out_dir / subdir
if not sub.exists():
continue
for fname in sorted(sub.iterdir()):
if fname.suffix in (".csv", ".png"):
extra_files.append(str(fname.relative_to(out_dir)))
# ── 汇总消息 ────────────────────────────────────────────────────────
left_v = (left_report.get("inspection") or {}).get("verdict") or "—"
right_v = (right_report.get("inspection") or {}).get("verdict") or "—"
left_d = (left_report.get("inspection") or {}).get("measured_mm")
right_d = (right_report.get("inspection") or {}).get("measured_mm")
msg = (
f"挠度测量完成。"
f"左梁 {left_d:.3f} mm({left_v}),"
f"右梁 {right_d:.3f} mm({right_v})。"
if left_d is not None and right_d is not None
else "挠度测量完成。"
)
write_result(
out_dir,
{
"message": msg,
"measurements": measurements,
"files": extra_files,
"extra": {"leftReport": left_report, "rightReport": right_report},
},
)
return 0
except Exception as exc:
write_error_result(
out_dir,
f"underframe-deflection 计算失败:{exc}",
extra={"traceback": traceback.format_exc()},
)
return 1
if __name__ == "__main__":
sys.exit(main())