<?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%B7%A1%E7%BA%BF%E8%A1%8C%E8%B5%B0</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%B7%A1%E7%BA%BF%E8%A1%8C%E8%B5%B0"/>
	<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=%E5%B7%A1%E7%BA%BF%E8%A1%8C%E8%B5%B0&amp;action=history"/>
	<updated>2026-05-16T14:57:58Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki2.lessokaji.com/index.php?title=%E5%B7%A1%E7%BA%BF%E8%A1%8C%E8%B5%B0&amp;diff=1008&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%B7%A1%E7%BA%BF%E8%A1%8C%E8%B5%B0&amp;diff=1008&amp;oldid=prev"/>
		<updated>2026-05-16T11:26:50Z</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;
&amp;quot;巡线行走&amp;quot;是 MDCS Clumsy 最基础的运动原语：给一个起点 (srcX, srcY) 和终点 (dstX, dstY)，AGV 沿直线段从起点驶到终点。它由 `SteeringLineFollowing`（正向）和 `SteeringLineFollowingReverse`（反向）两个 `MovementDefinition` 子类实现，所有其它复杂动作（取放货、绕障、双车联动）都是在它之上组合而成。&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Line following&amp;quot; is the most basic Clumsy motion primitive: given (srcX, srcY) and (dstX, dstY), the AGV runs a straight segment between them. It's implemented by `SteeringLineFollowing` (forward) and `SteeringLineFollowingReverse` (reverse), both `MovementDefinition` subclasses. Every higher action (pick/place, obstacle avoidance, twin-car coordination) composes on top.&lt;br /&gt;
&lt;br /&gt;
文件 / Files: `D:\src\Clumsy\ClumsyCore\Legacy\SteeringLineFollowing.cs`、`SteeringLineFollowingReverse.cs`。&lt;br /&gt;
&lt;br /&gt;
== 使用场景 / When to use ==&lt;br /&gt;
* 站点对点的直线行驶（无需绕障 / 无需精对位）。&lt;br /&gt;
* 取放货的 ''粗对位''阶段（开 [[Special:MyLanguage/自动识别工位并取放货|工位识别]] 之前的逼近）。&lt;br /&gt;
* 反向出库（用 `Reverse` 变体）。&lt;br /&gt;
* 简单调度的最小可用配置。&lt;br /&gt;
&lt;br /&gt;
* Point-to-point straight driving on uncongested aisles.&lt;br /&gt;
* Coarse-approach stage before [[Special:MyLanguage/自动识别工位并取放货|station-aware pickup]].&lt;br /&gt;
* Reverse withdraw (the `Reverse` variant).&lt;br /&gt;
* Minimum config for a quick-running scheduler.&lt;br /&gt;
&lt;br /&gt;
== 关键字段 / Key fields ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 字段 / Field !! 类型 !! 含义 / Meaning&lt;br /&gt;
|-&lt;br /&gt;
| `srcX`, `srcY` || `double` || 起点 / segment start (mm)&lt;br /&gt;
|-&lt;br /&gt;
| `dstX`, `dstY` || `double` || 终点 / segment end (mm)&lt;br /&gt;
|-&lt;br /&gt;
| `basespeed` || `int` || 巡航速度 / cruise speed (mm/s)&lt;br /&gt;
|-&lt;br /&gt;
| `lookAhead` || `float` || 纯跟踪前瞻距离 / pure-pursuit look-ahead (mm)&lt;br /&gt;
|-&lt;br /&gt;
| `dFactor` || `float` || 横向偏差转化为转向的增益 / lateral-error → steer gain&lt;br /&gt;
|-&lt;br /&gt;
| `slowdown` || `bool` || 临近终点时降速 / decelerate near goal (true by default)&lt;br /&gt;
|-&lt;br /&gt;
| `finSpeed` || `int` || 终点最低速度（slowdown 触发后）/ final speed when slowdown active&lt;br /&gt;
|-&lt;br /&gt;
| `slowdownDist` || `float` || 进入减速段的距离阈值 / decel-zone size (mm)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
`SteeringLineFollowingReverse` 字段完全一致；语义为车头朝向 ''不变''、车体后退到目标。&lt;br /&gt;
`SteeringLineFollowingReverse` has the same fields; the car drives in reverse while keeping its heading unchanged.&lt;br /&gt;
&lt;br /&gt;
== 工作机制 / How it works ==&lt;br /&gt;
1. `MovementDefinition.Get()` 是一个 ''可枚举的 bool 序列''，每个 tick 返回一次 `true`（表示继续），直到完成时返回 `false` / 退出枚举。&lt;br /&gt;
2. `DriveTask.WaitDriveTask(IEnumerable&amp;lt;bool&amp;gt;)` 把这个序列每隔 `Configuration.conf.DriveTaskInterval` ms 调一次，并阻塞调用方直到序列结束。&lt;br /&gt;
3. 每个 tick 内部：&lt;br /&gt;
   - 读当前位姿 `(x, y, th)`（来自 Detour，已订阅）。&lt;br /&gt;
   - 计算前瞻点（沿目标线段往前 `lookAhead`）。&lt;br /&gt;
   - 用纯跟踪法求转向角；`vCmd` 取 `basespeed`（若进入减速段则衰减到 `finSpeed`）。&lt;br /&gt;
   - 写到 Medulla 上位 IO。&lt;br /&gt;
