ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

text-to-cad 实战:从自然语言到 STEP、URDF、G-code 的几何生成链路

text-to-cad 实战:从自然语言到 STEP、URDF、G-code 的几何生成链路 1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多人脑子里浮现的画面大概是对着电脑敲一句“给我画一个带法兰的六角螺栓”然后屏幕上就自动出现一个可以旋转、可以导出、可以拿去加工的实体模型。这个画面放在五年前还属于科幻范畴但放到今天它已经是一条被反复验证过的技术路径。text-to-cad 的核心命题非常直白——把自然语言描述转换成计算机辅助设计系统能够识别和处理的几何数据。这里的“CAD”不是单指某个软件而是一整套几何表达体系包括参数化草图、实体建模、装配约束以及最终交付给下游的 STEP、URDF、G-code 等格式。我之所以对这个方向持续关注是因为它切中的是一个真实且长期存在的痛点。传统 CAD 工作流里从需求到模型之间隔着一层厚厚的“翻译”工作产品经理说“要一个能承重 50 公斤的支架”结构工程师得先把这句话拆解成尺寸、约束、材料、受力路径再在软件里一步步画草图、拉伸、倒角、打孔。这个过程高度依赖人的经验而且大量重复性建模任务——比如标准件、常见结构、批量变体——占用了工程师大量时间。text-to-cad 想做的就是把这层翻译工作部分自动化让语言直接驱动几何生成。适合关注这个方向的人其实比想象中广。做机械设计的工程师可以把它当成快速原型工具输入大致描述先出一个可编辑的毛坯模型再手动精修做机器人仿真的朋友会关心它能不能直接吐出 URDF省去手工搭建连杆和关节的麻烦做数控加工的人则盯着 G-code 输出希望从描述直接跳到刀路。甚至做建筑、做钣金、做电气布线的从业者也能从这个思路里找到自己场景的映射。当然现阶段它远没到“一句话替代工程师”的程度但作为辅助生成和快速迭代的手段已经足够让人认真对待。我在这篇文章里会拆开讲清楚几件事text-to-cad 的技术链路是怎么搭起来的为什么中间要经过 STEP、URDF、G-code 这些格式实际动手时有哪些坑以及我自己在折腾过程中总结出来的一些经验。不会堆砌论文式的术语尽量用从业者之间聊天的口吻把能直接抄作业的部分写明白。2. 技术链路拆解从文本到几何到底经历了什么2.1 自然语言理解层把“人话”变成结构化意图text-to-cad 的第一步也是最容易被低估的一步是让机器真正“读懂”那句描述。很多人以为随便接一个大语言模型就能搞定实际远没那么简单。自然语言里充满了模糊、省略和隐含约束。比如“一个 100 毫米长的轴两端各有一个轴承位”这句话里至少隐含了这些信息轴是圆柱体总长 100mm轴承位通常是直径略小于轴身的圆柱段两端意味着对称或至少两个特征轴承位需要标注公差配合。一个未经专门训练的模型很可能只提取出“轴”“100mm”“轴承”这几个词然后生成一个光秃秃的圆柱完全忽略轴承位的台阶结构。所以实际系统里语言理解层通常要做几件事。第一是实体识别与关系抽取把描述里的零件、特征、尺寸、位置关系、材料、工艺要求分别打标签。第二是意图分类判断用户是要生成新模型、修改已有模型还是查询某个参数。第三是约束补全根据领域常识把省略的信息填上比如“螺栓”默认带螺纹和头部“支架”默认有安装孔。这一步的产出不是几何而是一份结构化的中间表示通常用 JSON 或类似 schema 来描述里面明确列出每个特征的类别、尺寸、位置和相互关系。我试过用纯提示词让通用模型直接输出建模脚本结果很不稳定。同样的描述十次里能有三四次生成出结构合理的模型就算不错。后来改成先让模型输出结构化 JSON再用规则引擎把 JSON 翻译成建模指令成功率明显提升。这个经验说明语言理解层和几何生成层最好解耦中间那层结构化表示才是整个系统的骨架。2.2 几何生成层参数化建模与程序化建模的取舍拿到结构化意图之后下一步是真正生成几何。这里有两条主流路线参数化建模和程序化建模。参数化建模走的是传统 CAD 的路子用草图、约束、特征操作来构建模型典型代表是通过脚本驱动 FreeCAD、SolidWorks 或中望 CAD 这类软件。程序化建模则是用代码直接构造几何体比如用 CadQuery、OpenSCAD 或者直接操作 OpenCASCADE 内核。两条路线各有优劣。参数化建模的好处是生成的模型天然带有特征树后续修改方便工程师打开软件就能看到每一步操作符合传统工作习惯。缺点是依赖具体软件的 API跨平台性差而且脚本执行速度慢批量生成时容易卡顿。程序化建模的好处是轻量、快速、可批量适合云端部署和自动化流水线但生成的模型往往是一堆几何体的布尔运算结果没有特征历史后续手动编辑不友好。我的建议是根据使用场景选。如果是给工程师做辅助设计希望他们能在生成结果上继续改那就走参数化路线把模型导出成 STEP 再导入目标软件。如果是做批量生成、仿真前处理或者数据增强那就走程序化路线直接用 CadQuery 这类库速度快且容易集成到 Python 流水线里。实际项目中我倾向于混合使用先用程序化方式快速生成候选模型筛选后再用参数化方式重建关键零件兼顾效率和可编辑性。2.3 格式转换层STEP、URDF、G-code 各自扮演什么角色模型生成出来只是半成品真正让它产生价值的是导出成下游能用的格式。text-to-cad 场景里最常被提到的三种格式是 STEP、URDF 和 G-code它们分别对应不同的下游需求。STEP 是中性几何交换格式几乎所有的 CAD 软件都能读写。它的优势是保留精确的边界表示B-rep曲面和实体信息完整适合做跨软件协作和后续加工。text-to-cad 生成模型后导出 STEP基本是默认操作。需要注意的是STEP 有 AP203、AP214、AP242 等不同协议版本AP242 支持颜色、图层和产品制造信息如果下游要做装配或标注优先选 AP242。URDF 是机器人描述格式用 XML 描述连杆、关节、惯性矩阵和碰撞体。text-to-cad 如果面向机器人仿真输出 URDF 就非常关键。很多人不知道的是URDF 里的几何通常用基本形状立方体、圆柱、球或网格文件表示直接从 CAD 实体转 URDF 需要做简化否则仿真会非常慢。我一般会先用 text-to-cad 生成实体再写脚本把实体近似成基本形状或低面数网格最后组装成 URDF。导入 CoppeliaSim 这类仿真器时还要注意关节轴方向和坐标系对齐否则机器人会以奇怪的姿态散架。G-code 是数控加工指令描述刀具路径。从 text-to-cad 直接生成 G-code 的难度比前两者高一个量级因为加工涉及刀具选择、切削参数、装夹方式、材料特性等大量工艺知识。目前比较现实的做法是 text-to-cad 生成 STEP再导入 CAM 软件生成刀路而不是一步到位。如果非要端到端那通常只适用于非常简单的 2.5 轴铣削或激光切割场景比如从描述生成一个带孔的平板直接输出轮廓切割路径。格式主要用途关键特点常见坑STEP跨软件几何交换精确 B-rep支持装配协议版本不统一大装配体文件巨大URDF机器人仿真XML 描述连杆关节几何需简化坐标系易错G-code数控加工刀具路径指令工艺知识复杂难端到端3. 动手搭建一条最小可用流水线3.1 环境准备与工具选型要自己跑通 text-to-cad不需要一上来就搞大系统。我建议从一条最小流水线开始语言模型负责解析描述Python 脚本负责生成几何最后导出 STEP。这套组合足够验证想法后续再按需扩展。工具方面几何生成我首选 CadQuery它基于 OpenCASCADEAPI 设计比较 Pythonic文档也还算友好。安装直接用 pip 就行pip install cadquery如果要用参数化路线驱动 FreeCAD那就需要安装 FreeCAD 并确保它的 Python 环境可用。FreeCAD 的安装在不同系统上差异较大Windows 下建议用官方安装包Linux 下可以用 AppImage 或包管理器。安装完成后可以通过freecadcmd命令行执行脚本。这里有个常见问题FreeCAD 自带的 Python 版本可能和你系统里的不一致导致 pip 安装的库无法导入。我的做法是直接用 FreeCAD 内置的 Python 解释器来跑脚本避免版本冲突。语言模型这块如果只是本地实验可以用开源模型配合提示词工程如果要稳定输出结构化 JSON建议用支持函数调用或 JSON 模式的大模型 API。关键是要设计好输出 schema让模型严格按照字段填值而不是自由发挥。3.2 描述解析与结构化 JSON 设计结构化 JSON 的设计直接决定后续几何生成的难易。我的经验是字段不要太多但每个字段都要有明确的几何含义。以一个简单的“带孔平板”为例可以设计成这样{ part_type: plate, length: 100, width: 60, thickness: 5, holes: [ {diameter: 6, x: 10, y: 10}, {diameter: 6, x: 90, y: 10}, {diameter: 6, x: 10, y: 50}, {diameter: 6, x: 90, y: 50} ], unit: mm }这个 schema 里part_type决定用哪个生成函数尺寸字段直接对应几何参数holes数组描述孔的位置和大小。模型的任务就是把“一块 100 乘 60 的板厚 5 毫米四角各打一个直径 6 的孔孔中心距边 10 毫米”这样的描述填进这个结构。实际测试下来只要 schema 清晰模型填值的准确率相当高。对于更复杂的零件比如带台阶的轴schema 可以设计成特征列表{ part_type: shaft, segments: [ {diameter: 20, length: 30}, {diameter: 30, length: 10}, {diameter: 20, length: 30} ], unit: mm }这种“特征列表”式的设计扩展性好新增特征类型时只需增加对应的生成函数不用改整体结构。3.3 用 CadQuery 生成几何并导出 STEP拿到 JSON 之后生成几何就是写对应的 Python 函数。以带孔平板为例import cadquery as cq import json def build_plate(params): plate cq.Workplane(XY).box( params[length], params[width], params[thickness] ) for hole in params[holes]: plate ( plate.faces(Z) .workplane() .center( hole[x] - params[length] / 2, hole[y] - params[width] / 2 ) .hole(hole[diameter]) ) return plate with open(part.json) as f: params json.load(f) result build_plate(params) cq.exporters.export(result, plate.step)这段代码里有个细节值得说CadQuery 的box是以原点为中心的而 JSON 里的孔坐标通常以左下角为基准所以要做一次坐标平移。这个偏移量如果搞错孔就会打偏。我一开始就踩过这个坑生成的模型孔位整体偏移了半个板宽后来统一约定 JSON 里用中心坐标系才避免混乱。导出 STEP 时CadQuery 默认用的是 AP214 协议如果需要 AP242可以在导出时指定。实测下来大多数 CAD 软件对 AP214 的兼容性已经足够好除非下游明确要求否则不用刻意改。3.4 从 STEP 到 URDF 的转换要点如果目标是机器人仿真STEP 只是中间产物最终要转成 URDF。这个转换不是简单的格式另存而是要做几何简化和坐标系重建。我的做法是先用 CadQuery 或 FreeCAD 读取 STEP提取每个连杆的包围盒和主要尺寸然后用基本形状近似最后写 URDF 的 XML。举个例子一个简单的两连杆机械臂text-to-cad 生成的是两个带复杂倒角的实体。转 URDF 时我会把每个连杆近似成一个长方体加一个圆柱关节座惯性矩阵用长方体公式估算。这样仿真速度快而且视觉上不会太失真。如果非要保留精确外形可以把 STEP 转成 STL 网格在 URDF 里用 mesh 引用但要注意网格面数不能太高否则 CoppeliaSim 加载会很慢。坐标系对齐是另一个大坑。URDF 里每个连杆都有自己的坐标系关节轴方向决定了运动方式。从 CAD 实体转过来时实体的原点可能在几何中心也可能在某个角点而 URDF 要求关节原点在旋转轴上。我一般会在 CAD 里先把每个连杆的坐标系调整到关节位置再导出这样转 URDF 时省事很多。4. 实操中绕不开的坑与排查经验4.1 几何生成失败的常见原因text-to-cad 最让人抓狂的就是模型生成失败而且报错信息往往很模糊。我总结下来失败原因主要集中在几类。第一类是尺寸不合理比如孔径大于板厚或者台阶直径小于前一段直径导致布尔运算无法进行。第二类是特征顺序错误比如先倒角再打孔倒角把孔的边缘切掉了。第三类是坐标系混乱多个特征用了不同的参考平面结果位置全错。排查这类问题我的习惯是先把 JSON 打印出来逐字段核对数值和单位。单位错误特别常见模型可能默认用米而描述里是毫米结果生成一个巨大或极小的模型。CadQuery 默认单位是毫米但如果你从其他库导入几何单位可能不一致。另一个技巧是分步生成先只生成主体确认无误后再加孔、加倒角这样能快速定位是哪一步出的问题。提示每次生成后都用cq.exporters.export导出一份 STL用网格查看器快速看一眼形状比在代码里调试快得多。4.2 STEP 导入导出中的兼容性问题STEP 虽然号称中性格式但不同软件实现差异不小。我遇到过 CadQuery 导出的 STEP 在某个国产 CAD 里打开后圆角变成直角也遇到过 FreeCAD 导出的装配体在另一个软件里零件位置全乱。这些问题的根源通常是协议版本和单位设置不一致。解决办法有几个。第一导出时明确指定协议版本和单位不要依赖默认值。第二尽量用 AP214 或 AP242避免用太老的 AP203。第三如果下游软件对 STEP 支持不好可以先用中间软件转一道比如先导入 FreeCAD 再导出往往能修复一些兼容性问题。第四装配体导出时确保每个零件的坐标系和装配关系正确否则导入后可能重叠或散开。还有一个容易被忽略的点文件名和路径不要包含中文或特殊字符。有些 CAD 软件对非 ASCII 路径支持不好会导致导入失败或乱码。我一般用纯英文加下划线的命名方式省去很多麻烦。4.3 URDF 导入 CoppeliaSim 的典型故障把 URDF 导入 CoppeliaSim 是机器人仿真里的高频操作也是故障高发区。最常见的现象是机器人导入后散架连杆各自飞开。这通常是因为关节的父子关系和坐标系定义不对。URDF 里每个关节都要明确 parent 和 child以及 origin 的 xyz 和 rpy。如果 origin 写错连杆就会错位。另一个常见问题是关节类型不匹配。URDF 支持 revolute、prismatic、continuous、fixed 等类型如果该用旋转关节的地方写成了固定关节机器人就不会动。还有惯性矩阵如果质量或转动惯量设为零或负数仿真器可能直接报错或行为异常。我一般会给每个连杆设一个合理的质量和惯量哪怕是用简化公式估算的。导入后如果模型显示为白色或没有纹理那通常是 mesh 路径问题。URDF 里的 mesh 文件名是相对路径导入时要确保工作目录正确或者用绝对路径。CoppeliaSim 对 STL 和 OBJ 支持较好DAE 格式有时会有材质丢失的问题。故障现象可能原因排查方法机器人散架关节父子关系或 origin 错误检查 URDF 的 joint 定义关节不动关节类型设错确认 revolute/prismatic 是否正确仿真报错惯性矩阵异常检查质量和惯量是否为正模型不显示mesh 路径错误用绝对路径或调整工作目录4.4 G-code 生成的现实边界前面提到从 text-to-cad 直接生成 G-code 难度很大。我实际尝试过用描述生成简单的激光切割路径流程是text-to-cad 生成平板 STEP提取外轮廓和孔轮廓用 Python 生成 G-code 的 G01/G02 指令。对于纯轮廓切割这套流程能跑通但一旦涉及铣削、钻孔、攻丝就力不从心了。主要瓶颈在于工艺参数。同样一个孔用不同直径的钻头、不同的转速和进给G-code 完全不同。而这些参数取决于材料、刀具、机床刚性很难从一句自然语言描述里推断出来。所以我的建议是text-to-cad 在加工场景里定位为“生成几何毛坯”把 STEP 交给 CAM 软件或工艺工程师去生成最终 G-code。如果非要自动化那就把工艺参数做成可配置的模板针对特定材料和刀具预设好几套方案而不是让模型自由发挥。注意G-code 直接驱动机床任何错误都可能导致撞刀或工件报废。在真机上跑之前务必用仿真软件验证刀路并且先空跑一遍。5. 几个值得关注的扩展方向与个人体会5.1 批量生成与参数化变体text-to-cad 真正体现效率优势的场景不是生成单个零件而是批量生成参数化变体。比如一系列不同长度和孔径的支架或者一组不同减速比的齿轮。用传统 CAD每个变体都要手动改参数、重建、导出费时费力。用 text-to-cad 加脚本可以一次性生成几十上百个模型自动命名、自动导出甚至自动生成对应的 URDF 或工程图。我做过一个实验用一份 JSON 模板描述一个带孔平板然后写循环改变长宽和孔位批量生成 50 个 STEP 文件。整个过程不到两分钟包括导出和重命名。如果手动做至少要大半天。这个效率差距在需要大量模型做仿真训练或设计探索时价值非常明显。批量生成时要注意文件命名和目录组织。我一般用“零件类型_参数1_参数2”的格式命名比如plate_100x60_h6.step这样一眼就能看出关键参数。同时把生成用的 JSON 和脚本一起存档方便复现和修改。5.2 与现有 CAD 工作流的衔接text-to-cad 生成的东西最终还是要回到工程师熟悉的 CAD 环境里。衔接得好不好直接影响它能不能真正用起来。我的经验是不要试图替代现有软件而是做它的“前置生成器”。工程师用自然语言描述需求text-to-cad 生成一个可编辑的毛坯模型导出 STEP工程师导入自己常用的 CAD 软件在此基础上精修和出图。这样做的好处是工程师不用改变原有工作习惯只是省去了从零建模的重复劳动。而且生成的模型带有基本特征后续修改也方便。如果生成的是纯网格或布尔运算结果编辑起来就麻烦很多。所以我在选择生成方式时会优先考虑输出带特征历史的模型哪怕生成速度慢一点。另外text-to-cad 也可以和 PDM/PLM 系统结合把生成记录、参数、版本都管理起来。不过这就属于更工程化的范畴了小团队先用好本地脚本和文件夹管理已经能解决大部分问题。5.3 我踩过的几个印象深刻的坑第一个坑是单位。早期我没在 JSON 里明确单位模型有时按毫米理解有时按米理解生成出来的零件尺寸差了三个数量级。后来强制在每个 JSON 里加unit: mm字段并且在生成函数里做断言检查才彻底解决。第二个坑是布尔运算的顺序。有一次生成一个带凹槽的零件我先做了倒角再切凹槽结果倒角面被切掉一块模型出现破面。后来调整顺序先做主要切除特征最后统一倒角问题消失。这个经验让我养成了一个习惯把倒角、圆角这类修饰性特征放在最后做。第三个坑是 URDF 的惯性矩阵。我一开始偷懒把所有连杆的惯量都设成很小的值结果仿真时机器人抖动严重关节像得了帕金森。后来老老实实用长方体公式估算惯量仿真立刻稳定了。惯量不能随便设它直接影响动力学行为。第四个坑是 STEP 导入 CoppeliaSim。CoppeliaSim 对 STEP 的支持有限直接导入经常失败或丢失几何。后来我改成先转 STL 再导入虽然损失了精确曲面但仿真够用而且稳定得多。这个取舍在仿真场景里很常见精度让位于速度和稳定性。5.4 给刚入门的朋友几条实在建议如果你刚接触 text-to-cad我建议不要一上来就追求端到端全自动。先从一个小场景切入比如“生成带孔平板并导出 STEP”把这条链路跑通再逐步加复杂度。工具选择上CadQuery 加 Python 是最容易上手的组合文档和社区也相对活跃。提示词工程方面与其让模型自由发挥不如把 JSON schema 设计好让模型填槽位。schema 越明确输出越稳定。同时准备一些典型示例放在提示词里模型会模仿示例的格式和粒度。最后保持对生成结果的怀疑。text-to-cad 目前还不是可靠的生产工具它生成的东西必须经过人工检查。尺寸对不对、特征全不全、能不能加工这些都要工程师把关。把它当成一个不知疲倦但经验不足的助手而不是替代者心态会好很多。我在实际使用中最大的体会是text-to-cad 的价值不在于“一句话出模型”这个噱头而在于它把重复性建模的门槛降低了。那些画标准件、改参数、导格式的琐碎时间被省下来工程师可以专注在真正需要判断力的地方。这个方向还在快速演进今天需要写脚本补的部分明天可能就被模型直接搞定了。但不管工具怎么变对几何和工艺的理解始终是做出好东西的前提。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进