sweeper_whu/ros2_nodes.sh

191 lines
5.6 KiB
Bash
Raw Permalink Normal View History

2025-08-29 16:37:57 +08:00
#!/bin/bash
###############################################################################
# ros2_nodes.sh
2025-09-02 17:16:28 +08:00
# 一键启动 / 停止 / 重启 / 状态查询 6 个 ROS 2 节点(或仅核心 4 节点)
2025-08-29 16:37:57 +08:00
# 用法:
2025-09-02 17:16:28 +08:00
# ./ros2_nodes.sh start # 默认启动全部 6 节点
2025-08-29 16:37:57 +08:00
# ./ros2_nodes.sh start all # 同上
# ./ros2_nodes.sh start core # 仅启动 4 个核心节点
# ./ros2_nodes.sh stop # 停止
# ./ros2_nodes.sh restart [core] # 重启(可选 core / all
# ./ros2_nodes.sh status # 查看状态
# ./ros2_nodes.sh rotate # 手动轮换日志
###############################################################################
##== 基本路径与环境 ===========================================================
2025-09-02 17:16:28 +08:00
WORKSPACE_PATH="/home/nvidia/Downloads/sweeper_whu"
2025-08-29 16:37:57 +08:00
source "$WORKSPACE_PATH/install/setup.bash"
##== 日志目录与轮换配置 =======================================================
LOG_DIR="/var/log/ros2"
MAX_LOG_SIZE="10M" # 单个日志大小
MAX_LOG_FILES=5 # 保留文件数
##== 节点命令列表 ==============================================================
2025-09-02 17:16:28 +08:00
# 1) 全量 6 节点(键名 = 节点标识 , 值 = 启动命令)
2025-08-29 16:37:57 +08:00
declare -A NODES_ALL=(
2025-09-02 17:16:28 +08:00
["mc"]="ros2 run mc mc_node"
2025-08-29 16:37:57 +08:00
["radio_ctrl"]="ros2 run radio_ctrl radio_ctrl_node"
["ctrl_arbiter"]="ros2 run ctrl_arbiter ctrl_arbiter_node"
["mqtt_report"]="ros2 run mqtt_report mqtt_report_node"
["rtk"]="ros2 run rtk rtk_node"
["pub_gps"]="ros2 run pub_gps pub_gps_node"
)
# 2) 核心节点名称数组(便于 core 模式筛选)
CORE_NAMES=(mc radio_ctrl ctrl_arbiter mqtt_report)
##== 函数 =====================================================================
# 预启动环境准备CAN、USB 权限、日志目录与 logrotate
setup_environment() {
echo "[INFO] 设置 CAN0 波特率为 500K..."
sudo ip link set can0 down 2>/dev/null
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up
echo "[INFO] CAN0 配置完成。"
echo "[INFO] 设置 /dev/ttyUSB0 权限为 777..."
sudo chmod 777 /dev/ttyUSB0
echo "[INFO] ttyUSB0 权限设置完成。"
echo "[INFO] 设置 /dev/ttyTHS1 权限为 777..."
sudo chmod 777 /dev/ttyTHS1
echo "[INFO] ttyTHS1 权限设置完成。"
# 日志目录
echo "[INFO] 创建日志目录: $LOG_DIR"
sudo mkdir -p "$LOG_DIR"
sudo chown -R nvidia:nvidia "$LOG_DIR"
# logrotate 配置
local LOGROTATE_CONF="/etc/logrotate.d/ros2_nodes"
echo "[INFO] 配置 logrotate: $LOGROTATE_CONF"
sudo bash -c "cat > $LOGROTATE_CONF" <<EOF
$LOG_DIR/*.log {
su nvidia nvidia
daily
maxsize $MAX_LOG_SIZE
rotate $MAX_LOG_FILES
missingok
notifempty
compress
delaycompress
sharedscripts
copytruncate
}
EOF
}
# 启动节点start_nodes [core|all]
start_nodes() {
local mode=${1:-all} # 默认 all
setup_environment
# 选择节点集合
local names=()
if [[ "$mode" == "core" ]]; then
names=("${CORE_NAMES[@]}")
else
names=("${!NODES_ALL[@]}")
fi
echo "[INFO] 启动模式: $mode"
echo "[INFO] 节点列表: ${names[*]}"
echo "[INFO] 每个节点启动间隔 0.1s"
for name in "${names[@]}"; do
echo "[START] $name"
local log_file="${LOG_DIR}/${name}.log"
#=====================================================================
${NODES_ALL[$name]} >> "$log_file" 2>&1 &
# gnome-terminal --title="$name" \
# -- bash -c "source $WORKSPACE_PATH/install/setup.bash && ${NODES_ALL[$name]}; exec bash" &
#=====================================================================
local pid=$!
echo $pid > "/tmp/$name.pid"
echo "[INFO] $name PID: $pid | 日志: $log_file"
sleep 0.1 # 每个节点之间暂停 0.1 秒
done
echo "[INFO] 所有节点已启动 (${mode})."
}
# 停止全部正在运行的节点
stop_nodes() {
echo "[INFO] 停止 ROS 2 节点..."
for pidfile in /tmp/*.pid; do
[ -e "$pidfile" ] || continue
local name=$(basename "$pidfile" .pid)
local pid=$(cat "$pidfile")
if ps -p "$pid" > /dev/null 2>&1; then
kill -SIGINT "$pid" && echo "[STOP] $name (PID $pid) - 发送 SIGINT"
local timeout=5
while kill -0 "$pid" 2>/dev/null && [ $timeout -gt 0 ]; do
sleep 0.5; ((timeout--))
done
if kill -0 "$pid" 2>/dev/null; then
kill -9 "$pid" && echo "[STOP] $name (PID $pid) - 强制终止"
fi
fi
rm -f "$pidfile"
done
echo "[INFO] 所有节点已停止。"
}
# 手动触发日志轮换
rotate_logs() {
echo "[INFO] 手动轮换日志..."
sudo logrotate -f /etc/logrotate.d/ros2_nodes
echo "[INFO] 日志轮换完成。"
}
# 查看节点运行状态
show_status() {
echo "[INFO] 节点状态:"
for name in "${!NODES_ALL[@]}"; do
if [ -f "/tmp/$name.pid" ]; then
local pid=$(cat "/tmp/$name.pid")
if ps -p "$pid" > /dev/null 2>&1; then
echo "[RUNNING] $name (PID $pid)"
else
echo "[DEAD] $name (PID $pid)"
fi
else
echo "[STOPPED] $name"
fi
done
}
##== 主入口 ===================================================================
case "$1" in
start)
# 用法: ./ros2_nodes.sh start [core|all]
start_nodes "${2:-all}"
;;
stop)
stop_nodes
;;
restart)
stop_nodes
sleep 1
start_nodes "${2:-all}"
;;
rotate)
rotate_logs
;;
status)
show_status
;;
*)
echo "Usage: $0 {start|stop|restart|rotate|status} [core|all]"
echo " core : 仅启动 4 个核心节点 (mc radio_ctrl ctrl_arbiter mqtt_report)"
2025-09-02 17:16:28 +08:00
echo " all : 启动全部 6 个节点 (默认)"
2025-08-29 16:37:57 +08:00
;;
esac