1. 素材准备
1.1 地图验证
- 在建图完成后(已生成完整地图),保存地图:
# 生成my_map.pgm(地图图像)和my_map.yaml(地图配置)
rosrun map_server map_saver -f ~/catkin_ws/map/my_map
- 检查地图质量:确保障碍物轮廓清晰,无大面积灰色未探索区域,如果有不清晰,可以编辑修订
1.2 环境配置
设置机器人型号(根据实际选择):
# 配置车辆类型
export TURTLEBOT3_MODEL=waffle_pi
# 安装局部路径规划器
sudo apt install ros-noetic-dwa-local-planner
2. 启动导航
2.1 节点启动
# 启动Gazebo环境
roslaunch turtlebot3_gazebo turtlebot3_house.launch
# 启动导航(此命令启动move_base(路径规划)、AMCL(自适应蒙特卡洛定位)和map_server(地图加载))
roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/catkin_ws/src/maps/gmapping_house.yaml
2.2 RVIZ初始定位
在RVIZ中:点击 2D Pose Estimate → 在地图上长按机器人初始位置并拖拽方向(箭头代表机器人朝向)。
观察激光扫描线(白色)是否与地图墙壁重合,若不重合需重复定位直至匹配。
关键提示:定位后AMCL粒子(绿色箭头)会围绕机器人聚合,表示定位成功。
2.3 参数说明
- costmap参数(路径代价地图):
local_costmap_params.yaml:减小inflation_radius(膨胀半径)使机器人行走的路径可以更贴近障碍物。
global_costmap_params.yaml:增大update_frequency(更新频率)提升实时性 - 调整AMCL粒子数(默认500):
# amcl.launch中修改
<param name="max_particles" value="5000"/> # 复杂环境增加粒子数提升定位精度
3. 执行导航
3.1 手动设置目标
在RVIZ中:点击 2D Nav Goal → 点击目标点并拖拽方向(箭头为终点朝向)。
机器人自动规划路径(蓝色线)并移动,避开动态障碍物(实时更新红色区域)
3.2 终端设置
# 监听消息
rostopic echo /move_base/goal
#查看消息类型
rostopic info /move_base/goal
#查看消息格式
rosmsg show move_base_msgs/MoveBaseActionGoal
#发布目标位置消息
rostopic pub /move_base/goal move_base_msgs/MoveBaseActionGoal "
header:seq: 0stamp:secs: 0nsecs: 0frame_id: \"map\"
goal_id:stamp:secs: 0nsecs: 0id: \"\"
goal:target_pose:header:seq: 0stamp:secs: 0nsecs: 0frame_id: \"map\"pose:position:x: 1.0y: 1.0z: 0.0orientation:x: 0.0y: 0.0z: 0.7071w: 0.7071
" -1
设置到一个去不了的位置(这个位置是垃圾桶的位置),会提示无法到达。
3.3 代码设置
catkin_create_pkg nav rospy
cd nav
mkdir launch
mkdir scripts
touch scripts/set_goal.py
# 拷贝下面的launch内容
nano scripts/set_goal.py
# 增加下面的配置,以便编译时候自动拷贝launch scripts目录
nano CMakeLists.txt
install(DIRECTORY scripts launchDESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
# 编译
catkin_make_isolated --install --use-ninja
# 执行
roscd nav
python3 scripts/set_goal.py
#!/usr/bin/env python
import rospy
from move_base_msgs.msg import MoveBaseActionGoal, MoveBaseGoal
from geometry_msgs.msg import PoseStamped, Point, Quaternion
from std_msgs.msg import Header
from actionlib_msgs.msg import GoalIDdef send_goal(pub, x, y, orientation):# 构建消息goal_msg = MoveBaseActionGoal()# 填充 header (frame_id 通常为 "map")goal_msg.header = Header()goal_msg.header.seq = 0goal_msg.header.stamp = rospy.Time.now()goal_msg.header.frame_id = "map"# 填充 goal_id (可为空)goal_msg.goal_id = GoalID()goal_msg.goal_id.stamp = rospy.Time.now()goal_msg.goal_id.id = ""# 填充目标位姿goal_msg.goal = MoveBaseGoal()goal_msg.goal.target_pose = PoseStamped()# 目标位姿的 headergoal_msg.goal.target_pose.header = Header()goal_msg.goal.target_pose.header.seq = 0goal_msg.goal.target_pose.header.stamp = rospy.Time.now()goal_msg.goal.target_pose.header.frame_id = "map"# 目标位置goal_msg.goal.target_pose.pose.position = Point(x, y, 0)# 目标方向 (四元数)goal_msg.goal.target_pose.pose.orientation = Quaternion(*orientation # 解包传入的四元数列表 [x, y, z, w])# 发布消息pub.publish(goal_msg)rospy.loginfo("导航目标已发布!")if __name__ == '__main__':rospy.init_node('set_goal_node', anonymous=True)pub = rospy.Publisher('/move_base/goal', MoveBaseActionGoal, queue_size=10)rospy.sleep(1) # 示例:依次发送两个目标点send_goal(pub, 1.0, 0.5, [0.0, 0.0, 0.7071, 0.7071]) # 点1rospy.sleep(20) # 等待到达send_goal(pub, -2.0, 3.0, [0.0, 0.0, 0.0, 0.0]) # 点2
目标位置不可达会提示