查看“叉车适配案例”的源代码
←
叉车适配案例
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
管理员
您可以查看和复制此页面的源代码。
<languages/> == 概述 / Overview == 叉车(含牵引车、堆高车)是仓储 AMR 中最复杂的车型 —— 既要做 [[Special:MyLanguage/巡线行走|巡线行走]]、又要做 [[Special:MyLanguage/自动识别托盘取放货|托盘取放]]、再加上叉齿升降与平衡。本页用一台真实在产叉车(凌鸟 LB14)的源码 (`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\`,~330 行可读) 串起完整适配流程。 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. == 硬件清单 / Hardware == {| class="wikitable" ! 部件 / Part !! 典型规格 / Typical spec |- | 底盘 / Chassis || 三轮(前驱单舵 + 后双轮被动)/ Three-wheel (front steer + 2 rear passive) |- | 驱动电机 / Drive motor || 永磁同步 1.5–4 kW |- | 转向编码器 / Steer encoder || 绝对值,分辨率 ≥ 14 bit |- | 叉齿马达 / Fork motor || 液压泵 + 阀,行程 100–3000 mm |- | 倾角传感 / Tilt sensor || IMU + 阀块行程编码 |- | 前向激光 / Front lidar || 2D,高度对齐叉孔 / 2D at fork height |- | 后向激光(含侧扫)/ Rear lidar || 用于反向行驶 + 双车联动 V 槽观测 / reverse + V-groove for [[Special:MyLanguage/双车/多车联动|twin-car coordination]] |- | 负载传感 / Load sensor || 叉齿底油压或称重模块 / hydraulic pressure or load-cell |- | 通讯 / Comm || PLC 经 RS485 / Modbus 或专用 CAN / PLC via RS485 / Modbus, or proprietary CAN |} == 1. Medulla 适配 / Medulla side == 关键文件:`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\MedullaAdapter\` - `LB14Cart.cs` — `CartDefinition` 子类,声明 IO 与 LadderLogic - `Omron485.cs` / `OmronRoutine.cs` — RS485 报文层(与欧姆龙 PLC 通讯) - `LB14Remote.cs` — 与厂商遥控手柄的协议 最少需要的 IO 声明 / Minimum IO surface: <syntaxhighlight lang="csharp"> public class LB14Cart : CartDefinition { [AsInitParam] public string plcIp = "192.168.0.100"; [AsInitParam] public int plcPort = 502; [AsInitParam] public float wheelBase = 1320; // mm [AsInitParam] public float forkOffset = 760; // tine root to drive wheel // 上位 IO(调度 / Clumsy 下发的意图)/ Upper IO (intent flowing down) [AsUpperIO] public float vCmd; // 前进速度 / forward velocity (mm/s) [AsUpperIO] public float steerCmd; // 转向角 / steer angle (rad) [AsUpperIO] public float forkHeightTgt; // 叉齿目标高度 / fork target height [AsUpperIO] public float forkTiltTgt; // 叉门架倾角 / fork tilt [AsUpperIO] public bool brakeOn; [AsUpperIO] public bool hornOn; // 下位 IO(硬件回报的状态)/ Lower IO (status rising up) [AsLowerIO] public float vEst; [AsLowerIO] public float steerEst; [AsLowerIO] public float forkHeight; [AsLowerIO] public bool forkAtTarget; [AsLowerIO] public float loadKg; [AsLowerIO] public bool eStop; [AsLowerIO] public int batteryPercent; public override void Init() { // 1) 连接 PLC,握手 / connect & handshake plcConn = OmronRoutine.Connect(plcIp, plcPort); // 2) 注册看门狗 / register watchdog (LadderLogic ticks every ~50 ms) plcConn.AttachStateCallback(OnPLCStatus); } [UseLadderLogic(IntervalMs = 50)] public class ControlLoop : LadderLogic<LB14Cart> { public override void Run(LB14Cart self) { // 把 Upper IO 写到 PLC self.plcConn.WriteRegisters( vCmd: (int)(self.vCmd * 10), steerCmd: (int)(self.steerCmd * 10000), forkTgt: (int)self.forkHeightTgt ); // 读 Lower IO var s = self.plcConn.ReadStatus(); self.vEst = s.vEst / 10f; self.steerEst = s.steerEst / 10000f; self.forkHeight = s.forkHeight; self.forkAtTarget = s.forkAtTarget; self.loadKg = s.loadKg; self.eStop = s.eStop; self.batteryPercent = s.battery; } } } </syntaxhighlight> == 2. Clumsy 自动驾驶适配 / Clumsy autopilot side == 关键文件:`D:\src\cookbook\adaption-reference\苏州凌鸟\CartAdapters\LB14\ClumsyPilot\` - `AGV.cs` (255 行) — `SimpleAgvInterface` 子类,业务级动作 `Fetch / Put / ExitSite / ReverseGo1` - `Movements.cs` — 叉车特有的 `MovementDefinition` 子类 - `Configs.cs` / `CSGTypeF3CDef.cs` — 参数配置 叉车特有的 Movement / Movements specific to forklifts: <syntaxhighlight lang="csharp"> public class AGV : SimpleAgvInterface { public int baseSpeed = (int) Configuration.conf.basicSpeed; private SteeringLineFollowing lastDriver; private SteeringLineFollowingReverse lastDriverR; // 取货 / Fetch public void Fetch(double srcX, double srcY, int srcid, double dstX, double dstY, int dstid, double pivotX, double pivotY) { Queue( async () => { // 1) 巡线到 srcX/Y(叉孔正前方) DriveTask.WaitDriveTask(new SteeringLineFollowing { srcX = currentX, srcY = currentY, dstX = srcX, dstY = srcY, basespeed = baseSpeed }.Follow()); }, async () => { // 2) 升叉到取货高度 SetUpperIO("forkHeightTgt", Configuration.conf.fetchHeight); await WaitForLowerIO("forkAtTarget", timeout: 5000); }, async () => { // 3) 自动识别托盘并对位 DriveTask.WaitDriveTask(new AutoFetchGood { aX = srcX, aY = srcY, bX = dstX, bY = dstY, initSpeed = 500, inShelfSpeed = 150, stopDist = 80 }.Get()); }, async () => { // 4) 升叉离地 50 mm SetUpperIO("forkHeightTgt", forkHeight + 50); await WaitForLowerIO("forkAtTarget", 4000); }, async () => { // 5) 倒退离开工位 DriveTask.WaitDriveTask(new SteeringLineFollowingReverse { srcX = dstX, srcY = dstY, dstX = srcX, dstY = srcY, basespeed = (int)(baseSpeed * 0.6) }.ReverseFollow()); }); } } </syntaxhighlight> == 3. SimpleComposer 端 / SimpleComposer side == ClumsyCar 子类的最简实现见 [[Special:MyLanguage/如何基于SimpleCore核心库进行调度系统开发|SimpleCore 开发指南]]。叉车多了一个 ''带载包络'' 状态: A ClumsyCar subclass is minimal; the extra piece for forklifts is a '''carrying-load envelope''' state: <syntaxhighlight lang="csharp"> [CarType(Name = "LB14", Title = "凌鸟LB14 叉车 / Linbir LB14 forklift")] public class LB14 : ClumsyCar { public override Envelope GetActiveEnvelope() { if (carryingLoad) return loadedEnvelope; // 带载包络 / loaded envelope (longer) if (forkHeight > 500) return highRiseEnvelope; // 高位包络(重心抬高) return base.GetActiveEnvelope(); } } </syntaxhighlight> == 4. 调试与标定 / Calibration & tuning == 按下列顺序: Order: # '''基本运动''' / Basic motion: 站点对点行驶,调 `basespeed`、`steerCmd` 极性。 # '''激光雷达外参''' / Lidar extrinsics: 用 [[Special:MyLanguage/标定激光雷达外参|标定激光雷达外参]]。 # '''叉齿水平''' / Fork-tine horizontality: 用水平仪 + IMU 读数对齐。 # '''托盘检测先验''' / Pallet priors: 真实托盘测量 `pocketWidth`,写入 CAD。 # '''带载试运行''' / Loaded run-in: 不同载重 + 偏心载下跑同一路径,确认偏移收敛。 # '''高位放料''' / High-rise placement: 仅在 0–500–1500–2500 mm 多个高度测稳定性。 == 5. 常见问题 / Common pitfalls == * '''液压响应滞后导致超调''' / Hydraulic lag → 在 Movement 中加 ''下一目标提前 200 ms'' 的预设。 * '''叉孔对齐偏''' / Pocket misalign → 90% 是激光雷达水平度问题。 * '''带载横向漂''' / Lateral drift loaded → 检查 `wheelBase`、`forkOffset` 标定。 * '''反向行驶失败''' / Reverse line-follow fails → 后向激光遮挡或 `lastDriverR` 没设置成员。 * '''高位倒料''' / Tip-over at height → 高位包络未声明,调度允许了限速过高的路径。 == 6. 双车联动叉车 / Twin-car forklifts == 叉车做 [[Special:MyLanguage/双车/多车联动|双车联动]] 时,作为 ''领头''常见,跟随车需用后向激光雷达观测领头叉车背面的 V 槽。详见双车联动页。 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. == 相关页面 / See also == * [[Special:MyLanguage/MDCS引擎适配机器人入门教学|MDCS引擎适配机器人入门教学]] — 入门 * [[Special:MyLanguage/潜伏顶升车(KIVA类小车)适配案例|潜伏顶升车(KIVA类小车)适配案例]] * [[Special:MyLanguage/全向车适配案例|全向车适配案例]] * [[Special:MyLanguage/牵引车适配案例|牵引车适配案例]] * [[Special:MyLanguage/使用叉车自动取托盘功能|使用叉车自动取托盘功能]] * [[Special:MyLanguage/使用叉车料架堆叠功能|使用叉车料架堆叠功能]] [[Category:开发手册]]
返回
叉车适配案例
。
导航菜单
个人工具
中文(中国大陆)
创建账号
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息