CartDefinition属性参考

来自MDCS wiki2
Artheru讨论 | 贡献2026年5月16日 (六) 22:00的版本 (Initial bilingual draft (auto-published))
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索


概述 / 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`.

相关页面 / See also