作为一名参加过三届全国大学生智能汽车竞赛的老队员,我深知建图与导航环节在整个比赛中的核心地位。讯飞组的多点导航任务看似简单,实则包含了机器人定位与导航的核心技术栈。本文将基于ROS机器人操作系统,详细拆解从环境建图到自主导航的全流程实现。
讯飞组比赛的主线任务要求智能车在未知环境中实现自主移动和任务执行,这本质上是一个典型的SLAM(Simultaneous Localization and Mapping)问题。与工业AGV不同,竞赛场景对实时性和适应性要求更高:
实际比赛中常见误区:许多队伍直接使用官方默认参数,导致在转弯半径小的区域出现轨迹震荡。建议根据小车动力学参数调整
max_vel_x(最大线速度)和acc_lim_theta(角加速度限制)。
完整的导航系统需要多个硬件模块的精确配合:
| 模块 | 型号示例 | 数据接口 | 关键参数 |
|---|---|---|---|
| 激光雷达 | RPLIDAR A1 | USB/UART | 5.5Hz@8m范围 |
| 主控板 | Jetson Nano | ROS Serial | 1.43GHz四核 |
| 底盘电机 | 直流减速电机 | PWM控制 | 减速比30:1 |
| IMU | MPU6050 | I2C | ±16g量程 |
硬件连接需特别注意:
ticks_per_meter参数匹配官方提供的ucar_map功能包支持两种主流算法:
Gmapping方案:
bash复制roslaunch ucar_map gmapping_demo.launch
Cartographer方案:
bash复制roslaunch ucar_map cartographer_start.launch
实测数据:在Jetson Nano上,Gmapping建图精度误差约±3cm,Cartographer可达±1.5cm但CPU负载超过80%。竞赛场景推荐优先使用Gmapping。
bash复制roslaunch ucar_map ucar_mapping.launch
RViz可视化配置:
Fixed Frame为mapMap显示插件,订阅/map话题LaserScan显示检查原始数据手动控制建图:
bash复制rosrun teleop_twist_keyboard teleop_twist_keyboard.py
xml复制<launch>
<arg name="filename" value="$(find ucar_map)/maps/competition_room" />
<node name="map_saver" pkg="map_server" type="map_saver" args="-f $(arg filename)" />
</launch>
.pgm:栅格地图图像(灰度值0-255对应占用概率).yaml:地图元数据(分辨率通常0.05m/pixel)
左:理想建图效果 右:存在重影的建图结果
常见问题及解决方法:
地图重影:
map_update_interval(建议0.5-1s)墙壁断裂:
particles参数(建议30-50)角落变形:
修改ucar_navi功能包的导航启动文件:
xml复制<node name="map_server" pkg="map_server" type="map_server"
args="$(find ucar_map)/maps/competition_room.yaml">
<param name="frame_id" value="map" />
</node>
关键参数调整建议:
yaml复制# local_costmap_params.yaml
inflation_radius: 0.3 # 膨胀半径设为小车宽度1.5倍
# dwa_local_planner_params.yaml
max_vel_x: 0.5 # 最大前进速度
acc_lim_x: 1.0 # 线加速度限制
改进版的Python导航控制程序:
python复制#!/usr/bin/env python3
import rospy
from geometry_msgs.msg import PoseStamped
from move_base_msgs.msg import MoveBaseActionResult
class MultiGoalNavigator:
def __init__(self):
self.goal_pub = rospy.Publisher('/move_base_simple/goal', PoseStamped, queue_size=1)
self.goal_sub = rospy.Subscriber("/move_base/result", MoveBaseActionResult, self.goal_callback)
self.goal_list = [
{"x":1.13, "y":0.62, "z":0, "qx":0, "qy":0, "qz":1.0, "qw":0.002},
{"x":1.05, "y":3.42, "z":0, "qx":0, "qy":0, "qz":0.728, "qw":0.686}
]
self.current_goal = 0
def goal_callback(self, msg):
if msg.status.status == 3: # 到达目标
self.current_goal += 1
if self.current_goal < len(self.goal_list):
self.send_goal(self.current_goal)
def send_goal(self, index):
goal = PoseStamped()
goal.header.frame_id = "map"
goal.header.stamp = rospy.Time.now()
goal.pose.position.x = self.goal_list[index]["x"]
goal.pose.position.y = self.goal_list[index]["y"]
goal.pose.orientation.z = self.goal_list[index]["qz"]
goal.pose.orientation.w = self.goal_list[index]["qw"]
self.goal_pub.publish(goal)
if __name__ == "__main__":
rospy.init_node("multi_goal_navigator")
navigator = MultiGoalNavigator()
navigator.send_goal(0)
rospy.spin()
bash复制sudo apt-get install ros-noetic-teb-local-planner
yaml复制TebLocalPlannerROS:
max_vel_x: 0.6
acc_lim_x: 0.5
min_turning_radius: 0.2
xml复制<node pkg="amcl" type="amcl" name="amcl">
<param name="odom_alpha1" value="0.05"/> # 里程计旋转噪声
<param name="update_min_d" value="0.1"/> # 最小平移更新距离
</node>
wait_time参数(如识别任务点停留3s)actionlib实现任务状态机管理rviz的PoseArray显示预设路径点问题1:地图出现鬼影
rostopic echo /scan查看是否有异常测距值maxUrange参数(建议设为实际测距的80%)问题2:建图过程中小车定位丢失
particles数量(牺牲实时性提升稳定性)xml复制<node pkg="tf" type="static_transform_publisher" name="base_to_laser"
args="0 0 0.2 0 0 0 base_link laser 100"/>
问题1:小车在目标点附近震荡
xy_goal_tolerance(建议0.05-0.1m)pdist_scale和gdist_scale权重系数问题2:无法规划出可行路径
global_costmap的inflation_layer参数planner_frequency为更高值python复制try:
move_base_client.send_goal(goal)
except rospy.ServiceException:
rospy.logwarn("Planning failed, initiating recovery...")
clear_costmaps_service.call()
场地适应性训练:
系统容错设计:
python复制def navigation_retry(goal, max_retries=3):
for i in range(max_retries):
if send_goal_and_wait(goal):
return True
rospy.logerr(f"Navigation failed, retry {i+1}/{max_retries}")
reset_costmaps()
return False
dynamic_reconfigure实现比赛时参数微调经过三届比赛的实战检验,这套建图导航方案在保证稳定性的同时,能够满足比赛对精度的严苛要求。特别是在2021年的全国总决赛中,我们通过优化TEB规划器的min_obstacle_dist参数,成功在狭窄的S形赛道中实现了零碰撞导航。