ROS2 机器人 少年创客营:Day 7

🏆 ROS2 机器人 少年创客营:Day 7

主题:终极挑战 ------ 智能迷宫逃生 & 结营大典

🎉 恭喜!你已抵达终点线!

回顾旅程

  • Day 1-2: 你好,海龟!(节点、话题)
  • Day 3: 听我指挥!(服务)
  • Day 4: 复杂任务!(动作)
  • Day 5: 感知世界!(传感器数据闭环)
  • Day 6: 系统工程!(Launch 文件与参数)

今日使命

今天没有新的语法教学。今天是**"黑客马拉松"!你将综合运用过去 6 天学到的所有技能,解决一个真实的机器人难题:"智能迷宫逃生"**。

挑战目标

编写一个节点,控制海龟在充满未知障碍(或边界)的环境中,自主探索并找到出口(或存活最长时间),全程无需人工干预。


🗺️ 今日探险地图 (Checklist)

  • 🧠 算法设计:设计"避障 + 寻路"的简单逻辑。
  • 🤖 代码实现 :编写 maze_runner.py,融合订阅、发布、定时器逻辑。
  • 🚀 系统集成 :编写 escape_launch.py,一键启动仿真环境和你的 AI。
  • 🎬 演示时刻:运行程序,录制视频,见证奇迹。
  • 🎓 结营仪式:总结回顾,颁发电子证书。

🧠 第一关:算法设计 (伪代码)

在写代码前,先理清思路。我们不需要复杂的 SLAM 或 A* 算法,一个简单的**"随机游走 + 遇墙转向"**策略就足以应对今天的挑战。

🤖 核心逻辑:

  1. 一直向前跑:默认发送直线速度指令。
  2. 感知危险 :订阅 /turtle1/pose,检查当前位置 (x, y)
  3. 判断边界 :Turtlesim 的地图大小是 11x11 (0 到 11)。
    • 如果 x > 10x < 1y > 10y < 1 (接近墙壁):
      • 停止前进
      • 原地旋转 90 度 (或随机角度)。
      • 继续前进。
  4. (进阶) 寻找出口 :假设出口在 (10.5, 10.5)
    • 如果距离出口 < 0.5 米 -> 任务成功,停止并庆祝!

💻 第二关:代码实现 (maze_runner.py)

src/my_turtle_bot/my_turtle_bot/ 下新建 maze_runner.py

python 复制代码
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
import math
import random

