This commit is contained in:
2026-08-04 17:36:05 +08:00
parent d4e023696d
commit 74b3c89e1e
16 changed files with 487 additions and 34 deletions
+42
View File
@@ -0,0 +1,42 @@
# scripts/ · ROS2 学习套件常用命令脚本
> **设计**:把所有"长 shell 命令 + docker exec 路径"封装成可执行 shell 脚本,
> 避免小白每次都手敲容易出错的长命令。所有脚本都跑在**容器内** `ros2_dev`。
>
> **跟 Makefile / docker compose 不冲突**,就是更零碎场景的薄封装。
## 容器生命周期
| 脚本 | 作用 | 用法(PowerShell) |
|---|---|---|
| `build.sh` | 容器内编译 12 包(替代 `bash build.sh` 缺失的死链) | `docker exec ros2_dev bash /root/ros2_ws/scripts/build.sh` |
| `test.sh` | 容器内跑 12 包测试 + 汇总 + 详细日志 | `docker exec ros2_dev bash /root/ros2_ws/scripts/test.sh` |
| `launch.sh` | 容器内启动 `bringup/<name>.py` | `docker exec ros2_dev bash /root/ros2_ws/scripts/launch.sh pubsub_launch` |
| `shell.sh` | 自动判断容器状态,进入开发终端 | `bash scripts/shell.sh` |
## 调用方式(2 选 1)
```bash
# A. 直接通过 docker exec 调脚本(Widows / Linux 都行)
docker exec ros2_dev bash /root/ros2_ws/scripts/build.sh
docker exec ros2_dev bash /root/ros2_ws/scripts/test.sh
docker exec ros2_dev bash /root/ros2_ws/scripts/launch.sh pubsub_launch
```
```bash
# B. 整段进容器再跑(Windows 推荐 + 调试时)
docker exec -it ros2_dev bash
source /opt/ros/humble/setup.bash
source /root/ros2_ws/install/setup.bash
bash scripts/build.sh
```
## 维护脚本(项目根目录,不在容器内)
| 脚本 | 作用 |
|---|---|
| `make_build.ps1` | PowerShell 一键:`build 镜像 → up 容器` |
| `make_up.ps1` | PowerShell 一键:`docker compose -p ros2 up -d` |
| `make_shell.ps1` | PowerShell 一键:`make shell` 等价 |
*(计划中,后续补上)*
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# =============================================================================
# scripts/build.sh —— 在容器内编译所有 ROS2 包
#
# 修复 doc/01-quickstart.md 步骤 4.2 提到但仓库不存在的 `bash build.sh`。
#
# 使用:
# docker exec ros2_dev bash /root/ros2_ws/scripts/build.sh
# make colcon-build (走 docker-compose exec 包装,等价)
# =============================================================================
# 不用 -u:/opt/ros/humble/setup.bash 里有未定义变量,strict 会炸
set -eo pipefail
WORKSPACE="${WORKSPACE:-/root/ros2_ws}"
source /opt/ros/humble/setup.bash
cd "${WORKSPACE}"
colcon build --symlink-install \
--packages-select \
py_pubsub cpp_pubsub py_srv py_action_demo \
cpp_robot_tf2 py_vision_demo py_params \
cpp_custom_interface py_lifecycle_composable \
cpp_qos_demo py_overlay_dds bringup
echo "[build.sh] ✅ Done. Verify with: ls install/"
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# scripts/clean.sh —— 清空 build/install/log,修 symlink 冲突
#
# 触发场景:
# - 之前 build 过,再 build 报 "existing path cannot be removed: Is a directory"
# - 切换 RMW 实现
# - 编译产物膨胀想回收磁盘
#
# 使用:
# docker exec ros2_dev bash /root/ros2_ws/scripts/clean.sh
set -eo pipefail
WORKSPACE="${WORKSPACE:-/root/ros2_ws}"
cd "${WORKSPACE}"
echo "[clean.sh] rm -rf build install log"
rm -rf build install log
echo "[clean.sh] ✅ 清理完成。下一步:bash scripts/build.sh"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# scripts/clean_ros.sh —— 关停所有 chatter 相关后台进程
# (在调试 launch.sh forever 模式后调用,防止残留进程)
pkill -9 -f "ros2 launch" || true
pkill -9 -f chatter_publisher || true
pkill -9 -f chatter_subscriber || true
sleep 1
pgrep -af 'ros2|chatter' || echo "all clean"
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# scripts/e2e_check.sh —— 端到端冒烟测试
# 启动 bringup/pubsub_launch 8 秒,期间持续验证 chatter 真的有消息
set -eo pipefail
WORKSPACE="${WORKSPACE:-/root/ros2_ws}"
source /opt/ros/humble/setup.bash
source "${WORKSPACE}/install/setup.bash"
cd "${WORKSPACE}"
echo "[e2e] 启动 bringup/pubsub_launch.py (≈6s 冒烟)..."
ros2 launch bringup pubsub_launch.py > /tmp/e2e_launch.log 2>&1 &
LAUNCH_PID=$!
sleep 3
echo
echo "[e2e] === 验证 topic ==="
echo "[e2e] --- topic list ---"
ros2 topic list --no-daemon | head -10
echo
echo "[e2e] --- topic hz /chatter (3s) ---"
timeout 3 ros2 topic hz /chatter --no-daemon 2>&1 | tail -5 || true
echo
echo "[e2e] --- topic info /chatter -v ---"
ros2 topic info /chatter -v --no-daemon | head -20
echo
echo "[e2e] --- node list ---"
ros2 node list --no-daemon
echo
echo "[e2e] 关停 launch..."
kill -INT "${LAUNCH_PID}" 2>/dev/null || true
pkill -f "ros2 launch bringup" 2>/dev/null || true
wait "${LAUNCH_PID}" 2>/dev/null || true
echo
echo "[e2e] ✅ DONE. 详细日志: cat /tmp/e2e_launch.log"
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# scripts/launch.sh —— 跑 demo launch(可限时自动关停)
#
# 用法:
# # 一直跑(前台,Ctrl+C 停)
# docker exec -it ros2_dev bash /root/ros2_ws/scripts/launch.sh pubsub_launch
#
# # 跑 N 秒后自动停(脚本、CI、截图用)
# docker exec ros2_dev bash /root/ros2_ws/scripts/launch.sh pubsub_launch 10
#
# 第一个参数:launch 文件名(不带 .py),默认 pubsub_launch
# 第二个参数:运行时长(秒),默认 0 = 不限时
set -eo pipefail
WORKSPACE="${WORKSPACE:-/root/ros2_ws}"
NAME="${1:-pubsub_launch}"
RUNTIME="${2:-0}"
source /opt/ros/humble/setup.bash
source "${WORKSPACE}/install/setup.bash"
cd "${WORKSPACE}"
# RUNTIME 合法化:非整数 / 空 / "forever" → -1(一直跑)
if ! [[ "${RUNTIME}" =~ ^-?[0-9]+$ ]]; then
RUNTIME="-1"
fi
echo "[launch.sh] starting: ros2 launch bringup ${NAME}.py (runtime=${RUNTIME}s; -1 = forever)"
if [ "${RUNTIME}" -ge 0 ]; then
# 后台跑 + 给定时炸弹
ros2 launch bringup "${NAME}.py" &
LAUNCH_PID=$!
if [ "${RUNTIME}" -gt 0 ]; then
sleep "${RUNTIME}"
echo "[launch.sh] reaching runtime limit, killing..."
kill -INT "${LAUNCH_PID}" 2>/dev/null || true
pkill -f "ros2 launch bringup ${NAME}" 2>/dev/null || true
wait "${LAUNCH_PID}" 2>/dev/null || true
else
# 0 = 等用户 Ctrl+C
wait "${LAUNCH_PID}" 2>/dev/null || true
fi
else
# -1 = forever(后台跑,主进程立刻返回)
nohup ros2 launch bringup "${NAME}.py" >/dev/null 2>&1 &
disown
echo "[launch.sh] ✅ launched in background (forever mode, pid=$!)"
fi
echo "[launch.sh] ✅ exit"
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# scripts/shell.sh —— 进入容器开发终端(交互式)
#
# 使用:
# bash scripts/shell.sh (WSL / Git Bash / Linux / macOS)
#
# 容器长跑命令 = `tail -f /dev/null`,跟 docker-compose 等价。
set -eo pipefail
CONTAINER="${CONTAINER:-ros2_dev}"
# 容器已跑 → 直接 exec
if docker ps --format '{{.Names}}' | grep -qx "${CONTAINER}"; then
exec docker exec -it "${CONTAINER}" bash -lc \
'source /opt/ros/humble/setup.bash; source /root/ros2_ws/install/setup.bash; cd /root/ros2_ws; exec bash'
fi
# 容器没跑 → 尝试 start,不行就 run(用宿主当前目录挂进去)
if docker ps -a --format '{{.Names}}' | grep -qx "${CONTAINER}"; then
docker start "${CONTAINER}" >/dev/null
exec docker exec -it "${CONTAINER}" bash -lc \
'source /opt/ros/humble/setup.bash; source /root/ros2_ws/install/setup.bash; cd /root/ros2_ws; exec bash'
fi
echo "[shell.sh] 容器 ${CONTAINER} 不存在,自动用本目录启动..."
docker run -d -it \
--name "${CONTAINER}" \
-v "${PWD}:/root/ros2_ws" \
--network ros2_net \
ros2-humble-dev:latest \
bash >/dev/null
exec docker exec -it "${CONTAINER}" bash -lc \
'source /opt/ros/humble/setup.bash; source /root/ros2_ws/install/setup.bash; cd /root/ros2_ws; exec bash'
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# scripts/test.sh —— 跑 colcon test,所有 12 包
#
# 使用:
# docker exec ros2_dev bash /root/ros2_ws/scripts/test.sh
# make colcon-test
set -eo pipefail
WORKSPACE="${WORKSPACE:-/root/ros2_ws}"
source /opt/ros/humble/setup.bash
cd "${WORKSPACE}"
colcon test \
--packages-select \
py_pubsub cpp_pubsub py_srv py_action_demo \
cpp_robot_tf2 py_vision_demo py_params \
cpp_custom_interface py_lifecycle_composable \
cpp_qos_demo py_overlay_dds bringup
echo
echo "[test.sh] === 测试结果汇总 ==="
colcon test-result --all
echo "[test.sh] (要看详细日志,跑: colcon test-result --all --verbose)"