8.3 KiB
8.3 KiB
m_RightBtn(喷嘴开启)可用性真值表
0) 你要的重点:只整理“上层可点(E=true)”
这一节只看上层传给 setReclaimOpenBtnStatus(E) 的 E,不包含底层拦截(airPushing / RFID)。
关键调用位置:
上层 E=true 的来源只有 4 类:
- 停止打印后:
currReclaimTankPos == 0时传 true。 - 自检完成瞬间:直接传 true。
- 回收槽状态机:
reclaimTankstatus == 2时传 true。 - 回收槽状态机:
reclaimTankstatus == 4时传 true。
0.1) 上层 E=true 精简真值表(不含 A/R)
定义四个上层布尔量:
- S:自检完成事件(self check done edge)
- T:停止打印事件且
currReclaimTankPos == 0 - R2:
reclaimTankstatus == 2 - R4:
reclaimTankstatus == 4
则上层可点条件:
E = S OR T OR R2 OR R4
只看 E=true 的最小真值表(命中任一来源即可):
| S | T | R2 | R4 | E |
|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 0 | 1 | 1 |
说明:
- 这 4 行是“最小命中表”。多项同时为 1(例如 T=1 且 R2=1)也仍然是 E=1。
0.2) 上层 E=false 的主要覆盖路径(帮助你理解为何看起来复杂)
下面这些路径会频繁把 E 拉回 false:
- 开始打印后立即置 false:mainwidget.cpp
- 打印中周期置 false:mainwidget.cpp
- 自检启动/进行中置 false:InkJetPrinter.cpp
- 排气过程周期置 false:mainwidget.cpp
- 齿轮泵未进入运行态时置 false:InkJetPrinter.cpp
- 关机流程置 false:mainwidget.cpp
所以“上层 E=true”通常是阶段性信号,可能很快被其他流程覆盖为 false。
0.3) 我建议的上层简化口径(先统一 E,再叠加底层拦截)
你可以把现有分散调用统一理解为两步:
- 先算上层意图 E:
bool upperEnable = selfCheckDoneEdge
|| (stopPrint && currReclaimTankPos == 0)
|| (reclaimTankstatus == 2)
|| (reclaimTankstatus == 4);
- 再算最终可点:
bool finalEnable = upperEnable && !airPushing && !rfidBlocked;
这样分层后,排查会非常直接:
- 先问“上层想不想给点”(E)
- 再问“底层有没有拦截”(A/R)
1) 最终判定公式
m_RightBtn 最终是否可用,不只看调用处传入的 enable,还会在 MainWidget 内再次过滤。
关键实现位置:
可用公式:
FinalEnabled = E AND (NOT A) AND (NOT R)
变量定义:
- E:上层调用 setReclaimOpenBtnStatus(E) 时传入的 enable
- A:sysPara->status.airPushing(是否正在排气)
- R:RFID 层拦截(仅在编译启用 __RFID_CARD 时有效)
- inkCardTimeOut 或 solventCardTimeOut 或 needMaintenance 任一为真,则 R=1
说明:
- 若未启用 __RFID_CARD,R 恒为 0。
2) 最终可用真值表(硬条件)
| E | A | R | FinalEnabled |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 0 |
结论:
- 唯一能点的组合是 E=1、A=0、R=0。
2.1) 只看“按钮可用=true”的最小真值表
如果你只关心“什么时候能点”,那真值表可以压缩成 1 行:
| E | A | R | FinalEnabled |
|---|---|---|---|
| 1 | 0 | 0 | 1 |
反向速记(现场排查更快):
- 只要满足以下任一条件,按钮就一定不可用:
- E=0(上层当前不允许)
- A=1(正在排气)
- R=1(RFID 拦截)
2.2) 工程化简化版(建议你按这个理解)
把复杂条件改写成一个“守卫函数”,先算出 3 个阻塞原因,再统一决定可用性。
建议逻辑:
// 只表达逻辑,不改变现有业务行为
bool blockedByRFID = hasRFIDGuard && (inkCardTimeOut || solventCardTimeOut || needMaintenance);
bool blockedByAirPush = airPushing;
bool blockedByUpperLayer = !upperEnable;
bool finalEnabled = !blockedByRFID && !blockedByAirPush && !blockedByUpperLayer;
对应到 UI 语义:
- 可用态:Ready
- 不可用态:BlockedByUpperLayer / BlockedByAirPush / BlockedByRFID
这样简化后的好处:
- 读代码时从“多处 setReclaimOpenBtnStatus(true/false)”切换为“先看谁在设置阻塞原因”。
- 打日志更清晰:可直接输出第一个阻塞原因,而不是只看到按钮被置灰。
- 后续扩展更稳:新增条件只需新增一个 blockedByX,不会到处散落 if。
建议落地步骤(不改行为,只提可维护性):
- 第一步:在 MainWidget 内新增一个
computeReclaimOpenBtnEnabled(),所有按钮状态更新都走它。 - 第二步:在
setReclaimOpenBtnStatus里补充调试日志(仅 debug),打印 E/A/R。 - 第三步:把状态机处的“直接 true/false”改成“设置上层意图 upperEnable”,统一在一个点算最终值。
3) E(上层 enable)常见取值来源表
| 场景 | 调用代码 | 传入 E |
|---|---|---|
| 开始打印后 | mainwidget.cpp | 0 |
| 停止打印后,按回收槽位置决定 | mainwidget.cpp | currReclaimTankPos == 0 |
| 关机流程(回收槽未关) | mainwidget.cpp | 0 |
| 排气进行中(周期) | mainwidget.cpp | 0 |
| 打印中且自检完成(周期) | mainwidget.cpp | 0 |
| 自检开始 | InkJetPrinter.cpp | 0 |
| 自检完成 | InkJetPrinter.cpp | 1 |
| 回收槽状态机:状态=1或2 时 | InkJetPrinter.cpp | reclaimTankstatus == 2 |
| 回收槽状态机:状态=4(保持) | InkJetPrinter.cpp | 1 |
| 齿轮泵未进入运行态 | InkJetPrinter.cpp | 0 |
4) 按回收槽状态机的可用性(忽略 A/R 时的 E)
这张表只表示状态机“想给”的 E,最终仍需经过第 2 节硬条件过滤。
| reclaimTankstatus | 语义 | E(状态机给值) | 代码位置 |
|---|---|---|---|
| 1 | 开槽中 | 0 | InkJetPrinter.cpp |
| 2 | 关槽中 | 1 | InkJetPrinter.cpp |
| 4 | 保持 | 1 | InkJetPrinter.cpp |
| 5 | 开到位 | 未在该分支直接设置 E(通常由其他逻辑接管) | InkJetPrinter.cpp |
| 6 | 关到位 | 未在该分支直接设置 E(通常随后可再次开槽) | InkJetPrinter.cpp |
| 0x11/0x12 | 卡滞/异常 | 不会给出稳定可用态,偏禁用与告警处理 | InkJetPrinter.cpp |
5) 点击行为补充(按钮可用后点下去会发生什么)
入口:
行为分支:
- 若 reclaimTankBlockedAppending 为真:先弹告警确认,不直接开槽。
- 若 canRunAirPushing 为真 且 currReclaimTankPos==0:先排气,再开槽。
- 其他情况:直接调用 reclaimTanOpen。
补充状态位来源:
- canRunAirPushing 在开槽动作中会被置为 false。
- 自检完成、关槽完成后会恢复为 true。
6) 一句话版本
m_RightBtn 可用的必要且充分条件是:上层当前允许开启(E=1)+ 不在排气(A=0)+ RFID 不拦截(R=0)。在实际运行中,E 主要由“自检状态、打印状态、回收槽状态机、故障流程”共同驱动。
7) 给现场同事的超短口令
先看 E,再看 A,再看 R:
- E 由业务状态机决定“想不想让你点”。
- A/R 决定“即使想让你点,也要不要强制拦截”。
- 只有 E=1 且 A=0 且 R=0,m_RightBtn 才会真的可点。