☰
基于激光雷达的履带式ROS小车避障实现与调试全攻略
2026/9/28 6:59:13 网站建设 项目流程

1. 项目概述与总体设计

1.1 为什么选择履带底盘做ROS小车

这两年我前前后后做了三台ROS小车,从麦轮车到舵轮车再到这台履带车,如果让我给新手朋友推荐一个最容易出成果、跑起来最稳的平台,履带车绝对排第一。原因很简单:不挑地面,室内瓷砖、室外柏油路、草地、甚至有点小坡度的土路,它都能走,而且底盘结构简单、装起来省事,不需要像麦轮那样去精细调轮子角度,也不像舵轮那样要考虑复杂的转向机构。

这台履带车的硬件成本控制在一千五百块以内,核心组件包括:铝合金履带底盘一套、带编码器的直流减速电机两个、电机驱动板一块、Jetson Nano开发板(如果你预算紧张换成树莓派4B也完全没问题)、思岚RPLIDAR A1激光雷达一台,再加上一块12V锂电池和若干杜邦线。

选型的时候我最看重的是编码器。没有编码器的电机,你只能发速度指令,车轮实际转没转、转多快你完全不知道,这在做避障和后续的建图导航时是致命的短板。带编码器的电机可以让ROS读取到真实的轮速反馈,实现闭环控制,也能靠轮式里程计估算小车位置。这个钱不能省。

1.2 整体架构:从传感器到执行器的数据流

这套系统的数据流是典型的ROS发布订阅模式:激光雷达不停扫描周围环境,把距离数据以/scan话题发布出来;里程计节点读取编码器数据,计算小车的位移和速度,发布到/odom话题;避障节点同时订阅这两个话题,根据激光雷达测到的距离信息判断前方是否有障碍物,如果发现障碍物,就计算一个绕行方向,把新的速度指令发布到/cmd_vel话题;底盘驱动节点订阅/cmd_vel,把速度指令解析成左右电机的PWM值,最终驱动电机转动。

这里有一个很多新手容易想歪的点:避障不是把障碍物"识别"出来再去躲避,而是一个纯反应式的过程。代码只关心"某个方向上有没有东西、距离多远",然后根据障碍分布调整行进方向。不涉及目标检测、不涉及语义分割,激光雷达返回的只是一串距离值,我们拿这串距离值做判断即可。

对于"自动驾驶"这个概念,我得说句实在话:ROS小车上的自主导航和真正的自动驾驶汽车是两码事,但核心思想一脉相承。你在这台小车上实现的避障算法,本质上是自动驾驶里"局部路径规划"这个模块的简化版。把小车换成正儿八经的汽车,把激光雷达换成多线雷达,把电机换成线控底盘,框架依然成立。这也是这个项目最有学习价值的地方。

2. 开发环境与基础准备

2.1 ROS版本选择:别再纠结,直接上对应版本

ROS安装问题劝退了不知道多少人,我最早就是死在安装这一步上。先说结论:

  • 你用的是Ubuntu 20.04,就装ROS Noetic,这是ROS1最后一个长期支持版本,资料最多、遇到问题最容易搜到答案;
  • 你用的是Ubuntu 22.04,就装ROS2 Humble,这是目前主流的中长期支持版本;
  • 你用的是树莓派官方系统或者某些ARM架构的板子,优先考虑Ubuntu Server + ROS2。

我在Jetson Nano上用的是Ubuntu 20.04 + ROS Noetic,所以下面的内容都基于这个组合。如果你问ROS1和ROS2到底选哪个,我建议:学习用ROS1(资料多),新项目起步直接用ROS2(官方主推),但本文为了配合避障代码的简洁性,采用ROS1 Noetic的写法。

2.2 鱼香ROS一键安装:新手最大的福音

讲真,ROS的安装教程在网上一搜一大把,但绝大多数都过时了。早几年装ROS最痛苦的是添加软件源、导入GPG密钥、处理各种依赖冲突,光这些就能折腾一整天。现在有了鱼香ROS的一键安装脚本,这个痛点被彻底解决了。

wget http://fishros.com/install -O fishros && . fishros

运行之后会弹出菜单,选择对应的ROS版本安装即可。脚本会帮你把换源、添加密钥、安装依赖、初始化rosdep这些步骤全部搞定。我在三台不同环境(Jetson Nano、虚拟机、实体PC)上都用过这个脚本,没有一次翻车。

