提到“具身智能”,很多人脑子里浮现的是双腿人形机器人、万元级开发套件、大厂的实验室。但在真正做机器人开发的圈子里,还有一支数量庞大、风格务实的队伍:用树莓派当大脑、用两轮底盘当身体、用 ROS2 当神经系统的个人开发者、学生和创客。我给这支队伍起了一个名字——机器人的草根阶层。
草根不是贬义。恰恰相反,草根阶层代表的是具身智能领域最活跃的一部分:预算不高但敢于折腾,算力不强但能把每一份资源都用到位。本文不会去分析哪家人形机器人融资多少,而是聚焦草根开发者真正关心的问题:低成本机器人怎么选硬件、ROS2 怎么入门、一台能自己建图导航的小车如何从零搭起来。内容覆盖硬件选型、软件生态、完整实战和排错经验,既适合刚接触机器人的新手,也适合正在做课程设计或开源项目的开发者。
1. 机器人的草根阶层:先理解这个定位
1.1 什么是机器人的草根阶层
在机器人领域,“草根阶层”并不是一个官方分类,而是一种技术路线的概括。它通常指满足以下条件的机器人:
- 总成本控制在几百到几千元级别,而不是几十万元级别;
- 核心计算平台是树莓派、Jetson Nano、ESP32 这类低成本开发板;
- 借助开源框架和社区方案,由个人或小团队完成设计、装配和调试;
- 主要目标是学习、实验、教学和轻量级应用,而不是工业量产。
与草根阶层对应的是“正规军”:工业机械臂、仓储 AGV、商用配送机器人、人形机器人。这些产品在设计上追求可靠性、安全性和量产一致性,成本高、开发周期长、部署环境相对固定。草根开发者不会去和它们正面竞争,但可以在算法验证、快速原型、交互实验领域走出一条自己的路。
1.2 为什么草根路线越来越可行
过去想做一台能自主移动的机器人,门槛确实很高:传感器贵、计算平台贵、软件框架封闭。最近几年的变化非常明显:
- 树莓派等开发板性能足够跑 Linux 和 ROS2;
- 入门级 2D 激光雷达价格大幅下降,几百元就能买到;
- ROS2 生态逐渐成熟,建图、导航、定位都有现成开源工具;
- 社区教程和开源项目数量庞大,遇到问题能找到大量讨论。
这些条件叠加在一起,让“低成本具身智能机器人实现”成为一门可以自学的工程实践,而不是只有实验室才能完成的课题。
1.3 草根机器人能做什么
一台低成本 ROS2 小车能做的事情已经不少:
- SLAM 建图:在室内环境实时构建二维栅格地图;
- 自主导航:给定目标点后,自动规划路径并避障;
- 视觉追踪:通过摄像头识别目标物体并跟着移动;
- 语音交互:接入语音识别和语音合成,做简单的口令控制;
- 多机协作:多台小车之间通过 ROS2 通信完成简单任务。
这些能力虽然达不到人形机器人的复杂度,但足以覆盖 ROS2 学习、嵌入式开发练习、毕设选题、机器人课程实验等绝大多数场景。
2. 硬件选型:草根机器人的低配与高配
硬件选型是草根机器人面临的第一道选择题。预算有限,每一分钱都得花在刀刃上。下面按照“大脑 + 感知 + 运动”三个维度展开。
2.1 大脑:树莓派 4G 还是 8G
热词里有“具身智能小车树莓派需要4g还是8g”,这说明很多人在选型时纠结内存。结论可以分成几层来看:
如果小车只跑 ROS2 基础节点、激光雷达驱动、SLAM 和 Nav2 导航,4G 内存够用。这类任务的典型内存占用在 2GB 到 3GB 左右,4G 版本不会因为内存不足导致系统卡死。
如果除了导航,还希望本地运行轻量视觉模型,例如物体检测、视觉巡线、目标跟随,8G 版本更从容。视觉模型在推理时对内存和 CPU 的要求明显更高,4G 版本容易出现 Swap 频繁、节点被系统 OOM Kill 的情况。
还要看清一个事实:树莓派最大的瓶颈不是内存,而是 CPU。8G 版本和 4G 版本在 CPU 算力上没有区别,内存大了只是减少内存压力,并不会让模型推理变快。如果核心目标是跑深度学习模型,可以考虑 Jetson Nano 这类带 GPU/NPU 的平台,或者给树莓派加一块硬件加速模块。
2.2 感知:激光雷达、摄像头与 IMU
草根小车最常见的传感器组合是 2D 激光雷达 + 单目摄像头 + 选配 IMU。
2D 激光雷达负责测距、建图和避障,是 SLAM 导航小车的主力传感器。入门级产品常见原理是三角测距,有效测距范围通常在 8 到 12 米,扫描频率 5 到 10Hz。雷达通过串口或 USB 输出数据,厂家一般提供 ROS2 驱动包。 传感器安装时要注意:雷达应尽量水平安装,不能被底盘遮挡,扫描平面要避开轮子支架和电源线。
摄像头的价值在于补充视觉信息。ESP32-CAM 是一块非常便宜的摄像头开发板,适合做独立视觉节点,但它的 WiFi 稳定性一般,长时间传输画面存在断流风险。更稳妥的做法是把摄像头直接接到树莓派 CSI 接口,或者用 USB 摄像头,把数据在本机处理,减少无线链路带来的不确定性。
IMU 不是必需品。对于差速小车,编码器 + 陀螺仪的融合能提高定位精度,但入门阶段可以先不加 IMU,把里程计和激光雷达配合好,后续再逐步引入。
2.3 运动:差速底盘与电机驱动
草根机器人的底盘方案几乎被两轮差速底盘垄断。左右两个驱动轮 + 一个万向轮,结构简单、控制模型清晰、转弯半径可以为零,对新手非常友好。
驱动电机建议选择带编码器的直流减速电机。编码器是里程计的数据来源,只有知道每个轮子转了多少圈,才能估算机器人移动距离和角度。没有编码器的电机只能做开环控制,无法支撑 SLAM 和导航。
电机驱动板负责把树莓派的控制信号转换成电机的驱动电压。常见方案有 L298N、TB6612、DRV8833 等,选择时主要看电机工作电压和峰值电流。树莓派的 GPIO 无法直接驱动电机,必须经过驱动板,否则会烧毁主板。
2.4 一套可行的低成本配置清单
| 模块 | 推荐方案 | 说明 |
|---|---|---|
| 主控板 | 树莓派 4B 4GB 或 8GB | 根据是否跑视觉模型选择 |
| 激光雷达 | 入门级 2D 激光雷达 | 选择有 ROS2 驱动的型号 |
| 底盘 | 两轮差速底盘套件 | 可购买成品底盘或自己打印 |
| 电机 | 带编码器直流减速电机 | 选测速孔数 20 或更高的型号 |
| 电机驱动 | TB6612 或同类模块 | 注意与电机电压匹配 |
| 摄像头 | USB 摄像头或 ESP32-CAM | 可选,先搭建导航再扩展 |
| 供电 | 5V/3A 电源 + 电机独立电源 | 电源线尽量短且粗 |
| 系统 | Ubuntu Server + ROS2 | 具体版本根据架构选择 |
这个清单的核心思路是“先跑通,再升级”。第一台车不需要一次配齐所有传感器,先让雷达转起来、让小车能动起来,再逐步加视觉、加机械臂、加更复杂的算法。
3. 软件生态:ROS2 为什么适合草根开发者
3.1 ROS2 和 ROS1 的区别
ROS 是机器人操作系统(Robot Operating System)的简称,它本质上是一套分布式通信框架,让不同的传感器、算法模块、执行器节点之间可以互相发送消息。ROS1 是早期版本,ROS2 是面向现代机器人应用重新设计的版本。
对草根开发者来说,选择 ROS2 的理由很直接:
- ROS1 已经停止新功能迭代,社区资源逐步迁移到 ROS2;
- ROS2 基于 DDS 通信,天然支持多机分布式部署;
- 生命周期管理更好,节点崩溃后可以自动重启;
- 支持实时性更高的应用,适合后续接机械臂和运动控制。
网上很多旧教程还在讲 ROS1,新手一定要注意版本。按照 ROS2 的新接口和启动方式学习,能避免很多“教程过期”的问题。
3.2 ROS2 学习路线:从零到能跑导航
具身智能学习路线在热词里出现频率很高,说明很多人都在找一条明确路径。以 ROS2 小车为载体,可以按下面的顺序推进:
第一步,掌握基础命令行操作:Linux 基本命令、文件权限、Vim 或 Nano 编辑器的使用。这一步不需要太深,但必须熟练,因为后面所有操作都在终端里完成。
第二步,理解 ROS2 通信机制:话题(Topic)、服务(Service)、动作(Action)、参数(Parameter)。先用ros2 topic list、ros2 node list观察系统里的节点,再写一个简单的发布订阅程序。
第三步,学会使用 launch 启动文件:多节点项目的启动不是手动开十几个终端,而是通过 launch 文件统一管理。
第四步,掌握 TF 坐标变换:底盘、雷达、摄像头之间需要建立坐标关系,TF 树错误是新手最常见的故障来源。
第五步,跑通 SLAM 与导航:先用仿真环境跑通 Cartographer 或 slam_toolbox,再把整个流程迁移到真机。
3.3 仿真先行还是真机先行
对于完全没有经验的新手,建议先在电脑上通过 Gazebo 仿真跑通一整套流程,再着手买硬件装真机。仿真的优势是成本为零、出错容易定位、可以随时重置。但仿真永远代替不了真机,真机上会遇到雷达安装不平、电机响应不一致、供电不稳、串口丢包等“充满烟火气”的问题。
推荐的路径是:仿真理解概念 → 真机搭建系统 → 两台机器对照排错 → 回到仿真做算法实验。这样既不浪费硬件成本,也不会在没有任何基础的情况下直接面对一堆硬件问题。
4. 实战:搭建一台低成本 ROS2 导航小车
4.1 项目结构与硬件连接
下面要搭建的项目是一个最小可运行的 ROS2 差速小车,包含驱动节点、里程计节点、启动文件和导航相关配置。项目名称叫robot_base。
robot_base/ ├── launch/ │ └── robot_base.launch.py ├── resource/ │ └── robot_base ├── robot_base/ │ ├── __init__.py │ ├── diff_drive_node.py │ └── odometry_node.py ├── package.xml ├── setup.py └── setup.cfg硬件接线遵循一个基本原则:信号线和电源线分离。电机驱动板需要独立电源供电,树莓派只负责输出 PWM 和方向信号,不要用树莓派的 5V 引脚去带动电机。雷达通过 USB 连接到树莓派,摄像头根据接口类型选择 USB 或 CSI。
4.2 树莓派环境准备
首先给树莓派安装 64 位 Ubuntu Server,然后安装 ROS2。不同 ROS2 版本对应的 Ubuntu 版本不同,比如 Humble 对应 Ubuntu 22.04,Jazzy 对应 Ubuntu 24.04,安装前先确认系统版本与 ROS2 版本的匹配关系。
# 更新系统软件源 sudo apt update sudo apt upgrade -y # 设置编码 echo "export LC_ALL=en_US.UTF-8" >> ~/.bashrc echo "export LANG=en_US.UTF-8" >> ~/.bashrc source ~/.bashrc # 安装 ROS2(以 common 版本为例,具体版本名替换成你安装的发行版) sudo apt install ros-humble-ros-base -y # 安装常用的导航和仿真组件,按需选择 sudo apt install ros-humble-nav2 ros-humble-slam-toolbox ros-humble-cartographer -y安装完成后,把 ROS2 环境导入到 shell 配置中:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc这里需要注意:如果使用 zsh,需要把setup.bash改成setup.zsh,后续所有环境变量导入都要保持一致。
4.3 编写差速驱动节点
驱动节点的作用是接收/cmd_vel话题上的速度指令,把线速度和角速度换算成左右轮速度,再通过电机驱动板控制电机。下面是完整的差速驱动节点代码:
#!/usr/bin/env python3 # 文件路径:robot_base/robot_base/diff_drive_node.py import math import rclpy from rclpy.node import Node from rclpy.qos import QoSProfile from geometry_msgs.msg import Twist class SimpleMotorDriver: """ 抽象的电机驱动接口。 实际项目中请根据电机驱动板型号,把 set_speed 改写成: - 串口发送指令 - GPIO + PWM 输出 - 调用厂家的 Python 库 """ def __init__(self): self.left_speed = 0.0 self.right_speed = 0.0 def set_speed(self, left, right): self.left_speed = left self.right_speed = right # TODO: 在这里调用电机驱动板 # 例如串口发送如下指令: # self.serial.write(f"L{left:.2f}R{right:.2f}\n".encode()) class DiffDriveNode(Node): def __init__(self): super().__init__('diff_drive_node') qos = QoSProfile(depth=10) self.subscription = self.create_subscription( Twist, 'cmd_vel', self.cmd_vel_callback, qos) self.wheel_base = 0.23 # 左右轮距,单位米 self.wheel_radius = 0.0325 # 驱动轮半径,单位米 self.driver = SimpleMotorDriver() def cmd_vel_callback(self, msg): v = msg.linear.x w = msg.angular.z # 差速模型:把机器人速度拆成左右轮速度 left_linear = v - w * self.wheel_base / 2.0 right_linear = v + w * self.wheel_base / 2.0 # 线速度转角速度 left_rpm = left_linear / self.wheel_radius right_rpm = right_linear / self.wheel_radius self.driver.set_speed(left_rpm, right_rpm) self.get_logger().info( f'cmd_vel -> left: {left_rpm:.3f} rad/s, right: {right_rpm:.3f} rad/s' ) def main(args=None): rclpy.init(args=args) node = DiffDriveNode() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()这段代码中的差速模型是核心。公式中左右轮线速度分别等于机器人线速度加减角速度乘以半轮距,这一步是差速底盘运动学的标准推导。wheel_base和wheel_radius必须根据真实硬件测量,建图出现畸形的核心原因之一就是这两个参数不准确。
4.4 编写里程计节点
里程计节点负责根据电机编码器数据估算机器人的位姿,发布到/odom话题。下面给出一个简化版的示例代码,方便理解数据流:
#!/usr/bin/env python3 # 文件路径:robot_base/robot_base/odometry_node.py import math import rclpy from rclpy.node import Node from nav_msgs.msg import Odometry from geometry_msgs.msg import Quaternion def yaw_to_quaternion(yaw): return Quaternion( x=0.0, y=0.0, z=math.sin(yaw / 2.0), w=math.cos(yaw / 2.0) ) class OdometryNode(Node): def __init__(self): super().__init__('odometry_node') self.odom_pub = self.create_publisher(Odometry, 'odom', 10) self.x = 0.0 self.y = 0.0 self.yaw = 0.0 self.timer = self.create_timer(0.05, self.publish_odom) def publish_odom(self): # 示例中不接真实编码器,使用固定速度演示。 # 真机接入时,请从编码器读取左右轮实际转速。 v = 0.1 # m/s w = 0.05 # rad/s dt = 0.05 self.yaw += w * dt self.x += v * math.cos(self.yaw) * dt self.y += v * math.sin(self.yaw) * dt odom = Odometry() odom.header.stamp = self.get_clock().now().to_msg() odom.header.frame_id = 'odom' odom.child_frame_id = 'base_footprint' odom.pose.pose.position.x = self.x odom.pose.pose.position.y = self.y odom.pose.pose.position.z = 0.0 odom.pose.pose.orientation = yaw_to_quaternion(self.yaw) odom.twist.twist.linear.x = v odom.twist.twist.angular.z = w self.odom_pub.publish(odom) def main(args=None): rclpy.init(args=args) node = OdometryNode() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()真机运行时,需要把v和w从编码器读取的轮速换算出来:先读取左右轮角速度,再根据轮距和轮径计算机器人线速度和角速度。这段示例代码的核心目的是说明里程计发布的数据结构,以及frame_id的使用。
4.5 编写启动文件
启动文件可以让多个节点通过一条命令同时运行,还能统一管理参数。下面是一个简单的 launch 文件:
# 文件路径:robot_base/launch/robot_base.launch.py from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='robot_base', executable='diff_drive_node', name='diff_drive_node', output='screen' ), Node( package='robot_base', executable='odometry_node', name='odometry_node', output='screen' ) ])4.6 注册可执行节点
要让上面的 Python 文件能够通过ros2 run命令启动,需要在setup.py中配置入口点。setup.py必须放在包的根目录:
# 文件路径:robot_base/setup.py from setuptools import setup package_name = 'robot_base' setup( name=package_name, version='0.1.0', packages=[package_name], data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ], install_requires=['setuptools'], zip_safe=True, maintainer='your_name', maintainer_email='your_email@example.com', description='A low-cost differential drive robot base for ROS2', license='Apache-2.0', entry_points={ 'console_scripts': [ 'diff_drive_node = robot_base.diff_drive_node:main', 'odometry_node = robot_base.odometry_node:main', ], }, )同时还需要配置setup.cfg:
[develop] script_dir=$base/lib/robot_base [install] install_scripts=$base/lib/robot_basepackage.xml内容如下:
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>robot_base</name> <version>0.1.0</version> <description>A low-cost differential drive robot base for ROS2</description> <maintainer email="your_email@example.com">your_name</maintainer> <license>Apache-2.0</license> <buildtool_depend>ament_python</buildtool_depend> <depend>rclpy</depend> <depend>geometry_msgs</depend> <depend>nav_msgs</depend> <export> <build_type>ament_python</build_type> </export> </package>工作空间编译和运行的命令如下:
# 假设你的 ROS2 工作空间在 ~/ros2_ws cd ~/ros2_ws/src git clone <你的robot_base仓库地址> cd ~/ros2_ws colcon build --packages-select robot_base # 启用工作空间 source install/setup.bash # 启动小车 ros2 launch robot_base robot_base.launch.py4.7 接入雷达并验证主题数据
驱动节点跑起来后,接下来连接激光雷达。这里的命令因雷达型号而异,以你手里雷达的厂家驱动包为准。通常流程是:
# 查看雷达串口设备是否识别 ls /dev/ttyUSB* # 给设备添加读取权限 sudo chmod 666 /dev/ttyUSB0 # 启动雷达驱动节点 ros2 launch <雷达驱动包名> <驱动launch文件名>.launch.py启动后,在另一个终端查看当前所有话题:
ros2 topic list正常情况下应该能看到/scan、/odom、/cmd_vel等话题。用下面的命令检查雷达数据是否正常:
ros2 topic echo /scan --once如果/scan有数据输出,说明雷达已经正常工作。接着可以进入建图和导航阶段。
4.8 使用 SLAM 建图
建图的目标是让机器人在地图中移动,实时生成环境地图。这里以slam_toolbox为例:
# 启动 SLAM ros2 launch slam_toolbox online_async_launch.py # 打开一个新的终端,手动控制小车移动 # 控制前先检查小车驱动节点是否在运行 ros2 run teleop_twist_keyboard teleop_twist_keyboard控制小车在环境中缓慢走一圈,尽量覆盖房间的四个角落和墙壁边缘。建图过程中注意观察 Rviz 中的点云和轨迹线是否重合,如果地图出现重影或漂移,八成是里程计不准、速度过快或者雷达数据时间戳异常。
完成建图后保存地图:
ros2 run nav2_map_server map_saver_cli -f ~/maps/home_map保存后会在~/maps目录下生成home_map.pgm和home_map.yaml两个文件。前者是栅格图,后者是地图的元数据。
4.9 启动 Nav2 导航
导航阶段需要保证 TF 树完整、地图准确、代价地图参数合理。启动命令常见形式如下:
ros2 launch nav2_bringup bringup_launch.py map:=~/maps/home_map.yaml启动完成后,在 Rviz 中打开 Nav2 面板,点击2D Goal Pose,在地图上指定一个目标点。小车应当规划出一条路径,并沿着路径走过去。
如果导航失败,优先检查四个环节:
/cmd_vel是否有输出;- 驱动节点是否真正执行了速度控制;
- 里程计数据是否平滑;
- 地图与真实环境是否对齐。
5. 常见问题与排查思路
5.1 问题排查速查表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 树莓派 SSH 连不上 | 未开启 SSH 服务或 IP 地址变化 | 检查网络、开启 SSH、使用串口登录确认 IP |
雷达节点启动后无/scan数据 | 串口权限不足或驱动包与型号不匹配 | 执行sudo chmod 666 /dev/ttyUSB0,确认驱动包版本 |
| TF 树报错 extrapolation | 时间戳不同步或父坐标系设置错误 | 使用ros2 run tf2_tools view_frames检查 TF 树 |
| 建图出现重影 | 里程计不准、轮径或轮距参数错误 | 重新测量轮径和轮距,修正驱动节点参数 |
| 导航时路径规划失败 | 代价地图参数不合适或地图未对齐 | 检查地图文件原点配置,适当膨胀地图 |
| 树莓派 CPU 占用过高 | 节点太多或图像处理任务过重 | 减少节点数量,关闭不必要的可视化 |
| 电机不转但节点运行正常 | 驱动板电源不足或 PWM 配置错 | 检查电机独立电源和 GPIO 接线 |
5.2 树莓派 4G 运行卡顿怎么办
如果小车在运行 Nav2 和 SLAM 时出现明显卡顿,可以先怀疑节点数量过多。nav2会启动大量子节点,占用不少内存和 CPU。排查方法是执行top命令查看进程占用,把不需要的节点关掉,例如在 Rviz 中没有使用的 Nav2 View 模块。
如果 4G 内存确实不够用,可以考虑两个方向:
- 把建图和导航放在 PC 上处理,树莓派只负责驱动电机和采集雷达数据;
- 升级到 8G 版本,或者换一台算力更强的开发板。
5.3 为什么里程计漂移这么严重
里程计漂移的根源是编码器只能测量轮子转过的角度,无法感知轮子打滑、地面摩擦变化、电池电压波动。差速小车在一段时间后位姿误差累积,导致地图歪斜。缓解方法包括:
- 测量准确的车轮直径,不要用卡尺量完就不管,要结合实际打滑情况微调;
- 车速尽量平稳,避免急加速急刹车;
- 后期引入 IMU,通过传感器融合修正角速度积分误差;
- 在导航定位阶段使用 AMCL 或 Nav2 自带定位模块纠正累计误差。
6. 最佳实践与工程建议
6.1 先跑仿真,再上真机
没有仿真经验就直接组装真机,是做机器人最容易踩坑的路径。Gazebo 的好处是能在半小时内把上面整套流程跑一遍,你可以在仿真里熟悉 ROS2 的通信机制、launch 文件、SLAM 参数、Nav2 配置。等这些概念都清楚了,再面对真机上的硬件问题,思路会清晰很多。
6.2 把代码做成包,而不是堆脚本
初学者容易把所有逻辑写在一个大 Python 文件里,用ros2 run直接启动。工程化一点的写法是按包组织:驱动节点、里程计节点、传感器驱动、接口定义分开,用 launch 文件统一编排。这样做的好处是单个节点出错时定位快,后续替换传感器或底盘时也不需要重写全部代码。
6.3 重视 TF 树的正确性
导航系统对 TF 树的要求非常严格。base_link、odom、map、laser之间的关系必须明确,命名不能随意改。出现定位或导航异常时,先用下面的命令导出当前 TF 树:
ros2 run tf2_tools view_frames然后查看生成的frames.pdf,对照官方文档检查每个坐标系的父子关系。
6.4 电源管理不能省
低压机器人最容易出现的问题是电源供电不足。电机启动瞬间电流很大,如果电机和树莓派共用电源,电压骤降会导致树莓派重启。建议使用两路独立电源:
- 一路给树莓派和雷达,要求 5V 稳定输出;
- 一路给电机驱动,电压根据电机参数选择。
接线凌乱时,可以在雷达数据出现异常或建图重影时优先检查电源线是否接触良好。很多“诡异问题”的根因只是某根杜邦线松了。
6.5 日志、参数与可复现性
ROS2 的参数系统非常有用。像wheel_base、wheel_radius、雷达话题名、坐标系名这些经常变化的量,不要硬编码在源码里,而应该通过 yaml 参数配置文件传入。这样换一台车、换一套传感器时只需要改配置,不需要动代码。
节点启动时注意保留日志,output='screen'适合开发调试,长时间运行时建议将日志写入文件,方便回溯。
6.6 实验安全
任何涉及电机、电池、运动部件的实验都存在安全风险。做实验前先确认底盘不会碰撞到人或贵重物品,最好在桌面上加装急停开关。电机调试时先用小电压小功率验证逻辑,再逐步提高功率。电池充电时必须有人在场,不要过充过放。
7. 下一步学习路线
从这台低成本 ROS2 小车出发,可以继续走的方向很多:
- 机械臂:在底盘上增加机械臂,实现“移动 + 抓取”的复合操作;
- 视觉导航:把 Navigation 从纯激光导航升级为视觉导航,或者在导航中引入视觉避障;
- 控制算法:研究 MPC、纯追踪、LQR 等底层运动控制算法;
- 多机系统:多台小车组队通信,完成集群搬运或协同探索;
- 具身智能数据:将小车采集到的图像、里程计、雷达数据整理成数据集,训练端到端控制模型。
具体学习顺序上,建议先补三角学和线性代数的直觉,再看机器人运动学,然后刷一遍 ROS2 官方教程,最后回到真机迭代。草根路线的优势在于试错成本低,坏了就修,参数错了就改,这种快速反馈是学习机器人最好的方式。
7.1 给新手的五个建议
第一,不要追求一步到位。第一台车能把键盘遥控跑通,就算成功;能建图,就是进阶;能导航,已经超过多数入门玩家。
第二,多读报错信息。ROS2 的日志比 ROS1 更规范,报错信息里通常直接给出问题节点和原因,不要复制粘贴到搜索引擎之前先读完最后几行。
第三,版本一致很重要。硬件型号、Ubuntu 版本、ROS2 版本、驱动包版本,任何一个不匹配都可能导致诡异问题。每台设备都记录版本信息,很多人排查了一整天最后发现是依赖版本不兼容。
第四,控制车速和加速策略。草根小车的算力有限,导航中的速度反馈对 CPU 占用影响很大,适当降低最大线速度和角加速度,能明显减少建图漂移。
第五,把问题拆成节点来看。机器人系统出问题时,先判断是传感器节点、驱动节点、算法节点还是通信问题,定点排查,而不是把整个系统拆掉重来。
折腾机器人本来就是不断把小问题逐个解决的过程。草根阶层手里没有昂贵的设备,但有完整的开源生态和极高的试错自由。把一台几百块的树莓派小车调通,过程中学到的东西,往往比直接使用一台高端开发套件要多得多。