<?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=%E5%8F%89%E8%BD%A6%E9%80%82%E9%85%8D%E6%A1%88%E4%BE%8B</id>
	<title>叉车适配案例 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki2.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=%E5%8F%89%E8%BD%A6%E9%80%82%E9%85%8D%E6%A1%88%E4%BE%8B"/>
	<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=%E5%8F%89%E8%BD%A6%E9%80%82%E9%85%8D%E6%A1%88%E4%BE%8B&amp;action=history"/>
	<updated>2026-05-16T16:08:25Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki2.lessokaji.com/index.php?title=%E5%8F%89%E8%BD%A6%E9%80%82%E9%85%8D%E6%A1%88%E4%BE%8B&amp;diff=1006&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=%E5%8F%89%E8%BD%A6%E9%80%82%E9%85%8D%E6%A1%88%E4%BE%8B&amp;diff=1006&amp;oldid=prev"/>
		<updated>2026-05-16T11:26:45Z</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;
叉车（含牵引车、堆高车）是仓储 AMR 中最复杂的车型 —— 既要做 [[Special:MyLanguage/巡线行走|巡线行走]]、又要做 [[Special:MyLanguage/自动识别托盘取放货|托盘取放]]、再加上叉齿升降与平衡。本页用一台真实在产叉车（凌鸟 LB14）的源码 (`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\`，~330 行可读) 串起完整适配流程。&lt;br /&gt;
&lt;br /&gt;
Forklifts (incl. tractors, stackers) are the most complex class of warehouse AMR — they do [[Special:MyLanguage/巡线行走|line-following]], [[Special:MyLanguage/自动识别托盘取放货|pallet pick-and-place]], plus fork lift / tilt control and balance. This page walks through a real adaptation using Linbir LB14 source (`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\`, ~330 LOC) as the running example.&lt;br /&gt;
&lt;br /&gt;
== 硬件清单 / Hardware ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 部件 / Part !! 典型规格 / Typical spec&lt;br /&gt;
|-&lt;br /&gt;
| 底盘 / Chassis || 三轮（前驱单舵 + 后双轮被动）/ Three-wheel (front steer + 2 rear passive)&lt;br /&gt;
|-&lt;br /&gt;
| 驱动电机 / Drive motor || 永磁同步 1.5–4 kW&lt;br /&gt;
|-&lt;br /&gt;
| 转向编码器 / Steer encoder || 绝对值，分辨率 ≥ 14 bit&lt;br /&gt;
|-&lt;br /&gt;
| 叉齿马达 / Fork motor || 液压泵 + 阀，行程 100–3000 mm&lt;br /&gt;
|-&lt;br /&gt;
| 倾角传感 / Tilt sensor || IMU + 阀块行程编码&lt;br /&gt;
|-&lt;br /&gt;
| 前向激光 / Front lidar || 2D，高度对齐叉孔 / 2D at fork height&lt;br /&gt;
|-&lt;br /&gt;
| 后向激光（含侧扫）/ Rear lidar || 用于反向行驶 + 双车联动 V 槽观测 / reverse + V-groove for [[Special:MyLanguage/双车/多车联动|twin-car coordination]]&lt;br /&gt;
|-&lt;br /&gt;
| 负载传感 / Load sensor || 叉齿底油压或称重模块 / hydraulic pressure or load-cell&lt;br /&gt;
|-&lt;br /&gt;
| 通讯 / Comm || PLC 经 RS485 / Modbus 或专用 CAN / PLC via RS485 / Modbus, or proprietary CAN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1. Medulla 适配 / Medulla side ==&lt;br /&gt;
关键文件：`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\MedullaAdapter\`&lt;br /&gt;
- `LB14Cart.cs` — `CartDefinition` 子类，声明 IO 与 LadderLogic&lt;br /&gt;
- `Omron485.cs` / `OmronRoutine.cs` — RS485 报文层（与欧姆龙 PLC 通讯）&lt;br /&gt;
- `LB14Remote.cs` — 与厂商遥控手柄的协议&lt;br /&gt;
&lt;br /&gt;
最少需要的 IO 声明 / Minimum IO surface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class LB14Cart : CartDefinition&lt;br /&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 = 1320; // mm&lt;br /&gt;
    [AsInitParam] public float  forkOffset = 760; // tine root to drive wheel&lt;br /&gt;
&lt;br /&gt;
    // 上位 IO（调度 / Clumsy 下发的意图）/ Upper IO (intent flowing down)&lt;br /&gt;
    [AsUpperIO] public float vCmd;            // 前进速度 / forward velocity (mm/s)&lt;br /&gt;
    [AsUpperIO] public float steerCmd;        // 转向角 / steer angle (rad)&lt;br /&gt;
    [AsUpperIO] public float forkHeightTgt;   // 叉齿目标高度 / fork target height&lt;br /&gt;
    [AsUpperIO] public float forkTiltTgt;     // 叉门架倾角 / fork tilt&lt;br /&gt;
    [AsUpperIO] public bool  brakeOn;&lt;br /&gt;
    [AsUpperIO] public bool  hornOn;&lt;br /&gt;
&lt;br /&gt;
    // 下位 IO（硬件回报的状态）/ Lower IO (status rising up)&lt;br /&gt;
    [AsLowerIO] public float vEst;&lt;br /&gt;
    [AsLowerIO] public float steerEst;&lt;br /&gt;
    [AsLowerIO] public float forkHeight;&lt;br /&gt;
    [AsLowerIO] public bool  forkAtTarget;&lt;br /&gt;
    [AsLowerIO] public float loadKg;&lt;br /&gt;
    [AsLowerIO] public bool  eStop;&lt;br /&gt;
    [AsLowerIO] public int   batteryPercent;&lt;br /&gt;
&lt;br /&gt;
    public override void Init()&lt;br /&gt;
    {&lt;br /&gt;
        // 1) 连接 PLC，握手 / connect &amp;amp; handshake&lt;br /&gt;
        plcConn = OmronRoutine.Connect(plcIp, plcPort);&lt;br /&gt;
&lt;br /&gt;
        // 2) 注册看门狗 / register watchdog (LadderLogic ticks every ~50 ms)&lt;br /&gt;
        plcConn.AttachStateCallback(OnPLCStatus);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    [UseLadderLogic(IntervalMs = 50)]&lt;br /&gt;
    public class ControlLoop : LadderLogic&amp;lt;LB14Cart&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        public override void Run(LB14Cart self)&lt;br /&gt;
        {&lt;br /&gt;
            // 把 Upper IO 写到 PLC&lt;br /&gt;
            self.plcConn.WriteRegisters(&lt;br /&gt;
                vCmd:     (int)(self.vCmd * 10),&lt;br /&gt;
                steerCmd: (int)(self.steerCmd * 10000),&lt;br /&gt;
                forkTgt:  (int)self.forkHeightTgt&lt;br /&gt;
            );&lt;br /&gt;
            // 读 Lower IO&lt;br /&gt;
            var s = self.plcConn.ReadStatus();&lt;br /&gt;
            self.vEst         = s.vEst / 10f;&lt;br /&gt;
            self.steerEst     = s.steerEst / 10000f;&lt;br /&gt;
            self.forkHeight   = s.forkHeight;&lt;br /&gt;
            self.forkAtTarget = s.forkAtTarget;&lt;br /&gt;
            self.loadKg       = s.loadKg;&lt;br /&gt;
            self.eStop        = s.eStop;&lt;br /&gt;
            self.batteryPercent = s.battery;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2. Clumsy 自动驾驶适配 / Clumsy autopilot side ==&lt;br /&gt;
关键文件：`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\ClumsyPilot\`&lt;br /&gt;
- `AGV.cs` (255 行) — `SimpleAgvInterface` 子类，业务级动作 `Fetch / Put / ExitSite / ReverseGo1`&lt;br /&gt;
- `Movements.cs` — 叉车特有的 `MovementDefinition` 子类&lt;br /&gt;
- `Configs.cs` / `CSGTypeF3CDef.cs` — 参数配置&lt;br /&gt;
&lt;br /&gt;
叉车特有的 Movement / Movements specific to forklifts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class AGV : SimpleAgvInterface&lt;br /&gt;
{&lt;br /&gt;
    public int baseSpeed = (int) Configuration.conf.basicSpeed;&lt;br /&gt;
    private SteeringLineFollowing       lastDriver;&lt;br /&gt;
    private SteeringLineFollowingReverse lastDriverR;&lt;br /&gt;
&lt;br /&gt;
    // 取货 / Fetch&lt;br /&gt;
    public void Fetch(double srcX, double srcY, int srcid,&lt;br /&gt;
                     double dstX, double dstY, int dstid,&lt;br /&gt;
                     double pivotX, double pivotY)&lt;br /&gt;
    {&lt;br /&gt;
        Queue(&lt;br /&gt;
          async () =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
              // 1) 巡线到 srcX/Y（叉孔正前方）&lt;br /&gt;
              DriveTask.WaitDriveTask(new SteeringLineFollowing&lt;br /&gt;
              {&lt;br /&gt;
                  srcX = currentX, srcY = currentY,&lt;br /&gt;
                  dstX = srcX,     dstY = srcY,&lt;br /&gt;
                  basespeed = baseSpeed&lt;br /&gt;
              }.Follow());&lt;br /&gt;
          },&lt;br /&gt;
          async () =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
              // 2) 升叉到取货高度&lt;br /&gt;
              SetUpperIO(&amp;quot;forkHeightTgt&amp;quot;, Configuration.conf.fetchHeight);&lt;br /&gt;
              await WaitForLowerIO(&amp;quot;forkAtTarget&amp;quot;, timeout: 5000);&lt;br /&gt;
          },&lt;br /&gt;
          async () =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
              // 3) 自动识别托盘并对位&lt;br /&gt;
              DriveTask.WaitDriveTask(new AutoFetchGood&lt;br /&gt;
              {&lt;br /&gt;
                  aX = srcX, aY = srcY, bX = dstX, bY = dstY,&lt;br /&gt;
                  initSpeed = 500, inShelfSpeed = 150, stopDist = 80&lt;br /&gt;
              }.Get());&lt;br /&gt;
          },&lt;br /&gt;
          async () =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
              // 4) 升叉离地 50 mm&lt;br /&gt;
              SetUpperIO(&amp;quot;forkHeightTgt&amp;quot;, forkHeight + 50);&lt;br /&gt;
              await WaitForLowerIO(&amp;quot;forkAtTarget&amp;quot;, 4000);&lt;br /&gt;
          },&lt;br /&gt;
          async () =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
              // 5) 倒退离开工位&lt;br /&gt;
              DriveTask.WaitDriveTask(new SteeringLineFollowingReverse&lt;br /&gt;
              {&lt;br /&gt;
                  srcX = dstX, srcY = dstY,&lt;br /&gt;
                  dstX = srcX, dstY = srcY,&lt;br /&gt;
                  basespeed = (int)(baseSpeed * 0.6)&lt;br /&gt;
              }.ReverseFollow());&lt;br /&gt;
          });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. SimpleComposer 端 / SimpleComposer side ==&lt;br /&gt;
ClumsyCar 子类的最简实现见 [[Special:MyLanguage/如何基于SimpleCore核心库进行调度系统开发|SimpleCore 开发指南]]。叉车多了一个 ''带载包络'' 状态：&lt;br /&gt;
&lt;br /&gt;
A ClumsyCar subclass is minimal; the extra piece for forklifts is a '''carrying-load envelope''' state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
[CarType(Name = &amp;quot;LB14&amp;quot;, Title = &amp;quot;凌鸟LB14 叉车 / Linbir LB14 forklift&amp;quot;)]&lt;br /&gt;
public class LB14 : ClumsyCar&lt;br /&gt;
{&lt;br /&gt;
    public override Envelope GetActiveEnvelope()&lt;br /&gt;
    {&lt;br /&gt;
        if (carryingLoad)&lt;br /&gt;
            return loadedEnvelope;        // 带载包络 / loaded envelope (longer)&lt;br /&gt;
        if (forkHeight &amp;gt; 500)&lt;br /&gt;
            return highRiseEnvelope;      // 高位包络（重心抬高）&lt;br /&gt;
        return base.GetActiveEnvelope();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4. 调试与标定 / Calibration &amp;amp; tuning ==&lt;br /&gt;
按下列顺序：&lt;br /&gt;
Order:&lt;br /&gt;
&lt;br /&gt;
# '''基本运动''' / Basic motion: 站点对点行驶，调 `basespeed`、`steerCmd` 极性。&lt;br /&gt;
# '''激光雷达外参''' / Lidar extrinsics: 用 [[Special:MyLanguage/标定激光雷达外参|标定激光雷达外参]]。&lt;br /&gt;
# '''叉齿水平''' / Fork-tine horizontality: 用水平仪 + IMU 读数对齐。&lt;br /&gt;
# '''托盘检测先验''' / Pallet priors: 真实托盘测量 `pocketWidth`，写入 CAD。&lt;br /&gt;
# '''带载试运行''' / Loaded run-in: 不同载重 + 偏心载下跑同一路径，确认偏移收敛。&lt;br /&gt;
# '''高位放料''' / High-rise placement: 仅在 0–500–1500–2500 mm 多个高度测稳定性。&lt;br /&gt;
&lt;br /&gt;
== 5. 常见问题 / Common pitfalls ==&lt;br /&gt;
* '''液压响应滞后导致超调''' / Hydraulic lag → 在 Movement 中加 ''下一目标提前 200 ms'' 的预设。&lt;br /&gt;
* '''叉孔对齐偏''' / Pocket misalign → 90% 是激光雷达水平度问题。&lt;br /&gt;
* '''带载横向漂''' / Lateral drift loaded → 检查 `wheelBase`、`forkOffset` 标定。&lt;br /&gt;
* '''反向行驶失败''' / Reverse line-follow fails → 后向激光遮挡或 `lastDriverR` 没设置成员。&lt;br /&gt;
* '''高位倒料''' / Tip-over at height → 高位包络未声明，调度允许了限速过高的路径。&lt;br /&gt;
&lt;br /&gt;
== 6. 双车联动叉车 / Twin-car forklifts ==&lt;br /&gt;
叉车做 [[Special:MyLanguage/双车/多车联动|双车联动]] 时，作为 ''领头''常见，跟随车需用后向激光雷达观测领头叉车背面的 V 槽。详见双车联动页。&lt;br /&gt;
&lt;br /&gt;
When a forklift participates in [[Special:MyLanguage/双车/多车联动|twin-car coordination]], it is typically the leader; the follower observes the leader's rear-mounted V-groove via rear lidar. See the twin-car page for details.&lt;br /&gt;
&lt;br /&gt;
== 相关页面 / See also ==&lt;br /&gt;
* [[Special:MyLanguage/MDCS引擎适配机器人入门教学|MDCS引擎适配机器人入门教学]] — 入门&lt;br /&gt;
* [[Special:MyLanguage/潜伏顶升车(KIVA类小车)适配案例|潜伏顶升车(KIVA类小车)适配案例]]&lt;br /&gt;
* [[Special:MyLanguage/全向车适配案例|全向车适配案例]]&lt;br /&gt;
* [[Special:MyLanguage/牵引车适配案例|牵引车适配案例]]&lt;br /&gt;
* [[Special:MyLanguage/使用叉车自动取托盘功能|使用叉车自动取托盘功能]]&lt;br /&gt;
* [[Special:MyLanguage/使用叉车料架堆叠功能|使用叉车料架堆叠功能]]&lt;br /&gt;
&lt;br /&gt;
[[Category:开发手册]]&lt;/div&gt;</summary>
		<author><name>Artheru</name></author>
	</entry>
</feed>