跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

农业机器人自主导航:五种路径规划算法的实现与权衡

农业机器人要在复杂的田间自主行驶,路径规划是关键。这篇文章梳理了 A*、Dijkstra、DWA、RRT 和人工势场法五种常用算法,给出了 Python/C++ 的实现要点,并讨论了环境建模中 RTK 定位和传感器融合的实际做法。每种算法都有它的适用场景,实际部署往往需要取长补短,组合使用。

JavaCoder发布于 2026/6/300 浏览

田里跑自主机器人,路径规划是块硬骨头。几种常用算法试下来,我觉得这五种必须知道:A*、Dijkstra、DWA、RRT 和人工势场。各有各的脾气,用好了才稳。

先把地图和定位弄对

路径算得再好,基础数据差也没用。普通 GPS 在田里晃个几米太常见,RTK 几乎是刚需。写一个 Go 的客户端从基准站拉差分数据,移动站就可以把定位干到厘米级。

client.Connect("ntrip.base.com:2101")
client.Auth("user", "pass")
client.MountPoint("/RTCM3")
go func() {
    for data := range client.Stream() {
        rover.ApplyCorrection(data)
    }
}()

有了高精度坐标,再融合 IMU 的姿态补偿和卡尔曼滤波,能输出稳定的位姿。至于地图,常规就两种:栅格地图把田切成小格子,标记可走、不可走,适合播种喷洒这类精细活;拓扑地图只留关键节点和道路连接,存得少,适合大范围快速导航。我一般全局用拓扑,局部再转成栅格去避障。各有各的适用场合:

指标栅格地图拓扑地图
存储开销高低
更新频率实时动态周期性

判定一个格子是不是障碍,有时还得动态调阈值,比如作物高了就把栅格值上调,用下面这个小函数就行:

def is_obstacle(grid_map, x, y, threshold=0.8):
    return grid_map[x][y] > threshold

全自主农场系统架构

这张图是感知到执行的闭环:传感器、摄像头把数据送到边缘端处理,再汇总到云端规划,最后指令下到行走机构。说起来简单,做起来坑不少。

整个导航过程基本循环就是:

graph TD
A[开始] --> B{获取传感器数据}
B --> C[执行 SLAM 建图]
C --> D[调用路径规划算法]
D --> E[生成控制指令]
E --> F[驱动电机执行]
F --> G[实时修正位置]
G --> B

五种算法逐个看

A*:全局规划的标配

A* 的灵魂是 f(n)=g(n)+h(n),用一个优先队列挑 f 最小的节点扩展,出来的就是最短路径。实现起来并不复杂:

def a_star(grid, start, goal):
    open_set = PriorityQueue()
    open_set.put((0, start))
    came_from = {}
    g_score = {start: 0}
    while not open_set.empty():
        current = open_set.get()[1]
        if current == goal:
            return reconstruct_path(came_from, current)
        for neighbor in get_neighbors(current, grid):
            tentative_g = g_score[current] + cost(current, neighbor)
            if tentative_g < g_score.get(neighbor, float('inf')):
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g
            f_score = tentative_g + heuristic(neighbor, goal)
            open_set.put((f_score, neighbor))
    return []

在田里用的时候,启发函数换成曼哈顿距离,但要把土壤湿度、坡度这些折算进代价。让机器人自动绕开烂泥地,规划出来的路才真能走。

Dijkstra:慢是慢了,但绝对最优

Dijkstra 没有启发引导,硬生生往外扩散,保证给你最优解。在几百个节点的田块图上,这点延迟根本不算事儿。最小堆版本:

import heapq
def dijkstra(graph, start, end):
    queue = [(0, start)]
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    previous = {}
    while queue:
        current_dist, u = heapq.heappop(queue)
        if u == end: break
        for v, weight in graph[u].items():
            new_dist = current_dist + weight
            if new_dist < distances[v]:
                distances[v] = new_dist
                previous[v] = u
            heapq.heappush(queue, (new_dist, v))
    return previous, distances[end]

