<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki2.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=CartDefinition%E5%B1%9E%E6%80%A7%E5%8F%82%E8%80%83</id>
	<title>CartDefinition属性参考 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki2.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=CartDefinition%E5%B1%9E%E6%80%A7%E5%8F%82%E8%80%83"/>
	<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=CartDefinition%E5%B1%9E%E6%80%A7%E5%8F%82%E8%80%83&amp;action=history"/>
	<updated>2026-05-16T16:53:12Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki2.lessokaji.com/index.php?title=CartDefinition%E5%B1%9E%E6%80%A7%E5%8F%82%E8%80%83&amp;diff=1034&amp;oldid=prev</id>
		<title>Artheru：​Initial bilingual draft (auto-published)</title>
		<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=CartDefinition%E5%B1%9E%E6%80%A7%E5%8F%82%E8%80%83&amp;diff=1034&amp;oldid=prev"/>
		<updated>2026-05-16T14:00:06Z</updated>

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