重要提示:安装ROS时建议把虚拟机内存调到4GB以上、硬盘空间预留20GB以上。Noetic完整版桌面安装大概要占6~8GB空间,如果空间预留不够,中途磁盘满了会留下一堆半装状态的依赖包,后面修起来极其痛苦。

2.3 创建工作空间:三个基础命令

ROS的代码组织方式是工作空间(workspace),我习惯把它叫"catkin工作空间"。新手一定要动手敲一遍,理解这三行命令背后的逻辑,因为这决定了你后面所有代码放在哪、怎么编译。

mkdir -p ~/tracked_robot_ws/src cd ~/tracked_robot_ws/src catkin_init_workspace cd ~/tracked_robot_ws catkin_make

这里说一下为什么用catkin_make而不是catkin build:前者是ROS1最经典的编译方式,配置简单、不需要额外安装catkin_tools,适合新手;后者功能更多、支持并行编译加速,适合大型项目。对于这个小车项目,catkin_make完全够用。

还有一个细节:编译完成后source ~/tracked_robot_ws/devel/setup.bash这行命令要加到~/.bashrc里,不然每次打开新终端,系统都不知道你自定义的这些ROS功能包在哪。

2.4 硬件连接与串口权限配置

底盘驱动的硬件连接相对直接:两个直流减速电机的电源线接到驱动板的电机输出端口,编码器信号线(一般是A相、B相、VCC、GND四根)接到驱动板的编码器接口或Jetson Nano的GPIO/UART端口。具体的接线方式因驱动板型号而异,我这里用的是常见的一体化电机驱动板,已经集成了编码器读取和PWM输出功能,板子通过USB转串口模块连接到Jetson Nano。

这里最大的坑是串口权限。Linux默认情况下,普通用户没有权限直接访问USB串口设备,你会碰到权限不足之类的报错。解决方法是把当前用户加到dialout用户组:

sudo usermod -a -G dialout $USER

改完之后需要注销重新登录才能生效。这一步不做,后面跑驱动节点的时候会莫名其妙地打不开串口,排错排半天找不到原因。

确认设备是否被识别:

ls -l /dev/ttyUSB*

如果看到ttyUSB0之类的设备,说明驱动板已经被系统识别了。如果你插上板子却看不到任何ttyUSB设备,先检查USB线是不是只有供电没有数据,这种线市面上太多了,我踩过这个坑。

3. 激光雷达驱动与数据接入

3.1 RPLIDAR A1驱动安装与测试

思岚的RPLIDAR A1是入门级激光雷达里性价比极高的一款,360度扫描、测距范围0.15米到12米、采样频率约每秒8000次,对这个项目来说绰绰有余。驱动安装最省事的方式是直接用官方提供的ROS功能包:

cd ~/tracked_robot_ws/src git clone https://github.com/Slamtec/rplidar_ros.git cd ~/tracked_robot_ws catkin_make

装好之后,把雷达的USB线插到Jetson Nano上,先给雷达权限再启动驱动节点:

sudo chmod 777 /dev/ttyUSB0 roslaunch rplidar_ros rplidar.launch

正常情况下,终端会输出雷达固件版本、串口波特率等信息,然后开始持续发布/scan话题。

注意:RPLIDAR A1在ROS下的串口默认是/dev/ttyUSB0。如果你同时插了其他USB串口设备(比如下面要提到的底盘驱动板),雷达可能变成ttyUSB1。这时候需要修改rplidar.launch里的serial_port参数,把端口改成实际对应的那一个。

验证雷达数据是否正常,最直观的方式是打开rviz:

rviz

在左下角把Fixed Frame(固定坐标系)改成laser,然后点Add添加一个LaserScan显示,Topic选/scan,立刻就能看到周围环境的激光扫描轮廓。

3.2 用RViz可视化:真机调测的第一块试金石

看到雷达点云扫出房间轮廓的那一瞬间,整个项目就活了一半。我调试时最常用的验证方法:人站在雷达旁边,看屏幕上对应方向的距离值是否缩短;拿一块纸板在雷达前方0.5米处晃动,看rviz里对应角度是否出现了密集的点。这些动作能帮你快速确认雷达硬件工作正常、数据话题发布正常、坐标系配置正确。

