docs(nav): 阅读路径导航 + 数字统一

This commit is contained in:
xs
2026-08-04 16:10:27 +08:00
parent 549d6b337e
commit 6338f3d36a
95 changed files with 3838 additions and 1260 deletions
+237 -45
View File
@@ -1,67 +1,259 @@
# cpp_custom_interface
# cpp_custom_interface — C++ 自定义接口(.msg / .srv / .action)
ROS2 自定义接口演示包(C++)。属于 Level 1 基础机制第 10 块
> 学会自定义 ROS2 接口,跨包/跨语言共享数据结构
>
> 预计学习时间:2-3 小时。
## 自定义接口
---
| 类型 | 文件 | 字段 |
|---|---|---|
| `msg` | `SensorReading.msg` | header + sensor_id + unit + value |
| `srv` | `GetCalibration.srv` | req: sensor_id / resp: intrinsic_matrix[9] + bias[3] + date + valid |
| `action` | `MoveArm.action` | goal: target_pose + joint_names + scaling / feedback: progress + state / result: success + time |
## 这是什么?
## 节点
ROS2 自带的消息类型(`std_msgs/String``geometry_msgs/Twist`...)够用吗?不够。
- **`sensor_publisher_cpp`**: 周期性发布 `SensorReading`(正弦曲线模拟传感器读数)
- **`calibration_server_cpp`**: 提供 `GetCalibration` 服务(返回模拟相机内参)
- **`move_arm_server_cpp`**: 提供 `MoveArm` Action(5 阶段模拟移动)
**做项目一定要自定义接口**,比如:
- 机器人: `/robot_status.msg` (含电量、位置、状态)
- 机械臂: `/MoveArm.action` (含目标位姿 + 反馈进度 + 结果)
- 相机: `/CameraCalibration.srv` (含内外参矩阵)
## 关键概念
**本包演示**:
- `.msg` (消息,Topic 用): `SensorReading`(传感器读数)
- `.srv` (服务): `GetCalibration`(获取标定数据)
- `.action` (动作): `MoveArm`(机械臂运动)
| 概念 | 用途 |
|---|---|
| `rosidl_generate_interfaces` | 自动生成 C++ / Python 接口代码 |
| `.msg` / `.srv` / `.action` | 接口定义文件 |
| `rosidl_default_generators` | 构建时依赖 |
| `rosidl_default_runtime` | 运行时依赖 |
| `ament_cmake` | C++ 包构建类型 |
---
## 运行
## 🎯 学完之后你能做什么?
```bash
# 启动所有自定义接口节点
ros2 launch cpp_custom_interface custom_launch.py
1. ✅ 定义 `.msg` / `.srv` / `.action` 文件
2. ✅ 用 `rosidl_generate_interfaces` 生成 C++ / Python 代码
3. ✅ 在自己的包里 include 生成的 C++ 头文件
4. ✅ 跨包/跨语言用自定义类型通信
# CLI 调用服务
ros2 service call /get_calibration cpp_custom_interface/srv/GetCalibration "{sensor_id: 'lidar_front'}"
---
# CLI 发 Action goal
ros2 action send_goal /move_arm cpp_custom_interface/action/MoveArm "{
target_pose: {header: {frame_id: 'base_link'}, pose: {position: {x: 0.3, y: 0.0, z: 0.2}, orientation: {w: 1.0}}},
joint_names: ['joint1','joint2','joint3'],
max_velocity_scaling: 0.5,
max_acceleration_scaling: 0.5
}" --feedback
## 📁 文件结构
# CLI 看自定义消息
ros2 topic echo /sensor_reading
```
src/cpp_custom_interface/
├── msg/SensorReading.msg # 消息定义
├── srv/GetCalibration.srv # 服务定义
├── action/MoveArm.action # 动作定义
├── include/cpp_custom_interface/ # 生成的头文件会被装到这里
├── src/
│ ├── sensor_publisher.cpp/hpp # 发布自定义 msg 的 Publisher
│ ├── calibration_server.cpp/hpp # 自定义 srv 的 Server
│ └── move_arm_server.cpp/hpp # 自定义 action 的 Server
├── test/test_custom_interfaces.cpp # 测试生成的接口
├── CMakeLists.txt # ⭐ 关键:rosidl_generate_interfaces
└── package.xml
```
## 测试
---
## 📖 接口定义文件格式
### .msg(SensorReading.msg)
```
std_msgs/Header header # 用其他包的消息类型
string sensor_id
string unit
float64 value
```
类型:`string``int32``float64``bool`、嵌套其他 `msg/...`
### .srv(GetCalibration.srv)
```
string sensor_id # 请求字段
---
float64[9] intrinsic_matrix # 响应字段
float64[3] bias
string calibration_date
bool valid
```
`---` 上是请求,下面是响应。
### .action(MoveArm.action)
```
# Goal
float64 max_velocity_scaling
---
# Result
bool success
string error_message
float64 total_time_sec
---
# Feedback
float32 progress
string current_state
```
三段分别是 **Goal / Result / Feedback**
---
## 🚀 跑起来
### 启动自定义 Publisher
```bash
source /opt/ros/humble/setup.bash
source /root/ros2_ws/install/setup.bash
ros2 run cpp_custom_interface sensor_publisher_cpp
```
**预期输出**:
```
[INFO] [sensor_publisher]: SensorPublisher started: topic="/sensor_reading"
```
### 订阅看消息(另开终端)
```bash
ros2 topic echo /sensor_reading --once
```
**预期输出**:
```
header:
stamp:
sec: ...
nanosec: ...
frame_id: imu_frame
sensor_id: imu_0
unit: rad/s
value: 0.0
```
### 启动标定服务(另开终端)
```bash
ros2 run cpp_custom_interface calibration_server_cpp
```
```bash
# 调用服务
ros2 service call /get_calibration cpp_custom_interface/srv/GetCalibration "{sensor_id: 'lidar_front'}"
```
### 启动机械臂 Action(另开终端)
```bash
ros2 run cpp_custom_interface move_arm_server_cpp
```
```bash
# 发 goal
ros2 action send_goal --feedback /move_arm cpp_custom_interface/action/MoveArm "{max_velocity_scaling: 0.5}"
```
---
## 📖 CMakeLists.txt 关键配置
```cmake
# 1) 定义接口文件
set(MSG_FILES "msg/SensorReading.msg")
set(SRV_FILES "srv/GetCalibration.srv")
set(ACTION_FILES "action/MoveArm.action")
# 2) 生成 C++ + Python 代码(关键!)
rosidl_generate_interfaces(${PROJECT_NAME}
${MSG_FILES} ${SRV_FILES} ${ACTION_FILES}
DEPENDENCIES std_msgs geometry_msgs
)
# 3) 链接生成的 typesupport 库
rosidl_get_typesupport_target(cpp_typesupport
${PROJECT_NAME} "rosidl_typesupport_cpp")
target_link_libraries(${LIBRARY_NAME} ${cpp_typesupport})
# 4) 包必须 <member_of_group>rosidl_interface_packages</member_of_group>
```
**package.xml 必须加**:
```xml
<member_of_group>rosidl_interface_packages</member_of_group>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
```
---
## 📖 在自己的代码里使用生成的接口
### C++
```cpp
#include "cpp_custom_interface/msg/sensor_reading.hpp"
#include "cpp_custom_interface/srv/get_calibration.hpp"
#include "cpp_custom_interface/action/move_arm.hpp"
// 使用消息类型
auto msg = cpp_custom_interface::msg::SensorReading();
msg.sensor_id = "imu_0";
msg.value = 1.23;
// Publisher
auto pub = create_publisher<cpp_custom_interface::msg::SensorReading>("topic", 10);
```
### Python
```python
from cpp_custom_interface.msg import SensorReading
from cpp_custom_interface.srv import GetCalibration
from cpp_custom_interface.action import MoveArm
msg = SensorReading()
msg.sensor_id = 'imu_0'
```
**注意**:Python 包名是 `cpp_custom_interface.msg` 而不是 `cpp_custom_interface/msg`
---
## 🧪 跑测试
```bash
colcon test --packages-select cpp_custom_interface
colcon test-result --all --verbose
```
测试覆盖:
**预期**:`cpp_custom_interface: gtest 3/3 ✓` 全部通过。
| 用例 | 内容 |
|---|---|
| `SensorReadingFields` | msg 字段构造正确 |
| `GetCalibrationRequestResponse` | srv 字段 + 长度正确 |
| `MoveArmGoalFeedbackResult` | action 三段都正确 |
---
## 深度学习
## 🔧 自己定义接口
- 编程规范:[`doc/CODING_STYLE.md`](../doc/CODING_STYLE.md)
- 自定义接口:[`doc/16-custom-interfaces.md`](../doc/16-custom-interfaces.md)
1.`msg/``srv/``action/` 下新建 `.msg`/`.srv`/`.action` 文件
2.`CMakeLists.txt``MSG_FILES`/`SRV_FILES`/`ACTION_FILES` 列表
3. `colcon build`
4. 生成的代码在 `install/cpp_custom_interface/include/`(C++)或 `install/cpp_custom_interface/lib/python3.10/site-packages/`(Python)
---
## 📚 深入学习
- [doc/16-custom-interfaces.md](../../doc/16-custom-interfaces.md) — 自定义接口深度(嵌套 / 数组 / 常量)
---
## ⏭️ 下一个包
继续学 **[py_vision_demo](../py_vision_demo/README.md)** — 图像话题(cv_bridge + OpenCV)。
---
## 📍 学习路径导航
| ⏮ 上一个 | 🏠 当前位置 | ⏭ 下一个 |
|---|---|---|
| [py_params — Python Parameter](../py_params/README.md) | **cpp_custom_interface — C++ 自定义接口** | [py_vision_demo — Python 图像](../py_vision_demo/README.md) |
📍 完整 12 包学习顺序见 [主 README](../../README.md#-12-包推荐学习顺序)