【无标题】

节点修改方法:

节点7的正确理解是:

  • Step 1:ransac_perpendicular_corner → 底板L形角,补全出 base_plate_polyline(这就是"矩形多段线")

  • Step 2:删除底板层

  • Step 3:ransac_circle_square → 圆孔 + 同心正方形(即 case8 已有的函数)

原方案写成 ransac_circle_rectangle / ransac_circle_square 是多余的歧义,节点7的方法兰是正方形,应固定用 ransac_circle_square。

完整修改方案(终版)

每个节点的算法对应:

所有节点 Step 1 完全相同,只有 Step 2 不同。

改动总览(9处):

  1. model_est.py --- 新增 estimate_coaxial_circles

位置:紧接 estimate_concentric_coplanar_circles 之后,归属注释"第2层"。

4点采样逻辑:

pts0:3 → fit_circle → (center1, normal=共轴方向, radius1)

pts3 → 到轴线距离 → radius2

pts3 → 在轴方向的投影偏移量 + center1_xy → center2

校验(缺一不可):

  • radius2 > 0 且有限

  • 两圆心沿 normal 方向的高度差 > min_gap(防退化为共面)

返回格式(与现有 estimate_concentric_coplanar_circles 完全一致):

(circle1, circle2) # 每个 circle = (center: ndarray(3,), normal: ndarray(3,), radius: float)

  1. core/workers.py --- 新增 "coaxial_circles" 分支

位置:_trial_worker 里,elif model_type == "perpendicular_corner": 之前

elif model_type == "coaxial_circles":

c1, c2 = estimate_coaxial_circles(sample)

if c1 is None or c2 is None:

return None, -np.inf, None, 0

model = (c1, c2)

shapes = {"circles": [

{"center": c10.tolist(), "normal": c11.tolist(), "radius": c12},

{"center": c20.tolist(), "normal": c21.tolist(), "radius": c22},

]}

文件头 import 增加 estimate_coaxial_circles。

_trial_worker_fixed_normal 本次不改。

  1. core/models.py --- 新增 ransac_coaxial_circles

位置:紧接 ransac_concentric_circles 之后

def ransac_coaxial_circles(points, max_iter=1000, threshold=1.0,

soft_threshold=False, temperature=1.0,

n_workers=None):

"""同轴双圆(同轴不共面)。4点采样:3点定轴,第4点定圆2高度和半径。"""

return ransac(points, 4, max_iter, threshold,

soft_threshold, temperature, "coaxial_circles",

n_workers=n_workers)

  1. core/init.py

import 和 all 各加一行 ransac_coaxial_circles,风格与现有保持一致。

  1. viz/scenes.py --- 新增2个函数

5a. visualize_coaxial_circles(紧接 visualize_concentric_circles 之后)

同轴双圆专用可视化(两圆不共面,有高度差):

内点红色 / 外点灰色:make_inlier_pcd

圆1(低圆):make_circle_lineset(c10, c11, c12, BLUE)

圆2(高圆):make_circle_lineset(c20, c21, c22, BLUE)

共同轴线箭头:make_normal_arrow(c10, c11, 高度差) 从低圆圆心出发

低圆圆心标注:make_center_sphere(c10)

坐标系:frame_at_centroid(points)

5b. visualize_plate_node_result(文件末尾)

底板 + 目标几何联合可视化,一个窗口展示全部:

着色:

底板 L形角 内点 → 绿色 0.0, 0.8, 0.0

目标几何体 内点 → 红色 1.0, 0.0, 0.0

其余点 → 灰色 0.6, 0.6, 0.6

底板部分(固定):

L形角两段线段(绿色)+ 角点绿球

目标几何部分(按 node_type):

"big_ring" / "circular_flange":两个蓝色圆 lineset + 法向箭头 + 圆心球

"big_ring_back" / "circular_flange_back":两个蓝色圆 lineset(不同高度)+ 轴线箭头

"frame_flange":内外两个蓝色矩形 lineset + 法向箭头

"square_flange":蓝色圆 lineset + 蓝色正方形 lineset

签名:

def visualize_plate_node_result(points, base_corner, base_mask,

geometry, geom_mask, node_type,

title="节点测量结果"):

  1. viz/init.py

from .scenes import (...) 和 all 各增加:

  • visualize_coaxial_circles

  • visualize_plate_node_result

  1. pipeline/node_measurement.py(新建)

Step 1 : ransac_perpendicular_corner → base_corner(底板L形角,迭代数 corner_iter)

Step 2 : 由L形角两端点补全底板矩形顶点 → base_plate_polyline

corner → far_A → (far_A + far_B - corner) → far_B → corner

Step 3 : remove_plane_points(plane来自base_corner"plane") → 删除底板整层