RViz的操作有几个容易卡壳的地方:

  • Fixed Frame下拉框里找不到laser,多半是雷达节点没有成功启动,看看终端有没有报串口错误;
  • 添加LaserScan之后显示一堆散乱的点,但看不到连续的扫描线,这是因为雷达数据中某些角度的距离值不合法(值无穷大),在rviz的LaserScan显示属性里把Size调小、Style改成Points(点)就会清爽很多;
  • 雷达扫描出的房间轮廓是"歪"的,这通常是雷达安装角度问题,不是软件问题,重新固定一下雷达支架就好。

3.3 里程计发布:让小车知道自己走了多远

纯靠激光雷达数据做避障也能走,但你会发现小车在转向时对转弯角度的控制很"生硬":转多转少全靠蒙。加上里程计之后,避障程序就能知道"我弯过去了多少度、还要继续转多少度",控制精度和流畅度会上一个档次。

里程计计算的原理不复杂:编码器输出脉冲信号,电机每转一圈产生固定的脉冲数,驱动板把脉冲数换算成轮子转过的距离;左右轮子的距离差再推导出小车的角位移。这部分代码属于底盘驱动包的内部逻辑,ROS层面只需要接收一个累计了位姿信息的nav_msgs/Odometry消息。

如果做避障时你不想引入里程计,可以做一个简化版:用"原地旋转固定时长"来模拟固定角度的转弯(比如cmd_vel发0.3rad/s的角速度,持续1秒大约转17度)。这种办法不是不行,但误差累积很快,转几次弯之后方向就偏得没法看了。所以我建议:既然硬件上有编码器,就老老实实把里程计跑起来,这个模块后面做建图导航也必须要用。

4. 激光雷达避障代码实现

4.1 避障策略设计:先想清楚"避"的逻辑

写代码之前先想清楚策略。一个实用的反应式避障策略是:

  1. 把雷达扫描范围(0~360度)分成三个区域:前方(-30度到+30度)、左方(30度到90度)、右方(-90度到-30度);
  2. 分别计算每个区域内的最小障碍物距离;
  3. 如果三个区域的最小距离都大于安全阈值(比如0.35米),说明前方畅通,小车直行;
  4. 如果前方有障碍但侧方有空间,优先向空间更大的那一侧转弯;
  5. 如果三个区域都被障碍堵死,原地旋转180度掉头。

这个策略对应到真实场景里很好理解:小车在走廊里走,雷达发现前方3米处有墙,左侧距离2.5米、右侧距离1米,程序做出决策"优先左转",因为左侧空间更大。转弯不是把角度锁定死,而是边转边用雷达实时确认"侧前方是否打开",一旦发现前方又通了,就先回正方向继续前进。

这个方法不完美,比如它没法在"先进后退再转弯"的组合动作中做全局路径规划,但做为一个起步级避障算法,它能保证小车在大部分室内环境下不会长时间陷入死胡同。

4.2 代码拆解:Python版避障节点

下面给出一个可以直接跑起来的避障节点。把下面的代码保存为avoidance.py,放在你的功能包scripts目录下。

