diff --git a/README.md b/README.md index fd846cf..2e79a00 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,64 @@ -# RC2025 自动定位瞄准代码 +# 🎯 RC2025 自动定位瞄准代码 -基于ROS2的机器人自动定位与瞄准系统,支持激光雷达建图和导航功能。 +> 基于ROS2的机器人自动定位与瞄准系统,支持激光雷达建图和导航功能 -## 系统要求 +[![ROS2](https://img.shields.io/badge/ROS2-Humble-blue.svg)](https://docs.ros.org/en/humble/) +[![Ubuntu](https://img.shields.io/badge/Ubuntu-22.04-orange.svg)](https://ubuntu.com/) +[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) -- Ubuntu 22.04 -- ROS2 Humble -- 激光雷达:MID360 +## 📋 目录 -## 快速开始 +- [系统要求](#系统要求) +- [环境配置](#环境配置) +- [快速开始](#快速开始) +- [重要参数配置](#重要参数配置) +- [故障排除](#故障排除) +- [贡献指南](#贡献指南) + +## 🔧 系统要求 + +| 组件 | 版本/型号 | +|------|-----------| +| 操作系统 | Ubuntu 22.04 LTS | +| ROS版本 | ROS2 Humble | +| 激光雷达 | Livox MID360 | +| 处理器 | x86_64 (推荐) | +| 内存 | 8GB+ (推荐) | + +## 🚀 环境配置 + +### 1. 安装 Livox SDK2 + +```bash +# 安装依赖 +sudo apt update +sudo apt install cmake build-essential + +# 克隆并编译 Livox SDK2 +git clone https://github.com/Livox-SDK/Livox-SDK2.git +cd ./Livox-SDK2/ +mkdir build && cd build +cmake .. && make -j$(nproc) +sudo make install +``` + +### 2. 安装串口驱动 + +```bash +pip install pyserial +``` + +### 3. 安装ROS2依赖 + +```bash +# 进入工作区 +cd /Users/lvzucheng/Documents/R/RC2025 + +# 安装依赖包 +rosdep install -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y +``` + +## 🎯 快速开始 ### 1. 编译项目 @@ -16,7 +66,7 @@ . build.sh ``` -### 2. 建图模式 +### 2. 🗺️ 建图模式 用于创建环境地图和点云数据: @@ -24,46 +74,148 @@ . mapping.sh ``` -**建图前配置:** -1. 修改 `mapping.sh` 中的地图保存文件名(将 `RC2025` 改为您的项目名) -2. 同步修改 `src/rm_nav_bringup/config/reality/fastlio_mid360_real.yaml` 中的 pcd 文件名 +#### 建图前配置 -**建图操作:** -- 保存点云文件:`ros2 service call /map_save std_srvs/srv/Trigger` -- 保存地图:确保地图名称保持一致 +1. **修改地图保存文件名** + ```bash + # 编辑 mapping.sh + nano mapping.sh + # 将 'RC2025' 改为您的项目名 + ``` -### 3. 导航模式 +2. **同步修改点云文件配置** + ```bash + # 编辑 FAST-LIO 配置文件 + nano src/rm_nav_bringup/config/reality/fastlio_mid360_real.yaml + # 确保 pcd 文件名与 mapping.sh 中一致 + ``` + +#### 建图操作步骤 + +1. **启动建图程序** + ```bash + ./mapping.sh + ``` + +2. **控制机器人移动** + - 使用遥控器或键盘控制机器人 + - 确保覆盖所有需要建图的区域 + +3. **保存点云文件** + ```bash + ros2 service call /map_save std_srvs/srv/Trigger + ``` + +4. **保存地图文件** + - 在RViz中使用地图保存功能 + - 确保地图名称保持一致 + +#### 建图效果展示 + +
+点击查看建图效果图 + +![建图效果1](doc/img/07b3c725_11812035.png) +![建图效果2](doc/img/5032aa1d_11812035.png) +![建图效果3](doc/img/bea7dae2_11812035.jpeg) + +
+ +### 3. 🧭 导航模式 使用已建立的地图进行导航: ```bash -. nav.sh +chmod +x nav.sh +./nav.sh ``` +#### 导航操作说明 -## 重要参数配置 +1. **启动导航程序** +2. **在RViz中设置初始位置** +3. **设置目标点进行导航** +4. **监控导航状态** -### 激光雷达安装位置 +## ⚙️ 重要参数配置 -**位置参数配置:** -- 文件:`src/rm_nav_bringup/config/reality/measurement_params_real.yaml` -- 修改:`x`, `y`, `z` 坐标 -- 注意:不要修改 `rpy` 参数 +### 📍 激光雷达安装位置 -**姿态参数配置:** -- 文件:`src/rm_nav_bringup/config/reality/MID360_config.json` -- 修改:`yaw`, `pitch`, `roll` 角度 -- 注意:不要修改 `xyz` 参数 +#### 位置参数配置 +```yaml +# 文件:src/rm_nav_bringup/config/reality/measurement_params_real.yaml +translation: + x: 0.0 # 前后位置 (m) + y: 0.0 # 左右位置 (m) + z: 0.0 # 上下位置 (m) +``` +> ⚠️ **注意**:不要修改 `rpy` 参数 -### 地面点云分割 +#### 姿态参数配置 +```json +// 文件:src/rm_nav_bringup/config/reality/MID360_config.json +{ + "yaw": 0.0, // 偏航角 + "pitch": 0.0, // 俯仰角 + "roll": 0.0 // 翻滚角 +} +``` +> ⚠️ **注意**:不要修改 `xyz` 参数 -- 文件:`src/rm_nav_bringup/config/reality/segmentation_real.yaml` -- 参数:`sensor_height`(激光雷达距离地面的高度) -- 参数:`max_dist_to_line`(地面点云分割的最低高度) -- 说明:此参数影响地面点云的正确分割 +### 🌍 地面点云分割 -### 目标点设定 +```yaml +# 文件:src/rm_nav_bringup/config/reality/segmentation_real.yaml +sensor_height: 0.3 # 激光雷达距离地面的高度 (m) +max_dist_to_line: 0.05 # 地面点云分割的最低高度 (m) +``` -- 文件:`nav.sh` -- 参数:篮筐目标点的 `x` 和 `y` 坐标 -- 用途:设定机器人瞄准的目标点 +### 🎯 目标点设定 + +```bash +# 文件:nav.sh +# 篮筐目标点坐标 +TARGET_X=1.0 # X坐标 +TARGET_Y=0.0 # Y坐标 +``` + +## 🔧 故障排除 + +### 常见问题 + +
+激光雷达无法连接 + +1. 检查网络连接 +2. 确认IP地址配置 +3. 检查防火墙设置 +4. 验证SDK安装 + +
+ +
+建图效果不佳 + +1. 检查激光雷达安装位置 +2. 调整地面分割参数 +3. 确保移动速度适中 +4. 检查环境光照条件 + +
+ +
+导航精度不够 + +1. 重新标定雷达参数 +2. 优化地图质量 +3. 调整导航参数 +4. 检查里程计数据 + +
+ +## 📝 使用技巧 + +- **建图时**:保持稳定的移动速度,避免急转急停 +- **导航时**:确保地图与实际环境一致 +- **调试时**:使用RViz可视化工具监控状态 +- **维护时**:定期更新地图数据 diff --git a/r1.sh b/r1.sh new file mode 100644 index 0000000..08c20a1 --- /dev/null +++ b/r1.sh @@ -0,0 +1,19 @@ +source install/setup.bash + +commands=( + "/bin/python3 /home/robofish/RC2025/src/rm_driver/rm_serial_driver/script/pub_aim.py" + "ros2 launch rm_nav_bringup bringup_real.launch.py \ + world:=RC2025 \ + mode:=nav \ + lio:=fastlio \ + localization:=icp \ + lio_rviz:=false \ + nav_rviz:=true" + "ros2 launch rm_simpal_move simple_move.launch.py" + "ros2 topic pub /move_goal rm_msgs/msg/MoveGoal '{x: 0.56, y: 3.960, angle: 0.0, max_speed: 10.0, tolerance: 0.1, rotor: false}' --once" +) + +for cmd in "${commands[@]}"; do + gnome-terminal -- bash -c "source install/setup.bash; $cmd; exec bash" + sleep 0.5 +done \ No newline at end of file diff --git a/src/rm_driver/rm_serial_driver/script/pub_OnlyAim.py b/src/rm_driver/rm_serial_driver/script/pub_OnlyAim.py new file mode 100644 index 0000000..af70745 --- /dev/null +++ b/src/rm_driver/rm_serial_driver/script/pub_OnlyAim.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +import rclpy +from rclpy.node import Node +import serial +import struct +from rm_msgs.msg import DataAim # 假设使用DataAim消息类型,您可以根据实际消息类型调整 +class AimDataSerial(Node): + def __init__(self): + super().__init__('aim_data_serial') + + # 串口配置 + self.serial_port = '/dev/ttyUSB0' # 根据实际串口设备调整 + self.baud_rate = 115200 + + try: + self.serial_conn = serial.Serial( + port=self.serial_port, + baudrate=self.baud_rate, + timeout=1 + ) + self.get_logger().info(f'Serial port {self.serial_port} opened successfully') + except Exception as e: + self.get_logger().error(f'Failed to open serial port: {e}') + return + + # 订阅话题 + self.subscription = self.create_subscription( + DataAim, # 根据实际消息类型调整 + '/chassis/data_aim', + self.aim_callback, + 10 + ) + + self.get_logger().info('Aim data serial node started') + + def aim_callback(self, msg): + try: + # 提取yaw和distance数据 + # 根据实际消息结构调整,这里假设使用Point32的x和y字段 + yaw = msg.yaw + distance = msg.distance + + self.get_logger().info(f'Received - yaw: {yaw}, distance: {distance}') + + # 构建发送数据包 + # 格式: 包头(0xFF) + yaw(4字节float) + distance(4字节float) + 包尾(0xFE) + packet = bytearray() + packet.append(0xFF) # 包头 + packet.extend(struct.pack(' 0: + data = self.receive_serial.read(self.receive_serial.in_waiting) + buffer.extend(data) + + # 查找完整的数据包 + while len(buffer) >= 22: # 最小包长度:包头(1) + 数据(16) + 校验(1) + 包尾(1) = 19 + # 查找包头 + start_idx = buffer.find(0xFF) + if start_idx == -1: + break + + # 移除包头前的数据 + if start_idx > 0: + buffer = buffer[start_idx:] + + # 检查包长度 + if len(buffer) < 22: + break + + # 查找包尾 + if buffer[21] == 0xFE: + # 校验数据 + checksum = 0 + for i in range(1, 20): + checksum ^= buffer[i] + + if checksum == buffer[20]: + # 解析数据 + x = struct.unpack('