Python / Linux / Shell / Jetson / ROS 2 / Docker / HTTP

端侧 Multi-Agent VLM 导航系统技术架构

该项目围绕 Jetson Orin 上的机器人导航链路,将高层任务拆成观测、规划、执行和安全审查模块, 并通过 Search Loop + Replan、端云混合推理、ROS 2/Nav2/Stream-VLN 执行适配,把自然语言任务落到可运行的机器人闭环。

系统集成/核心开发 边缘设备集成 端云混合推理 服务编排与稳定性优化
Runtime Jetson Orin + ROS 2
Agent Observer / Planner / Skill / Safety
Inference Cloud VLM + local vLLM
Backend Nav2 / Visual Servo / Stream-VLN
01 / Architecture Map

技术架构图

从前端任务输入到 Jetson 端侧执行,所有模块围绕“可观测、可重规划、可执行、可审查”的导航闭环组织。

任务决策主链路
Preact / HTTP

前端控制台

  • 提交自然语言任务与图像
  • 展示会话、计划、执行状态
  • 调用 /api/chat 与 runtime probe
cmd/nav-server

Go 导航服务

  • 维护任务阶段和会话历史
  • 统一编排观测、规划、执行
  • 隔离前端和机器人运行时
Observer / Planner / Skill / Safety

Multi-Agent 决策层

  • Observer 解析图像与传感器上下文
  • Planner 输出可解释导航计划
  • Skill 选择执行后端
Search Loop + Replan

目标搜索闭环

  • 目标不可直达时旋转采集
  • VLM 识别后触发重规划
  • 发现目标后进入接近或导航
端云推理服务
Cloud VLM

云端规划/观测模型

  • 承载复杂视觉理解
  • 保留较大上下文窗口
  • 适合 Planner / Observer
Jetson + vLLM + Qwen3.5-0.8B

端侧 Skill 模型

  • Docker Compose 编排容器
  • 固定模型路径、缓存、端口
  • 提供健康检查和日志排查入口
OpenAI-Compatible HTTP

推理适配层

  • 按 Agent 角色切换本地/云端
  • 统一请求/响应协议
  • 隔离 Jetson 镜像和 vLLM 版本差异
机器人执行链路
Execution Router

执行层选择

  • 地图/位姿可用时走 Nav2
  • 目标可见时走视觉伺服
  • 需要视觉语言轨迹时接 Stream-VLN
ROS 2 / Nav2

导航栈

  • Cartographer 定位
  • planner/controller/bt_navigator 执行
  • execute_nav2_goal_once.py 下发目标
Jetson Orin / Linux / Shell

端侧服务编排

  • 底盘、相机、传感器统一启动
  • CANable2 + AGX_V2 底盘接入
  • 脚本化恢复和远端联调
Safety Agent / Runtime Probe

稳定性与安全边界

  • 执行前检查运行状态
  • 异常时 hold / stop
  • 置信度不足时保持保守搜索
02 / Search Loop

目标不可直达时怎么做

常规 VLM 一次性静态规划容易在“找灭火器/找目标物”这类任务中失败,因此这里把搜索显式做成可重复的运行时闭环。

采集观测

从相机和运行时状态生成 PerceptionContext,包含图像、机器人位姿、可见对象和地图上下文。

VLM 识别

Observer 判断目标是否出现、方向和置信度;低置信度结果不会直接转换成导航目标。

Planner 重规划

Planner 根据新观测决定继续 search、靠近目标、保持停止或回退到 Nav2。

执行下一步

SearchRuntime 执行旋转、捕获、视觉伺服或导航动作,并把结果写回会话。

03 / Jetson vLLM

端侧推理服务怎么落地

端侧 vLLM 服务的重点不是“能启动一次”,而是把模型路径、缓存、端口、健康检查、日志和配置切换固定下来,能稳定接入主链路。

服务部署边界

  • Jetson Orin 上使用 Docker Compose 拉起 vLLM 容器。
  • Qwen3.5-0.8B 作为本地 Skill agent 的推理后端。
  • 容器对外暴露 OpenAI-compatible HTTP 接口。
  • 主系统只关心 base_url、model、timeout,不直接感知容器细节。

稳定性优化点

  • 启动脚本统一检查 GPU、模型目录、缓存目录和端口占用。
  • 健康检查脚本验证 /v1/models 或 /healthz 是否可用。
  • 日志集中到固定目录,便于排查模型加载、镜像和接口兼容问题。
  • 按 Agent 角色做端云切换,避免单点模型失败拖垮全链路。
04 / Execution Routing

不同导航后端怎么选

执行层不是固定写死 Nav2,而是根据任务类型、视觉可见性、位姿/地图上下文和传感器条件动态路由。

输入条件

任务类型、目标是否可见、观测置信度、robot_pose、map context、Nav2 readiness。

Skill 决策

将 Planner 的语义计划转换为可执行动作,并选择 Nav2、visual_servo、Stream-VLN 或 search_pattern。

执行结果

成功、失败、hold/stop、继续搜索或触发 replan,结果回写会话供下一轮决策使用。

05 / Code Snippets

页面中可讲解的关键代码段

这些代码段不是完整项目源码,而是用于讲清“如何实现”的核心骨架。

Search Loop 控制骨架Python-like
def run_search_loop(task, max_steps=4):
    session.bind(task)
    for step in range(max_steps):
        ctx = collect_perception_context()
        obs = observer.detect_target(ctx)

        if obs.confidence >= 0.7 and obs.visible:
            plan = planner.replan(task, obs)
            return executor.run(plan)

        action = search_skill.next_action(ctx, step)
        search_runtime.execute(action)

    return safety.hold("target_not_found")
执行后端选择Go-like
switch {
case target.Visible && target.Distance < visualServoRange:
    backend = "visual_servo"
case navContext.HasMapPose && runtime.Nav2Ready:
    backend = "nav2"
case task.NeedsLanguageTrajectory:
    backend = "stream_vln"
default:
    backend = "search_pattern"
}

result := execution.Run(ctx, backend, plan)
session.AppendExecutionResult(result)
Jetson vLLM Compose 片段YAML
services:
  skill-vllm:
    image: vllm-jetson:0.19.0
    runtime: nvidia
    ports:
      - "8001:8000"
    volumes:
      - "/models/qwen:/models/qwen:ro"
      - "/data/vllm-cache:/root/.cache"
    command:
      - "--model=/models/qwen/Qwen3.5-0.8B"
      - "--host=0.0.0.0"
      - "--port=8000"
端云推理配置切换Shell
# Planner / Observer 留在云端,Skill 切到 Jetson 本地 vLLM
export PLANNER_BASE_URL="https://cloud.example/v1"
export OBSERVER_BASE_URL="https://cloud.example/v1"
export SKILL_BASE_URL="http://jetson-orin:8001/v1"
export SKILL_MODEL="Qwen3.5-0.8B"

curl -fsS "$SKILL_BASE_URL/models" >/dev/null
./start_nav_server.sh