#!/usr/bin/env python3 import rospy import math from sensor_msgs.msg import LaserScan from geometry_msgs.msg import Twist class ObstacleAvoidance: def __init__(self): rospy.init_node('obstacle_avoidance_node', anonymous=True) # 发布速度指令到/cmd_vel话题 self.cmd_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1) # 订阅激光雷达的扫描数据 self.scan_sub = rospy.Subscriber('/scan', LaserScan, self.scan_callback) # 安全距离阈值,单位:米 self.safe_dist = 0.35 # 小车的最大线速度和角速度 self.linear_speed = 0.15 self.angular_speed = 0.4 # 分别保存前方、左方、右方的最小障碍距离 self.front_min = float('inf') self.left_min = float('inf') self.right_min = float('inf') self.scan_received = False def scan_callback(self, msg): # 一次扫描的角度范围,单位:弧度(通常是从0到2*pi) angle_min = msg.angle_min angle_increment = msg.angle_increment ranges = msg.ranges self.front_min = float('inf') self.left_min = float('inf') self.right_min = float('inf') for i, r in enumerate(ranges): # 跳过无效数据(nan、inf、或者极小值) if not math.isfinite(r) or r < 0.01: continue angle = angle_min + i * angle_increment # 把角度映射到 -pi ~ pi 范围,方便判断 while angle > math.pi: angle -= 2 * math.pi while angle < -math.pi: angle += 2 * math.pi if -math.radians(30) <= angle <= math.radians(30): self.front_min = min(self.front_min, r) elif math.radians(30) < angle <= math.radians(90): self.left_min = min(self.left_min, r) elif -math.radians(90) <= angle < -math.radians(30): self.right_min = min(self.right_min, r) self.scan_received = True def decide_and_move(self): if not self.scan_received: rospy.logwarn("等待激光雷达数据...") return cmd = Twist() # 策略判断 if self.front_min > self.safe_dist: # 前方畅通,直行 cmd.linear.x = self.linear_speed cmd.angular.z = 0.0 else: # 前方有障碍,停一下再转弯 cmd.linear.x = 0.0 # 优先转向空间更大的一侧 if self.left_min >= self.right_min: cmd.angular.z = self.angular_speed # 左转 else: cmd.angular.z = -self.angular_speed # 右转 self.cmd_pub.publish(cmd) def run(self): rate = rospy.Rate(10) # 10Hz控制频率 while not rospy.is_shutdown(): self.decide_and_move() rate.sleep() if __name__ == '__main__': try: node = ObstacleAvoidance() node.run() except rospy.ROSInterruptException: pass

这段代码的逻辑很清晰:scan_callback里做数据预处理和分区最小距离计算,decide_and_move里根据三区距离做决策,主循环以10Hz的频率持续发布控制指令。

为什么控制频率选10Hz?这要看雷达的扫描周期。RPLIDAR A1完成一圈360度扫描大约需要100多毫秒(8Hz左右),如果控制指令发太快(比如50Hz),会出现"雷达数据还没更新,程序却拿着旧数据反复做决策"的问题;如果太慢(比如2Hz),机器人对突发障碍的反应会严重滞后。10Hz是个兼顾实时性和稳定性的折中值。

4.3 功能包配置:CMakeLists和package.xml

光有Python脚本还不够,ROS要求每个功能包都有正确的配置。你要在功能包目录下确认CMakeLists.txt中有这么一段(确保Python脚本能被找到并赋予执行权限):

catkin_install_python(PROGRAMS scripts/avoidance.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )

同时在package.xml中声明依赖:

<build_depend>rospy</build_depend> <build_depend>sensor_msgs</build_depend> <build_depend>geometry_msgs</build_depend> <exec_depend>rospy</exec_depend> <exec_depend>sensor_msgs</exec_depend> <exec_depend>geometry_msgs</exec_depend>

注意:rospy是Python版本的ROS客户端库,如果你用C++,对应的依赖是roscpp。

改完配置记得编译一下:

cd ~/tracked_robot_ws catkin_make chmod +x src/你的功能包/scripts/avoidance.py

chmod +x这步经常被新手漏掉,漏掉的后果是运行节点时报"Permission denied",到时候一脸懵。

4.4 让小车动起来:三终端联调法

运行整个系统需要三个终端:

  • 终端1:启动激光雷达驱动
roslaunch rplidar_ros rplidar.launch
  • 终端2:启动底盘驱动(把cmd_vel话题的指令转成电机PWM)
roslaunch tracked_robot_bringup tracked_robot_base.launch
  • 终端3:启动避障节点
rosrun 你的功能包 avoidance.py

如果一切正常,你会看到避障节点在终端里输出"等待激光雷达数据..."之后就不再刷屏,小车在远端手动推一下(或者直接用键盘控制节点teleop_twist_keyboard测试底盘是否响应),确认底盘能收到cmd_vel。

经验之谈:第一次联调时,把小车架起来、让履带悬空,先不要放地上跑。手动给一个速度指令,观察两个履带的转向是否一致。如果左转时右履带正转、左履带反转,说明电机方向接反了,在底盘驱动代码里把对应电机的方向标志位取反即可,不用改接线。

5. 整机调试与常见问题排查实录

5.1 雷达数据正常但小车不动的排查路径