class MazeRunnerNode(Node):
    def __init__(self):
        super().__init__('maze_runner_node')
        
        # --- 参数配置 ---
        self.declare_parameter('safe_distance', 1.0) # 离墙多远开始转向
        self.declare_parameter('turn_angle', 1.57)   # 转向角度 (弧度,1.57 ≈ 90度)
        self.declare_parameter('linear_speed', 2.0)
        self.declare_parameter('angular_speed', 1.5)
        
        self.safe_dist = self.get_parameter('safe_distance').value
        self.turn_angle = self.get_parameter('turn_angle').value
        self.lin_speed = self.get_parameter('linear_speed').value
        self.ang_speed = self.get_parameter('angular_speed').value
        
        self.pose = None
        self.state = 'MOVE' # 状态机:MOVE, TURNING
        self.turn_start_theta = 0.0
        self.target_theta = 0.0
        
        # 定义地图边界 (Turtlesim 默认 11x11)
        self.map_min = 0.5
        self.map_max = 10.5
        
        # 创建发布者和订阅者
        self.cmd_pub = self.create_publisher(Twist, 'turtle1/cmd_vel', 10)
        self.pose_sub = self.create_subscription(Pose, 'turtle1/pose', self.pose_callback, 10)
        
        # 创建定时器 (10Hz)
        self.timer = self.create_timer(0.1, self.control_loop)
        
        self.get_logger().info('🤖 迷宫逃生系统已启动!正在寻找出路...')

    def pose_callback(self, msg):
        self.pose = msg

    def control_loop(self):
        if self.pose is None:
            return

        cmd = Twist()
        
        # --- 状态机逻辑 ---
        
        if self.state == 'MOVE':
            # 1. 检查是否撞墙 (简化版:检查距离边界的距离)
            dist_left = self.pose.x - self.map_min
            dist_right = self.map_max - self.pose.x
            dist_bottom = self.pose.y - self.map_min
            dist_top = self.map_max - self.pose.y
            
            min_dist = min(dist_left, dist_right, dist_bottom, dist_top)
            
            if min_dist < self.safe_dist:
                # 危险!准备转向
                self.get_logger().warn(f'⚠️ 检测到墙壁 (距离: {min_dist:.2f}),正在转向...')
                self.state = 'TURNING'
                self.turn_start_theta = self.pose.theta
                # 随机向左或向右转 90 度
                direction = 1 if random.random() > 0.5 else -1
                self.target_theta = self.turn_start_theta + (self.turn_angle * direction)
                cmd.linear.x = 0.0
                cmd.angular.z = self.ang_speed * direction
            else:
                # 安全,继续前进
                cmd.linear.x = self.lin_speed
                cmd.angular.z = 0.0
                
        elif self.state == 'TURNING':
            # 计算当前角度与目标角度的差
            angle_diff = self.target_theta - self.pose.theta
            
            # 标准化角度 (-pi 到 pi)
            while angle_diff > math.pi:
                angle_diff -= 2.0 * math.pi
            while angle_diff < -math.pi:
                angle_diff += 2.0 * math.pi
            
            if abs(angle_diff) < 0.1: # 转向完成
                self.get_logger().info('✅ 转向完成,继续探索。')
                self.state = 'MOVE'
                cmd.linear.x = 0.0
                cmd.angular.z = 0.0
            else:
                # 继续旋转
                cmd.linear.x = 0.0
                cmd.angular.z = self.ang_speed * (1.0 if angle_diff > 0 else -1.0)

        self.cmd_pub.publish(cmd)

def main(args=None):
    rclpy.init(args=args)
    node = MazeRunnerNode()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

🔧 第三关:集成与 Launch 文件

1. 更新 setup.py

别忘了注册新的可执行文件!

python 复制代码
entry_points={
    'console_scripts': [
        'go_to_goal = my_turtle_bot.go_to_goal:main',
        'maze_runner = my_turtle_bot.maze_runner:main', # 🆕 新增
    ],
},
# 确保 data_files 包含 launch 文件夹 (参考 Day 6)

2. 创建 escape.launch.py

launch/ 文件夹下新建 escape.launch.py

python 复制代码
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess

def generate_launch_description():
    return LaunchDescription([
        # 1. 启动仿真器 (背景设为黑色,增加神秘感)
        Node(
            package='turtlesim',
            executable='turtlesim_node',
            name='simulator',
            parameters=[{'background_r': 20, 'background_g': 20, 'background_b': 20}]
        ),
        # 2. 启动我们的 AI 导航员
        Node(
            package='my_turtle_bot',
            executable='maze_runner',
            name='ai_pilot',
            output='screen',
            parameters=[
                {'safe_distance': 1.5}, # 离墙远点就开始转
                {'linear_speed': 3.0}   # 跑快点!
            ]
        ),
        # 3. (可选) 自动打开键盘控制作为备用
        # ExecuteProcess(cmd=['ros2', 'run', 'turtlesim', 'turtle_teleop_key']),
    ])

3. 编译与运行

bash 复制代码
cd ~/ROS2
colcon build --packages-select my_turtle_bot
source install/setup.bash

# 一键启动逃生挑战!
ros2 launch my_turtle_bot escape.launch.py

👀 观察现象

  • 海龟会自动向前冲。
  • 快到墙壁时,它会急刹车,然后帅气地转个弯,继续探索。
  • 它永远不会撞墙!

🎨 创意升级挑战 (选做)

