10 KiB
柔性排产 · 全流程模拟操作手册
面向:产品演示、方案讲解、验收。
场景:康尼芜湖「多品种小批量 + 设备可移动」柔性排产(高压线束 / PDU 共线)。
两种走法:A 一键脚本(最快看全貌)|B 逐接口操作(贴近真实系统)。
现场真实单:先跑python scripts/load_kangni.py(或口令「导入完整生产路线」)替换演示 flex*,再用柔性排产;口径见 demand-data-intake.md 附「完整生产路线」。
数据口径见 demand-data-intake.md;需求背景见 demand-kangni-wuhu.md。
第一部分 · 自然语言:一次排产到底发生了什么
用大白话把整条链讲一遍。假设计划员接到一张订单「高压线束总成 100 套,7 天后交」。
1)设备不再绑死产线——「设备虚拟化」
传统做法:这条活固定走「线束产线」。但芜湖的现实是压接机今天在线束区、明天被调去 PDU 区。所以系统里每台设备是一份独立档案,记录它「能干哪几道工序、能不能移动、移动要多久、当前在哪个区、能装哪些模具」。产线不再是固定的钢筋水泥,而是用的时候临时拼出来的。
2)同类设备汇成一个「产能池」
系统不问「哪条线」,只问「哪道工序」。所有能做压接的设备(4 台可移动压接机)汇成一个压接能力池;所有能焊接的(1 台激光焊接机)汇成焊接池。排产时从池子里动态取设备,谁空闲、谁装了合适模具就用谁。
3)为这张订单临时拼一条「虚拟产线」
系统把订单按工艺路线展开成工序序列(来料检验→下线→压接→装配→测试→包装),然后逐道工序去对应能力池取一台设备,拼出一条虚拟产线 VL-FO-001:
- 压接这道是瓶颈工序,从压接池挑一台负载最轻的压接机,并确认它装了适配模具(没装就算换型时间);
- 如果这台压接机需要从别的区调过来,就把「移动耗时」插进时间轴(移动时不能生产);
- 每道工序占用设备的一个时间槽,前道没干完后道不能开始。 排完这条虚拟产线就「拼完即用、用完即散」,设备回到池子等下一单。
4)产能到底有多少——「瓶颈产能法」
不再用「设备台数×理论工时×拍脑袋 70%」。系统只认最慢那道工序:
全厂日产能 = 瓶颈工序可用工时 ÷ 单件工时。
本场景里 PDU 的激光焊接只有 1 台(≈88 件/天),它就是天花板;而压接池 4 台并行看着能做 1920 件/天,那是虚高,没意义。哪道最慢,产能就由它说了算。
5)销售问「这批什么时候能交」——「交期承诺模拟」
系统不回答「按产能算 X 天」,而是把这张询单试着插进当前排程,给三个数:
- 乐观(独占资源):最早能哪天完成;
- 预计(和在制订单抢资源):大概率哪天完成;
- 资源缺口:要更早,得加哪台设备 / 外包哪道工序。
6)计划总在变——「动态重排」
- 紧急插单:来一张 VIP 急单,冻结当前窗口重排,急单优先占瓶颈资源,其余顺延;
- 设备故障:某台设备停机,系统实时把它从能力池剔除,用剩下的重排。这里有个关键区别:可移动压接机坏一台,池子还有 3 台冗余,交期几乎不受影响;但激光焊接机就 1 台,一坏 PDU 直接停摆,系统立刻报「无可用设备」,提示上备机 / 外包 / 重新议交期。
一句话总结:任何时刻,系统都能回答计划员那三个问题——现在能做什么、做多少、什么时候做完。
第二部分 · 走法 A:一键脚本模拟(最快)
不用起服务、不用点页面,一条命令把上面 6 步全跑出来,全中文可读输出。
前置
# 仓库根目录,已建好 .venv 并 pip install -r requirements.txt
cd <aps-agent-repo>
运行
.venv\Scripts\python.exe scripts\flex_simulation.py
输出会分 7 段(对应上面的业务流程)
| 阶段 | 你会看到 | 怎么读 |
|---|---|---|
| 阶段 0 主数据/产能池 | 区域、每个能力池的设备清单(★=瓶颈)、模具、订单 | 确认「压接池 4 台可移动 / 焊接池 1 台」这类池结构 |
| 阶段 1 初始排产 | 5 条虚拟产线,每条逐工序打印:设备·模具·换型/移动/加工耗时·时间段 | 看「★瓶颈」那行是不是占了压接/焊接设备并挂了模具 |
| 阶段 2 瓶颈产能法 | 各池日产能表 + 限制性瓶颈 | 看「限制性瓶颈=激光焊接 88 件/天」,对照台账法虚高 1920 |
| 阶段 3 三模式对比 | 正排/倒排/瓶颈锚的延迟、准时单、最晚完工 | 压力下倒排明显更差(295h/0 准时),说明模式选择有意义 |
| 阶段 4 交期承诺 | PDU 500 套的乐观/预计完工 + 缺口提示 | 看两个日期差多少,缺口指向焊接工序 |
| 阶段 5 紧急插单 | 插单前后虚拟产线数、最晚完工、急单排入时段 | 看急单是否优先占了瓶颈 |
| 阶段 6 设备故障 | 案例①压接机故障(有冗余)|案例②焊接机故障(停摆报错) | 对比「池化韧性」与「单点瓶颈」两种结局 |
脚本是内存态确定性运行(种子固定),任何机器任何时间跑结果一致,适合反复演示。改数据后重跑即可。
第三部分 · 走法 B:逐接口操作(贴近真实系统)
先起后端,再按「看主数据 → 排产 → 看产能 → 问交期」的顺序调接口;或直接打开前端右侧「柔性工作台」点选同一条链路。
0)起服务
.venv\Scripts\python.exe -m uvicorn server.main:app --reload --port 8000
以下命令用 PowerShell 的 Invoke-RestMethod(另起一个终端)。
1)看柔性主数据与产能池(P0 只读)
Invoke-RestMethod http://localhost:8000/api/flex/world | ConvertTo-Json -Depth 6
返回:zones 区域、pools 能力池(含是否瓶颈/设备清单)、equipment 设备、molds 模具、orders 订单、以及最近一次排产的 virtualLines / workOrders / conflicts。
2)执行一次柔性排产(P1 直通,写草稿)
$body = @{ sortMode = "BOTTLENECK" } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType "application/json" `
-Uri http://localhost:8000/api/flex/schedule -Body $body
sortMode可选ASC(正排) /DESC(倒排) /BOTTLENECK(瓶颈锚),不传取默认瓶颈锚;- 可加
orderIds=@(1,2)只排指定订单; - 返回摘要:
vlCount虚拟产线数、woCount工单数、makespan最晚完工、onTimeCount准时单、conflictCount冲突、bottleneck瓶颈工序。
排完再调一次 GET /api/flex/world 看 virtualLines(每条虚拟产线的工序-设备-模具-时间)。
3)瓶颈产能法分析(P0 只读)
Invoke-RestMethod http://localhost:8000/api/flex/capacity | ConvertTo-Json -Depth 5
返回各池 dailyCapacity 日产能、workDays 本版本工作量折合天数、bottleneckPool 限制性瓶颈池。
4)交期承诺模拟(P0 只读沙盒,不改主干)
$body = @{ productCode = "PDU-UNIT"; quantity = 500 } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType "application/json" `
-Uri http://localhost:8000/api/flex/simulate-due -Body $body
返回 optimisticFinish 乐观完工、expectedFinish 预计完工、bottleneck 瓶颈提示。
接口速查
| 步骤 | 方法 | 端点 | 权级 |
|---|---|---|---|
| 看主数据/产能池/最新排产 | GET | /api/flex/world |
P0 |
| 执行柔性排产 | POST | /api/flex/schedule |
P1 |
| 瓶颈产能分析 | GET | /api/flex/capacity |
P0 |
| 交期承诺模拟 | POST | /api/flex/simulate-due |
P0(沙盒) |
第四部分 · 走法 C:换成你的真实数据
模拟数据都在种子的 flex* 键里(server/state/seed.py 的 _seed_flex)。换真实数据不用改引擎,只需:
- 按 demand-data-intake.md 的 11 张表准备数据(P0 五张必填:区域 / 设备 / 工序 / 模具 / 工艺路线);
- 逐表替换
_seed_flex里对应的flexZones/flexEquipment/flexOperations/flexMolds/flexRoutings/flexBom/flexMaterials/flexTeams/flexCalendar/flexOrders/flexParams; - 删除
server/data/world.json(若存在)让种子重播,或重启后端; - 重跑走法 A 或 B 即可。
字段口径一致即可,编码自定;不要把工厂名/产品名写进引擎或意图,保持行业无关。
第五部分 · 验收清单(照着勾)
- 阶段 0 能看到「压接池 4 台可移动 / 焊接池 1 台」的池结构与★瓶颈标记
- 阶段 1 每条虚拟产线工序顺序正确、压接工序挂了适配模具、可移动设备有移动耗时痕迹
- 阶段 2 限制性瓶颈=激光焊接(约 88 件/天),且明显低于压接池
- 阶段 3 倒排在压力场景下延迟明显高于正排/瓶颈锚(模式选择有意义)
- 阶段 4 交期给出乐观/预计两个日期 + 缺口指向焊接
- 阶段 5 急单优先占瓶颈、其余顺延
- 阶段 6 压接机故障影响小(池化韧性)、焊接机故障 PDU 停摆并报 NO_CAPABILITY
pytest tests/golden -q全绿(当前 48 passed)
常见问题
- 必须起后端吗? 走法 A 不用,纯内存跑;走法 B/前端需要
uvicorn。 - 为什么三模式有时结果一样? 交期宽松、产能有余时三模式趋同;只有产能吃紧才分化(脚本阶段 3 / 工作台「三模式对比」会压缩交期制造压力)。
- 重排是局部还是全量? 故障与急单当前为全量重排(L4);缩池体现 L1;窗内 L2/L3 为后续切片。
- 前端在哪看? 右侧「柔性工作台」+ 视口柔性甘特/产能池;也可继续用脚本/接口。
变更登记见 ../CHANGELOG.md。