具身智能--体育馆机器人项目
1.正常启动流程
下位机端启动的环境:
终端1:电机驱动节点
cd myslam_car/
source install/setup.bash
ros2 run myslam_car_driver driver_node终端2:TF树转换节点
cd myslam_car/
source install/setup.bash
ros2 run myslam_car_driver robot_static_tf_pub_node可以用launch来启动:
cd myslam_car/
colcon build --packages-select myslam_car_driver
source install/setup.bash
ros2 launch myslam_car_driver driver.launch.py终端3:激光雷达节点
cd rplidar_ws/
source install/setup.bash
ros2 launch rplidar_ros rplidar_a1_launch.py终端4:udp通信_mcp_asr_llm_tts节点
cd mymcp_test/MCP_Cilent/
#可选
python3 voice_controller_udp_only.py
python3 voice_controller_udp.py
python3 voice_controller.py上位机启动的环境:
终端1:nav2
cd mynav2/
source install/setup.bash
ros2 launch my_navigation2 navigation2.launch.py终端2:获取当前位置服务
cd mynav2/
source install/setup.bash
ros2 run nav2_application get_robot_pose终端3:导航到指定点服务
cd mynav2/
source install/setup.bash
ros2 run nav2_application nav_to_pose_server终端4:手动记录当前位置坐标
cd mynav2/
source install/setup.bash
ros2 run nav2_application get_robot_pose_client舞蹈区: { "x": 9.359366245257787, "y": 3.564596643645066, "z_orientation": 0.02363433371564239, "w_orientation": 0.9997206701223186 }
羽毛球区: { "x": 5.14054943198869, "y": -7.72390824411865, "z_orientation": -0.2150626724056419, "w_orientation": 0.9766002493025197 }
乒乓球区: { "x": 5.14054943198869, "y": -7.72390824411865, "z_orientation": -0.2150626724056419, "w_orientation": 0.9766002493025197 }
乒乓球区坐标占位标记: 在三个映射表中都添加了注释 # TODO_TABLE_TENNIS: ...,搜索 TODO_TABLE_TENNIS 即可定位到所有需要替换坐标的地方(修改 navigation_points.json 中的 table_tennis_area 坐标即可)。
运行后会直接输出:
{
"x": 5.922759942073858,
"y": 4.23051337938535,
"z_orientation": -0.09355766629208634,
"w_orientation": 0.9956138624376313
}可直接拿去给下位机做定点导航参数。
2.建图流程
下位机端启动的环境:
终端1:电机驱动节点
cd myslam_car/
source install/setup.bash
ros2 run myslam_car_driver driver_node终端2:TF树转换节点
cd myslam_car/
source install/setup.bash
ros2 run myslam_car_driver robot_static_tf_pub_node终端3:激光雷达节点
cd rplidar_ws/
source install/setup.bash
ros2 launch rplidar_ros rplidar_a1_launch.py终端4:键盘控制节点
ros2 run teleop_twist_keyboard teleop_twist_keyboard上位机端启动的环境:
终端1:slam_toolbox
ros2 launch slam_toolbox online_async_launch.py终端2:rviz 记得手动添加tf、scan、map
rviz2终端3:建完图再保存:
ros2 run nav2_map_server map_saver_cli -f my_map3.nav2切换地图
你这个项目里,Nav2 地图是在启动文件 my_navigation2/launch/navigation2.launch.py:19 里通过 map 参数 传进去的,默认值现在是:
map_yaml_path = launch.substitutions.LaunchConfiguration(
'map', default=os.path.join(my_navigation2_dir, 'maps', 'iot1.yaml'))所以有两种用法。
第一种:临时切换,不改文件,直接启动时指定地图
cd mynav2/
source install/setup.bash
ros2 launch my_navigation2 navigation2.launch.py map:=/home/chuiyu/mynav2/src/my_navigation2/maps/
你的地图.yaml第二种:修改默认地图,改这个文件:
my_navigation2/launch/navigation2.launch.py:19把默认的:
default=os.path.join(my_navigation2_dir, 'maps', 'iot1.yaml')改成:
default=os.path.join(my_navigation2_dir, 'maps', '你的地图.yaml')另外,如果你是新建一张地图,要确认地图 yaml 文件本身也正确,比如现在的 my_navigation2/maps/ iot1.yaml:1 里第一行是图片路径:
image: /home/chuiyu/mynav2/src/my_navigation2/maps/iot1.pgm如果你换了新地图,比如 my_map.yaml,里面的 image: 也要对应到正确的 .pgm 文件路径,否则 Nav2 会加载失败。
- 新测试脚本 mymcp_test/test_arm_sequence.py
完整捡球序列(init→prepare_grab→open_gripper→grab→init)
python3 test_arm_sequence.py
只测单个动作
python3 test_arm_sequence.py --action init python3 test_arm_sequence.py --action prepare_grab python3 test_arm_sequence.py --action open_gripper python3 test_arm_sequence.py --action grab
出问题了紧急复位
python3 test_arm_sequence.py --action init
列出所有动作组指令
python3 test_arm_sequence.py --list
调整动作间隔(默认2秒)
python3 test_arm_sequence.py --interval 3.0
指定不同串口
python3 test_arm_sequence.py --port /dev/ttyUSB1
拍摄视频的建议
核心原则:把"全自动一气呵成"变成"分段可控"。
准备阶段(拍之前)
- 先单独跑 test_arm_sequence.py 把抓取动作调好,确认每步舵机都到位
- 固定羽毛球位置:在地上贴胶带标记,每次拍摄都把球放到同一位置,减少30秒内手动调整的量
- 确认导航点坐标:让机器人先跑一次空导航,看它停在哪里,再决定羽毛球放哪
拍摄策略(分段拍+剪辑)
┌───────┬────────────────────────┬──────────────────────────────┐ │ 段落 │ 内容 │ 技巧 │ ├───────┼────────────────────────┼──────────────────────────────┤ │ ①出发 │ 机器人从原点开始导航 │ 广角拍全局,显示地图和轨迹 │ ├───────┼────────────────────────┼──────────────────────────────┤ │ ②到达 │ 到达羽毛球区,30秒等待 │ 这段可以剪短,对着机械臂特写 │ ├───────┼────────────────────────┼──────────────────────────────┤ │ ③抓取 │ 机械臂执行动作序列 │ 从侧面拍特写,这段是亮点 │ ├───────┼────────────────────────┼──────────────────────────────┤ │ ④返回 │ 导航回原点 │ 广角拍,和①对称 │ └───────┴────────────────────────┴──────────────────────────────┘
▎ 30秒等待段:一镜头先拍机器人到位,然后你自然走进去手动微调,不用藏着掖着,这本身就是人机协作的展示。
应急处理
- Ctrl+C 中止任务后,立刻 python3 test_arm_sequence.py --action init 让机械臂复位
- 如果导航跑偏了,直接 keyboard 节点把机器人开回来,不影响重新触发任务
第一段对话
你: 你好,请你简单介绍一下吧
🤖 OpenAI: 你好呀!欢迎来到天津理工大学中环信息学院体育馆!我是你的专属机器人向导,很高兴为你服务!
我们体育馆是隶属于体育部管理的校园综合运动场馆,致力于为全校师生提供专业、舒适的运动健身环境。场馆内设有多个专业功能区域:羽毛球区、乒乓球区、健美操区等,满足大家多样化的运动需求。
我可以带你参观各个运动场地,也可以帮你捡球、送物品,或者解答你关于场馆的任何问题。你想先去哪里看看呢?
你: 带我去篮球区看看
[Calling tool navigate_to with args {"location_name": "篮球区"}]
🤖 OpenAI: 好的,这就带你去篮球区!请跟紧我,我们出发啦~
篮球区已经到啦!这里就是我们体育馆的篮球活动区域,你可以看看场地设施。有什么想了解的随时问我哦!第二段对话
你: 帮我去羽毛球区域捡一下羽毛球
[Calling tool fetch_shuttlecock_from_badminton_area with args {}]
🤖 OpenAI: 好的,我这就去羽毛球区帮你把羽毛球捡回来!你在这里稍等一下~
捡球任务圆满完成!我已经成功去羽毛球区捡到了羽毛球并返回原点。给你,接好啦!还需要我做什么吗?第三段对话
你: 去看一眼乒乓球区域有人吗?
🤖 OpenAI: 好的,我这就去乒乓球区帮你看看情况,马上回来汇报!
我回来啦!汇报一下乒乓球区的情况:现场可以看到摆放整齐的乒乓球桌,旁边有带"天津理工大学中环信息学院"字样的挡板,场地整洁干净。不过目前没有看到有人在打球,乒乓球区暂时是空的。你要现在过去占个位吗?