如果你想让项目更酷,尝试以下升级:

  1. 🌈 彩虹轨迹
    • 修改代码,每当海龟成功转向时,调用 /clear 服务,并改变背景颜色或海龟颜色。
  2. 🎯 定点寻宝
    • 结合 Day 5 的 go_to_goal 逻辑。设定一个随机目标点,海龟必须先避障走到目标点,然后再找下一个。
  3. 👻 多龟大逃杀
    • 使用 ros2 run turtlesim spawn 生成 5 只海龟。
    • 修改 maze_runner 支持多只海龟(通过 remapping 话题名称 turtleX/cmd_vel)。
    • 看谁最后还在地图上活着!

🎓 结营大典:你学到了什么?

恭喜你完成了 ROS2 机器人 少年创客营!让我们盘点一下你的技能树:

领域 技能点 应用场景
通信机制 Topic (发布/订阅) 传感器数据流、控制指令
Service (请求/响应) 开关灯、重置位置、清屏
Action (目标/反馈/结果) 长时任务、导航、可中断操作
节点开发 Class 结构、Timer、Callback 构建稳健的机器人逻辑
数学基础 坐标系转换、PID 思想、角度归一化 运动控制核心算法
工程工具 Colcon 编译、Package.xml 项目管理与依赖处理
系统集成 Launch FilesParameters 一键部署、动态配置、产品化

🎁 毕业作业

请将你的 src/my_turtle_bot 文件夹打包,或者上传到 GitHub。

在你的简历或作品集中,你可以自豪地写下:

项目名称 :基于 ROS 2 的自主移动机器人仿真系统
技术栈 :Python, ROS 2 (Humble/Iron/Jazzy), Launch System, State Machines
功能描述:实现了基于话题通信的运动控制、基于 Action 的任务管理、以及基于参数化 Launch 文件的自动化部署系统。具备自主避障与路径规划能力。


🚀 未来的路

今天的结束,是你机器人工程师生涯的开始。

  • 下一步建议
    • 尝试在 真实机器人 (如树莓派 + 小车) 上运行类似的代码。
    • 学习 Nav2 (ROS 2 官方导航栈),那是工业级的避障与路径规划。
    • 探索 SLAM (即时定位与地图构建),让机器人在未知环境中画地图。
    • 学习 MoveIt 2,机械臂控制的王者。

保持好奇,保持创造。世界需要你的代码!

🎓 谨此颁发 "ROS2 机器人 少年创客营" 结业证书 (电子版)

授予:[你的名字]

鉴于其在 2026 年 3 月期间,成功掌握了 ROS 2 核心架构,完成了从单节点控制到系统集成自主导航的全部挑战,特发此证,以资鼓励。

签发人:AI 导师
日期:2026-03-24


© 2026 ROS2 机器人 少年创客营 | 愿你的代码永远 Compile Pass,愿你的机器人永不 Bug! 🤖✨

相关推荐
ai生成式引擎优化技术2 小时前
---从黑盒死穴到合规重构:论自研大模型GEO的必然终结与TS概率化递推的唯一出路
人工智能
沉木渡香2 小时前
【AI协作开发实践指南:从25%到50%+效率提升的实战方法论】编程领域
人工智能·ai编程·最佳实践·工程化·开发效率·前后端协作
牢七2 小时前
jfinal_cms-v5.1.0 白盒 nday
开发语言·python
前端摸鱼匠2 小时前
【AI大模型春招面试题14】前馈网络(FFN)在Transformer中的作用?为何其维度通常大于注意力维度?
网络·人工智能·ai·面试·大模型·transformer
披着羊皮不是狼2 小时前
CNN卷积输出尺寸计算(公式+实例)
人工智能·神经网络·cnn
dreambyday2 小时前
Java 后端 AI 面试题(RAG + Agent 专项)
人工智能·面试
newsxun2 小时前
羊城聚力启新程 星脉联盟多维生态赋能文娱商业融合发展
大数据·人工智能
LuoQuHen2 小时前
第八章:多Agent系统—— 当智能体开始“分工协作“
人工智能·ai·agent
落痕的寒假2 小时前
[深度学习] 大模型学习7-多模态大模型全景解析
人工智能·深度学习·学习