Step 4 : 按 node_type 选择 RANSAC 函数,拟合目标几何(迭代数 geom_iter)

Step 5 : mask 映射回原始 points,组装返回字典

node_type → RANSAC 接口:

_GEOMETRY_FN = {

"big_ring": ransac_concentric_circles,

"big_ring_back": ransac_coaxial_circles,

"circular_flange": ransac_concentric_circles,

"circular_flange_back": ransac_coaxial_circles,

"frame_flange": ransac_concentric_rectangles,

"square_flange": ransac_circle_square,

}

函数签名:

def run_plate_node_pipeline(

points, node_type,

threshold=5.0, soft_threshold=True, temperature=3.0,

corner_iter=100000, geom_iter=200000,

plane_removal_threshold=20.0,

**geom_kwargs):

返回字典:

{

"base_corner": base_corner, # L形角模型

"base_plate_polyline": ..., # 底板闭合顶点列表

"geometry": geometry_model, # 目标几何体

"base_mask_full": base_mask, # 底板内点掩码

"geometry_inliers_full": geom_inliers, # 目标内点掩码

"geometry_count": count,

}

  1. pipeline/init.py

新增 run_plate_node_pipeline 的 import 和 all 条目。

  1. main.py --- 新增 case12_plate_node_pipeline

一个 case 覆盖全部节点,通过 node_type 切换:

def case12_plate_node_pipeline():

"""Case 12 通用节点测量流水线(改 node_type 切换节点2~7)。"""

pts = load_point_cloud(r"D:\ransac_v4\data\...\xxx.pcd")

print(f"case 12 原始输入点数:{len(pts)}")

visualize_raw(pts, title="Before: 节点测量")

start = time.perf_counter()

result = run_plate_node_pipeline(

pts,

node_type="big_ring", # ← 改此处切换节点

threshold=5.0, soft_threshold=True, temperature=3.0,

corner_iter=100000, geom_iter=200000,

plane_removal_threshold=20.0,

)

elapsed = time.perf_counter() - start

print(f"Case 12 流水线总耗时 {elapsed:.2f}s")

print 各节点关键参数(角点、内外径/半宽高、内点数等)

visualize_plate_node_result(

pts,

base_corner=result"base_corner",

base_mask=result"base_mask_full",

geometry=result"geometry",

geom_mask=result"geometry_inliers_full",

node_type="big_ring", # ← 与上面保持一致

title="After: 节点测量",

)

main 块增加:

Case 12 通用节点测量流水线

case12_plate_node_pipeline()

风险点:

R1:底板与目标几何高度差太小,remove_plane_points 误删目标点

缓解方式:plane_removal_threshold 暴露为参数

R2:同轴双圆4点采样噪声敏感,退化为共面

缓解方式:min_gap 校验,不稳定可后续改6点,不破坏接口

R3:base_plate_polyline 由L角两端补全,仅适合矩形底板

缓解方式:当前约束明确,不规则底板后续扩展

R4:visualize_plate_node_result 内部按 node_type 分派

缓解方式:与现有 visualize_three_pairs_concentric_circles 风格一致,可接受

节点的真实关键参数和我已经实现的方法能不能实现真实关键参数完成:

❯ 现在需要你根据我给你的keyparam,判断我实现的方法,返回的模型里面能不能满足下面真实的参数,将下面所有的关键参数完成实例化:2

(盖板)大圆环

通常是油箱盖板上的,用于连接圆柱形升高座的密封圈。

圆环

平板

圆环与平板共面而且同轴

ring_inner_diameter

圆环内径

ring_outer_diameter

圆环外径

ring_center_x

ring_center_y

ring_center_z

圆环上表面中心点

ring_normal_x

ring_normal_y

ring_normal_z

圆环上表面法向

base_plate_polyline

底板外轮廓多段线表示

Polyline定义在geometry.py中

底板本身开圆孔,其直径比圆环的外径小,比内径大

共面前提下高度即为厚度

@dataclass

class LineSegment:

"""A segment between two 3D points.

``None`` means the endpoint is currently unknown or will be inferred by a

later recognizer/reasoner step.

"""

start: OptionalVec3 = None

end: OptionalVec3 = None

metadata: dictstr, Any = field(default_factory=dict)

@dataclass

class SegmentConstraint:

"""Constraint between two segments in the same polyline-like primitive."""

segment_a: int

segment_b: int

type: SegmentConstraintType

metadata: dictstr, Any = field(default_factory=dict)

@dataclass

class Polyline(Primitive):

primitive_type: ClassVarPrimitiveType = PrimitiveType.POLYLINE

segments: listLineSegment = field(default_factory=list)

