查看“插件开发清单”的源代码
←
插件开发清单
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
管理员
您可以查看和复制此页面的源代码。
<languages/> == 概述 / Overview == 本页是 MDCS 插件开发中 ''该做与不该做''(Do's & Don'ts)的速查表。从生产经验中总结,每一条都对应一个真实踩过的坑。 This page is the MDCS plugin-development Do's & Don'ts. Each rule reflects a real production pitfall. == Do's == === 命名与契约 / Naming & contract === * '''Medulla 插件入口类名必须叫 `MainIOObject`''' —— 严格大小写。 Medulla plugin entry class must be exactly `MainIOObject`. * '''每个插件目录加 README + CHANGELOG''',写清适配的硬件型号 + 版本 + 联系人。 * '''AssemblyInformationalVersion 含 ''助记词''''' 如 `1.4.0+kindling`,便于现场区分两个数字相同的二进制。 === 生命周期 / Lifecycle === * '''构造函数廉价无副作用''' —— 硬件连接放在 `Init()`。 Constructor must be cheap and side-effect-free; hardware contact in `Init()`. * '''`Init()` 内捕获异常,设 `eStop = true` + Hedingben toast''' —— ''不要''让 `Init()` 抛出,否则 LadderLogic 部分启动部分不启动,难诊断。 Catch exceptions in `Init()`; set `eStop = true` rather than throwing. * '''每次部署前用 `io load` 在 ''干净''控制台测试一次加载''' —— 提前发现 Costura 缺失依赖。 === LadderLogic === * '''不阻塞 `Operation()` 超 scanInterval''' —— 起 worker 线程或用 `TriggerOnce` / `WaitSignal` 拆分。 Don't block `Operation()` for longer than `scanInterval`. Spawn a worker or split with helpers. * '''共享字段加锁''' —— 多个 LadderLogic 并发访问同一字段时用 `lock` 或 `Interlocked`。 * '''发布期间监控 Hedingben''' —— `resume = true` 默认会静默重启 buggy 循环 ;新插件上线时人在场看 toast。 === IO 表 / IO fields === * '''上位字段 `*Cmd` 后缀,下位 `*Est` 后缀''' —— 项目约定,避免同名冲突。 * '''`[AsInitParam]` 字段加默认值''' —— 即使没人设也能初始化。 * '''敏感字段加 `[IOObjectWatch]`''' —— 电量低 / 温度高 自动告警。 === Movement / Clumsy === * '''Movement 实现可重入''' —— 不要 static 字段保存状态。 * '''在 `Get()` 第一帧读 pose''',不要在构造时读 —— 构造与执行间车可能已经移动。 * '''Movement 长度 ≤ 50 行''' —— 超过就拆成多个 Movement 组合。 === Detour / 定位 / TightCoupler === * '''诚实报协方差''' —— 谎报会让 TightCoupler 让该源 ''统治''融合 → 全局发散。 * '''外部反馈 `counter` 单调递增''' —— 用来检测丢帧 / 乱序。 * '''`integrated = true` 配 `startingTick`''' —— 重置(IMU 重启)时给新 baseline。 === 工程 / Project === * '''每个 csproj 用 `..\tools\` HintPath''' —— 仓库一致约定。 * '''FodyWeavers.xml 含 Costura + LessokajiWeaver'''。 * '''Release 模式发布''' —— Debug 会保留更多 PDB / 符号;体积大。 * '''测试 .NET 4.8 ↔ .NET 6/8 兼容''' —— 部分老 driver 还在 .NET Framework。 === DObject === * '''名 ≤ 32 字符''' —— 超长会被静默截断。 * '''读者用 `Wait()` 阻塞''' —— 比轮询省 CPU。 * '''每次 Post 含 frame counter''' —— 读者能检测丢帧。 === 文档 / Documentation === * '''README 写清 ''硬件型号 + 协议版本'''''。 * '''CHANGELOG 含具体行为变化''' —— 不是 "fix bug"。 * '''startup.iocmd 示例放在 INSTALL.txt''' —— 客户照抄。 == Don'ts == === 命名 === * ❌ '''不要把入口类改名'''(如 `MyLidar : Lidar2DIOObject`) —— 加载器找不到。 * ❌ '''不要给 IOObject 加 `[Plugin]` 属性''' —— MDCS 不用 manifest,加了也无效。 === 加载 === * ❌ '''不要热替换 DLL''' —— Costura 缓存导致未定义行为。停 → 替换 → 启动。 * ❌ '''不要在 `static` 构造函数里碰硬件''' —— 加载时立刻触发。 * ❌ '''不要假设 `Init()` 立刻被调''' —— 它要 startup.iocmd 里的 `<inst> Init` 显式触发。 === IO 表 === * ❌ '''`[AsUpperIO]` 不要标在 `readonly` 字段上''' —— 编译过,运行时 `MissingMethodException`。 * ❌ '''不要从外部直接写 `MedullaCartUpperIO<tag>` DObject''' —— 总走 `SetUpperIO`,否则失同步。 * ❌ '''不要把高速字段都 `[IOObjectMonitor]` 加 `VerboseLog`''' —— 日志爆炸。 === LadderLogic === * ❌ '''不要在 `Operation()` 里 `Thread.Sleep`''' —— 阻塞整个 loop 线程。 * ❌ '''不要假设 LadderLogic 是实时''' —— Windows 上 1–15 ms 抖动;真实时需要 PLC。 * ❌ '''不要在多 LadderLogic 之间共享 ''可变''字段而不加锁'''。 === Movement === * ❌ '''不要在 Movement 里 `Thread.Sleep`''' —— 用 `yield return` 多次。 * ❌ '''不要在 `Get()` 抛异常但不写 `eStop = true`''' —— 车继续按上一帧 `vCmd` 走。 * ❌ '''不要从 ''UI 线程''调 `DriveTask.WaitDriveTask`''' —— 它阻塞。 === Queue === * ❌ '''不要假设 Queue 的不同行真的并行''' —— 当前实现是串行(行 i 等行 i-1)。详见 [[Special:MyLanguage/SimpleAgvInterface Queue机制|Queue 机制]] 的"超标量实际行为"段。 * ❌ '''不要在 action 内 ''忽略''异常''' —— 让它传出,让上层决定恢复。 === Detour === * ❌ '''不要在雷达插件里调 `TightCoupler.PostExternalFeed`''' —— 雷达走 DObject `output()` 路径;TightCoupler 是 ''非雷达''来源的入口。 * ❌ '''不要谎报协方差''' —— 永远不要 "我超准请相信我"。 * ❌ '''不要在 SLAM 输出帧间 ''内部''重新加载地图''' —— 用 Detour 的 reload API。 === SimpleComposer / Fleet === * ❌ '''不要在 `BusinessLogic.Plan` 里阻塞超过 100 ms''' —— UI 假死。 * ❌ '''`[CarType]` 标 ''class'',不要标实例字段''' —— 反射查找按 Type。 * ❌ '''不要在 SimpleComposer 进程内调阻塞 HTTP''' —— 用 async/await。 === Costura / 构建 === * ❌ '''不要给 ''核心 DLL'' 加 Costura.Fody''' —— `MedullaCore.dll` / `ClumsyCore.dll` 等保持 ''loose'' DLL,让插件共载。 * ❌ '''不要直接引用 ''impl DLL''''' —— 引用 `Ref<Name>.dll`;否则带入 Costura 内嵌的整套依赖。 === DObject === * ❌ '''不要在 Linux 上假设 `io_shared` MMF''' —— Linux 上是文件后备。 * ❌ '''不要 cache 多个 `new DObject("name")` 实例''' —— 一个 name 一个,跨进程共享。 == 性能反模式 / Performance anti-patterns == * ❌ '''每帧 `new` 大数组''' —— 用 buffer 池或预分配。 * ❌ '''每帧 `Console.WriteLine`''' —— 日志走 DLog,主题化、可关闭。 * ❌ '''每帧序列化大对象到 DObject''' —— 用紧凑二进制,避免 JSON。 * ❌ '''Movement 内每帧 `LINQ` 链''' —— `foreach` + 索引循环。 == 安全 / Safety == * '''e-stop 必须 ''独立''于 Movement 逻辑''' —— 硬件 e-stop 线 + 软件 watchdog 双层。 * '''激光雷达 < 300 mm 范围内任何点 → 触发硬 stop''' —— 不能等 Movement 层减速。 * '''功能安全设备(SIL-2 / PL-d)独立于 MDCS''' —— MDCS 是控制层,不是安全层。 == 相关页面 / See also == * [[Special:MyLanguage/插件契约与打包约定|插件契约与打包约定]] * [[Special:MyLanguage/插件测试与发布|插件测试与发布]] * [[Special:MyLanguage/插件开发指南|插件开发指南]] * [[Special:MyLanguage/LadderLogic框架|LadderLogic框架]] * [[Special:MyLanguage/MovementDefinition详解|MovementDefinition详解]] * [[Special:MyLanguage/SimpleAgvInterface Queue机制|SimpleAgvInterface Queue机制]] [[Category:二次开发相关说明]] [[Category:开发手册]]
返回
插件开发清单
。
导航菜单
个人工具
中文(中国大陆)
创建账号
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息