该状态机包含 3 个主阶段(GOTO_START, FOLLOW_PATH, FINISHED),以及多个子状态和模式标志。
stateDiagram-v2
[*] --> GOTO_START: 初始化
state GOTO_START {
[*] --> Rotate
Rotate --> Move: abs(heading_err) <= start_turn_first_heading
Move --> Approach: dist_to_start < start_approach_dist
Move --> Align: dist_to_start < start_tolerance
Approach --> Align: dist_to_start < start_tolerance
Align --> [*]: dist_to_start < start_tolerance AND\nabs(heading_err_final) < start_heading_tolerance
note right of Rotate
原地转向面向起点
forward=0, turn=yawrate
条件:heading_err > start_turn_first_heading
end note
note right of Move
面向起点前进
forward=scaled, turn=correction
条件:dist_to_start >= start_tolerance
end note
note right of Approach
减速接近起点
speed = slow_speed * dist_ratio
条件:dist < start_approach_dist
end note
note right of Align
原地对齐路径起始航向
forward=0, turn=yawrate
条件:到达起点但航向不对
end note
}
GOTO_START --> FOLLOW_PATH: 到达起点且航向对齐
state FOLLOW_PATH {
[*] --> NormalFollow
NormalFollow --> WaypointApproach: 检测到未转向拐点\n且 dist < 2.0m
NormalFollow --> Recovery: abs(xte) > recovery_dist (2.0m)
state WaypointApproach {
[*] --> ApproachingCorner
ApproachingCorner --> [*]: dist_to_waypoint < waypoint_turn_tolerance (0.12m)
note right of ApproachingCorner
直接朝向拐点前进(忽略路径)
减速:dist<0.5m时逐渐降速
forward=scaled, turn=to_waypoint
end note
}
WaypointApproach --> WaypointTurn: 到达拐点位置
state WaypointTurn {
[*] --> TurningInPlace
TurningInPlace --> [*]: abs(heading_err) < waypoint_turn_heading_tol (0.1rad)
note right of TurningInPlace
原地转向到下一段路径方向
forward=0, turn=yawrate
完成后标记拐点已转向
end note
}
WaypointTurn --> NormalFollow: 转向完成
state Recovery {
[*] --> RecoveringToPath
RecoveringToPath --> [*]: abs(xte) < recovery_exit_dist (0.8m)
note right of RecoveringToPath
大偏离恢复模式
朝向路径投影点前进
speed = recovery_speed (0.55 m/s)
end note
}
Recovery --> NormalFollow: 回到路径附近
state NormalFollow {
[*] --> PurePursuit
PurePursuit --> SlowZone: final_dist < slow_zone (1.5m)
SlowZone --> FinalApproach: final_dist < final_approach_dist (0.8m)
FinalApproach --> PurePursuit: final_dist >= final_approach_dist
note right of PurePursuit
标准纯追踪控制
lookahead = f(speed, xte)
速度 = base_speed * scale(曲率,航向误差,xte)
转向 = PID(heading_err) + xte_correction
end note
note right of SlowZone
接近终点减速区
speed *= dist_scale
end note
note right of FinalApproach
终点精确接近
speed *= 0.6
增加航向/xte精度要求
end note
}
NormalFollow --> [*]: final_dist < goal_tolerance (0.3m)
}
FOLLOW_PATH --> FINISHED: 到达终点
state FINISHED {
[*] --> Stopped
note right of Stopped
forward=0, turn=0
任务完成
end note
}
FINISHED --> [*]
| 状态 | 说明 | 进入条件 | 退出条件 |
|---|---|---|---|
| GOTO_START | 从任意位置移动到路径起点 | 初始化 | 到达起点且航向对齐 |
| FOLLOW_PATH | 跟随路径行驶 | 完成 GOTO_START | 到达终点 |
| FINISHED | 停止 | 到达终点 | 无 |
| 子状态 | 说明 | 控制输出 | 进入条件 | 退出条件 |
|---|---|---|---|---|
| Rotate | 原地转向面向起点 | forward=0, turn=k*heading_err | 初始/航向偏差大 | abs(heading_err) <= start_turn_first_heading (~15°) |
| Move | 朝向起点前进 | forward>0, turn=correction | 完成 Rotate | dist_to_start < start_tolerance (0.12m) |
| Approach | 减速接近起点 | forward=slow_speed*scale | dist < start_approach_dist (1.5m) |
到达起点容差内 |
| Align | 原地对齐路径起始航向 | forward=0, turn=k*heading_err_final | 到达位置但航向不对 | abs(heading_err_final) < start_heading_tolerance (0.01rad) |
关键参数:
- start_tolerance = 0.12m - 位置到达容差
- start_heading_tolerance = 0.01rad (~0.57°) - 航向对齐容差
- start_approach_dist = 1.5m - 开始减速距离
- start_turn_first_heading = pi/50 (~3.6°) - 先转向再前进的航向阈值
lookahead_min + lookahead_time * speed - 0.3 * xte速度调度
base_speed = 0.5 m/s1 / (1 + abs(curvature) * 2.0)1 / (1 + abs(heading_err) * 1.5)1 / (1 + abs(xte) * 1.0)target_speed = base_speed * 混合缩放转向控制(PID + 横向修正)
k_heading * heading_err (k=1.8)k_heading_d * heading_err_d (k=0.25)k_heading_i * heading_err_sum (k=0.01)-k_xte * xte_normalized (k=1.2)| 模式 | 说明 | 触发条件 | 控制策略 | 退出条件 |
|---|---|---|---|---|
| WaypointApproach | 接近拐点 | 检测到未转向拐点 & dist<2m | 直接朝向拐点前进(忽略路径),dist<0.5m时减速 | dist < waypoint_turn_tolerance (0.12m) |
| WaypointTurn | 原地转向 | 到达拐点位置 | forward=0, turn=k*heading_err | abs(heading_err) < waypoint_turn_heading_tol (0.1rad ~6°) |
拐点检测条件:
- 原始路径点前后方向变化 > 45° (pi/4)
- 未在 waypoint_turned 集合中(避免重复)
- 按路径顺序依次处理(不跳过)
| 属性 | 值/说明 |
|---|---|
| 触发条件 | abs(xte) > recovery_dist (2.0m) |
| 退出条件 | abs(xte) < recovery_exit_dist (0.8m) |
| 控制策略 | 朝向路径投影点前进,固定速度 recovery_speed = 0.55 m/s |
| 优先级 | 覆盖所有其他速度调度逻辑 |
| 区域 | 距离阈值 | 速度调整 | 精度要求 |
|---|---|---|---|
| Slow Zone | < slow_zone (1.5m) |
speed *= dist_scale (0.3~1.0) |
标准 |
| Final Approach | < final_approach_dist (0.8m) |
speed *= 0.6, 再乘 dist_scale |
航向<pi/10, xte<0.15m 时再*0.7 |
| Goal Tolerance | < goal_tolerance (0.3m) | 停止 | - |
扩展完成条件:
- final_dist < goal_tolerance * 1.5 (0.45m)
- current_target_idx >= n - 2
- abs(heading_err) < 0.3rad
- abs(xte) < 0.2m
stage: GOTO_START / FOLLOW_PATH / FINISHEDgoto_substage: rotate / move / align(仅在 GOTO_START 有效)waypoint_approach_mode: bool(拐点接近模式)waypoint_turn_mode: bool(拐点转向模式)in_recovery: bool(恢复模式)finished: bool(任务完成)min_follow_speed = 0.08 m/s(防止静止)accel = 0.2 m/s²(软启动)abs(heading_err) > 2.9rad (~166°)forward_signal = int(round((current_speed / max_forward_mps) * 100))
turn_signal = int(round((yawrate_cmd / max_yawrate) * 100))
范围:[-100, 100]
- forward: -100 → -0.2 m/s (倒车), 0 → 静止, +100 → +0.6 m/s
- turn: -100 → -pi/4 rad/s (右转), 0 → 直行, +100 → +pi/4 rad/s (左转)
[*] → GOTO_START(Rotate)
→ 原地转向面向起点 (heading_err 从 120° 降到 3°)
→ GOTO_START(Move)
→ 前进接近起点 (dist 从 5m 降到 1.5m)
→ GOTO_START(Approach)
→ 减速接近 (dist 从 1.5m 降到 0.1m)
→ GOTO_START(Align)
→ 原地调整航向对齐路径方向 (heading_err_final 从 8° 降到 0.5°)
→ FOLLOW_PATH(NormalFollow/PurePursuit)
→ 标准纯追踪跟随路径
FOLLOW_PATH(NormalFollow)
→ 检测到前方 2m 处有拐点(方向变化 60°)
→ WaypointApproach
→ 直接朝向拐点前进,逐渐减速 (dist 从 2m 降到 0.1m)
→ WaypointTurn
→ 原地转向到下一段方向 (heading_err 从 60° 降到 5°)
→ 标记拐点已转向,回到 NormalFollow
FOLLOW_PATH(NormalFollow)
→ 横向误差 xte 增大到 2.5m(触发恢复)
→ Recovery
→ 朝向路径投影点,固定速度 0.55 m/s (xte 从 2.5m 降到 0.7m)
→ 回到 NormalFollow
FOLLOW_PATH(NormalFollow/PurePursuit)
→ final_dist < 1.5m → SlowZone(速度降到 0.3~0.5 m/s)
→ final_dist < 0.8m → FinalApproach(速度进一步降到 0.2 m/s)
→ final_dist < 0.3m → FINISHED(Stopped)
| 参数 | 默认值 | 说明 |
|---|---|---|
max_forward_mps |
0.6 | 最大前进速度 (m/s) |
max_reverse_mps |
0.2 | 最大倒车速度 (m/s) |
max_yawrate |
pi/4 | 最大偏航角速度 (rad/s) |
base_speed |
0.5 | 基础速度 (m/s) |
k_heading |
1.8 | 航向误差比例增益 |
k_heading_d |
0.25 | 航向误差微分增益 |
k_xte |
1.2 | 横向误差修正增益 |
lookahead_min |
0.35 | 最小前视距离 (m) |
lookahead_max |
1.5 | 最大前视距离 (m) |
lookahead_time |
2.0 | 前视时间系数 (s) |
goal_tolerance |
0.3 | 终点到达容差 (m) |
start_tolerance |
0.12 | 起点到达容差 (m) |
waypoint_turn_tolerance |
0.12 | 拐点到达容差 (m) |
recovery_dist |
2.0 | 触发恢复模式距离 (m) |
recovery_exit_dist |
0.8 | 退出恢复模式距离 (m) |
// 主状态枚举
typedef enum {
STAGE_GOTO_START,
STAGE_FOLLOW_PATH,
STAGE_FINISHED
} MowerStage;
// GOTO_START 子状态
typedef enum {
GOTO_SUBSTAGE_ROTATE,
GOTO_SUBSTAGE_MOVE,
GOTO_SUBSTAGE_ALIGN
} GotoSubstage;
// FOLLOW_PATH 模式标志
typedef struct {
bool waypoint_approach_mode;
bool waypoint_turn_mode;
bool in_recovery;
} FollowModeFlags;
// 控制器状态
typedef struct {
MowerStage stage;
GotoSubstage goto_substage;
FollowModeFlags follow_flags;
uint16_t current_target_idx;
uint16_t waypoint_turn_target_idx;
float current_speed;
bool finished;
} MowerControlState;
// 状态转移函数原型
void update_goto_start_state(MowerControlState *state, float dist, float heading_err);
void update_follow_path_state(MowerControlState *state, float xte, float waypoint_dist);
void compute_goto_start_control(const MowerControlState *state, int16_t *forward, int16_t *turn);
void compute_follow_path_control(const MowerControlState *state, int16_t *forward, int16_t *turn);
_find_nearest_original_waypoint 函数出现两次,后者覆盖前者start_heading_tolerance = 0.01 注释说 ~14°,实际 ~0.57°生成时间:2025-11-13
基于:mower_controller.py (约 1200 行)