MDCS跨切面约定
概述 / Overview
本页汇总 MDCS 平台 跨子系统的约定 —— 命名、线程、错误处理、版本、文件布局。新加入团队或修改核心代码前先读这里。
This page collects MDCS-wide cross-cutting conventions — naming, threading, error handling, versioning, file layout. Read this before joining the team or modifying core code.
命名约定 / Naming conventions
| 实体 / Entity | 约定 / Convention | 例 / Example |
|---|---|---|
| Medulla 插件入口类 / Medulla plugin entry | `MainIOObject`(严格大小写) | `LidarController.MainIOObject` |
| 插件文件夹(一方) | `D:\src\M2\OfficialPlugins\<VendorModel>\` | `OfficialPlugins\LidarController\` |
| 引用程序集 / Reference DLL | `Ref<Name>.dll` | `RefMedullaCore.dll` |
| Simple 车型类 / Simple car class | 用 `[CarType]` 属性,类名任意 | `[CarType] public class LB14 : ClumsyCar` |
| DObject 槽名 / DObject slot name | `<Producer><Tag>` | `MedullaCartLowerIO<tag>` |
| Wiki 页 / Wiki page | 现有约定 :`开发手册 - ...`, `使用手册 - ...`, `XXX适配案例`, `XXX技术概述` | `开发手册 - SimpleComposer界面开发 - CAD工具` |
| 上下位 IO 字段 / IO field | 上位 `*Cmd`,下位 `*Est`(或更具体的 `*OK`, `*Pct` 等) | `vCmd`, `vEst`, `batteryPercent` |
线程约定 / Threading conventions
- LadderLogic 每个 `[UseLadderLogic]` 类自己的线程;threads 共享 CartDefinition 字段,自行同步。
- DriveTask 每个 Movement 自己的线程(`ThreadPriority.AboveNormal`)。
- DObject `Wait()` 阻塞当前线程;要并行多源就开多线程。
- CycleGUI Draw 调用 从任意线程都安全(内部 marshall 到 UI 线程)。
- SimpleComposer Nancy 处理器 在 Nancy 线程池跑;不要长阻塞。
- Tasks 多用 `async`/`await`;尽量避免 `Task.Run`(除非 explicit 后台计算)。
- LadderLogic, DriveTask each have own thread.
- DObject `Wait()` is blocking; parallelise across sources via worker threads.
- CycleGUI Draw is thread-safe.
- Nancy handlers run on Nancy's thread pool; no long blocks.
- Use `async/await`; avoid `Task.Run` unless explicit background work.
错误处理三层 / 3-layer error model
Layer 1 — 插件级 / Plugin-level
`[UseLadderLogic(resume = true)]`(默认)捕获 `Operation()` 异常并在 `resumeRetryDelay` 后重试。日常 可恢复错误用这一层。
The default `resume = true` catches LadderLogic exceptions + retries after `resumeRetryDelay`. Use for routine recoverable errors.
Layer 2 — 进程级 / Process-level
`Hedingben.ToastText(message, source)` 把异常呈现给操作工。逻辑能继续但人需要知道时用。
`Hedingben.ToastText` surfaces errors as UI toasts. Use when logic can proceed but the human should know.
catch (Exception e)
{
Hedingben.ToastText($"Failed: {e.Message}", $"{Name}:ERR");
}
Layer 3 — 看门狗级 / Watchdog-level
Wawa(看门狗Wawa使用说明)是进程监控;进程崩了会重启。对应"世界着火"级别的错误 —— 让它 `throw`,让 watchdog 接手。
Wawa is the process watchdog. For "the world is on fire" — `throw` and let the watchdog restart.
选层 / Picking the right layer
| 情况 / Situation | 用哪层 / Use |
|---|---|
| PLC 通讯偶尔超时 | Layer 1(resume + 重试) |
| 雷达连接断开 | Layer 1(重连循环)+ Layer 2(toast) |
| 关键传感器永久失效 | Layer 2(toast)+ 把 `eStop = true` |
| 内存溢出 / panic | Layer 3(throw → watchdog 重启) |
不要 同时做三层 —— 选最合适的。 Don't do all three; pick the right one.
版本与助记词 / Versioning
每次修改编译产物 : Every modification of a compiled artefact:
- `AssemblyInformationalVersion` 加 单词助记词 :`1.4.0+kindling`
- 下次改 :`1.4.1+lantern`
- 助记词 单一单词;不要 hyphen / 空格
或用 `[ReplaceWithCompileInfo]` —— LessokajiWeaver 自动注入时间戳 + git hash。 Or `[ReplaceWithCompileInfo]` — auto-inject timestamp + git hash.
目的 :现场调试时区分两个数字看起来一样的二进制。 Purpose: visually disambiguate field binaries with same number.
文件 / 路径 约定 / Path conventions
| 用途 / Use | 约定路径 / Convention |
|---|---|
| 临时工作文件 / 草稿 | `D:\src\ai-deck\<project>\` (非 repo 根;可丢弃) |
| 项目级开发日志 | `D:\src\<repo>\DEV_LOG.md`(仓库根;append-only) |
| 插件 csproj 引用 / HintPath | `..\tools\Ref<Name>.dll` |
| 部署时 plugin 位置 | `medulla/plugins/<vendor>/<plugin>.dll`,`simplecomposer/plugins/` |
| startup 脚本 | `startup.iocmd`(Medulla CWD) |
| SLAM 地图文件 | `*.2dlm` / `*.gtex` / `*.gtm` / `*.memslam` / `tagmap.json` |
| DObject 录制 | `.dorec` |
| 日志 / Logs | `logs/<YYYY-MM-DD>.log`(DLog)+ `hedingben.log` |
DEV_LOG.md
仓库根 `DEV_LOG.md` 是 append-only的开发日志 : The `DEV_LOG.md` at each repo root is the append-only dev log:
- 每条新条目追加到末尾,绝不修改旧条目。
- 重要发现用前缀 :`【发现】 / 【注意】 / 【灵感】`
- 编译产物的版本助记词也记在这里。
DEV_LOG 的目的是让 下一个读者(也许 6 个月后的自己)能复原当时的判断。 DEV_LOG's goal: the next reader (maybe you in 6 months) can reconstruct the decisions.
注释风格 / Comment style
- 头部注释稀疏 —— 代码应自解释。
- 中文注释常见于领域特定处(运动学、标定、传感)。
- 关键代码用 发现标记 —— 文件里也用 `// 【发现】 ...` 提醒后续读者。
- Header comments sparse — code should be self-evident.
- Chinese comments are normal in domain-specific spots.
- `// 【发现】 ...` flags for important inline notes.
测试纪律 / Testing discipline
- 单元测试稀疏;机器人代码本质上靠 集成测试。
- `D:\src\Fundamentals\Test\` 覆盖 DObject + DLog(最关键基础)。
- 多数"测试"通过 `[MovementTest]` / `[IOObjectUtility]` UI 按钮跑。
- 改 DObject 后必跑 Fundamentals 单元测试 —— IPC bug 灾难性。
- 改 *Core 后跑仿真车 SimpleComposer 集成测试。
文档 / Documentation
- Wiki 是事实标准;代码注释 / DEV_LOG 是 临时记。
- 公共 API 改动必同时 update wiki。
- 私下试验在 `ai-deck/`,不要污染 wiki。
Git 约定 / Git
- Branch 名 :`feature/<short-name>`, `fix/<issue>`, `release/<version>`
- Commit 消息含助记词与一句话变更摘要
- PR / MR 描述含 :变更动机 + 关键决策 + 测试方法
License / 许可
- 客户机器绑定 license 由 `auth.lessokaji.com` 签发;`LessokajiProtect.dll` 在 Fundamentals。
- 开发机用 dev license(无限期但带水印)。
- 不要在源码里 hardcode license / serial。
相关页面 / See also
- MDCS仓库布局与构建链
- 插件契约与打包约定
- 插件开发清单
- 核心开发指南
- 看门狗Wawa使用说明
- 通用约定 — 已有的"通用约定"页(业务侧)