这是我被问得最多的问题。出现"激光雷达有数据、避障节点也启动了、但小车死活不动"的现象,90%的情况是以下三个原因之一:

  • cmd_vel话题没有连接:避障节点发布的是/cmd_vel,但底盘驱动节点订阅的可能是/cmd_vel,也可能因为它启动时定义了不同的命名空间,导致没有匹配上。用rostopic info /cmd_vel查看发布者和订阅者的数量,发布者应该至少有1个,订阅者至少有1个,如果某一侧是0,就说明话题没有对上。
  • 底盘驱动节点没有收到指令:用rostopic echo /cmd_vel查看当前速度指令的实时数值。如果一直显示零,说明避障节点的决策逻辑根本没有产生"直行"指令,检查雷达数据里front_min的值,是不是一直接近0或者无穷大。
  • 驱动板没有进入使能状态:很多电机驱动板有使能引脚,默认状态下电机是不通电的,需要驱动代码主动拉高使能信号。这个看驱动板的说明文档,单独写一个测试节点发送恒定速度指令,排除避障代码的干扰,直接验证底盘驱动链路是否完整。

排查的顺序建议是:先绕开避障程序,用键盘控制节点或命令行直接发速度指令,确认底盘能转,再上避障程序,一层层往上测。

5.2 "激光雷达建图飘"的问题

标题的热搜词里就有"激光雷达建图飘",这个问题在做建图时几乎人人都会遇到。所谓"飘",指的是rviz里看到的激光扫描点云和实际环境对不上,比如笔直的墙面显示成了波浪形曲线,或者扫描点云在移动过程中整体产生漂移。

建图飘的根因通常有三个层面:

  • 里程计不准:轮子打滑、编码器数据有噪声、底盘结构松动,都会让里程计计算出的位姿和真实位姿产生偏差。履带车在这方面比轮式车更容易飘,因为履带转向时和地面的摩擦更复杂。排查办法:让小车原地旋转90度,看rviz里里程计是否也显示转过了大约90度,如果明显偏多或偏少,需要校准轮距和编码器分辨率参数。
  • 雷达数据的时间戳不同步:建图算法把雷达数据和里程计数据按时间戳对齐,如果雷达驱动节点和底盘驱动节点的主机时间不一致,数据就会错位。尤其在Jetson Nano这类没有内置实时时钟的板子上,每次开机时间可能都是错的,建议先sudo apt install chrony做一下时间同步,或者至少手动date确认系统时间是对的。
  • 雷达本身的安装位置或角度有误:雷达倾斜、雷达在rviz里的TF变换没有配置对,会导致扫描出的地面反射点被当成墙面点云,看起来就像"飘"。

处理思路是先排除最伤元气的那个问题:先让小车静止,看激光数据还会不会飘。如果静止时点云稳定,说明雷达硬件没问题,问题出在运动中的里程计或坐标变换上;如果静止时点云都在跳,先查供电,雷达的电压不稳定会导致测量异常,换一根质量好一点的USB线或者用一个带屏蔽的电源模块。

5.3 避障节点消耗CPU过高怎么办

Jetson Nano的CPU算力有限,跑避障节点的时候如果整机负载过高,会直接影响电机控制的实时性。我遇到过一次:避障代码和可视化界面全开,CPU占用率直逼90%,小车反应明显变"肉"。

排查后发现主要耗CPU的是rviz的3D渲染和雷达数据可视化,不是避障算法本身。优化手段有几个:

  • 避障调试期间不要开rviz,用rosrun rqt_console或者直接订阅/scan话题看数据摘要就够了;
  • 降低雷达相关可视化的话题频率,比如rviz里把LaserScan的Decay Time调大,减少每帧点云的点数;
  • 在避障节点里做一次降采样,不需要处理全360度的所有点,比如每隔2度取一个点,计算量可以直接砍一半,对精度影响不大。

5.4 常见问题速查表

现象可能原因解决办法
串口设备找不到USB线是充电线不支持数据换一根数据线
雷达有数据但距离全为0雷达供电不足或USB接触不良检查供电电压,重插USB
/cmd_vel有数据但电机不动驱动板未使能或PWM通道接反查看驱动板文档,检查使能信号和PWM极性
左转和右转方向颠倒左右电机的方向标志位配置反了在驱动代码里对调两个电机的方向参数
避障时小车频繁原地打转安全距离阈值设置过大把safe_dist从0.5调低到0.35再试
雷达点云在rviz里只有一半雷达在某个角度被遮挡,或串口丢包检查雷达周围是否有遮挡物,换短线材重试
建图时地图越来越歪里程计不准或时间不同步先校准里程计,再检查系统时间同步
履带跑偏严重两侧电机转速不一致测量左右履带实际转速,做PWM补偿
电池掉电太快驱动板待机态功耗过高加一个机械开关,不用时彻底断电