建图时把平坦区权重设 1,斜坡设 1.5,障碍物就不连边。Dijkstra 出结果很稳,不像 A* 启发函数设计不好会走弯路。

几个算法性能简单比一下:

算法路径最优性计算耗时 (ms)
Dijkstra最优48
A*最优32
贪心次优18

时间是在一张普通栅格图上测的,具体得看自己的地图。

DWA:实时避障的利器

全局路径有了,行驶中还得躲开突然窜出的东西。DWA 的做法是在当前速度允许的范围内,枚举一堆 (v, ω) 组合,模拟一小段轨迹,然后打分。分数看三点:朝向目标近不近、离障碍远不远、速度快不快。

void DWAPlanner::computeVelocityCommands(double& cmd_v, double& cmd_w) {
    double vs[5] = {robot_v_min, robot_v_max, robot_w_min, robot_w_max, acc_limit};
    for (double v = vs[0]; v <= vs[1]; v += dv) {
        for (double w = vs[2]; w <= vs[3]; w += dw) {
            if (isInDynamicWindow(v, w, vs)) {
                double score = evaluateTrajectory(v, w);
                if (score > best_score) {
                    best_v = v; best_w = w;
                }
            }
        }
    }
}

调参可以参考下表,然后再上路微调。

参数名作用推荐值(TurtleBot3)
max_vel_x最大前进速度(m/s)0.26
min_vel_theta最小旋转速度(rad/s)0.4
sim_time轨迹预测时间(s)1.0

泥地惯性大,加速度就得设低些。

RRT:没地图也能撞出路来

很多田根本没有现成地图,RRT 这时候就管用了。它纯靠随机采样往外长树,碰到障碍就换个方向,直到有分支靠近目标。

def rrt_step(tree, goal, step_size):
    random_point = sample_free_space()
    nearest_node = find_nearest(tree, random_point)
    new_point = extend_towards(nearest_node, random_point, step_size)
    if is_collision_free(nearest_node, new_point):
        tree.add_node(new_point)
        tree.add_edge(nearest_node, new_point)
    if distance(new_point, goal) < step_size:
        return True
    return False

这样找出来的路弯弯绕绕,直接让机器走会急转磨轮胎。所以必须平滑一下,我用三次 B 样条插值:

def smooth_path(path, degree=3):
    t = np.linspace(0, 1, len(path))
    t_smooth = np.linspace(0, 1, 5 * len(path))
    x, y = zip(*path)
    cs_x, cs_y = CubicSpline(t, x), CubicSpline(t, y)
    return [(cs_x(t_val), cs_y(t_val)) for t_val in t_smooth]

平滑后再输给 PID 控制器,走起来才像样。

人工势场:简单,但容易陷进去

人工势场就建一个虚拟势场:目标吸,障碍推,合力方向就是该走的方向。代码也很短:

def compute_total_force(robot_pos, goal_pos, obstacles):
    attractive = k_att * (goal_pos - robot_pos)
    repulsive = np.zeros(2)
    for obs in obstacles:
        dist = np.linalg.norm(robot_pos - obs)
        if dist < d0:
            repulsive += k_rep * (1/dist - 1/d0) * (1/dist**2) * (robot_pos - obs)/dist
    return attractive + repulsive

缺点就是容易陷入局部极小,引力斥力扯平了机器人就不动了。一般加点随机扰动强行推出来,或者直接用 A* 做全局引导。不能单靠它干活。

辅助环节:融合、控制与取舍

多传感器融合也是个必须过的坎。激光雷达和摄像头的数据得先时间对齐,我一般用最近邻:

def sync_sensors(lidar_ts, camera_ts):
    aligned = []
    for lidar_t in lidar_ts:
        closest_cam = min(camera_ts, key=lambda x: abs(x - lidar_t))
        aligned.append((lidar_t, closest_cam))
    return aligned

对齐之后再做融合,看需要是前融合还是后融合:

方法优点适用场景
前融合信息完整,原始级整合静态地图构建
后融合计算快,鲁棒动态障碍跟踪

