去年陪一个做红外热像仪的朋友排查量产镜头的低温成像问题,室温下点列图漂亮到可以当教科书案例,结果整机丢进高低温箱,-40℃下画面直接糊成一团。当时大家第一反应是镜片炸裂或者胶层脱落,拆开检查一切完好,最后把Zemax模型里的环境温度从20℃改成-40℃重新追迹,才发现整个像面焦点后移了将近0.3 mm,探测器焦深根本兜不住。从那以后,我经手的光学设计,不管客户有没有提温度要求,都会先跑一遍热分析。这篇文章就把Zemax热分析里最常用的两个工具——多重结构编辑器(Multi-Configuration Editor)和操作数(Operand)——怎么配合起来做无热化优化的完整思路写出来,顺便把几个容易导致"假收敛"的坑也一并讲清楚。内容适合刚开始接触热分析的光学设计工程师,也适合那些已经会建多重结构、但优化结果一到高低温实测就翻车的朋友。
1. 热分析这个需求到底在解决什么:先聊透"温度对光学系统做了什么"
1.1 温度变化引发的四类光学参数改变
很多人一提到热分析,第一反应是"把镜片参数改一改再算一遍",但如果不理解温度到底动了哪些物理量,后面建多重结构时一定会漏东西。温度对光学系统的影响,归纳起来是四类:
第一类是折射率温度系数(dn/dT)。这是最核心的一项。温度升高,玻璃的折射率跟着变。不同材料的dn/dT差异很大,普通冕牌玻璃一般是几个ppm/K的量级,而红外材料比如锗(Ge)的dn/dT高达396×10⁻⁶/K,是可见光玻璃的一百多倍。这就是为什么红外镜头对温度极其敏感,热分析在红外系统里几乎是标配。需要注意的是,Zemax玻璃库里存的是"相对空气的折射率温度系数",不是绝对折射率温度系数,因为空气的折射率本身也随温度、气压变化,我们实际关心的是玻璃和空气的折射率差,也就是光学系统真正感受到的折射能力变化。
第二类是镜片几何尺寸变化。温度变化时,镜片本身的厚度、曲率半径、口径都会按材料的热膨胀系数(TCE)缩放。可见光玻璃的TCE一般在5到10×10⁻⁶/K,这个量级对单个镜片的影响通常不大,但在高精度系统里不能忽略。曲率半径变化会直接改变光焦度,厚度变化会影响共轭距离。
第三类是空气间隔变化,也就是镜筒的膨胀和收缩。这一项在实际工程里往往比镜片本身的变化还致命。铝合金镜筒的膨胀系数大约23×10⁻⁶/K,从常温到-40℃温差60多度,一根50 mm的镜筒间隔会收缩约0.07 mm,换成红外系统,这个量已经足够让像质从衍射极限崩到没法看。殷钢(Invar)镜筒能把膨胀系数压到1.2×10⁻⁶/K左右,但重量、成本和加工难度都上去了。
第四类是玻璃内部应力引起的光学不均匀性,以及胶层、隔圈等非光学件的变形。这类问题在Zemax标准序列模式里很难直接建模,通常靠经验留余量,或者用有限元分析把变形面形导入Zemax里做进一步评估。
1.2 无热化设计的本质是"像面位置博弈"
搞清楚了温度影响什么,就能看懂无热化设计的目标。说白了,一个系统的像面位置由各镜片的光焦度和各空气间隔共同决定,温度一变,每个镜片的光焦度都在变、每个间隔的长度也在变,最终焦点位置相对于探测器的偏离量叫热离焦(thermal defocus)。
无热化设计做的事,就是让光学系统在整个工作温度范围内,焦点偏移量始终落在探测器焦深之内。注意,这里不是说让焦点完全不动,而是让"焦点漂移范围"小于焦深。焦深跟F数和波长有关,典型红外系统的焦深可能就二三十微米,而热离焦很容易跑到几百微米,所以必须拿设计手段去压。
实现路径主要有三条:光学被动无热化(靠不同dn/dT和TCE的材料搭配,让热离焦互相抵消)、机械被动无热化(靠镜筒材料的膨胀或机械结构补偿)、电子主动补偿(电机带动镜片调焦或移动探测器)。Zemax多重结构优化主要服务于第一种,配合第二种的镜筒参数做验证,第三种则需要预留机械调节量,这些在优化时都要想清楚。
1.3 在Zemax里做热分析的两条路线
我见过很多新手把热分析理解成"把系统温度改成想要的温度,直接看像质",这是静态单点分析。这种方式只能告诉你在某个温度下系统好不好,没法告诉你系统在整个温度区间里怎么变,更不能用来做无热化优化。
真正实用的方式是多重结构(Multi-Configuration):把每个典型温度定义成一个组态(Configuration),在组态之间切换温度的同时,让Zemax自动计算折射率、曲率、厚度的变化。这样你可以在同一个设计文件里同时看-40℃、+20℃、+60℃三个温度下的点列图、MTF、波前,也可以直接在评价函数里把三个组态的像质加权到一起优化。
另一条路线是用Zemax的扩展功能,比如ZPL宏批量扫描温度,或者通过ZOS-API和MATLAB联动做自动化分析。这个属于进阶玩法,第六节再展开。先说清楚,不管哪条路线,底层都离不开多重结构编辑器和操作数的配合。
2. 多重结构编辑器实操:把三个温度工况装进同一个设计
2.1 先理解"组态":不是多套镜头,是同一套镜头的环境快照
第一次打开多重结构编辑器的人,很容易被它的表格吓到——每一行是一个操作数,每一列是一个组态,看起来像是在管理几套完全不同的镜头。实际上多重结构并不是让你复制三套镜片,而是同一套光学系统在不同环境或不同状态下的参数快照。
举个例子,变焦镜头在不同焦段下,镜片间隔不同,可以用多重结构来管理。热分析也是类似的逻辑:同一个镜头,在-40℃、20℃、60℃下,镜片曲率、厚度、折射率、空气间隔都不同,这些差异本质上是因为环境温度导致材料属性变化,而不是光学设计本身变了。
所以你在Lens Data Editor(透镜数据编辑器)里看到的依然是一套镜片,只是在System Explorer里启用了温度计算后,Zemax会基于材料数据自动更新每个组态下的参数。你在多重结构编辑器里主要做两件事:定义每个组态的温度/气压,以及覆盖那些不会被系统自动计算的参数(比如镜筒膨胀导致的空气间隔)。
2.2 一组可直接照抄的TEMP/THIC多重结构配置
下面给出一个最基础但完整的热分析多重结构配置流程,以三组态为例:-40℃(低温)、+20℃(常温)、+60℃(高温)。
第一步,在Lens Data Editor里把整个系统的名义参数建好,常温20℃作为参考温度。然后在System Explorer里找到环境相关设置,把参考温度(Reference Temperature)设为20℃,确保后续的温差计算有基准。
第二步,打开Multi-Configuration Editor,右键或者通过菜单插入新行,选择TEMP操作数。这个是温度操作数,每个组态列里填的就是该组态对应的系统温度。再插入一行PRES操作数,如果你不考虑气压影响,三列都填1 atm(标准大气压)就行,但行要留着,Zemax对气压的处理会影响空气折射率,高压或高空环境尤其不能忽略。
第三步,检查System Explorer里"Use Temperature"相关的选项是否打开。这一步很关键,否则你TEMP行填了温度,系统还是用20℃的常温参数去算,等于白忙活。打开之后,Zemax才会用玻璃库里的dn/dT数据更新折射率,用Surface Properties里的TCE数据更新曲率和镜片厚度。
第四步,处理空气间隔。光学镜片本身的膨胀系统会自动算,但镜片之间那段空气间隔的变化,Zemax默认不会自动替你算——它不知道这段间隔是被铝筒包着、钛筒包着还是殷钢包着。你需要告诉它。最简单的方式是在多重结构编辑器里插入THIC操作数,指定某个空气间隔所在的面序号,然后在每个组态列里填入该温度下这个间隔的实际厚度值。
第五步,从20℃到-40℃,铝合金镜筒的收缩量按公式ΔL=L×α×ΔT计算。比如某段空气间隔名义长度为30 mm,铝的α=23×10⁻⁶/K,温差60 K,那收缩量就是30×23×10⁻⁶×60=0.0414 mm,低温组态的厚度就填30-0.0414=29.9586 mm。高温组态则相反,填30.0276 mm。如果镜筒是钛合金,α=8.8×10⁻⁶/K,同样间隔收缩量只有0.0158 mm。
表:常见结构材料热膨胀系数参考
| 材料 | 热膨胀系数(10⁻⁶/K) | 备注 |
|---|---|---|
| 铝合金 | 23 | 常用,便宜,热敏感 |
| 钛合金 | 8.8 | 热稳定性好,重量轻 |
| 殷钢 | 1.2 | 近零膨胀,但加工难、贵 |
| 光学玻璃 | 5~10 | 用在镜片本身 |
| 碳纤维复合材料 | 0~2 | 轻量镜筒常用 |
也可以不用手动算,在多重组态里用表达式(EXPR)直接写,让Zemax按公式计算。比如把THIC单元格的值设成表达式"30*(1+23e-6*(TEMP-20))"的形式,但要注意表达式的变量引用写法跟Zemax版本有关,我个人的习惯是先手动算好填进去,等模型稳定了再改成表达式,避免公式写错导致整组数据错乱。
2.3 材料数据校验:玻璃库dn/dT和Surface TCE最容易出错
这一步是我反复提醒同行重点检查的:玻璃库里的dn/dT数据不一定是你想要的那组数据,而且面属性里的TCE默认值经常是0。
Zemax玻璃库里每种材料都有折射率温度系数数据,但不同材料库的测试波长、温度范围不同。比如某款红外硫系玻璃的dn/dT在8~12 μm波段的数值和3~5 μm波段差异很大。你用哪个波段,就应该确认玻璃库里的数据是针对哪个波段的。如果材料库数据缺失,Zemax有时会用默认模型估算,这个估算结果只能当参考,不能直接用于生产设计。
另一个问题在Surface Properties(表面属性)里的热膨胀系数设置。光学面的TCE如果保持默认0,意味着温度变化时这个面的曲率半径和厚度不发生变化——对镜片来说,这就等于忽略了玻璃的热膨胀。所以务必要把每一片镜片的面TCE填成对应玻璃的膨胀系数,或者确认你用的玻璃库/面模板自动关联了TCE。
我见过一个实际项目,整机热分析结果特别好,高低温下MTF曲线几乎重合,结果打样出来一测就糊。查了半天才发现,项目里的玻璃库是同事从网上下载的非官方版本,所有玻璃的TCE字段全是0。镜片的热膨胀完全没被算进去,仿真当然"完美"。
2.4 后焦间隔:无热化优化里最值得关注的一个厚度
在所有空气间隔里,最后一个空气间隔——也就是后焦(back focal distance)——对温度最敏感,也最值得做文章。因为后焦的变化直接等于焦面位置的变化,而前面所有间隔变化最终都会反映成焦点位置的漂移。
在多重结构编辑器里,后焦通常也叫像面厚度(surface thickness before the image plane)。做无热化设计时,我要么把它固定在一个折中值,让三个温度下的RMS半径都能接受;要么把它设成变量,在优化过程中让Zemax自动找最佳折中位置。更进阶的做法是,把后焦留给机械补偿组,比如给后焦预留一个可调范围,用电机在不同温度下微量调整。
这个思路反映到多重结构里,就是:对于后焦这个面,不直接用THIC操作数把三组厚度统一,而是在每个组态列里各放一个THIC单元格,把它们全部设成变量。这样优化时Zemax可以独立调整三个温度下的后焦——等等,这里要格外小心,如果三个组态的后焦是三个独立变量,优化器很可能会把每个温度的后焦都调到各自最佳位置,最终得到的结果是"每个温度都很好,但没有任何一个实际位置能同时满足三个温度"。这属于典型的"假收敛",第五节我会重点展开。
3. 操作数选型与评价函数构建:别把"像质评价"做成玄学
3.1 点列图操作数:RSCE、RSCH、TRCX/TRCY 的分工
多重结构把温度工况搭好了,接下来就要让优化器知道"什么样的系统算好"。这一步靠评价函数里的操作数。热分析里最常用的是点列图相关操作数,因为它们计算快、物理意义直观、优化效率高。
RSCE(RMS Spot Radius w.r.t. Centroid):相对于质心的RMS点列图半径。它衡量的是光斑的能量集中度,不关心主光线指向,适合评价探测器上的能量分布。热分析里我最常用它来作为主像质指标,尤其是在红外非成像系统里。
RSCH(RMS Spot Radius w.r.t. Chief Ray):相对于主光线的RMS点列图半径。它关心的是光线相对于主光线的弥散,如果系统存在较大的畸变或主光线偏移,RSCH会明显大于RSCE。做像质评价时,RSCE和RSCH差距过大说明系统有较大的彗差或畸变分量,需要考虑是不是某些组态下出现了严重像差。
TRCX/TRCY(Real Ray X/Y Coordinate at Image Surface):这个操作数给出的是某根光线在像面上的实际坐标,而不是半径。热分析中它的用处是监控像点漂移。当温度变化时,系统的畸变和放大倍率会变,像点位置可能跟着跑。如果你的探测器对对准要求很高(比如制冷型探测器),可以用TRCX/TRCY约束某个视场的主光线在三个温度下的坐标差不能超过多少微米。
在评价函数编辑器里插入这些操作数的写法很直接。比如要监控第3组态、0.7视场的RMS点列图半径,就插入RSCE,在Operand参数的视场那一栏填0.7,组态那一栏填3,目标值设为0,权重按你的需要给。注意,组态栏不填的话,Zemax默认用当前组态,这在多重结构优化里很容易搞错——你明明想约束低温组态的像质,结果权重加到常温组态上去了。
3.2 波前与MTF操作数在热分析中的配合
点列图操作数计算快、适合优化,但它对系统的评价不够"宏观"。热分析里我更倾向于在点列图优化的基础上,用波前和MTF操作数做验证和收尾。
**波前RMS(WFE)**操作数反映的是整个波面的RMS误差,它对低频像差(离焦、球差、彗差)很敏感,是判断系统是否接近衍射极限的核心指标。在热分析里,如果某个温度下波前RMS明显变大,配合点列图看,通常能很快分辨是离焦主导还是高阶像差主导。
MTFT/MTFS(子午/弧矢MTF)操作数虽然计算量大,但是它能直接给出某个空间频率下的调制传递函数,这是和探测器匹配最直接的指标。比如你用的是17 μm像元、奈奎斯特频率约30 lp/mm的红外探测器,就可以在评价函数里加MTFT/MTFS,目标设在30 lp/mm处MTF大于0.3。
我的习惯是:优化初期用RSCE把大像差压下来,中期切到波前RMS做精修,最后用MTF操作数验证各温度下是否满足探测器需求。三个阶段的评价函数权重完全不同,一开始就上MTF会让优化速度慢到怀疑人生,而且容易陷入局部极小值。
3.3 权重的设置逻辑:不同温度组态怎么平衡
多重结构里做热优化时,评价函数里会出现同一操作数在多个组态下的重复项。权重怎么分配,直接决定优化结果偏向哪个温度。
一个常见的错误想法是"三组温度权重一样,公平对待"。但实际工程中,不同温度的使用时间、性能要求往往不同。比如很多红外系统在常温附近使用时间最长,极端低温可能只是储存条件而非工作状态,那低温组态的权重就可以低一些。再有,如果客户明确要求-40℃到+60℃全温区成像质量都要达标,那三个组态的权重就应该是1:1:1,并且要关注最差温度点的性能,而不是平均值。
我个人的经验是分两步走:第一步,三个温度组态等权重优化,目标是找到一个所有温度都能接受的折中方案;第二步,把常温组态权重提高,进一步优化常温性能,同时盯着高低温组态的性能不跌破下限。这个"先均值、再偏置"的策略比一开始就设一组复杂的权重要好用得多。
还要注意,评价函数里不要只放点列图操作数,一定要放边界约束操作数。热分析优化的本质是"在结构尺寸合理的前提下,把多温度下的像质压下去",没有约束的话,优化器会为了像质把镜片中心厚度优化到0.1 mm以下,或者把后焦拉到离谱的长度。MNCA/MXCA(最小/最大中心厚度)、MNEA/MXEA(边缘厚度)、MXAG(最大空气间隔)这些操作数都要给足余量,而且是对每个温度组态都生效的。
3.4 我自己常用的热分析评价函数骨架
写一下我在红外无热化项目里比较常用的一组评价函数布局,给新手一个参考。假设系统有3个组态(-40/20/60℃),3个视场(0、0.7、1),主评价用RSCE。
- 每个组态、每个视场各加一个RSCE,共9项,权重先从1:1:1起步,目标值0;
- 每个组态加一个RSCE的"轴上视场"监控项,权重提高1.5倍,因为轴上表现通常对离焦最敏感;
- 每个组态加一个TRCY,监控0.7视场的主光线Y坐标,目标值设为和常温组态一致,权重压小一点(比如0.1),防止放大倍率随温度漂移太多;
- 全组态各加一组边界约束:MNCA=2 mm、MXCA=15 mm、MNEA=1 mm、MXAG=50 mm;
- 最后加总长控制(TOTR),不让系统在优化过程中越变越长。
这组骨架并不复杂,但它把"像质、温度一致性、结构合理性"三个方面都覆盖了。实际项目里可以在这个基础上按需增删。
4. 无热化优化实战流程:从初始结构到收敛的完整链路
4.1 优化前先把所有材料参数核对一遍
这一步听起来像废话,但我在实际项目里吃过亏,必须单独拎出来讲。开始优化之前,我会建一个检查清单:
- 玻璃库里的每种材料的dn/dT是否存在,数据波长范围和我的工作波段是否一致;
- 每片镜片的Surface Properties里的TCE是不是填了正确值(不是0,也不是默认的玻璃库数值);
- 空气间隔对应的镜筒等效膨胀系数选对没有,是按铝算还是按钛算;
- 系统参考温度是20℃还是25℃,因为dn/dT数据本身有测试基准温度,基准对不上,温差计算就全偏了;
- 离焦补偿机制有没有想好,后焦到底是固定、可调、还是留给机械补偿。
材料参数这个环节,工作波段越红外越敏感。可见光设计里dn/dT填错一个量级,结果可能只是像质略变差;红外系统里锗的dn/dT填错,直接导致从设计阶段就废掉。
4.2 第一步:先在常温组态下把基础像质拉起来
不要一上来就开三温度联调。我是强烈建议先在单一常温组态下把基础像质优化到接近衍射极限,再去做热分析。原因很简单,多重结构优化是把所有组态的像质加权求和,如果常温组态本身像差很大,整个评价函数会被离焦和像散主导,优化器根本没精力去平衡温度差异。
所以在建多重结构之前,把常温20℃下的RSCE优化到设计指标附近,MTF验证达标,记录下这时候的像面位置、各间隔厚度、各镜片光焦度分配。这就是后面热分析优化的"基底"。这个基底越健康,后面做多温度平衡越轻松。
4.3 第二步:打开多重结构,做三温度联调
常温基底优化好之后,按照第二节的方法建好三个温度组态,把空气间隔的热膨胀值填好,然后开始三温度联调。
第一步先别急着把曲率半径和玻璃设为变量,先把所有空气间隔设为变量,尤其是镜组之间的主间隔和后焦。跑一轮优化,观察三个温度下RSCE的分布。这一步的目的就是看:只靠调整空气间隔,能不能把热离焦压下去。很多系统在这个阶段就能找到不错的折中,因为热离焦本质上是焦点位置问题,调整间隔往往立竿见影。
如果空气间隔优化后,某个温度组态的像质还是压不下去,再把镜片的曲率半径(或者少数几个非球面系数)加入变量。用变量要克制,一次性加入太多变量,优化器很容易陷入局部极小值,而且会出现镜片形状变得很怪但像质还是差的局面。我的经验是:每次加2到3个变量,跑收敛,看结果,再决定下一步加什么。
4.4 第三步:玻璃替换与被动消热差
如果间隔和曲率都调过了,三个温度下仍然有较大热离焦,那就要着手材料层面的被动消热差了。
被动消热差的核心逻辑是:把正光焦度镜片和负光焦度镜片用不同dn/dT的材料搭配,让温度升高时正负镜片的光焦度变化互相抵消,同时它们的镜筒间隔变化也恰好补偿焦点漂移。一个经典的经验法则是:正透镜尽量选低dn/dT的材料(比如氟化钙、某些低色散玻璃),负透镜选高dn/dT的材料(比如硫系玻璃、锗),这样温度升高时正透镜光焦度微微下降、负透镜光焦度也微微下降,系统整体光焦度变化被对冲掉。
在实际操作中,我一般会先把某一个镜片的材料设为变量,用Zemax的玻璃替换功能跑一轮玻璃优化,看哪几种材料组合能让三温度下的像质同时变好。玻璃优化结果不一定能直接生产(要考虑成本、透过率、热稳定性、加工难度),但它能给出一个有价值的选材方向。比如玻璃替换结果反复出现某款硫系玻璃,就说明系统确实需要它来补偿热差。
4.5 判断收敛:看RMS只是门槛,离焦曲线才是关键
很多时候,优化器跑了几千轮,评价函数值降得很低,你以为收敛了,实际上可能是走进了一个"所有温度单独看都不差、但实际系统没法用"的陷阱。
我判断热分析优化是否真正收敛,通常看三样东西:
第一,各温度下的RSCE或MTF是否都满足指标。这是最基础的,但注意不要看平均值,要看最差的那个温度点。
第二,离焦曲线。在Zemax里对每个温度组态做离焦分析(通过改变像面位置,观察RMS半径或MTF随离焦量的变化曲线),看每个温度的最佳焦面位置。如果三个温度的最佳焦面位置相差超过焦深,说明热离焦没有被消除,只是被评价函数平均掉了。
第三,后焦的独立变量是不是收敛到了同一个值附近。如果你把三个温度组态的后焦都设成了变量,收敛之后去看这三个变量的值,如果它们天然收敛到了相近的位置(比如-40℃后焦20.02 mm,20℃后焦20.00 mm,60℃后焦19.98 mm),说明系统有很好的热稳定性。如果它们各奔东西(-40℃后焦20.5 mm,60℃后焦19.5 mm),说明评价函数把问题"藏"在了后焦变量里,实际装配时根本没法同时照顾三个温度。
一个我经常跟同行强调的细节:判断热分析结果,离焦曲线比单点RMS靠谱得多。因为单点RMS可能只反映特定焦面下的情况,而离焦曲线能看到系统在不同焦面下的表现趋势,能告诉你到底该把像面定在哪儿,也能帮你判断是不是需要机械调焦补偿。
5. 坑与排错:多重结构热分析中那些容易"假收敛"的地方
5.1 坑一:空气间隔没有链接热膨胀,系统在"假装热分析"
这是我在代码审查时见过最多的一个问题。设计者建好了多重结构、填好了TEMP、优化结果也漂亮,但打开多重结构编辑器一看,THIC那一行要么压根没有,要么只在常温组态下填了值,低温高温组态共用常温的间隔厚度。
后果很直接:系统温度变了,但空气间隔纹丝不动,整个系统的热离焦被严重低估。仿真结果显示热性能很好,实际产品一进高低温箱就露馅。
排查方法其实很简单:在多重结构编辑器里,切到-40℃组态,打开透镜数据编辑器,看各空气间隔有没有变化;再用"Analysis"里的热分析工具,或者手动把系统温度改成-40℃,看间隔值是否会跟着变。如果纹丝不动,说明THIC行或TCE设置有问题。
5.2 坑二:参考温度没有对齐,dn/dT计算偏差
Zemax里的TEMP操作数、系统的参考温度、材料库的dn/dT测试温度,这三者如果不一致,计算结果就会有偏差。比如你在System Explorer里参考温度设为25℃,多重结构里TEMP填的是-40、20、60,这里的温差是以哪个为基准算的?
大多数光学玻璃的dn/dT本身也不是在整个温区线性不变,如果材料库给的是20℃参考值,你算-40℃时直接用这个值外推,就可能引入误差。对于红外材料尤其明显,锗在低温段和高温段的dn/dT差异可以达到10%以上。
所以做热分析之前,建议把参考温度明确设为20℃,TEMP操作数也以20℃为基准来填,然后确认材料库的dn/dT数据是在哪个温度下测得的。如果数据表里有多个温度点的dn/dT,尽量用Zemax材料模型的插值能力,而不是手动填单一值。
5.3 坑三:只优化高低温端点,中间温度完全失控
很多工程师只建两个组态:-40℃和+60℃。优化时让这两个端点的像质都满足,就以为全温区OK了。但材料的dn/dT和镜筒膨胀在温度轴上不一定是线性的,尤其是红外材料,dn/dT随温度变化明显,两个端点都满足,中间某温度点完全可能离焦超差。
我建议至少建三个组态,且中间温度不一定是常温,可以根据你的实际工作温度范围切成4到5个组态。比如-40、-10、20、40、60五个组态。组态越多,优化越慢,但热分析这件事,宁可前期多花点计算时间,也不要后期在温箱里反复试错。
如果计算资源确实有限,可以做"两段式验证":先用-40/20/60三组态优化,收敛后再临时加一两个中间温度组态进去,看像质是否仍然达标。只要中间组态不达标,说明你的系统存在明显的非线性热行为,需要重新审视材料和间隔的匹配。
5.4 坑四:ZPL宏里遇到unknown symbol类报错
热分析里常用ZPL宏做批量处理,比如遍历温度、提取不同温度下的像面位置、输出离焦量。写宏的时候最烦的就是"unknown symbol"这种报错。这里有一个真实场景:我想用ZPL宏读取某个表面的厚度,写的是getthickness,Zemax提示unknown symbol。
排查思路是这样:先确认函数名拼写是否完整正确,在Zemax的宏帮助文档里搜一下,有些函数名带版本后缀,旧版本不支持新函数;再检查是不是光标位置或参数问题,比如宏试图读取一个不存在的表面序号;最后确认函数是否需要在特定模式下使用,比如某些函数只能序列模式用,非序列模式下调用就直接报错。
我的建议是:ZPL宏里每个函数在引用前先查文档,不要靠记忆;出问题先加注释把可疑行隔离,用PRINT逐行输出中间变量定位;实在查不出来,就把函数换成等效的替代写法,比如读取厚度可以用GETTHICK也可以直接读取透镜数据编辑器里的单元格值,绕开有问题的函数。
这里多说一句,Zemax的宏报错信息往往很笼统,不要指望它直接告诉你哪一行错了,自己加日志输出是最高效的排错方式。我在写宏时习惯在每个关键计算后加一行PRINT,把温度、间隔、RMS半径打出来,一遍跑下来就知道问题出在哪一步。
5.5 坑五:非序列模式做热分析的局限
有些系统不得不用非序列模式做,比如分光棱镜、复杂照明光路,但热分析在非序列模式下有几个明显的局限:一是一般不会自动应用玻璃库的dn/dT和面的TCE,温度开关对非序列组件的支持有限;二是优化速度比序列模式慢很多,多重结构+非序列做全局优化会非常痛苦。
我的做法是:尽可能把热分析和无热化优化放在序列模式里做,用近似模型替代非序列里的复杂组件;等序列模式优化收敛了,再把最终结构转回非序列模式做一次全温度验证。如果非要全程非序列,那也要明确一点:能做热分析,但优化效率低,而且对玻璃参数的依赖更大,材料数据一定要核对好。
表:热分析常见问题速查
| 症状 | 可能原因 | 排查方向 |
|---|---|---|
| 温度改变但像质几乎不变 | Use Temperature未开启 | System Explorer温度选项 |
| 温度改变但间隔厚度不变 | 空气间隔THIC未设置或TCE=0 | 多重结构编辑器 |
| 高低温都很好,中间温度崩 | 组态数量太少/材料dn/dT非线性 | 增加中间温度组态 |
| 三个温度下最佳焦面差异巨大 | 热离焦未补偿 | 检查玻璃材料搭配 |
| 宏报unknown symbol | 函数名/参数/序列模式限制 | 查文档、加PRINT隔离 |
| 优化收敛但实际装配像质差 | 后焦变量被独立优化了 | 检查THIC变量收敛值 |
6. 进阶玩法:把Zemax和MATLAB连起来做全温度域扫描
6.1 什么时候需要外部联动
多重结构编辑器本身已经能搞定大多数热分析需求,但它有一个软肋:温度组态是离散的。你建了-40、20、60三个组态,就只能看这三个温度点。而实际工程中,我更想看全温区连续变化的离焦曲线,找到最恶劣的温度点,看看是不是落在-20℃这种中间位置。这时候在Zemax里手动改温度、记录像质,一次两次还行,整个温区扫上几十个点就会崩溃。
所以我一般用MATLAB做全温度域扫描。更准确地说,是用ZOS-API(OpticStudio的应用程序接口)把Zemax的计算能力嵌入到MATLAB脚本里,循环控制温度、批量追迹、读取点列图或离焦数据,然后在MATLAB里统一做后处理和画图。
6.2 通过ZOS-API做批量扫描的基本思路
ZOS-API支持的连接方式有独立模式(Standalone)和应用内模式(In-Process)。最简单的场景是:MATLAB脚本启动OpticStudio,打开一个设计文件,逐次修改温度,读取表面的厚度和像质评价结果。
大致脚本思路如下(以MATLAB和ZOS-API交互为例,省略具体API调用细节,重点是流程):
% 伪代码:遍历温度,读取不同温度下最佳像面位置 temperature_list = -40:10:60; best_focus = zeros(size(temperature_list)); rms_spot = zeros(size(temperature_list)); for i = 1:length(temperature_list) % 连接并打开设计文件 app = ZOSAPI_Connect(); system = app.OpenFile('thermal_lens.zmx'); % 把当前组态温度设为 temperature_list(i) % 通过多重结构接口修改 TEMP 操作数值,或使用系统温度属性 % 先粗扫像面位置,找最小RMS对应的像面偏移 best_focus(i) = scan_focus_position(system, -0.2, 0.2, 0.01); % 在最佳焦面位置读取点列图RMS rms_spot(i) = get_rms_spot(system); % 保存数据 fprintf('T=%.1f, best_focus=%.4f, RMS=%.4f\n', ... temperature_list(i), best_focus(i), rms_spot(i)); end % 画离焦-温度曲线 plot(temperature_list, best_focus, 'o-'); xlabel('温度 (℃)'); ylabel('最佳像面位置偏移 (mm)');这个脚本的真正价值在于,它能让你看到温度轴上像面位置的连续变化趋势。尤其是当你的镜头工作温区很宽、材料非线性明显时,这种扫描能快速定位"最恶劣温度点",而不是靠经验猜测。
6.3 用MATLAB优化工具箱做更复杂的目标
如果你不满足于扫描,想直接让MATLAB来主导优化——比如在Zemax默认优化器跑不出满意结果时,改用MATLAB的遗传算法或fmincon来搜索玻璃组合、间隔参数——也是可行的。
思路是把Zemax当成一个"计算黑箱":MATLAB生成一组设计变量值(比如各镜片间隔、某几片镜子的曲率),传给Zemax,Zemax返回对应的加权像质指标,MATLAB根据这个指标更新下一组设计变量,反复迭代。
好处是可以用MATLAB里灵活的约束和目标函数编写能力,比如自定义"全温区最大RMS最小化",或者"常温性能和高温性能加权"这种Zemax默认评价函数里不好表达的目标。代价是速度慢,因为每次迭代都要启动一次Zemax计算。我的建议是先用Zemax自己的优化器跑收敛,再通过MATLAB做局部搜索或参数化扫描,而不是一上来就外部接管全局优化。
6.4 从"被动无热化"走向"主动热补偿"
走到这一步的人,通常已经不满足于"设计一个被动无热化镜头"了。现实工程里,很多高性能红外系统采用主动热补偿:探测器或者某片补偿镜装在微型直线电机上,系统根据温度传感器读数实时调整后焦位置。
这种系统的Zemax建模思路其实还是多重结构:把后焦在不同温度下的最佳位置做成一张查找表,这就是前面用MATLAB扫描出来的"温度-最佳像面位置"曲线。结构工程师拿到这张表,就能设计调焦机构的行程和控制算法;软件工程师据此写温度查表程序。你会发现,Zemax热分析工作做得好不好,直接决定了主动补偿系统能不能用起来——如果连不同温度下最佳焦面在哪都不知道,补偿就无从谈起。
另外,现在的AI辅助设计也逐渐被引入热分析环节。比如用优化算法自动搜索镜筒材料、玻璃材料组合,或者用神经网络拟合温度-离焦响应模型。不过目前这些方法更多还是作为传统Zemax优化的补充,核心的物理建模和操作数评价仍然离不开多重结构这套体系。
我在实际项目中反复验证的一个体会是:Zemax热分析这门手艺,工具操作只占三成,剩下的七成是"对温度物理过程的理解"和"对评价函数目标的设计"。多重结构编辑器无非是承载这些理解的容器,操作数只是把目标翻译成计算机能听懂的语言放在容器里。只要把"温度到底改变了什么""哪些参数能补偿这些变化""怎么判断收敛是真的收敛"这三件事想清楚,不管Zemax界面怎么改版、操作数怎么变化,你都能很快上手。