feat: 算法升级、整车配准集成与性能分析文档

算法更新: delivery v1.2.1、平整度v1.5、测距v2.2、整车配准v1.3
适配器: vehicle-registration 新增、各算法 manifest 和 adapter 更新
后端: taskCadFiles/source 字段迁移、derivedPointClouds 注册、取消任务联动
前端: ElapsedTime 时长显示、两步算法流程、canRun 逻辑修复
文档: 新增5份算法性能分析报告
This commit is contained in:
2026-06-25 08:22:20 +00:00
parent cec0766e67
commit 29f1d45d66
266 changed files with 1311475 additions and 2846 deletions

View File

@@ -1,8 +1,13 @@
"""coupler-panel 算法适配器 (v1.2)。
"""coupler-panel 算法适配器 (v1.2.1)。
v1.2.1 变更:
- 算法包升级至 delivery_v1.2.1
- 新增项点 Excel 报表(write_inspection_report):
项点名称/理论尺寸/公差要求/测量结果/误差结果/测量结论
- PYTHONPATH 指向 delivery_v1.2.1/coupler_panel_release
v1.2 变更:
- 算法包升级至 delivery_v1.2(新增 autotune 自动调参与 layer_select 分层选点)
- PYTHONPATH 指向 delivery_v1.2/coupler_panel_release
- 新增 autotune 自动调参与 layer_select 分层选点
v1.1 变更:
- 入口从 compute_coupler_measurement → run_coupler_measurement_pipeline
@@ -20,7 +25,6 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from _plugin_io import (
emit_progress,
ensure_ascii_ply,
first_pointcloud,
load_input,
write_error_result,
@@ -46,23 +50,45 @@ def main() -> int:
out_dir.mkdir(parents=True, exist_ok=True)
try:
emit_progress(0.05, "加载 coupler_panel v1.2 算法包")
emit_progress(0.05, "加载 coupler_panel v1.2.1 算法包")
from coupler_panel.pipeline import run_coupler_measurement_pipeline # type: ignore
pc_path = first_pointcloud(payload)
emit_progress(0.15, f"读取点云:{os.path.basename(pc_path)}")
# 若是二进制 PLY,先转成 ASCII PLY(算法内置 reader 不依赖 open3d)
pc_path = ensure_ascii_ply(pc_path, out_dir / "_ply_cache")
profile = str(config.get("profile") or "auto")
right_axis_sign = int(config.get("rightAxisSign") or 1)
# 可选 CAD STP 路径(前端传入 cadPath 时使用)
cad_stp_path = inputs.get("cadPath") or None
# 可选 ROI JSON 路径(前端传入 roiJson 时使用)
# ROI 裁剪:优先用 roiJson 文件,其次用前端填的 6 个坐标参数
roi_json = inputs.get("roiJson") or None
roi_spec = None
if not roi_json:
def _f(key: str) -> float | None:
v = config.get(key)
try:
return float(v) if v is not None and str(v).strip() != "" else None
except (TypeError, ValueError):
return None
x_min, x_max = _f("roiXMin"), _f("roiXMax")
y_min, y_max = _f("roiYMin"), _f("roiYMax")
z_min, z_max = _f("roiZMin"), _f("roiZMax")
# 至少有一对轴的范围被填写时才构建 ROI
if any(v is not None for v in (x_min, x_max, y_min, y_max, z_min, z_max)):
from coupler_panel.roi import ROISpec # type: ignore
roi_spec = ROISpec(
x_min=x_min if x_min is not None else float("-inf"),
x_max=x_max if x_max is not None else float("inf"),
y_min=y_min if y_min is not None else float("-inf"),
y_max=y_max if y_max is not None else float("inf"),
z_min=z_min if z_min is not None else float("-inf"),
z_max=z_max if z_max is not None else float("inf"),
)
emit_progress(0.20, f"ROI 裁剪:x[{x_min},{x_max}] y[{y_min},{y_max}] z[{z_min},{z_max}]")
emit_progress(0.25, "调用 run_coupler_measurement_pipeline")
@@ -74,7 +100,8 @@ def main() -> int:
out_dir=str(out_dir),
profile=profile,
cad_stp_path=cad_stp_path,
roi_json=roi_json,
roi_spec=roi_spec, # 优先用坐标参数构建的 ROISpec
roi_json=roi_json, # 备选:直接传 ROI JSON 文件
progress=_on_progress,
)
@@ -83,6 +110,41 @@ def main() -> int:
# right_axis_sign 影响 theta_right_deg 的符号约定
theta_right = float(result.theta_right_deg) * right_axis_sign
theta_ref = float(result.theta_ref_deg)
# ── 项点 Excel 报表(v1.2.1 新增)────────────────────────────────────
# 用未截断的拟合平面法向量算原始角度(避免微小角被钳为 0),
# 公差按斜率形式给出:参考面 0.8/375mm,纵向中心 1/700mm。
# 产物 xlsx 由 write_result 自动发现并写入 files 字段。
try:
import math
from coupler_panel.reporting import InspectionItem, write_inspection_report # type: ignore
raw_right, raw_ref = theta_right, theta_ref
report_dict = result.report if isinstance(result.report, dict) else {}
normal = (report_dict.get("plane") or {}).get("normal")
if normal and len(normal) == 3:
nx, ny, nz = (float(v) for v in normal)
raw_right = math.degrees(math.atan2(ny, nx)) * right_axis_sign
raw_ref = math.degrees(math.atan2(nz, nx))
item_ref = InspectionItem(
name="车钩面板距参考面的右偏转角(头车一位端处车钩)",
theta_deg=raw_ref,
baseline_mm=375.0,
tol_value_mm=0.8,
)
item_long = InspectionItem(
name="车钩面板距纵向中心的右偏转角(头车一位端处车钩)",
theta_deg=raw_right,
baseline_mm=700.0,
tol_value_mm=1.0,
)
write_inspection_report(item_ref, out_dir / "report_ref_plane.xlsx")
write_inspection_report(item_long, out_dir / "report_longitudinal.xlsx")
except Exception:
# Excel 报表失败不影响主结果
traceback.print_exc()
dx_y = float(result.dx_y_max_mm)
dx_z = float(result.dx_z_max_mm)
D_y = float(result.D_y_max_mm)