跟踪出动态目标后,再用来更新栅格地图,路径规划就能实时避开。

路径生成了,跟踪也得稳。最简单的 PID 横向控制就能对付:

double error = target_y - current_y;
integral += error * dt;
double derivative = (error - prev_error) / dt;
double output = Kp * error + Ki * integral + Kd * derivative;
prev_error = error;

参数用 Ziegler-Nichols 搞个初值,然后上车试。测过几组,Kp=1.2, Ki=0.08, Kd=0.2 的时候偏差能压到 10cm 以内,挺稳定的。这个方法跟具体机子关联大,自己的机器还得自己测。

未来的影子与现在的坑

现在不少地方开始在边缘设备上跑轻量模型做实时感知,比如用 Jetson 跑 YOLOv5 识别病虫害:

import cv2, torch
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', device='cpu')
cap = cv2.VideoCapture("rtsp://camera-ip:554/stream")
while True:
    ret, frame = cap.read()
    if not ret: break
    results = model(frame)
    detections = results.pandas().xyxy[0]
    for _, row in detections.iterrows():
        if row['confidence'] > 0.6:
            cv2.rectangle(frame, (int(row['xmin']), int(row['ymin'])),
                          (int(row['xmax']), int(row['ymax'])), (0,255,0), 2)
    if len(detections[detections.confidence > 0.8]) > 0:
        upload_to_cloud(compress_frame(frame))

还有能源这块,田里设备供电得自给。实际部署中有个大概的参考:

设备类型功耗(W)供电方案实测续航
LoRa 网关5太阳能板 + 锂电池连续阴天 7 天
巡检机器人120换电机器人自动补能每日作业 16 小时

这些数字来自实实在在的部署,不是纸上谈兵。

每种算法都没有绝对的好坏。我的选择通常是:RTK 建好底图,A* 或 Dijkstra 做全局,DWA 管局部避障;碰到完全没地图的新田,先用 RRT 探路再平滑;人工势场偶尔拿来在线微调,但不会独立用。实际落地,把基础打扎实比追新概念靠谱得多。

目录

  1. 先把地图和定位弄对
  2. 五种算法逐个看
  3. A*:全局规划的标配
  4. Dijkstra:慢是慢了,但绝对最优
  5. DWA:实时避障的利器
  6. RRT:没地图也能撞出路来
  7. 人工势场:简单,但容易陷进去
  8. 辅助环节:融合、控制与取舍
  9. 未来的影子与现在的坑
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 用 DRF 搞定企业 API:从视图到监控的实战经验
  • 用 Docker 跑 MySQL、Redis 及编译 C++ 环境,顺便管管资源
  • 从零搭建在线投稿系统:SSM + Vue 实战笔记
  • MCP AI Copilot 运维实践:从智能告警到故障自愈的量化复盘
  • Dify + Skill 本地部署实战:构建企业级 AI Agent 完整指南
  • 从表单到 JSON:Spring Boot 前后端交互三案例
  • 13个开发工具速览:从编辑器到部署的常用选择
  • Claude Skill-Creator 内部解读:如何把 AI 技能开发做成工程循环
  • 实际项目里用了用 Copilot、Comate 和通义灵码,聊点真实感受
  • Linux 命名管道 FIFO 实战:跨进程通信与常见坑
  • 用 Nginx 部署 Vue 项目全过程
  • 我用过的7款AI写小说工具:加上这套SOP,终于不卡文了
  • 从零部署 OpenClaw:接入 QQ 的全流程踩坑记录
  • 动手实现 C++ 字符串类:从内存管理到运算符重载
  • Java面试:基础、并发与容器高频考点整理
  • Java 终面追问实录:HashMap 底层、Spring 理念与 Snowflake 分布式 ID
  • 在 Windows 中安装并配置 Neo4j 图数据库
  • Kotlin中的Contract、委托与Flow:几个实用的Android开发技巧
  • 用Q-learning做无人机三维避障路径规划
  • 本地运行 Qwen-Image:Windows 上 ComfyUI 部署记录

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online