电机效率Map图数据处理与MATLAB绘制:统一实测、Maxwell与MotorCAD数据 做电机开发这几年效率map图大概是最常打交道但又最烦整理的东西。仿真阶段要看Maxwell算出来的效率分布设计阶段要用MotorCAD快速评估样机出来后又要拿台架实测数据校验。三份数据格式完全不一样转速点、扭矩步长、效率计算方式各有各的脾气每次画图都要重新写脚本调半天。后来我干脆用MATLAB做了个小工具把实测、Maxwell和MotorCAD三种数据统一读进来生成标准化的电机效率map图顺便还能叠加外特性曲线自用到现在省了很多事。这篇文章就说说这个工具的设计思路、关键处理逻辑和实际踩过的坑适合正在为效率map图发愁的电机工程师、仿真工程师和测试工程师参考。1. 效率Map图不只是张彩色云图1.1 先弄明白map图在表达什么效率map图本质是电机在不同转速-扭矩工作点下的效率分布。横轴是转速纵轴是扭矩颜色代表效率值高低。台架实测得到的是离散点每个点有转速、扭矩、效率三组数Maxwell仿真导出的一般是二维矩阵或表格MotorCAD也可以导出类似的表。把离散点变成可读的连续图靠的是插值和网格化。这一步看起来不复杂但真正做起来有不少门道。效率map图在电机开发中相当于体检报告。看最高效率区在哪个区域是不是落在了常用工况点上看高效区范围够不够宽是不是只有窄窄一条看低速大扭矩区的效率是不是塌陷得厉害这都直接影响整车能耗和系统发热。平时我们口头说这电机效率还行一张图就能看出它的真实水平。评审会上效率map图也是最直观的对比依据两个设计方案摆在面前谁的云图更饱满谁的高效区更靠左一目了然。1.2 为什么实测、Maxwell、MotorCAD三份数据不能直接画图对比先别急着画图三份数据的脾气完全不一样。实测数据往往只有部分工况点因为台架跑全map耗时很长一般按转速间隔200rpm、扭矩间隔10Nm或20Nm来布点还要考虑稳定时间一个全map下来可能要几个小时甚至一天所以点数有限且分布不均匀。Maxwell仿真数据通常来自电磁场有限元计算每个工作点都要求解同样不会太密而且受限于网格和计算时间转速范围或扭矩范围可能缺失一部分。MotorCAD的数据来自热-磁路法快速计算速度快但精度和边界条件跟有限元有差异而且MotorCAD自带的map图算法默认了某些等效处理得到的数据需要甄别。更麻烦的是三者的文件格式、单位、坐标系都不统一。实测数据可能是Excel也可能是测功机导出的文本Maxwell导出csv或txt转速单位可能是rpm扭矩可能用N.mMotorCAD导出xlsx转速可能用rad/s。如果各画各的放在一起对比就得手动转换坐标轴费时还容易错。这个小工具的核心就是统一数据入口、统一网格、统一出图让你能在一张图上叠加三类数据或者分别生成规范化的map图做对比。这也是工具最有价值的地方——不是画图本身而是把脏乱差的数据收拾得整整齐齐。2. 小工具架构与数据读取那点事2.1 按功能拆模块比做GUI更实在这个工具我按功能拆成四个模块数据读取模块、数据清洗模块、插值与网格化模块、绘图模块。数据读取模块分别处理实测Excel表、Maxwell导出的csv/txt、MotorCAD导出的xlsx清洗模块处理空值、重复点、异常值和单位换算插值模块负责把离散点插到统一的转速-扭矩网格上绘图模块生成效率云图、等效率线和外特性曲线叠加图。每个模块独立封装成函数主脚本只负责调用。以后增加新的数据源或者改图样式只动一个函数就行。对于这种工具不一定要上App Designer也不一定要做GUI命令行脚本配合参数控制反而更快。我一开始也想做成GUI后来发现每天处理的数据格式变化太快GUI反而绑手。直接写几个函数配合输入参数再配合一个config脚本统一定义颜色条、转速间隔、扭矩间隔、插值方法每次出图一行命令搞定。如果你喜欢交互式界面再套一层App Designer也不迟核心算法逻辑都在迁移成本不高。2.2 实测数据读取表头混乱、单位不一、异常值处理实测数据最常见的是直接从测功机系统导出的文本文件表头可能有转速(r/min) 扭矩(Nm) 效率(%)也可能有更多通道比如电压、电流、功率、温度等。用readtable读取之后先提取需要的三列然后按顺序清洗删除效率为0或大于1/100%的点有时测功机会因为传感器未连接输出0删除重复的转速扭矩组合保留平均值或者最后一点对明显偏离趋势的异常点做剔除。我在项目中常用这一小段来读取实测数据% 读取实测数据VariableNamingRule防止表头被改成合法变量名 data readtable(bench_data.csv, VariableNamingRule, preserve); % 手动指定各列避免自动识别出错 n data{:, Speed_rpm}; T data{:, Torque_Nm}; eff data{:, Efficiency}; % 剔除明显无效点 valid isfinite(n) isfinite(T) isfinite(eff) eff 0 eff 1; n n(valid); T T(valid); eff eff(valid);实测数据的效率通常从输入功率和输出功率计算如果测功机给出的效率本身有噪声尤其是低转速小扭矩段电机输入功率很小测量误差会造成效率点忽高忽低这种点在map图上会表现为特别亮的斑点。处理办法是在插值前先做一次滤波或者直接不给这些区域赋值让云图显示为空白避免误导。这个在后面的常见问题部分还会细说。2.3 Maxwell导出数据处理先确认单位再处理空格Maxwell 2D/3D在电机效率map仿真中一般通过参数化扫描不同转速和电流角/电流幅值然后利用toolkit生成效率map图。导出的数据可能是csv或txt最常见的是包含Speed、Torque、Efficiency这些列有的版本还会附带Core Loss、Copper Loss等结果。读取时一定要先确认单位转速是不是rpm扭矩是不是Nm效率是百分比数字还是0-1小数。我见过不少项目因为扭矩单位是mNm没注意导致map图上的扭矩轴差了1000倍整个图全部错位。Maxwell导出文件有时会带多余的空行、注释行或BOM头readtable可能直接报警。稳妥的做法是先用detectImportOptions扫描然后手动设置起始行opts detectImportOptions(maxwell_emap.csv); opts.DataLines [2, inf]; % 跳过第一行标题里的非标准内容 opts.VariableNames {Speed, Torque, Efficiency}; data readtable(maxwell_emap.csv, opts);另一个常见坑是Maxwell的效率map数据并不覆盖完整的矩形网格。因为仿真可能只扫描了特定电流角范围内的工况或者只输出电动工况导出的表中就会有大片空缺。直接插值会产生越界的外推值需要把插值边界限制在已知点的凸包内或者先对缺失区域做标记。这个处理逻辑在算法部分会给出具体做法。2.4 MotorCAD数据读取多行表头与rad/s换算MotorCAD的效率map导出一般在Loss Map或Efficiency Map界面可以导出工作点表格包括转速、扭矩、效率、各类损耗等。它的转速可以是rpm也可以是rad/s扭矩可能是N.m也可能写成N.m效率一般是百分比。我遇到过MotorCAD导出的数据里转速间隔不一定均匀因为用户可能手动设置了扫描点而且MotorCAD自带的map图计算基于平均扭矩和有效值跟Maxwell的相位扫描结果会有些差异对比时要注意。MotorCAD导出xlsx经常有多行表头或者第一列不是数据列直接readtable会出错。我用的办法是先用readcell读取再找到表头行手动指定DataRangeraw readcell(motorcad_emap.xlsx); % 假设表头在第3行数据从第4行开始 headerRow 3; data readtable(motorcad_emap.xlsx, Range, [num2str(headerRow1), :, 10000]); % 单位换算转速如果为rad/s转成rpm if max(abs(data{:,1})) 20000 % 粗略判断是rad/s而不是rpm n_rpm data{:,1} * 60 / (2*pi); end单位换算上如果转速是rad/s要乘以60/(2*pi)转成rpm扭矩如果是mNm要除以1000。效率如果写的是0.92直接使用写的是92要除以100。这些看起来是小事但数据来自不同部门时最容易在单位上翻车。3. 插值算法、网格与可视化实现3.1 插值方法怎么选scatteredInterpolant用起来把离散点插值到规则网格上MATLAB里可以用griddata也可以用scatteredInterpolant。我都试过griddata简单但每次都要重新构造查询点而且对重复点处理麻烦scatteredInterpolant可以创建一次插值对象反复查询性能更好而且支持自然邻域插值。实测点经常出现同转速同扭矩重复测量用scatteredInterpolant之前先用unique或accumarray做平均避免插值时出现不连续。插值方法我推荐linear和natural两种。linear速度最快边界表现还行natural基于自然邻域对不均匀数据更稳定不容易出现overshoot。cubic虽然光滑但容易出现超过[0,100]范围的效率值比如效率变成108%这种离谱值物理上完全解释不了。我整理过一个对比表方法速度稳定性边界表现适用场景linear快中等一般数据量大、要求速度时natural中高好默认推荐大多数情况cubic慢低容易过冲不推荐用于效率map我的默认设置是自然邻域插值如果数据量很大且要求速度快再切回线性。另一个关键点插值前必须先去除异常值否则一个坏点会影响周围一片区域效率map上会出现孤岛。3.2 统一网格与边界裁剪避免画出一堆假数据统一网格我用转速向量和扭矩向量双向构造。转速范围从数据的最小值到最大值每100rpm或200rpm一个点扭矩范围类似每5Nm或10Nm一个点。网格太密会让插值后的map看起来噪声很大太稀则丢失细节。我的经验是网格步长不要小于原始数据最小间隔的1.5倍。比如实测数据扭矩间隔10Nm那么网格扭矩步长设20Nm就行如果设5Nm会过度拟合导致云图出现一圈圈洋葱纹这其实是插值在放大数据噪声。边界裁剪是效率map图最容易忽略的细节。原始数据只覆盖了部分区域比如低速大扭矩没有数据如果直接对整个矩形网格插值插值函数会强行算出外推值让图看起来有一个虚假的角。解决方法是先构建已知点的边界多边形然后判断每个网格点是否在多边形内。具体代码% 构造外部边界alphaShape可以包络任意形状 shp alphaShape(n, T, 0.5); % 0.5是alpha半径数据越密取值越小 % 生成统一网格 n_grid min(n):20:max(n); T_grid min(T):5:max(T); [nG, TG] meshgrid(n_grid, T_grid); in inpolygon(nG, TG, shp.boundary(:,1), shp.boundary(:,2)); % 把边界外的点设为NaN eff_grid interpF(nG(:), TG(:)); eff_grid(~in(:)) NaN; eff_grid reshape(eff_grid, size(nG));通过边界裁剪map图只会显示数据实际覆盖的区域不会出现一大块没有数据却硬画出来的区域。这个技巧在Maxwell和实测数据上都很有用。3.3 云图、等值线、外特性曲线叠加与高清导出基础云图用contourf就可以。X轴是转速Y轴是扭矩Z坐标是效率。颜色条建议用parula效率map图行业里常用的是从蓝到红渐变但我更推荐parula因为它在低亮度区域的表现更好不会给人一种低效区域很热的错觉。如果要标定出95%、90%、85%这些关键效率线再叠加contour只在指定等级绘制并标上数字。注意这里contour和contourf的等级设置要一致不然云图和等值线的颜色对不上。画完云图后通常要叠加外特性曲线。外特性曲线就是把每个转速下能输出的最大扭矩连成折线它把map图划分成可运行区和不可运行区。外特性数据可以从实测数据中提取每个转速下的最大扭矩也可以用MotorCAD或Maxwell的额定外特性。叠加时用line函数设置线宽2左右颜色用白色或黑色根据底色选择。注意外特性曲线只画到最高转速超过的部分要截断否则会延伸到空白区域看起来很奇怪。最后用legend说明数据来源因为一张图上可能同时有实测、仿真两条外特性。导出图片我用exportgraphics设置分辨率300dpi格式PNG这样图片清晰度足够放在报告和PPT里。同时可以把插值后的效率矩阵和网格坐标保存成mat文件或者写成Excel方便后续做数据对比、二次计算或者输入到系统级仿真模型中。矩阵的维度是length(T_grid) × length(n_grid)对应关系要写清楚不然换个同事就不知道怎么用了。4. 实操中的坑与排查技巧4.1 零转速和空载点效率为0到底留不留实测台架在转速为零时输出功率为零而输入功率不为零效率恒等于0这是物理上正确的。但如果把零速点放到插值数据里转速为0而扭矩很大的区域会被这些零效率点压出一个低谷看起来像是低速高扭效率特别差。实际上低速段效率低是对的但用0来插值并不准确因为效率定义在零转速时本身没意义。我的做法是如果测试数据包含零转速点直接剔除掉效率map图默认从最低正转速开始如果非要显示零转速就把零转速行的效率设为NaN。同样扭矩为零的空载点效率也是0但空载效率0并不表示该点不能工作所以一般也剔除map图通常只画电动工况的负载区域。有些工具会在效率map上把空载点附近画出一块深蓝色区域看起来特别吓人其实就是这个原因。剔除零速和空载点之后map图才能反映真实效率分布。4.2 Maxwell的NaN空洞与补点思路Maxwell用自带toolkit生成效率map时有时候数据点并不规则。比如效率map计算过程中有一部分工作点因为电流或电流角设置不合理没有收敛导出表中会留下NaN或空白还有时正转矩和负转矩区域分开而你只需要电动工况直接取正转矩结果扭矩从10Nm到20Nm之间有一个缺口。这个问题让我折腾很久后来想到可以用alphaShape构造包络只插值包络内部的点缺口区域会表现为NaN云图会自动留白。这样至少不会出现无中生有的高效率岛。如果缺口很小比如只有一两个点可以忽略但如果缺口比较大最好回到Maxwell模型里补算工作点重新扫描。靠插值补出来的数据始终是估计值用在仿真评审上容易引起争议。我还会把Maxwell数据中有NaN的点单独导出做一个检查清单看是哪些电流角、转速下的点没有收敛然后针对性调整扫描设置而不是盲目用水泵方法。4.3 MotorCAD效率超100%的处理MotorCAD在快速计算时有的版本按照扭矩/转速表格式输出存在同一转速下多个扭矩点但扭矩值不一定单调递增。读取后要sortrows按转速和扭矩排序然后再去重。还有一次遇到MotorCAD导出的效率值超过100%普遍在101%左右这是因为损耗计算过程中出现了负值比如某些数值误差在叠加上来或者参考功率的取值不同。这种点不能直接进插值要么剔除要么用相邻点平滑替换。我一般会把效率限制在0-100之间超过的置为NaN再用局部的5×5窗口均值填充。这里注意填充窗口不能开太大否则会把真实的效率峰值抹掉。窗口大小可以用数据点密度的中位间距来估计或者干脆只填NaN不重算其他点。总之效率超过100%在物理上不可能保留这种点做对比只会让评审报告被质疑。4.4 一个自动标记异常点的辅助脚本手工查异常点太累我写了一个辅助函数输入原始数据输出被标记的异常点并在三维散点图中高亮。判断逻辑很简单对每个点取它周围最近的20个点计算这些点的效率中位数如果当前点的效率与中位数之差超过15个百分点就标记为异常。这个阈值可以根据数据质量调节噪声大的数据就放宽到20噪声小的可以收紧到10。核心代码大致这样function idx markOutliers(n, T, eff, k, thresh) pt [n(:), T(:)]; idx false(size(eff)); for i 1:length(n) d sqrt((pt(:,1)-pt(i,1)).^2 (pt(:,2)-pt(i,2)).^2); [~, ord] sort(d); neigh ord(2:min(k1, length(d))); % 去掉自身 medEff median(eff(neigh), omitnan); if abs(eff(i) - medEff) thresh idx(i) true; end end end标出来后人工确认是传感器丢包还是真实跳变再决定删不删。这个方法不能完全替代人眼但能省很多事。我通常把标记出的异常点单独画在原始散点图上用红色圆圈标出来一眼就能看出哪些位置的数据不可信。5. 工具落地后的效率提升和扩展方向5.1 用起来到底有多省时间之前处理一次三种数据的效率map对比从整理数据到出图至少要大半天还不包括返工。现在流程化之后只要把数据丢进对应文件夹运行一个main脚本输出三张对比图和一张叠图整个过程不到5分钟。关键是格式统一了评审会上大家看到同一套坐标、同一套色标对比才有意义。以前各团队用各自的模板画图明明效率差2%却因为色标范围不同看起来差距巨大。现在强制统一色标范围比如80-100%谁高谁低一眼就能看出来。实际使用中我最常用的操作是把实测、Maxwell、MotorCAD三张map图上下排列统一转速轴和扭矩轴范围这样能直接看到不同工具之间的差异。比如某个转速段Maxwell预测的效率是94%实测只有90%这时候就要去查是因为铁损模型不准还是因为实际样机的温度高于仿真设置。这个对比在项目里用得非常频繁。5.2 还可以往损耗map、工况点评估、Simulink数据接口扩展效率map图工具还可以继续扩展。比如增加损耗map的绘制把铜耗、铁耗、永磁体涡流耗分别画出来定位效率损失的来源。这方面Maxwell和MotorCAD都提供了损耗数据只需要在读取模块里多保留几个字段插值时分别处理。再比如增加工况点扫描功能把整车的WLTC或CLTC工况点投射到效率map上计算综合效率这对整车能耗评估特别实用。我的实现思路是读入工况点序列转速-扭矩时间序列在插值后的效率矩阵上查值然后按时间做加权平均得到一个综合效率指标。还可以直接把插值后的数据导出成Map描述文件给系统级模型Simulink用。Simulink里的电机模型经常需要查表格式就是转速轴、扭矩轴、效率矩阵比手动敲Excel快得多。这些扩展功能虽然不复杂但需要数据接口足够干净现在工具把数据清洗和插值也做了加功能就变得很自然。5.3 个人心得先理数据再谈功能做这类小工具最重要的不是算法多高级而是先搞清楚数据的脾气。效率map图的原始数据来源五花八门每一份都需要单独写清洗逻辑。先花时间把数据接口做扎实后面什么功能都好加。如果一开始就追求界面美观和自动化数据没理清做出来的图反而误导人。我现在的习惯是每收到一份新格式的数据先写一个针对性的清洗函数再纳入统一流程而不是试图用一个万能读取函数覆盖所有情况。实测、Maxwell、MotorCAD三种数据各有各的坑但只要你把每个坑都记下来工具就会越用越顺。这个工具目前在内部已经用了大半年除了效率对比我还加了温度修正的简单处理如果实测数据是在某个特定油温下测的就按铁损和铜损的温度系数做一次粗略修正让map图更接近实际工况。虽然精度谈不上很高但至少给团队提供了一个共同讨论的基础。以后如果有精力我打算把这个工具编译成独立应用让完全没有MATLAB基础同事也能直接打开点两下就用。不过这是后话了先把数据理清楚永远是第一位的。