segment_constraints: listSegmentConstraint = field(default_factory=list)

closed: bool = False

@property

def segment_count(self) -> int:

return len(self.segments)

Polyline是由一系列 LineSegment(线段)首尾拼接而成的路径。每个线段包含起点和终点, 其次还会存储线段的约束关系,比如垂直平行等

通常和圆柱形升高座尺寸相似,常见直径约400~600mm,也存在特例,一般是连接其他的管道或检测装置:

搭接板板厚20~30mm。

圆环板厚20-30mm

有平整度要求,要实现气密性,所以会用铣边机铣过,表面是亮面。

可行 3

(滴答)

3 大圆环背部

image-2026-3-6_15-25-14.png

底板带圆环一起翻转

圆环

平板

ring_inner_diameter

圆环内径

plate_hole_diameter

平板孔径

center_x

center_y

center_z

平板孔面中心点

ring_center_x

ring_center_y

ring_center_z

圆环内孔中心点

normal_x

normal_y

normal_z

圆环下表面法向

base_plate_polyline

底板外轮廓多段线表示

同上 可行 3

2026年5月19日

朱琳

(滴答)

4 搭接圆法兰

圆形法兰

平板

flange_inner_diameter

法兰内径

flange_outer_diameter

法兰外径

flange_center_x

flange_center_y

flange_center_z

法兰上表面中心点

flange_normal_x

flange_normal_y

flange_normal_z

法兰上表面法向

base_plate_polyline

底板外轮廓多段线表示

底板不需要建孔

法兰厚度是 max(高度差,法兰先验厚度)

需要区分是连接升高座的,还是连接管道的。

连接管道的板厚一般在10~20mm,连接升高座的板厚更大20~30mm。

尺寸多变,直径100~600mm。

可行 3

2026年5月19日

梅景

(滴答)

5 搭接圆法兰背部

圆形法兰

平板

flange_inner_diameter

法兰内径

plate_hole_diameter

平板孔径

center_x

center_y

center_z

平板孔面中心点

flange_center_x

flange_center_y

flange_center_z

法兰内孔中心点

normal_x

normal_y

normal_z

圆环下表面法向

base_plate_polyline

底板外轮廓多段线表示

可行 3

2026年5月19日

梅景

(滴答)

6 方框法兰

常见的作用是视窗,安装透明玻璃,用于观察油箱内部液面的情况或者变压器某些度数。

方框法兰

平板

同轴共面

flange_rectangle

方形法兰两个矩形的多段线表示

base_plate_polyline

底板外轮廓多段线表示

螺栓孔用先验知识建模

内部没有焊缝

板厚20~30mm。

尺寸宽约300~500mm,长500~1000mm甚至会更长

可行

3

朱琳 (滴答)

7 搭接方法兰

方法兰

平板

flange_square

方形法兰矩形的多段线表示

inner_diameter

法兰内径

flange_center_x

flange_center_y

flange_center_z

法兰上表面中心点

flange_normal_x

flange_normal_y

flange_normal_z

法兰上表面法向

base_plate_polyline

底板的多段线表示

螺栓孔用先验知识建模

板厚10~20mm,边长100~150mm,上方可能带螺栓可能不带

导角有三类:

(1)无导角

(2)圆弧导角,半径10~20mm

(3)直边导角,边长10~20mm

可行

初始位置x为长轴

3

,帮我检查是否满足,不需要修改,告诉我即可

相关推荐
Rain5091 小时前
mini-cc 的 MCP 协议:给 AI 装个 USB-C 接口
c语言·开发语言·前端·人工智能·架构·node.js·ai编程
XLYcmy1 小时前
全链路验证测试系统:一个针对智能代理(Agent)系统全链路能力的自动化验证脚本
分布式·python·http·网络安全·ai·llm·agent
蒟蒻的贤1 小时前
关于文法G2算符优先分析的一个坑
算法
IOT.FIVE.NO.11 小时前
2026-05-30-Codex更新后对话消失和沙盒失效:适用人群、问题背景、解决方式与原因分析
人工智能·windows
yubo05091 小时前
计算机视觉第八课:形状识别(自动认出 圆形、方形、三角形)
人工智能·opencv·计算机视觉
阿部多瑞 ABU1 小时前
AI红队攻防演化史(2023-2026):从虚拟角色到RLHF劫持——所有攻击方法全景总结与最新趋势分析
网络·人工智能·安全
有味道的男人1 小时前
电商效率翻倍:京东全量商品信息抓取
python
AsiaSun.1 小时前
我把 Codex 协作经验,整理成了一套公共 Skills
人工智能
变量未定义~1 小时前
单调栈、单调队列(模板)、子矩阵、连通块中点的数量、堆箱子(4星)
算法