4. 当车体距 `(dstX, dstY)` 小于阈值（默认 50 mm），返回 `false` 结束。&lt;br /&gt;
&lt;br /&gt;
1. `MovementDefinition.Get()` returns an `IEnumerable&amp;lt;bool&amp;gt;` ticked once per control cycle; `true` = keep going, end-of-iteration = done.&lt;br /&gt;
2. `DriveTask.WaitDriveTask(...)` ticks at `Configuration.conf.DriveTaskInterval` ms and blocks the caller until the iteration ends.&lt;br /&gt;
3. Each tick: read pose → compute look-ahead point → pure-pursuit steer → write `vCmd` / `steerCmd`.&lt;br /&gt;
4. Exits when within ~50 mm of `(dstX, dstY)`.&lt;br /&gt;
&lt;br /&gt;
== 调用样例 / Example ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public void DriveStraight(double sx, double sy, double dx, double dy)&lt;br /&gt;
{&lt;br /&gt;
    Queue(async () =&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        DriveTask.WaitDriveTask(new SteeringLineFollowing&lt;br /&gt;
        {&lt;br /&gt;
            srcX = sx, srcY = sy,&lt;br /&gt;
            dstX = dx, dstY = dy,&lt;br /&gt;
            basespeed = 600,&lt;br /&gt;
            lookAhead = 500,&lt;br /&gt;
            dFactor   = 1.2f,&lt;br /&gt;
            slowdown  = true,&lt;br /&gt;
            finSpeed  = 100&lt;br /&gt;
        }.Follow());&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 调试要点 / Tuning ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 现象 / Symptom !! 调整 / Adjustment&lt;br /&gt;
|-&lt;br /&gt;
| 路径偏移 / Drifts off the line || 增大 `dFactor`（默认 1.2），但太大会震荡&lt;br /&gt;
|-&lt;br /&gt;
| 在终点震荡 / Oscillates at goal || 启用 `slowdown` 并增大 `slowdownDist`&lt;br /&gt;
|-&lt;br /&gt;
| 终点冲过 / Overshoots || 降低 `basespeed` 或减小 `finSpeed`&lt;br /&gt;
|-&lt;br /&gt;
| 弯道内切 / Cuts inside corner (短线段段拼接时) || 减小 `lookAhead`&lt;br /&gt;
|-&lt;br /&gt;
| 慢速时跟不准 / Poor tracking at low speed || `dFactor` 与速度成反比；低速时增大&lt;br /&gt;
|-&lt;br /&gt;
| 反向跑歪 / Reverse drifts || 检查后向激光雷达视野；可能未启用，导致姿态误差累积&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 与其它 Movement 的衔接 / Composing with other Movements ==&lt;br /&gt;
* 取货 / 放货前的接近 — 后接 `AutoFetchGood` / `AutoShelfFetching_ManyLegs`。&lt;br /&gt;
* 绕障 — 见 [[Special:MyLanguage/绕障行走|绕障行走]]。&lt;br /&gt;
* 反向出库 — 用 `SteeringLineFollowingReverse`，搭配同样的字段。&lt;br /&gt;
* 长路径 — SimpleComposer 调度会把长路径切成若干段 LineFollowing 拼接，每段一个 `srcX/Y → dstX/Y`。&lt;br /&gt;
&lt;br /&gt;
== 注意 / Caveat ==&lt;br /&gt;
LineFollowing 是 ''几何意义''上的直线段跟踪，''与车型无关''。但具体 Movement 内部隐含假设：阿克曼 / 差速车型可以 ''转向即改向''。对全向车应改用 `OmniLineFollowing`（见 [[Special:MyLanguage/全向车适配案例|全向车适配案例]]），它允许车身朝向独立于运动方向。&lt;br /&gt;
&lt;br /&gt;
`SteeringLineFollowing` is a geometric line-segment tracker but implicitly assumes Ackermann / differential kinematics. For omni vehicles use `OmniLineFollowing` (heading independent of motion direction) — see the omni case study.&lt;br /&gt;
&lt;br /&gt;
== 相关页面 / See also ==&lt;br /&gt;
* [[Special:MyLanguage/绕障行走|绕障行走]]&lt;br /&gt;
* [[Special:MyLanguage/车体抽象原理|车体抽象原理]]&lt;br /&gt;
* [[Special:MyLanguage/Clumsy-API|Clumsy-API]]&lt;br /&gt;
&lt;br /&gt;
[[Category:运动控制使用手册]]&lt;/div&gt;</summary>
		<author><name>Artheru</name></author>
	</entry>
</feed>