6. 后续扩展方向与个人总结

6.1 从避障到建图导航:下一站怎么走

避障跑通之后,自然就会想给小车上"地图"能力。最推荐的下一步是用Gmapping或Cartographer做SLAM建图,然后用move_base做自主导航。

热搜词里出现"ros2+cartographer+激光雷达建图并保存",其实这套在ROS1下也能做。流程大概是:

# 启动底盘驱动 roslaunch tracked_robot_bringup tracked_robot_base.launch # 启动激光雷达 roslaunch rplidar_ros rplidar.launch # 启动gmapping建图 roslaunch my_navigation gmapping.launch

然后你控制小车在房间里慢慢走一圈(用teleop_twist_keyboard),边走路边建图,房间的轮廓就会逐渐出现在rviz的地图视图里。建完保存:

rosrun map_server map_saver -f ~/maps/room1

这会生成room1.pgm和room1.yaml两个文件,前者是图像格式的地图,后者是地图的元信息(分辨率、原点坐标、占用阈值等)。

有了地图之后,再用AMCL做定位,用move_base发布目标点,小车就能自己规划路径并避开动态障碍物了。这个过程全部走通,你对ROS的导航栈就算有完整理解了。

6.2 把激光雷达点云用起来:给你的车加"眼睛"

避障代码里用到的LaserScan消息本质上是一个一维距离数组。但如果想识别更复杂的环境特征(比如识别行人、区分桌椅腿),就需要升级到点云数据处理。方法也不难:把LaserScan用laser_geometry的projectLaser函数投影成PointCloud2,然后用pcl库做聚类、分割、特征提取。

我自己在第二版小车上就加过一个简单的"腿检测"模块:把点云中高度在0.2到0.6米之间的点聚类,每个聚类的点数达到一定阈值就认为是一个"潜在的人腿"。这个玩法很适合用来扩展避障策略,比如遇到人时不是急停而是减速绕行,体验立刻不一样。

6.3 个人踩坑总结

最后说几个我在整个过程中最有体感的坑,每一个都花了我不少时间:

  • 串口权限的坑:无论雷达还是底盘驱动,只要通过USB串口通信,都要先把dialout用户组加上。我第一台小车因为忘做这一步,反复折腾了两天,最后排查到问题竟然这么简单。
  • ROS工作空间路径的坑:写避障节点的时候,如果提示ModuleNotFoundError找不到自定义的ROS消息,八成是没有source对devel/setup.bash,或者工作空间没有编译成功。排查顺序:先catkin_make看有没有报错,再echo $ROS_PACKAGE_PATH确认环境变量包含了你的工作空间路径。
  • 雷达供电的坑:RPLIDAR A1对供电电压比较敏感,如果你的USB口供电能力不足(比如通过USB HUB转接),雷达会间歇性丢数据。最优做法是雷达单独用一个5V/1A的电源模块供电,USB线只负责数据通信,不承担供电任务。
  • 电机编码器线的坑:编码器的信号线很长的情况下容易受到电机电流的干扰,导致里程计脉冲数乱跳。如果你的里程计数据在电机转起来之后明显异常,试着把编码器线绞合(双绞线结构),或者远离电机电源线布线。

这个项目做到最后,最大的感受是:ROS小车的难点不在任何一个单独环节,而在于把硬件、驱动、算法、调试串起来的那套"系统工程"能力。你装好了ROS、点亮了雷达、跑通了电机,这些单独看都不难,难的是让它们像一个团队一样协同工作。把这套协同能力练好,后面不管是做建图、做导航、还是做机械臂控制,底子都能用得上一辈子。

我后来把避障代码里的安全距离参数从固定值改成了动态值:车速越快,安全距离越大。这个改动通过一个简单的线性关系实现,safe_dist = 0.25 + 1.5 * current_speed。效果立竿见影——小车在高速直行时刹车距离明显变短,不再一头怼上障碍物才慢慢转向。一个小小的参数改动,体验提升了一个档次,这也是做机器人项目最让人上瘾的地方:一个数值的变化,就能让机器的"性格"发生变化。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询