2. Hexagon PC-DMIS测量程序与MES数据接口配置
任务拆解:从PC-DMIS测量到MES报警闭环
本案例要打通一条最小但完整的链路:在PC-DMIS中编写一个简单零件(以法兰盘为例)的测量程序,把关键尺寸的实测值通过文件/接口输出,再由MES侧读取并判断超差,触发返工流程。核心难点不在测量本身,而在于数据字段的约定与超差判定的责任边界——PC-DMIS负责给出实测值与公差,MES负责按规则判定并驱动流程。
第一步:在PC-DMIS中建立测量程序
以法兰盘为例,需要测量的关键尺寸为:外径Ø80±0.05、内孔Ø40±0.03、厚度12±0.10。在PC-DMIS中按以下顺序建立程序:
- 建立零件坐标系:以端面为Z基准面,内孔为X/Y原点,找正后设置零件名
FLANGE-80、工序号OP20。 - 依次测量三个特征:外圆柱(4点)、内圆柱(4点)、上下端面(各3点)。
- 对每个尺寸设置标称值与上下公差,PC-DMIS会在报告中自动标注超差项。
- 在程序末尾添加文件输出命令,将结果写入固定路径的CSV文件。
PC-DMIS的文件输出可通过其内置的File I/O命令实现,关键是把零件号、工序号、特征名、实测值、标称值、上公差、下公差、判定结果这8个字段按固定顺序写出。下面给出一个可直接参考的输出格式定义:
零件号,工序号,特征名,实测值,标称值,上公差,下公差,判定
FLANGE-80,OP20,外径,80.032,80.000,0.050,-0.050,PASS
FLANGE-80,OP20,内孔,40.041,40.000,0.030,-0.030,FAIL
FLANGE-80,OP20,厚度,12.060,12.000,0.100,-0.100,PASS
注意:判定列由PC-DMIS根据公差自动生成,但MES不应盲信该列,而应基于实测值与公差重新计算,避免因程序配置错误导致漏判。这是接口设计中的一条重要原则。
第二步:配置MES侧的数据接口
MES侧需要完成三件事:文件采集、工单匹配、超差判定与报警。以下给出一个可运行的Python采集脚本示例,模拟MES文件采集器的核心逻辑:
import csv
import os
import time
from datetime import datetime
# 配置区
WATCH_DIR = r"D:\PC-DMIS\Output" # PC-DMIS输出目录
PROCESSED_DIR = r"D:\MES\Processed" # 已处理文件归档目录
ALARM_LOG = r"D:\MES\alarm_log.csv" # 报警记录
# 工单公差表(实际应从MES数据库读取)
TOLERANCE = {
("FLANGE-80", "OP20", "外径"): (80.000, 0.050, -0.050),
("FLANGE-80", "OP20", "内孔"): (40.000, 0.030, -0.030),
("FLANGE-80", "OP20", "厚度"): (12.000, 0.100, -0.100),
}
def judge(part, op, feature, measured):
"""基于MES侧公差表重新判定,不依赖PC-DMIS的判定列"""
key = (part, op, feature)
if key not in TOLERANCE:
return "UNKNOWN", None
nominal, upper, lower = TOLERANCE[key]
if measured > nominal + upper:
return "FAIL", measured - (nominal + upper)
if measured < nominal + lower:
return "FAIL", measured - (nominal + lower)
return "PASS", 0.0
def process_file(filepath):
alarms = []
with open(filepath, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
part = row["零件号"].strip()
op = row["工序号"].strip()
feature = row["特征名"].strip()
measured = float(row["实测值"])
result, deviation = judge(part, op, feature, measured)
if result == "FAIL":
alarms.append({
"时间": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"零件号": part,
"工序号": op,
"特征名": feature,
"实测值": measured,
"偏差": round(deviation, 4),
"动作": "触发返工工单"
})
return alarms
def write_alarms(alarms):
if not alarms:
return
file_exists = os.path.exists(ALARM_LOG)
with open(ALARM_LOG, "a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=alarms[0].keys())
if not file_exists:
writer.writeheader()
writer.writerows(alarms)
def main():
os.makedirs(PROCESSED_DIR, exist_ok=True)
while True:
for fname in os.listdir(WATCH_DIR):
if not fname.endswith(".csv"):
continue
fpath = os.path.join(WATCH_DIR, fname)
try:
alarms = process_file(fpath)
write_alarms(alarms)
os.rename(fpath, os.path.join(PROCESSED_DIR, fname))
print(f"[{datetime.now()}] 处理 {fname},报警 {len(alarms)} 条")
except Exception as e:
print(f"处理 {fname} 失败: {e}")
time.sleep(5)
if __name__ == "__main__":
main()
脚本的关键设计点:公差表独立维护在MES侧,与PC-DMIS程序解耦;判定逻辑重新计算,不直接使用PC-DMIS的判定列;处理完成后归档文件,避免重复读取。运行后,若内孔实测40.041超出上公差40.030,脚本会生成一条报警记录,动作字段为“触发返工工单”。
第三步:验证超差报警与返工触发
验证时,先用上述示例数据(内孔40.041)运行一次,检查alarm_log.csv是否出现对应记录。然后修改PC-DMIS输出文件,把内孔改为40.020(合格),确认不再产生报警。最后检查MES的返工工单表是否被正确写入——这一步需要MES侧提供工单写入接口,通常是一个数据库插入或API调用,具体形式取决于MES产品。
接口字段与判定关系图
下图展示了从PC-DMIS测量到MES报警的完整数据流,以及各字段在链路中的传递关系。重点看公差表在MES侧独立维护这一设计,它决定了超差判定的最终责任方。
常见问题与排查
- CSV文件被占用无法读取:PC-DMIS写入时可能锁定文件,采集器应捕获异常并跳过,下一轮再试;或让PC-DMIS先写临时文件再重命名。
- 字段编码不一致:PC-DMIS默认可能用GBK,MES侧用UTF-8读取会乱码。统一在输出时指定UTF-8,或在采集器里做编码探测。
- 公差表与PC-DMIS程序不同步:这是最危险的情况。建议在MES侧维护公差表后,定期与PC-DMIS程序中的公差做一致性校验,发现偏差立即告警。
- 返工工单重复触发:同一文件被重复读取会导致重复报警。处理完成后必须归档或标记,采集器只处理未处理文件。