CartDefinition属性参考
概述 / Overview
本页是底盘适配插件(`: CartDefinition`)所用的 全部属性的速查表。这些属性住在 `CartActivator` 插件,由 LessokajiWeaver 在编译期注入实际行为。
This page is the cheat sheet for all attributes used in cart-adapter plugins (`: CartDefinition`). They live in the `CartActivator` plugin, with actual behaviour injected at compile time by LessokajiWeaver.
定义:`D:\src\M2\OfficialPlugins\CartActivator\Attrs.cs`。 Definitions: `D:\src\M2\OfficialPlugins\CartActivator\Attrs.cs`.
字段属性 / Field attributes
[AsInitParam]
目标 / Target: 字段 / field
效果 / Effect: 该字段成为 启动配置项;可通过 startup.iocmd 或 JSON 配置传入;持久化到 LowerIO JSON 流。 The field becomes a startup config item; settable from startup.iocmd or JSON config; persisted to the LowerIO JSON stream.
[AsInitParam] public string plcIp = "192.168.0.100";
[AsInitParam] public int plcPort = 502;
[AsInitParam] public float wheelBase = 1320f;
设置方式 / How to set:
# startup.iocmd
cart.plcIp = "192.168.0.50"
cart.plcPort = 502
cart Init
[AsUpperIO]
目标 / Target: 字段 / field
效果 / Effect: 上位 IO —— 命令向下流。Weaver 把字段重写为 property,setter 自动同步到 DObject `MedullaCartUpperIO<tag>`。 Upper IO — commands flowing down. Weaver rewrites the field as a property whose setter syncs to DObject `MedullaCartUpperIO<tag>`.
[AsUpperIO] public float vCmd; // forward velocity command
[AsUpperIO] public float steerCmd; // steer angle command
[AsUpperIO] public bool brakeOn;
调度 / Clumsy 写这些字段;CartDefinition 的 LadderLogic 读后写硬件。 Scheduler / Clumsy writes; the CartDefinition's LadderLogic reads + writes hardware.
[AsLowerIO]
目标 / Target: 字段 / field
效果 / Effect: 下位 IO —— 状态向上流。Weaver 把字段写入自动同步到 DObject `MedullaCartLowerIO<tag>`。 Lower IO — status flowing up. Field writes auto-sync to DObject `MedullaCartLowerIO<tag>`.
[AsLowerIO] public float vEst;
[AsLowerIO] public float steerEst;
[AsLowerIO] public int batteryPercent;
[AsLowerIO] public bool eStop;
LadderLogic 读硬件后写这些字段;调度 / Clumsy 订阅 DObject 读。 LadderLogic writes after reading hardware; scheduler / Clumsy subscribes to the DObject.
类属性 / Class attributes
[UseLadderLogic]
目标 / Target: 嵌套类 `: LadderLogic<MyCart>` / nested class extending `LadderLogic<MyCart>`
效果 / Effect: 启动一个独立线程 + Timer,按 `IntervalMs` 周期调用嵌套类的 `Operation()`。 Spawns an independent thread + Timer that calls the nested class's `Operation()` every `IntervalMs`.
详见 LadderLogic框架。
参数 / Parameters:
| 字段 / Field | 默认 | 含义 |
|---|---|---|
| `IntervalMs` (alias `scanInterval`) | 50 | tick 周期 (ms) |
| `resume` | true | 异常自动重启 |
| `resumeRetryDelay` | 1000 | 重启前等多久 (ms) |
| `realTime` | false | 保留 |
| `timeoutInterval` | 10000 | 保留 |
可以在同一 CartDefinition 上重复声明 —— 多个循环共存。 Can be declared multiple times on the same CartDefinition for multiple concurrent loops.
[UseMedullaAPI]
目标 / Target: 类 / class
效果 / Effect: 启用 Medulla 高级 API(详细文档见 Medulla-API)。 Enables Medulla higher-level APIs (see linked API page).
[UseManualController]
目标 / Target: 类 / class
效果 / Effect: 注册手动遥控器接管 —— 启用后操作工可用手柄覆盖自动控制。 Registers manual override — operator can take over autonomous control via a handheld.
调用契约 / Calling contract
初始化顺序 / Init order
io load <plugin>.dll
→ MedullaIO.load() finds MainIOObject → new MainIOObject() (no hardware contact)
cart Init
→ Init() runs → connect to PLC / CAN / serial
→ CartDefinition.createLadders() introspects [UseLadderLogic]
→ for each ladder: spawn timer + thread
→ first Operation(iteration=0)
→ ...
【注意】 构造函数必须 廉价且无副作用。硬件接触放在 `Init()` 里。
The ctor must be cheap and side-effect-free. Hardware contact lives in `Init()`.
DObject 同步时机 / DObject sync timing
- `[AsUpperIO]` 字段 setter 触发 DObject `Post`(命令向下)
- `[AsLowerIO]` 字段 setter 触发 DObject `Post`(状态向上)
- `[AsInitParam]` 一次性 JSON 注入;运行时改 不会重新初始化硬件
第三条意味着 :运行时改 `[AsInitParam]` 字段不会自动重连 PLC;需要重新 `cart Init`。
Changing an `[AsInitParam]` field at runtime won't reconnect the PLC; you must re-`cart Init`.
还可以用 IOObject 系列属性 / IOObject attributes also apply
`CartDefinition` 继承 `IOObject`,所以 `[IOObjectMonitor] / [IOObjectUtility] / [IOObjectWebUtility] / [IOObjectWatch]` 都能用 —— 详见 IOObject属性参考。
`CartDefinition` inherits from `IOObject`, so `[IOObjectMonitor] / [IOObjectUtility] / [IOObjectWebUtility] / [IOObjectWatch]` apply. See the IOObject reference.
常见错误 / Gotchas
- `[AsUpperIO]` 标在 `readonly` 字段上 → 编译过,运行时 `MissingMethodException`(Weaver 注入 setter 与 readonly 冲突)。
`[AsUpperIO]` on a `readonly` field → compiles, runtime `MissingMethodException`. Make it mutable.
- 忘了 `cart Init` → ladder 没启动,但插件加载成功,看起来"工作"但 Lower IO 不更新。
- Init 抛异常 → 部分 ladder 起来部分没起来;难以排查。在 Init 里捕获异常,设 `eStop = true` 而不是抛。
Catch exceptions in `Init()`; set `eStop = true` instead of throwing.
- 字段名冲突 → 同名 `[AsUpperIO]` 和 `[AsLowerIO]` 用不同 setter,运行时迷惑。约定 :上位字段加 `Cmd` 后缀,下位加 `Est` 后缀。
Same-named fields with different IO directions confuse the runtime. Convention: upper = `*Cmd`, lower = `*Est`.