如果你打算从零攒一台能自己跑起来的移动机器人,第一时间涌上来的问题大概率不是“用哪个激光雷达”,而是“用什么当它的脑子”。这个选择直接影响后续的算法部署、传感器接线、甚至整车的电源设计。第一篇我就想聊这一步:从 Jetson 到 ROS 2,把机器人的“大脑”和开发底座搭起来。这套内容适合两类人——一类是从没碰过机器人但会写代码、想快速入门的开发者,另一类是已经在折腾底盘和传感器、被驱动问题和环境冲突劝退的硬件党。看完你会明白,为什么绝大多数移动机器人项目会选 Jetson 当主控,以及从刷机到 ROS 2 环境,再到远程开发、硬件预留,这条底座链路到底该怎么一步步落地。
我见过太多机器人项目死在“入手第三周”:板子买回来了,系统刷好了,WiFi 连不上,ROS 2 装到一半依赖冲突,最后连个话题都没跑通就搁置了。这些坑其实都能提前避开,关键是把底座当成一个正经工程来对待,而不是“反正确认系统能开机就算完”。
1. 先想清楚:机器人“大脑”在整机里到底负责什么
1.1 移动机器人对主控的真实需求长什么样
移动机器人不是一台普通电脑装上轮子就能跑。它的主控要同时处理几路完全不同的数据流:激光雷达每秒数万点的扫描数据、相机每一帧图像、IMU 的六轴姿态数据、底盘发回的里程计和编码器值。这些数据到了主控之后,还要被 SLAM 算法、路径规划、避障逻辑轮流消化,最终生成一个转向或调速指令发回底盘。
也就是说,主控的定位是“感知 + 决策”,而电机的电流环、速度环这类毫秒级实时控制,通常不应该由它直接干。这背后有一个很实际的物理原因:Linux 系统本身不是硬实时系统,进程调度、网络中断、GPU 运算都会带来不确定的延迟。如果你让主控直接通过 GPIO/PWM 去驱动电机,一旦系统被某个视觉算法占满,轮子转速就会抖动,甚至是灾难性的失控。
所以理性拆解下来,一台移动机器人对主控的需求其实是四层:
- 算力层:能跑得动 SLAM、路径规划、目标检测这类算法,尤其是相机或点云处理,最好有 GPU 或 NPU 加速。
- 生态层:能跑 Linux、能方便装驱动、能兼容 ROS/ROS 2 的通信框架。
- 外设层:自带或容易扩展串口、USB、I2C、SPI、CAN 等接口,方便接激光雷达、轮式编码器、IMU。
- 功耗与体积:机器人是电池供电的移动设备,动辄 100W 的桌面主机显然不合适,板子体积也要能塞进底盘或上层支架。
这四个条件同时满足,可选范围就窄很多了。
1.2 Jetson 为什么能站在那个“平衡点”上
把候选平台摊开对比,结论很直观。树莓派生态成熟、功耗低,但 GPU 算力非常有限,跑轻量视觉算法都费劲,更别说实时处理深度相机的点云;Intel NUC 算力强、x86 软件兼容好,但体积和功耗都不友好,机器人本体还得再配一个大容量电池;STM32 这类单片机负责底层的电机控制没问题,但当“大脑”算力完全不够,连浮点矩阵运算都吃力。Jetson 恰好站在平衡点上——它有 NVIDIA GPU 提供并行算力,跑 CUDA 加速的视觉和深度学习框架是天然优势;同时它本身是一台完整的 Linux 电脑,USB、GPIO、串口、SPI、I2C 全都具备,接激光雷达、摄像头、IMU 都很顺手。
再往深一层说,Jetson 还有一个很隐蔽的优势:它的 JetPack 软件栈是 NVIDIA 官方维护的,从内核到 CUDA 库、TensorRT、OpenCV 的预编译版本都打包在一个镜像里。做机器人开发时最痛苦的不是写算法,而是“装环境”,而 JetPack 至少把最底层那一层帮你对齐了。这也是我后来坚持用 Jetson 而不是“任意一台 x86 笔记本放车上”的原因——桌面系统的驱动分散、内核版本和 CUDA 版本经常打架,在移动机器人这个场景里纯属自找麻烦。
当然,Jetson 不是万能药。它不适合直接驱动大功率电机,不适合硬实时任务,也不适合连续高负载推理而不加散热模块。但这些短板可以通过“分层架构”补掉:Jetson 负责大脑,底层用单片机做执行,两层之间用串口或 CAN 通信。这种架构在工业机器人、AGV、自动驾驶测试车里都是标配,也是全栈开发最值得先建立的整体认知。
2. 具体选型:Nano、Xavier NX、Orin Nano 按什么逻辑挑
2.1 主流 Jetson 模组的一页纸对比
Jetson 家族隔两年更新一次,很多新手上来就懵:Nano、Xavier NX、Orin Nano、Orin NX,到底买哪个?我的建议是先把参数表压成一页纸看:
| 模组 | 算力参考(FP16/密集型) | 内存 | 典型功耗 | 适合场景 |
|---|---|---|---|---|
| Jetson Nano 4GB | 约 472 GFLOPS | 4GB LPDDR4 | 5W~10W | 入门学习、简单视觉、串口/IO 调试 |
| Jetson Xavier NX 8GB | 约 21 TOPS | 8GB LPDDR4x | 10W~20W | 激光 SLAM、深度相机、移动机器人导航 |
| Jetson Orin Nano 8GB | 约 20 TOPS(密集) | 8GB LPDDR5 | 7W~25W | 入门到中级、轻量视觉、边缘 AI |
| Jetson Orin NX 16GB | 约 50 TOPS(密集) | 16GB LPDDR5 | 10W~25W | 多传感器融合、端侧大模型部署、复杂导航 |
需要说明的是,表中数据是官方公开资料的参考值,NVIDIA 在不同 JetPack 版本下对算力的标注方式不一样(有密集算力和稀疏算力两种口径),所以不要拿这个表去跑分 PK,重点看量级和定位。更关键的其实是第二条:内存和功耗决定了你能同时跑多少个节点。
2.2 按“你要做哪类项目”来倒推配置
选型号不要从预算出发,要从“项目最重的那个算法”往回推。如果你只是想学习 ROS 2 通信、写写底层驱动、跑跑 turtle 模拟器,那 Jetson Nano 的算力其实都够用,它最大的问题是内存小,开个 RViz2 再跑个点云可视化就容易卡。想做激光雷达 + 视觉融合,至少得 Xavier NX 或 Orin Nano 8GB,这两个模组能流畅跑 Cartographer、Nav2,也能在本地部署 YOLO 类检测模型。想上多线激光雷达、双相机、端侧跑大模型或检测网络,那就直接考虑 Orin NX 16GB,留给以后扩展的余地大得多。
还有一个经常被忽略的维度:开发调试时的“主观体验”。算力刚好够用的板子,编译一个 workspace 可能要好几分钟,跑起来风扇狂转,热得烫手。全栈开发本来就是一个反复修改、编译、重启的过程,机器性能多吃紧,人的耐心就多受罪。我实际用下来,Orin Nano 8GB 做车规级以外的中小型机器人项目,已经属于“舒服”的起点;预算允许直接上 Orin NX,也不会后悔。
2.3 二手板、QSPI 固件与渠道安全的提醒
因为 Jetson 模块价格不低,市场上会有二手、拆机、改装过的开发套件流通。新人很容易被“便宜两百块”吸引,结果买回来遇到两个经典问题:一是系统引导彻底坏了,开机黑屏、连 Recovery 模式都没反应;二是某些商家因为搞坏了引导芯片,试图通过更换板载 QSPI Flash 芯片来修复,普通用户拿到这种板子几乎没法自检。QSPI 芯片在 Jetson 开发套件里存放的是最底层的 bootloader 固件,正常使用完全不需要用户折腾它。
所以这里给出一个非常实际的建议:新手阶段尽量买正规渠道的全新开发套件或官方整机,系统选择官方 Jetson 镜像。省下来的那几百块,大概率会在后续“刷机刷不进去”“开机无显示”的排查中被加倍浪费掉。如果确实想玩二手,至少问清楚:能否进 Recovery 模式?能否显示 JetPack 版本号?烧录时的串口日志是否完整?这些问题比成色和价格重要得多。
3. 从刷机到点亮:JetPack 的两种路线与两个经典坑
3.1 第一次刷机:SDK Manager 和 SD 卡镜像怎么选
Jetson 刷系统有两条主流路线。第一条是用 NVIDIA SDK Manager,在另一台 x86 Ubuntu 主机上安装,通过 USB-C 线连接 Jetson,把板子切换到 Recovery 模式,然后把 JetPack 整套刷进去。这条路线适合你想定制组件、或者需要安装 CUDA/ cuDNN / TensorRT 的精确版本时使用;缺点是需要额外一台 Ubuntu 主机,过程也相对繁琐,新手在“进入 Recovery 模式”这一步就可能卡住(要在开发套件上按住 Recovery 按键再插电,不同型号按键位置不同,稍不留神就刷了个寂寞)。
第二条路线对新手友好得多:直接下载官方 SD 卡镜像(比如 JetPack 5.1.x 或 6.x 对应的 SD Card Image),用 balenaEtcher 或者 dd 命令把镜像写入一张 64GB 以上的 microSD 卡,插入开发套件直接开机。这个流程不需要额外电脑,不需要进 Recovery 模式,第一次点亮系统的成功率最高。系统起来之后,再把根文件系统迁移到 NVMe SSD 上(如果板子支持),启动速度和读写性能会比 SD 卡舒服不少。
我个人的建议是:第一周先用 SD 卡镜像把系统跑起来,把 WiFi、ROS 2、SSH 都验证一遍,然后再考虑要不要折腾 NVMe 启动。很多新手一步到位想用 SDK Manager 定制刷机,结果卡在组件选择和参数配置上,反而把“底座”阶段拉长到好几周,完全没必要。
3.2 开机没有 WiFi:硬件、网络管理器与临时联网手段
“Jetson 开机没有 WiFi”这个关键词几乎伴随每一个新手阶段,我自己第一次开机也撞上了。先别急着重刷系统,按顺序排查。
第一步看硬件。Jetson 开发套件的 WiFi 天线接口非常小,出厂时如果天线没有牢固拧紧,或者金属触点没有完全接触,信号强度会低到系统显示“找不到无线网络”。我见过一个案例,用户折腾了一个下午,最后发现只是天线没装好。用手机开热点靠近板子,如果热点可见但信号弱,大概率是天线问题。
第二步看系统网络管理器。JetPack 默认的 Ubuntu 桌面在某些版本里不会自动弹出 WiFi 面板,此时可以用nmcli命令手动连接:
nmcli device status nmcli dev wifi list nmcli dev wifi connect "你的WiFi名" password "你的密码"如果nmcli提示找不到无线设备,再检查是不是 NetworkManager 服务没起来,或者系统里压根没装对应的无线网卡固件。这一步其实比前面更常见:JetPack 精简镜像默认不启用 NetworkManager 的 WiFi 管理,桌面右上角自然就没有 WiFi 图标。
第三步,如果以上都正常但你就是急需联网,可以先插一根 USB 网线转接器,或者直接用手机 USB 共享网络。手机通过数据线接到 Jetson,在手机设置里打开“USB 网络共享”,Linux 会直接出一个 usb0 网卡,至少能保证立刻上网装包。这个方法在前期调试里非常管用,完全不需要依赖无线网络的稳定性。
3.3 没有屏幕时的串口调试兜底方案
开发套件不一定随时接着显示器,尤其机器人装起来之后,主控可能被塞在底盘里。这时候一条 USB-TTL 串口线就是你的“最后一道眼睛”。Jetson 的 40-pin 排针上通常引出了 UART0,其中 TX 接转接板的 RX,RX 接 TX,GND 必须共地。系统起来后,设备节点一般是/dev/ttyTHS0或/dev/ttyS0,在另一台电脑上用一个串口工具连上去就行:
sudo apt install screen ls /dev/ttyUSB* sudo screen /dev/ttyUSB0 115200看到L4T Console和登录提示,说明串口通了。这套思路哪怕是十年前的老 Jetson TK1 也一样适用,嵌入式 Linux 的调试逻辑从来没大变过:GUI 会崩、网络会断、SSH 可能连不上,但串口只要线接对了,总能给你吐日志。平时我把串口当作“备用诊断口”常年插着,只有等系统稳定到不需要看内核日志了,才会拔掉。
4. 把 ROS 2 装成底座:版本、DDS 与第一轮通信验证
4.1 先看 JetPack 再选 ROS 2 版本
ROS 2 的版本和 Ubuntu 版本绑定得很死,而 JetPack 又直接决定 Ubuntu 版本,所以这条对应链必须记牢:Jetson 上 JetPack 5.x 对应 Ubuntu 20.04,适合安装 ROS 2 Foxy(LTS);JetPack 6.x 对应 Ubuntu 22.04,适合安装 ROS 2 Humble(LTS)。不要跨版本硬装,跨版本要么没有预编译包,要么会遇到一堆 ABI 冲突。
这里我遇到过一个很现实的问题:很多教学视频还在讲 ROS 1 时代的老流程,告诉你apt install ros-melodic-desktop,但 ROS 1 已经停止维护,新项目完全没有理由再入坑。ROS 2 的节点通信模型一开始可能不习惯,但它解决的是 ROS 1 单机主节点的痛点,多机通信、DDS 动态发现、生命周期管理都更适合移动机器人这种“设备在动”的场景。如果你所在团队没有历史 ROS 1 包袱,直接 Humble 起步是最优解。
4.2 安装与初始化:不要跳过 source 和 bashrc
ROS 2 官方给的是 apt 安装方式,在 Jetson 的 Ubuntu 上同样适用。先加 ROS 2 软件源和密钥,然后安装桌面版或基础版。桌面版ros-humble-desktop包含 RViz、Gazebo、demo 节点,适合开发调试;如果做纯机器人部署,装ros-humble-ros-base就够。
sudo apt update && sudo apt install curl gnupg lsb-release sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update sudo apt install ros-humble-desktop装完第一件事,把环境变量写进~/.bashrc:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc这个步骤看着简单,但很多人漏了,导致每次打开终端都要手动source一遍,还总怀疑“是不是没装成功”。ROS 2 的环境变量和系统环境变量是两套体系,setup.bash负责把ros2、colcon这些命令路径以及共享库路径加载进来,不写进 bashrc 的话,新建终端就找不着命令。
验证安装是否正常,最快的方式是跑一对 talker 和 listener:
ros2 run demo_nodes_py talker ros2 run demo_nodes_py listener终端 A 在发 "Hello World" 计数,终端 B 在收数据,说明通信管道已经通了。这一步跑通了,“ROS 2 底座”才算真正成立。
4.3 DDS 切换:无线环境下最容易踩的发现延隔
ROS 2 底层默认使用基于 DDS 的实时通信协议。JetPack 上默认的 DDS 实现是 Eclipse Fast DDS(之前叫 Fast RTPS),功能完整但有一个实际体验问题:在 WiFi 网络环境里,节点之间的自动发现经常出现延迟,一个节点启动后,另一个节点需要等几十秒才能在ros2 topic list里看到,甚至偶尔直接发现不了。
这个问题在移动机器人场景特别明显,因为车上的 Jetson 通常通过 WiFi 和上位机、其他传感器通信,网络广播和组播在无线环境下不像有线那么可靠。我的处理方法是切换到 Cyclone DDS,它默认的发现机制更简洁,节点启动速度在弱网环境下有明显改善。
sudo apt install ros-humble-rmw-cyclonedds-cpp echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> ~/.bashrc source ~/.bashrc切换完成后,重复跑一次talker / listener,你会发现节点发现的响应变快了。需要提醒的是,同一个机器人系统里所有节点必须使用同一种 DDS 实现,否则通信会直接失败,官方给的RMW_IMPLEMENTATION环境变量必须所有机器统一设置。
5. 远程开发组合:SSH 为主,VNC 为辅,IP 固定是底线
5.1 SSH 免密与基础操作
机器人装起来之后,你不可能每次调试都搬个显示器跟着车跑,SSH 是远程开发的第一件工具。登录终端:
ssh 用户名@机器人IP第一次连接会提示确认主机指纹,回车输入密码即可。但天天输密码太烦,配置一把 SSH 公钥一劳永逸:
# 在开发机上执行 ssh-keygen -t ed25519 ssh-copy-id 用户名@机器人IP之后登录就不需要密码了。这一步对后续全栈开发非常关键,因为你后续大概率会写脚本自动同步代码、自动colcon build,免密是这些自动化流程的前提。
5.2 固定 IP 和主机名:多设备协作的隐形效率
移动机器人调试时经常遇到一个问题:开发机的 DHCP 给车上的 Jetson 分了一个 IP,第二天重启变成另一个 IP,你所有脚本里的 IP 白瞎了。所以固定 IP 不是“可选项”,而是开发效率底线。
最简单的方式是在路由器后台给 Jetson 开 DHCP 静态绑定,让 MAC 地址始终拿到同一个 IP。如果没有路由器管理权限,就直接改 netplan:
# /etc/netplan/01-netcfg.yaml network: version: 2 renderer: NetworkManager ethernets: eth0: dhcp4: no addresses: - 192.168.1.100/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 192.168.1.1IP 地址、网关、DNS 要按你实际路由器网段改,改完执行sudo netplan apply。同时建议给板子起一个独立主机名:
sudo hostnamectl set-hostname mobile-robot有了主机名和固定 IP,你在 SSH、VNC、后续多机 ROS 2 通信里就不容易点错设备。多台机器人同时调试的时候,这一步能救命的。
5.3 VNC 桌面:什么时候装、怎么装、性能注意
SSH 适合命令操作,但机器人开发经常需要看图形界面:RViz2 里的点云、RQT 的节点图、摄像头的实时画面。这些都是 GUI 程序,光靠 SSH 看不到。这时可以给 Jetson 装一个 VNC 服务,最简单的是 x11vnc:
sudo apt install x11vnc x11vnc -forever -shared -passwd 你的密码 -display :0然后在开发机上用任意 VNC 客户端连接机器人IP:5900。这样你在没有显示器的情况下也能看到 JetPack 桌面上正在跑的 RViz2 窗口,摄像头调试、URDF 可视化都会方便很多。
但注意一点:VNC 是通过网络传图形帧,带宽占用高,操作延迟明显。不要依赖 VNC 去跑实时导航或者大算力任务,它只适合“偶尔瞄一眼界面”和“短时图形调试”。机器人正式跑任务时,建议关掉 VNC 服务,把系统资源留给算法和传感器驱动。如果你觉得 VNC 延迟太大、画面撕裂严重,可以试试 NoMachine,它用 NVIDIA 的编码加速在 Jetson 上能流畅不少,但本质还是“远程看屏幕”,不是“远程高性能计算”。
6. 把底座接到硬件:电气链路上的几个关键理解
6.1 底盘控制并不该由 Jetson 直接负责
很多第一次做机器人的朋友会问我:能不能直接用 Jetson 的 GPIO 发 PWM 给电机驱动板,省掉单片机?答案是能,但非常不推荐。Linux 非实时、GPIO 抖动大、一旦主控死机电机就失去控制,这在移动机器人上是不可接受的。成熟的架构是三层:Jetson 负责感知决策,通过串口或 CAN 下发期望速度;中间的单片机负责 PID 闭环和电机驱动;电机编码器数据再通过单片机回传到 Jetson 供里程计使用。
实际操作中,Jetson 与底层单片机之间最常见的通信方式有两种。串口简单,数据结构自己定义,开发快,适合原型验证;CAN 总线抗干扰、支持多节点、传输距离远,适合正式产品。不管用哪种,通信协议里一定要包含:期望速度、转向角、使能/急停指令、底盘状态回传、编码器原始值,这五类信息基本覆盖了移动机器人底盘的通信需求。
6.2 读电气原理图时的四类必查信息
市面上很多移动机器人开发套件会随箱附赠底盘电气原理图,或者你从网上搜“移动机器人电气原理图”也能找到大量开源图纸。拿到一张图先不要从头读,按四个方向去找关键信息。
第一是供电链路:电池电压进来到哪个 DC-DC 降压,分出多少路电源轨,Jetson 的供电是先经过稳压模块还是直接接电源板,这个决定了你加传感器时会不会拉垮主控。第二是通信链路:哪些串口连了哪些设备,CAN 总线上挂了几片控制板,有没有共地问题。第三是电平转换:单片机侧是 3.3V 还是 5V,Jetson 的 GPIO 是 3.3V,互相连接时是否经过电平转换,接错就可能烧 IO。第四是保护电路:有没有反接保护、限流、EMI 滤波,移动机器人电机一启动,电源上的毛刺经常导致单片机重启,原理图里如果是“裸连”,后期就得自己加滤波电容。
读图的目的是建立“故障排查路线图”:机器人某个传感器不工作,你应该能根据原理图判断这条信号链路经过了哪些器件,而不是拿万用表到处乱戳。
6.3 给后续全栈功能预留的接口习惯
底座搭得好的标准,不是今天能跑起来,而是接下来加功能时不返工。基于我的经验,有三件事值得在初期预留好:一是传感器和底盘的数据接口用 ROS 2 标准消息格式,比如底盘回调用nav_msgs/Odometry、激光雷达用sensor_msgs/LaserScan或PointCloud2,这样后面接 Nav2、Cartographer 就是改参数而不是改代码;二是建立一个明确的 workspace 结构,至少区分src、build、install、log四个目录,用colcon build统一管理所有功能包;三是在一开始就把“传感器热插拔”视为常态,每个传感器用独立串口或 USB 设备节点,并在启动脚本里做好设备节点丢失的容错,因为移动机器人运行中最常见的故障就是某个 USB 摄像头掉线、某个雷达没插紧。
最后分享一点我的个人体会
如果你第一次搭 Jetson 上的 ROS 2 环境,我劝你克制住“把能装的库都装一遍、把能配的软件都配上”的冲动。我踩过最深的坑,就是一开始把 VNC、SSH、SDK Manager、多套 CUDA 版本、无敌的网络代理配置全挤在一块,结果任何一个组件更新都可能把另一个环境搞坏。全栈开发讲究的是一个“可用基线”:JetPack 版本固定,ROS 2 版本固定,机器人在局域网里的 IP 固定,远程开发方式固定,剩下的功能模块再往这条基线上加。每次加完新东西,先从 talker/listener 通信验证开始,再跑真实硬件。
底座搭起来之后,移动机器人真正的“体力活”才刚开始——底盘驱动、传感器标定、SLAM 建图、导航避障,这些都是后续系列要拆开细聊的内容。下一篇我打算接着写“底盘驱动与 ROS 2 控制”,把单片机、编码器、串口协议和ros2_control之间的那层关系说透。如果你也正在搭自己的机器人底座,欢迎把你在刷机、WiFi、ROS 2 安装上遇到的问题留在评论区,这些问题也是系列后续内容的最佳选题。