ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

python的先进制造技术工业场景模拟第八十二篇:仿真数控粗精工序加工流程,模拟刀具磨损逐步累积,观察零件粗糙度逐步劣化。

python的先进制造技术工业场景模拟第八十二篇:仿真数控粗精工序加工流程,模拟刀具磨损逐步累积,观察零件粗糙度逐步劣化。 周五白班精加工工位巡检。“这批轴套前50件还亮得像镜子到第80件开始发雾第120件三坐标一量Ra从0.8飘到1.6了”数控操作工老肖拿指甲刮了刮工件表面“以前换刀按件数定比如150件换可实际跟材料批次、切深、转速都有关刀尖磨钝是慢慢爬的粗糙度也是跟着爬的等发现就超差了。”我接上导出的刀补日志、工序参数、每件的表面粗糙度抽检表。“这里面有啥”我问。“粗加工刀轨、精加工进给F、主轴转速S、每件的Ra实测、刀具半径补偿值都有”老肖说“但系统只给单件结果不模拟‘刀尖后刀面磨损VB怎么随件数爬’‘磨损怎么映射到残留高度’‘Ra怎么逐步劣化’。想换种材料又得跑一炉看趋势。”“最亏的是中段”老肖补一句“50到100件之间Ra从0.8爬到1.2还没超差质检按批检就漏了到120件直接报废几件。排产还按150件换刀等于拿超差换产能。”“我就想干一件事”老肖说“给粗精工序参数刀具初始状态模拟VB磨损逐件累积反推残留高度算出每件Ra曲线标出从哪件开始进临界区、哪件必须换刀像个小刀具寿命仿真器不用跑一炉。”“数控不是看程序跑没跑”我接话“是看‘刀尖每走一件磨掉多少、残留高度怎么涨、Ra曲线怎么斜着爬’。用 numpy 做磨损递推pandas 管工序件表scipy 算残留高度与Ra映射matplotlib 画磨损-Ra双轴曲线刀纹云图networkx 建工序-刀具-粗糙度关联sklearn 做超差预警分类。”“对”老肖点头“要能说清‘第1件VB0.02mm Ra0.78第82件VB0.12mm Ra1.21进临界第118件VB0.18mm Ra1.62超差建议第110件换刀主因是精加工进给VB耦合’。”“OOP 封好”我开工程“工序加载器、刀具磨损模型、残留高度映射、粗糙度递推器、超差分类器、可视化器合成多批次多材料数据下载就能跑。”敲了行原型# 目标: 粗精工序 → 刀具VB磨损递推 → 残留高度 → Ra逐件劣化# 方法: 磨损累积模型 几何残留高度 RF超差分类 关联图老肖凑近看“那以后看报告VB磨损曲线Ra双轴残留高度随件数变化刀纹热力图工序-刀具-粗糙度网络超差预测散点。新批次上机前先跑黄线就是换刀点。”“对”我接话“数控仿真不是‘画个刀轨’是‘提前看见刀尖哪件开始钝、表面哪件开始毛’。数字孪生里挂这个刀具看板就是操作工的‘换刀闹钟’。”一、实际应用场景真实痛点场景设定数控车/铣精加工轴套类零件粗加工去量、精加工保表面质量。刀具后刀面磨损 VB 随加工件数逐步累积残留高度随之增大Ra 从 0.8μm 逐步爬到超差。现场按固定件数换刀未耦合磨损-粗糙度动态关系中段劣化被批检漏掉。现场原话叙事化“不是程序编错了”老肖说“是刀尖钝得悄无声息。前50件手摸都滑到80件看着就发雾三坐标一量Ra1.3批检还按10件抽1件正好抽到的都还行。”“最亏的是换刀策略”老肖说“定死150件换可这批料硬点110件就超了后面8件全废。等于用超差换那40件的产能。”核心矛盾“固定件数换刀单件Ra抽检” 与 “VB磨损递推残留高度映射Ra逐件曲线超差预警关联图” 之间的断层。二、痛点分析映射到滨州职业学院《先进制造技术》课程模型《先进制造技术》课程模块 本篇痛点对应数控加工与CAD/CAM技术粗精加工、刀具磨损、切削参数、表面粗糙度、残留高度 VB递推Ra劣化换刀点先进制造技术基础几何精度、表面质量评价、材料去除机理 残留高度→Ra映射FMS与先进生产管理刀具寿命管理、换刀策略、在制品质量追踪 动态换刀点质量追踪智能制造与数字孪生刀具状态数字映射、粗糙度看板 磨损/ Ra挂孪生先进制造新模式工艺知识库材料-参数-刀具寿命库 磨损模型复用一句话总结我们需要一个“粗精工序参数→刀具VB磨损递推→残留高度→Ra逐件曲线→超差预警关联图”程序实现从“固定件数换刀”到“按磨损状态动态换刀”的闭环。三、核心逻辑讲解大白话3.1 问题本质把刀尖想成“慢慢变圆的铅笔头”把精加工刀尖想成削铅笔的刀刚磨完是尖的削出来的面光用久了变圆削出来的面就有一道道棱* VB磨损 刀尖后刀面磨掉的宽度单位mm从0.02慢慢爬到0.2* 残留高度 刀尖是圆弧走刀后工件表面留下的微小波峰刀尖越钝波峰越高* Ra 这些波峰波谷平均出来的粗糙度值* 粗加工 先挖掉大部分料不管光洁度* 精加工 吃刀浅、走刀密靠刀尖圆弧保光洁度* 固定换刀 数件数不管刀钝没钝* 动态仿真 每加工一件VB加一点残留高度算一次Ra跟一次画成曲线3.2 业务逻辑 → 代码映射输入工序参数刀具初始状态│▼ ProcessParamLoader (pandas)读取表:件号, 工序(粗/精), 主轴转速S, 进给F, 切深ap,刀尖圆弧半径re, 材料硬度, 初始VB│▼ ToolWearModel (numpy)VB磨损递推:ΔVB_i k * (ap*F/S) * 材料系数 * (1已磨损放大项)VB_i VB_{i-1} ΔVB_i粗加工磨损权重高, 精加工慢但敏感│▼ ResidualHeightModel (scipy numpy)残留高度:h f(F, re, VB) 刀尖变钝→等效re增大理论: h ≈ F²/(8*(reVB))│▼ RoughnessPropagator (numpy scipy)Ra递推:Ra ≈ C * h^0.8 刀具振动项逐件输出Ra序列分级: 优(Ra≤0.8) / 良(≤1.6) / 临界(1.2~1.6) / 超差(1.6)│▼ OverLimitClassifier (sklearn)超差预警:特征: VB, Ra, 件号, 材料硬度, F, ap标签: 安全/临界/超差RF三分类 5折宏F1预测“还有几件到超差”│▼ CncVisualizer (matplotlib networkx)可视化:1. VB磨损Ra双Y轴曲线(标换刀线)2. 残留高度随件数曲线3. 刀纹表面热力图(模拟不同VB下刀纹)4. 工序-刀具-粗糙度关联网络5. 超差预测vs实际散点6. 单件Ra分布箱线(分段)│▼ SyntheticCncBatch (numpy)合成数据:多批次×多材料, 机制: 硬料VB爬得快, F大残留高, VB耦合放大3.3 为什么不能“固定件数换刀”视角 问题按件数换刀 漏掉材料硬度差异单件Ra抽检 中段劣化被平均掉看程序参数 看不到刀尖变圆VB递推 每件磨多少都算残留高度 刀钝→波峰涨可量化Ra曲线 斜爬过程全看见RF预警 提前报“还有N件超差”3.4 分析前后对比维度 传统方式 本程序换刀依据 150件固定 VB0.18动态换刀(第110件)劣化发现 超差后返工 第82件进临界即预警中段质量 批检漏掉 逐件Ra曲线可见主因分析 凭经验 VB进给耦合量化知识沉淀 老师傅记忆 材料-参数-寿命库四、OOP 代码实现4.1 项目结构cnc_wear_roughness/├── cnc_wear_roughness/│ ├── __init__.py│ ├── process_param_loader.py # 工序参数加载│ ├── tool_wear_model.py # VB磨损递推(numpy)│ ├── residual_height_model.py # 残留高度(scipy)│ ├── roughness_propagator.py # Ra递推│ ├── over_limit_classifier.py # 超差分类(sklearn)│ ├── cnc_visualizer.py # 可视化│ └── synthetic_cnc_batch.py # 合成批次├── tests/│ ├── __init__.py│ └── test_cnc.py├── results/│ ├── wear_ra_curve.png│ ├── residual_height_curve.png│ ├── tool_mark_heatmap.png│ ├── process_tool_network.png│ ├── overrun_pred_scatter.png│ ├── ra_boxplot_stage.png│ ├── cnc_detail.csv│ └── cnc_report.txt└── run_cnc.py4.2 核心源码detailssummary/summary数控工序参数加载器。import pandas as pdfrom pathlib import Pathclass ProcessParamLoader:加载粗精工序参数与刀具初始状态。def __init__(self, filepath: str cnc_process.csv,encoding: str utf-8):self.filepath Path(filepath)self.encoding encodingdef load(self) - pd.DataFrame:if not self.filepath.exists():raise FileNotFoundError(self.filepath)df pd.read_csv(self.filepath, encodingself.encoding)req [part_no, op, spindle_s, feed_f, ap,tool_re, material_hb, vb_init]miss [c for c in req if c not in df.columns]if miss:raise ValueError(f缺列: {miss})for c in req[1:]:df[c] pd.to_numeric(df[c], errorscoerce)return df.dropna(subsetreq).reset_index(dropTrue)def summary(self, df: pd.DataFrame) - str:s f计划件数: {len(df)}\ns f精加工转速S: {df[df.opfinish][spindle_s].iloc[0]}rpm\ns f精加工进给F: {df[df.opfinish][feed_f].iloc[0]}mm/r\ns f刀尖圆弧re: {df[tool_re].iloc[0]}mm\ns f材料硬度: {df[material_hb].iloc[0]}HB\ns f初始VB: {df[vb_init].iloc[0]}mmreturn s.rstrip()/detailsdetailssummary/summary刀具后刀面磨损VB递推 (numpy)。import numpy as npfrom dataclasses import dataclassdataclassclass WearResult:vb: np.ndarraydvb: np.ndarrayclass ToolWearModel:VB累积模型(教学级):ΔVB k * (ap*F/S) * 材料系数 * (10.5*VB/VB_ref)粗加工权重1.0, 精加工权重0.35(吃刀浅但敏感)已磨损刀具摩擦加剧, 磨损加速(自放大)def __init__(self, k: float 1.2e-4, vb_ref: float 0.2):self.k kself.vb_ref vb_refdef simulate(self, n_parts: int, op: np.ndarray,s: float, f: float, ap: np.ndarray,material_hb: float, vb_init: float) - WearResult:vb np.zeros(n_parts)dvb np.zeros(n_parts)mat_coef 0.6 material_hb / 200.0 # 硬料磨损快for i in range(n_parts):w 1.0 if op[i] rough else 0.35base self.k * (ap[i] * f / max(s, 1)) * mat_coef * wamp 1.0 0.5 * (vb[i-1] / self.vb_ref if i 0 else 0.0)d base * ampif i 0:vb[i] vb_init delse:vb[i] vb[i-1] ddvb[i] dreturn WearResult(vb, dvb)/detailsdetailssummary/summary残留高度模型 (scipy numpy)。import numpy as npfrom dataclasses import dataclassdataclassclass ResidualResult:h_res: np.ndarrayclass ResidualHeightModel:刀尖圆弧磨损等效放大:re_eff re VB (刀钝等效圆弧变大)h F^2 / (8 * re_eff) (几何残留高度)def __init__(self):passdef compute(self, f: float, re: float,vb: np.ndarray) - ResidualResult:re_eff re vbh (f ** 2) / (8.0 * re_eff)return ResidualResult(h)/detailsdetailssummary/summaryRa粗糙度递推 (numpy scipy)。import numpy as npfrom dataclasses import dataclassfrom scipy.ndimage import gaussian_filter1ddataclassclass RoughnessResult:ra: np.ndarraygrade: np.ndarrayclass RoughnessPropagator:Ra ≈ C * h^0.8 微振动项分级:excellent: Ra0.8good: 1.6critical: 1.2~1.6overrun: 1.6def __init__(self, c: float 0.9, vib: float 0.05):self.c cself.vib vibdef propagate(self, h_res: np.ndarray,n_parts: int) - RoughnessResult:ra self.c * (h_res ** 0.8) * 1000.0 self.vib * np.arange(n_parts)/n_partsra gaussian_filter1d(ra, sigma1.0) # 平滑工艺噪声grade np.array([self._grade(r) for r in ra])return RoughnessResult(ra, grade)def _grade(self, r: float) - str:if r 0.8:return excellentif r 1.2:return goodif r 1.6:return criticalreturn overrun/detailsdetailssummary/summary超差预警分类 (sklearn RF)。import numpy as npimport pandas as pdfrom typing import Dictfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import cross_val_score, KFoldclass OverLimitClassifier:安全/临界/超差 三分类 剩余件数预测。def __init__(self, random_state: int 42):self.random_state random_stateself.model_ Noneself.feat [vb, ra, part_idx, material_hb, feed_f, ap]def fit(self, df: pd.DataFrame, y: np.ndarray):self.model_ RandomForestClassifier(n_estimators300, max_depth6, min_samples_leaf2,random_stateself.random_state, n_jobs-1)self.model_.fit(df[self.feat].values, y)return selfdef feature_importance(self) - Dict:imp dict(zip(self.feat, self.model_.feature_importances_))return dict(sorted(imp.items(), keylambda x: x[1], reverseTrue))def cross_validate(self, df: pd.DataFrame, y: np.ndarray) - Dict:kf KFold(n_splits5, shuffleTrue, random_stateself.random_state)sc cross_val_score(self.model_, df[self.feat].values, y,cvkf, scoringf1_macro)return {f1_macro_mean: float(sc.mean()), f1_macro_std: float(sc.std())}def predict(self, df: pd.DataFrame) - np.ndarray:return self.model_.predict(df[self.feat].values)/detailsdetailssummary/summary数控可视化 (matplotlib networkx)。import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pathlib import Pathimport networkx as nxplt.rcParams[font.sans-serif] [SimHei, WenQuanYi Micro Hei, DejaVu Sans]plt.rcParams[axes.unicode_minus] FalseGRADE_COLOR {excellent:#27AE60,good:#2ECC71,critical:#F39C12,overrun:#E74C3C}class CncVisualizer:def __init__(self, results_dir: str results):self.results_dir Path(results_dir)self.results_dir.mkdir(exist_okTrue)def wear_ra_curve(self, idx, vb, ra, change_point, overrun_point):fig, ax1 plt.subplots(figsize(12, 6))ax1.plot(idx, vb*1000, color#2C3E50, lw1.8, labelVB磨损(μm))ax1.set_xlabel(加工件数, fontsize12)ax1.set_ylabel(VB磨损 (μm), color#2C3E50, fontsize12)ax2 ax1.twinx()for i, g in enumerate([excellent,good,critical,overrun]):m ra gif m.any():ax2.scatter(idx[m], ra[m], cGRADE_COLOR[g], s18,labelfRa-{g}, zorder5)ax2.set_ylabel(Ra (μm), color#E67E22, fontsize12)ax1.axvline(change_point, color#F39C12, ls--, lw2,labelf临界点#{change_point})ax1.axvline(overrun_point, color#E74C3C, ls--, lw2,labelf超差点#{overrun_point})ax1.set_title(刀具VB磨损 Ra粗糙度双轴曲线,fontsize13, fontweightbold)ax1.grid(alpha0.25)lines1, labels1 ax1.get_legend_handles_labels()lines2, labels2 ax2.get_legend_handles_labels()ax1.legend(lines1lines2, labels1labels2, fontsize8,locupper left, ncol2)plt.tight_layout()plt.savefig(self.results_dir/wear_ra_curve.png,dpi150, bbox_inchestight)plt.close()def residual_curve(self, idx, h_res):fig, ax plt.subplots(figsize(11, 5))ax.plot(idx, h_res*1000, color#8E44AD, lw1.8)ax.fill_between(idx, 0, h_res*1000, color#8E44AD, alpha0.1)ax.set_xlabel(加工件数, fontsize12)ax.set_ylabel(残留高度 (μm), fontsize12)ax.set_title(残留高度随件数变化(刀钝→波峰涨),fontsize13, fontweightbold)ax.grid(alpha0.3)plt.tight_layout()plt.savefig(self.results_dir/residual_height_curve.png,dpi150, bbox_inchestight)plt.close()def tool_mark_heatmap(self, vb_end, re, f, n_grid80):fig, ax plt.subplots(figsize(9, 5))# 模拟刀纹: 横向走刀, 纵向波峰随VBx np.linspace(0, 5, n_grid)y np.linspace(0, 1, 20)X, Y np.meshgrid(x, y)re_eff re vb_endwave (f**2)/(8*re_eff)*1000 * np.sin(2*np.pi*X/0.05)**2im ax.imshow(wave, aspectauto, cmapcopper,extent[0,5,0,1], originlower)ax.set_xlabel(工件周向展开 (mm), fontsize12)ax.set_ylabel(轴向 (mm), fontsize12)ax.set_title(f刀纹表面形貌(VB{vb_end*1000:.0f}μm时),fontsize13, fontweightbold)plt.colorbar(im, axax, label高度(μm))plt.tight_layout()plt.savefig(self.results_dir/tool_mark_heatmap.png,dpi150, bbox_inchestight)plt.close()def process_network(self, imp: Dict):fig, ax plt.subplots(figsize(11, 8))G nx.DiGraph()G.add_node(Ra超差, kindtarget)for n in [VB磨损,残留高度,进给F,切深ap,材料硬度,件号]:G.add_node(n, kindfactor)key_map {vb:VB磨损,ra:Ra超差,feed_f:进给F,ap:切深ap,material_hb:材料硬度,part_idx:件号,h_res:残留高度}for k,v in imp.items():if k in (vb,ra):continueG.add_edge(key_map.get(k,k), Ra超差, weightv)G.add_edge(VB磨损,残留高度, weight0.9)G.add_edge(残留高度,Ra超差, weight0.9)G.add_edge(进给F,残留高度, weight0.5)pos nx.spring_layout(G, seed42)cmap [#E74C3C if nRa超差 else #3498DB for n in G.nodes()]nx.draw_networkx_nodes(G,pos,node_colorcmap,node_size3200,alpha0.9,axax)nx.draw_networkx_edges(G,pos,arrowstyle-|,arrowsize20,edge_color#555,width2,axax)nx.draw_networkx_labels(G,pos,font_size11,axax,font_colorwhite,font_weightbold)ax.set_title(工序-刀具-粗糙度关联网络, fontsize14, fontweightbold)ax.axis(off)plt.tight_layout()plt.savefig(self.results_dir/process_tool_network.png,dpi150, bbox_inchestight)plt.close()def pred_scatter(self, y_true, y_pred):fig, ax plt.subplots(figsize(8, 8))labels [安全,临界,超差]ct np.array([labels.index(y) for y in y_true])cp np.array([labels.index(y) for y in y_pred])ax.scatter(ct, cp, c#27AE60, s60, edgecolorsk, alpha0.8)ax.plot([-0.5,2.5],[-0.5,2.5],r--,lw2,label理想)ax.set_xticks([0,1,2]); ax.set_xticklabels(labels)ax.set_yticks([0,1,2]); ax.set_yticklabels(labels)ax.set_xlabel(实际状态, fontsize12)ax.set_ylabel(预测状态, fontsize12)ax.set_title(超差预警 预测vs实际, fontsize13, fontweightbold)ax.legend(fontsize10); ax.grid(alpha0.3)plt.tight_layout()plt.savefig(self.results_dir/overrun_pred_scatter.png,dpi150, bbox_inchestight)plt.close()def ra_boxplot(self, idx, ra, stages):fig, ax plt.subplots(figsize(10, 6))data [ra[(idxs[0])(idxs[1])] for s in stages]labels [f{s[0]}-{s[1]}件 for s in stages]bp ax.boxplot(data, labelslabels, patch_artistTrue)for patch, g in zip(bp[boxes], [excellent,good,critical,overrun]):patch.set_facecolor(GRADE_COLOR[g]); patch.set_alpha(0.7)ax.set_ylabel(Ra (μm), fontsize12)ax.set_xlabel(加工阶段, fontsize12)ax.set_title(分段Ra分布箱线图, fontsize13, fontweightbold)ax.grid(alpha0.25)plt.tight_layout()plt.savefig(self.results_dir/ra_boxplot_stage.png,dpi150, bbox_inchestight)plt.close()/detailsdetailssummary/summary合成数控加工批次数据。import numpy as npimport pandas as pdfrom pathlib import Pathfrom typing import Optionalclass SyntheticCncBatch:多批次×多材料机制:硬料VB爬得快精加工F大→残留高VB自放大def __init__(self, rng: Optional[np.random.RandomState] None):self.rng rng or np.random.RandomState(42)def generate(self, out_path: str cnc_process.csv,n_parts: int 130,material_hb: float 180.0,feed_f: float 0.08,spindle_s: float 3000.0,tool_re: float 0.4,vb_init: float 0.02) - pd.DataFrame:rows []for i in range(n_parts):# 前5件粗加工, 其余精加工op rough if i 5 else finishap 0.8 if op rough else 0.1rows.append({part_no: fP{i1:03d},op: op,spindle_s: spindle_s,feed_f: feed_f,ap: ap,tool_re: tool_re,material_hb: material_hb,vb_init: vb_init,})df pd.DataFrame(rows)Path(out_path).parent.mkdir(parentsTrue, exist_okTrue)df.to_csv(out_path, indexFalse, encodingutf-8)return df/detailsdetailssummary/summary数控粗精工序仿真: 刀具磨损累积 → 残留高度 → Ra逐步劣化课程映射滨州职业学院《先进制造技术》数控加工与CAD/CAM粗精加工/刀具磨损/残留高度/表面粗糙度先进制造技术基础几何精度/表面质量评价FMS与先进生产管理刀具寿命管理/动态换刀智能制造与数字孪生刀具状态看板先进制造新模式材料-参数-寿命知识库技术栈严格pandas / numpy # 工序表/磨损递推scipy # 平滑/几何处理scikit-learn # RF超差分类matplotlib / networkx# 双轴曲线关联图import sys, ossys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))import numpy as npimport pandas as pdfrom pathlib import Pathfrom cnc_wear_roughness.process_param_loader import ProcessParamLoaderfrom cnc_wear_roughness.tool_wear_model import ToolWearModelfrom cnc_wear_roughness.residual_height_model import ResidualHeightModelfrom cnc_wear_roughness.roughness_propagator import RoughnessPropagatorfrom cnc_wear_roughness.over_limit_classifier import OverLimitClassifierfrom cnc_wear_roughness.cnc_visualizer import CncVisualizerfrom cnc_wear_roughness.synthetic_cnc_batch import SyntheticCncBatchdef main():print( * 70)print(数控粗精工序仿真: 刀具磨损→残留高度→Ra逐步劣化)print( * 70)results_dir Path(results); results_dir.mkdir(exist_okTrue)# 1. 合成print(\n[1/8] 生成工序批次...)gen SyntheticCncBatch(rngnp.random.RandomState(42))df gen.generate(cnc_process.csv, n_parts130,material_hb185.0, feed_f0.08,spindle_s3000.0, tool_re0.4, vb_init0.02)print(f 130件, 前5件粗加工, 材料185HB, 精加工F0.08mm/r)# 2. 加载print(\n[2/8] 加载工序参数...)df ProcessParamLoader(cnc_process.csv).load()print(ProcessParamLoader().summary(df))n len(df)op df[op].valuess df[spindle_s].iloc[0]f df[feed_f].iloc[0]ap df[ap].valuesre df[tool_re].iloc[0]hb df[material_hb].iloc[0]vb0 df[vb_init].iloc[0]idx np.arange(1, n1)# 3. VB磨损递推print(\n[3/8] 刀具VB磨损递推...)wear ToolWearModel(k1.2e-4, vb_ref0.2).simulate(n, op, s, f, ap, hb, vb0)print(f 首件VB{wear.vb[0]*1000:.1f}μm, f末件VB{wear.vb[-1]*1000:.1f}μm)# 4. 残留高度print(\n[4/8] 残留高度计算...)res ResidualHeightModel().compute(f, re, wear.vb)print(f 首件残留高度{res.h_res[0]*1000:.3f}μm, f末件{res.h_res[-1]*1000:.3f}μm)# 5. Ra递推print(\n[5/8] Ra粗糙度递推...)rp RoughnessPropagator(c0.9, vib0.05)rr rp.propagate(res.h_res, n)ra rr.ra# 定位关键点critical_idx int(np.argmax(ra 1.2)) 1overrun_idx int(np.argmax(ra 1.6)) 1# 建议换刀利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛
返回列表