这篇文档把一套常用的清理函数整理成简单版本,适合日常排查:
- ROS 2 进程残留
- Gazebo 进程冲突
- Fast DDS 共享内存脏状态
- ROS_DOMAIN_ID 混乱导致看不到话题
1. 你会得到什么
两个函数:
ros_domain <id>:只切换ROS_DOMAIN_IDros_clean [id]:清理 ROS/Gazebo 相关环境,可选同时切换ROS_DOMAIN_ID
2. 函数代码(可直接放到 ~/.bashrc)
bash
# ==============================
# ROS 2 / Gazebo / Autoware clean helpers
# Usage:
# ros_clean # clean processes + daemon + shm
# ros_clean 0 # same as above, then export ROS_DOMAIN_ID=0
# ros_clean 42 # same as above, then export ROS_DOMAIN_ID=42
# ros_domain 0 # only switch ROS_DOMAIN_ID
# ==============================
ros_domain() {
if [ -z "$1" ]; then
echo "Usage: ros_domain <id>"
return 1
fi
export ROS_DOMAIN_ID="$1"
echo "[ros_domain] ROS_DOMAIN_ID set to: $ROS_DOMAIN_ID"
}
ros_clean() {
local NEW_DOMAIN_ID="$1"
echo "======================================"
echo "[ros_clean] Start cleaning ROS/Gazebo"
echo "======================================"
echo "[1/9] Killing ROS 2 / Autoware / RViz / Gazebo related processes..."
# ROS 2 / Autoware common
pkill -9 -f "ros2" 2>/dev/null
pkill -9 -f "rviz" 2>/dev/null
pkill -9 -f "rviz2" 2>/dev/null
pkill -9 -f "autoware" 2>/dev/null
pkill -9 -f "component_container" 2>/dev/null
pkill -9 -f "component_container_mt" 2>/dev/null
pkill -9 -f "component_container_isolated" 2>/dev/null
pkill -9 -f "static_transform_publisher" 2>/dev/null
pkill -9 -f "robot_state_publisher" 2>/dev/null
pkill -9 -f "joint_state_publisher" 2>/dev/null
pkill -9 -f "joint_state_broadcaster" 2>/dev/null
pkill -9 -f "parameter_bridge" 2>/dev/null
pkill -9 -f "pointcloud_to_laserscan" 2>/dev/null
pkill -9 -f "slam_toolbox" 2>/dev/null
pkill -9 -f "nav2" 2>/dev/null
pkill -9 -f "planner_server" 2>/dev/null
pkill -9 -f "controller_server" 2>/dev/null
pkill -9 -f "bt_navigator" 2>/dev/null
pkill -9 -f "waypoint_follower" 2>/dev/null
pkill -9 -f "map_server" 2>/dev/null
pkill -9 -f "amcl" 2>/dev/null
echo "[2/9] Killing Gazebo / Ignition / gz simulator related processes..."
# Gazebo classic / Ignition / Gazebo Sim
pkill -9 -f "gz sim" 2>/dev/null
pkill -9 -f "gzserver" 2>/dev/null
pkill -9 -f "gzclient" 2>/dev/null
pkill -9 -f "gazebo" 2>/dev/null
pkill -9 -f "ign gazebo" 2>/dev/null
pkill -9 -f "ignition" 2>/dev/null
pkill -9 -f "ruby $(which ign)" 2>/dev/null
pkill -9 -f "ruby $(which gz)" 2>/dev/null
echo "[3/9] Killing ros_gz / gazebo bridge / control helpers..."
pkill -9 -f "ros_gz" 2>/dev/null
pkill -9 -f "ros_ign" 2>/dev/null
pkill -9 -f "spawn_entity" 2>/dev/null
pkill -9 -f "create " 2>/dev/null
pkill -9 -f "spawner" 2>/dev/null
pkill -9 -f "controller_manager" 2>/dev/null
pkill -9 -f "gz_ros2_control" 2>/dev/null
echo "[4/9] Stopping ros2 daemon..."
ros2 daemon stop >/dev/null 2>&1
sleep 1
echo "[5/9] Cleaning Fast DDS / shared memory leftovers..."
rm -f /dev/shm/fastrtps_* 2>/dev/null
rm -f /tmp/fastdds_* 2>/dev/null
rm -f /tmp/fastrtps_* 2>/dev/null
echo "[6/9] Cleaning user-level ROS temporary files..."
rm -rf ~/.ros/log/latest 2>/dev/null
find ~/.ros/log -maxdepth 1 -type d -name "20*" -mtime +7 -exec rm -rf {} \; 2>/dev/null
echo "[7/9] Cleaning Gazebo temporary cache (safe subset)..."
rm -rf ~/.gazebo/log/* 2>/dev/null
rm -rf ~/.ignition/gazebo/log/* 2>/dev/null
rm -rf ~/.gz/sim/log/* 2>/dev/null
echo "[8/9] Restarting ros2 daemon..."
ros2 daemon start >/dev/null 2>&1
sleep 1
echo "[9/9] Resetting ROS_DOMAIN_ID if requested..."
if [ -n "$NEW_DOMAIN_ID" ]; then
export ROS_DOMAIN_ID="$NEW_DOMAIN_ID"
echo "[ros_clean] ROS_DOMAIN_ID set to: $ROS_DOMAIN_ID"
else
echo "[ros_clean] ROS_DOMAIN_ID unchanged: ${ROS_DOMAIN_ID:-<unset>}"
fi
echo "--------------------------------------"
echo "[ros_clean] Done."
echo "Current ROS_DOMAIN_ID: ${ROS_DOMAIN_ID:-<unset>}"
echo "Tip: run source ~/.bashrc if needed."
echo "======================================"
}
3. 使用方法(最常用)
3.1 只切换 Domain
bash
ros_domain 88
3.2 清理并保留当前 Domain
bash
ros_clean
3.3 清理并切到指定 Domain
bash
ros_clean 88
4. 推荐排查流程(实战)
bash
ros_clean 88
source ~/.bashrc
# 然后再启动仿真 + Autoware
如果你出现这些症状,优先跑一遍:
ros2 topic list看到的话题不全- 同名节点重复(duplicated node)
- route 已设置但车不走
- 终端和主进程不在同一个
ROS_DOMAIN_ID
5. 注意事项
- 脚本里使用了大量
pkill -9,适合强制清场排障,不适合保留现场调试。 - 如果你有其他 ROS 工程同时运行,也会被一起清掉。
- 多终端场景下,记得每个终端都确认
echo $ROS_DOMAIN_ID。
6. 一句话总结
这套函数的核心价值:
- 先统一清场,再统一 Domain,再重启流程。
对 ROS 2 / Autoware 来说,这一步往往能直接解决大量通信异常问题。