更新 run_all.sh
This commit is contained in:
parent
6431727f4a
commit
7c4ff06d3b
692
run_all.sh
692
run_all.sh
|
|
@ -1,345 +1,347 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
export DISPLAY=:1
|
||||||
# Unified launcher for TurtleBot3 office workflow:
|
|
||||||
# - Terminal A: simulation / bridge / (optional SLAM) / RViz
|
# Unified launcher for TurtleBot3 office workflow:
|
||||||
# - Terminal B: Nav2
|
# - Terminal A: simulation / bridge / (optional SLAM) / RViz
|
||||||
# - Optional C: explore_lite
|
# - Terminal B: Nav2
|
||||||
# - Optional websocket + gzweb-demo frontend
|
# - Optional C: explore_lite
|
||||||
#
|
# - Optional websocket + gzweb-demo frontend
|
||||||
# Modes:
|
#
|
||||||
# mapping : online SLAM mapping
|
# Modes:
|
||||||
# localization : map-based localization/navigation
|
# mapping : online SLAM mapping
|
||||||
#
|
# localization : map-based localization/navigation
|
||||||
# Mapping mode interactive commands:
|
#
|
||||||
# s : save map and switch to localization mode
|
# Mapping mode interactive commands:
|
||||||
# q : stop all
|
# s : save map and switch to localization mode
|
||||||
#
|
# q : stop all
|
||||||
# Examples:
|
#
|
||||||
# ./run_all.sh mapping --explore --gzweb
|
# Examples:
|
||||||
# ./run_all.sh localization --gzweb --map /abs/path/office_map.yaml
|
# ./run_all.sh mapping --explore --gzweb
|
||||||
|
# ./run_all.sh localization --gzweb --map /abs/path/office_map.yaml
|
||||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
MODE="${1:-mapping}"
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
shift || true
|
MODE="${1:-mapping}"
|
||||||
|
shift || true
|
||||||
ROBOT_MODEL="${ROBOT_MODEL:-waffle}"
|
|
||||||
USE_SIM_TIME="${USE_SIM_TIME:-true}"
|
ROBOT_MODEL="${ROBOT_MODEL:-waffle}"
|
||||||
GZ_PARTITION="${GZ_PARTITION:-tb3_office_gz}"
|
USE_SIM_TIME="${USE_SIM_TIME:-true}"
|
||||||
WORLD_PATH_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/worlds/office_gz_dartsim.sdf"
|
GZ_PARTITION="${GZ_PARTITION:-tb3_office_gz}"
|
||||||
MAP_YAML_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/map/office_map.yaml"
|
WORLD_PATH_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/worlds/office_gz_dartsim.sdf"
|
||||||
MAP_BASENAME_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/map/office_map"
|
MAP_YAML_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/map/office_map.yaml"
|
||||||
SLEEP_NAV2="${SLEEP_NAV2:-18}"
|
MAP_BASENAME_DEFAULT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/map/office_map"
|
||||||
EXPLORE_WAIT_TIMEOUT="${EXPLORE_WAIT_TIMEOUT:-420}"
|
SLEEP_NAV2="${SLEEP_NAV2:-18}"
|
||||||
|
EXPLORE_WAIT_TIMEOUT="${EXPLORE_WAIT_TIMEOUT:-420}"
|
||||||
WORLD_PATH="${WORLD_PATH:-$WORLD_PATH_DEFAULT}"
|
|
||||||
MAP_YAML="${NAV2_MAP_PATH:-$MAP_YAML_DEFAULT}"
|
WORLD_PATH="${WORLD_PATH:-$WORLD_PATH_DEFAULT}"
|
||||||
MAP_BASENAME="${MAP_BASENAME:-$MAP_BASENAME_DEFAULT}"
|
MAP_YAML="${NAV2_MAP_PATH:-$MAP_YAML_DEFAULT}"
|
||||||
|
MAP_BASENAME="${MAP_BASENAME:-$MAP_BASENAME_DEFAULT}"
|
||||||
WITH_EXPLORE=false
|
|
||||||
WITH_GZWE`B`=false
|
WITH_EXPLORE=false
|
||||||
NO_RVIZ=false
|
WITH_GZWE=false
|
||||||
# 与 --gzweb 同用:只起 gz websocket(9002) 等资源,不起 office 内 npm run dev;页面用镜像内 /opt/gzweb(foundation)
|
NO_RVIZ=false
|
||||||
NO_GZWEB_VITE=false
|
# 与 --gzweb 同用:只起 gz websocket(9002) 等资源,不起 office 内 npm run dev;页面用镜像内 /opt/gzweb(foundation)
|
||||||
|
NO_GZWEB_VITE=false
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--explore) WITH_EXPLORE=true; shift ;;
|
while [[ $# -gt 0 ]]; do
|
||||||
--gzweb) WITH_GZWEB=true; shift ;;
|
case "$1" in
|
||||||
--no-gzweb-vite) NO_GZWEB_VITE=true; shift ;;
|
--explore) WITH_EXPLORE=true; shift ;;
|
||||||
--no-rviz) NO_RVIZ=true; shift ;;
|
--gzweb) WITH_GZWEB=true; shift ;;
|
||||||
--map) MAP_YAML="$2"; shift 2 ;;
|
--no-gzweb-vite) NO_GZWEB_VITE=true; shift ;;
|
||||||
--world) WORLD_PATH="$2"; shift 2 ;;
|
--no-rviz) NO_RVIZ=true; shift ;;
|
||||||
--help|-h)
|
--map) MAP_YAML="$2"; shift 2 ;;
|
||||||
cat <<'EOF'
|
--world) WORLD_PATH="$2"; shift 2 ;;
|
||||||
Usage:
|
--help|-h)
|
||||||
./run_all.sh mapping [--explore] [--gzweb] [--no-gzweb-vite] [--no-rviz] [--world PATH]
|
cat <<'EOF'
|
||||||
./run_all.sh localization [--gzweb] [--no-gzweb-vite] [--no-rviz] [--map PATH] [--world PATH]
|
Usage:
|
||||||
|
./run_all.sh mapping [--explore] [--gzweb] [--no-gzweb-vite] [--no-rviz] [--world PATH]
|
||||||
--no-gzweb-vite 需与 --gzweb 同时使用:不启动 workspace 内 gzweb-demo 的 Vite;浏览器用 /opt/gzweb(8000)。
|
./run_all.sh localization [--gzweb] [--no-gzweb-vite] [--no-rviz] [--map PATH] [--world PATH]
|
||||||
EOF
|
|
||||||
exit 0
|
--no-gzweb-vite 需与 --gzweb 同时使用:不启动 workspace 内 gzweb-demo 的 Vite;浏览器用 /opt/gzweb(8000)。
|
||||||
;;
|
EOF
|
||||||
*)
|
exit 0
|
||||||
echo "[run_all] unknown argument: $1" >&2
|
;;
|
||||||
exit 1
|
*)
|
||||||
;;
|
echo "[run_all] unknown argument: $1" >&2
|
||||||
esac
|
exit 1
|
||||||
done
|
;;
|
||||||
|
esac
|
||||||
if [[ "$MODE" != "mapping" && "$MODE" != "localization" ]]; then
|
done
|
||||||
echo "[run_all] mode must be mapping or localization" >&2
|
|
||||||
exit 1
|
if [[ "$MODE" != "mapping" && "$MODE" != "localization" ]]; then
|
||||||
fi
|
echo "[run_all] mode must be mapping or localization" >&2
|
||||||
|
exit 1
|
||||||
if [[ ! -f "$WORLD_PATH" ]]; then
|
fi
|
||||||
echo "[run_all] world not found: $WORLD_PATH" >&2
|
|
||||||
exit 1
|
if [[ ! -f "$WORLD_PATH" ]]; then
|
||||||
fi
|
echo "[run_all] world not found: $WORLD_PATH" >&2
|
||||||
|
exit 1
|
||||||
if [[ "$MODE" == "localization" && ! -f "$MAP_YAML" ]]; then
|
fi
|
||||||
echo "[run_all] map yaml not found: $MAP_YAML" >&2
|
|
||||||
exit 1
|
if [[ "$MODE" == "localization" && ! -f "$MAP_YAML" ]]; then
|
||||||
fi
|
echo "[run_all] map yaml not found: $MAP_YAML" >&2
|
||||||
|
exit 1
|
||||||
set +u
|
fi
|
||||||
source /opt/ros/humble/setup.bash
|
|
||||||
|
set +u
|
||||||
# 仅在 install 目录缺失时构建(避免每次启动都重复构建,同时修复未 source ROS 环境导致的 ament_cmake 找不到)
|
source /opt/ros/humble/setup.bash
|
||||||
if [[ ! -d "${ROOT}/install" ]]; then
|
|
||||||
colcon build --symlink-install
|
# 仅在 install 目录缺失时构建(避免每次启动都重复构建,同时修复未 source ROS 环境导致的 ament_cmake 找不到)
|
||||||
fi
|
if [[ ! -d "${ROOT}/install" ]]; then
|
||||||
|
colcon build --symlink-install
|
||||||
source "${ROOT}/install/setup.bash"
|
fi
|
||||||
set -u
|
|
||||||
export TURTLEBOT3_MODEL="$ROBOT_MODEL"
|
source "${ROOT}/install/setup.bash"
|
||||||
|
set -u
|
||||||
LOG_DIR="${ROOT}/logs/run_all_$(date +%Y%m%d_%H%M%S)"
|
export TURTLEBOT3_MODEL="$ROBOT_MODEL"
|
||||||
mkdir -p "$LOG_DIR"
|
|
||||||
mkdir -p "$(dirname "$MAP_BASENAME")"
|
LOG_DIR="${ROOT}/logs/run_all_$(date +%Y%m%d_%H%M%S)"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
PIDS=()
|
mkdir -p "$(dirname "$MAP_BASENAME")"
|
||||||
|
|
||||||
start_bg() {
|
PIDS=()
|
||||||
local name="$1"; shift
|
|
||||||
local logfile="${LOG_DIR}/${name}.log"
|
start_bg() {
|
||||||
echo "[run_all] starting ${name} ..."
|
local name="$1"; shift
|
||||||
"$@" >"$logfile" 2>&1 &
|
local logfile="${LOG_DIR}/${name}.log"
|
||||||
local pid=$!
|
echo "[run_all] starting ${name} ..."
|
||||||
PIDS+=("$pid")
|
"$@" >"$logfile" 2>&1 &
|
||||||
echo "[run_all] ${name} pid=${pid}, log=${logfile}"
|
local pid=$!
|
||||||
}
|
PIDS+=("$pid")
|
||||||
|
echo "[run_all] ${name} pid=${pid}, log=${logfile}"
|
||||||
cleanup() {
|
}
|
||||||
echo "[run_all] stopping all processes..."
|
|
||||||
for pid in "${PIDS[@]:-}"; do
|
cleanup() {
|
||||||
kill "$pid" 2>/dev/null || true
|
echo "[run_all] stopping all processes..."
|
||||||
done
|
for pid in "${PIDS[@]:-}"; do
|
||||||
}
|
kill "$pid" 2>/dev/null || true
|
||||||
trap cleanup EXIT INT TERM
|
done
|
||||||
|
}
|
||||||
wait_for_topic() {
|
trap cleanup EXIT INT TERM
|
||||||
local topic="$1"
|
|
||||||
local timeout="${2:-60}"
|
wait_for_topic() {
|
||||||
local i=0
|
local topic="$1"
|
||||||
while (( i < timeout )); do
|
local timeout="${2:-60}"
|
||||||
if ros2 topic list 2>/dev/null | grep -Fxq "${topic}"; then
|
local i=0
|
||||||
return 0
|
while (( i < timeout )); do
|
||||||
fi
|
if ros2 topic list 2>/dev/null | grep -Fxq "${topic}"; then
|
||||||
sleep 1
|
return 0
|
||||||
((i+=1))
|
fi
|
||||||
done
|
sleep 1
|
||||||
return 1
|
((i+=1))
|
||||||
}
|
done
|
||||||
|
return 1
|
||||||
wait_for_port() {
|
}
|
||||||
local port="$1"
|
|
||||||
local timeout="${2:-30}"
|
wait_for_port() {
|
||||||
local i=0
|
local port="$1"
|
||||||
while (( i < timeout )); do
|
local timeout="${2:-30}"
|
||||||
if ss -ltn 2>/dev/null | grep -q ":${port} "; then
|
local i=0
|
||||||
return 0
|
while (( i < timeout )); do
|
||||||
fi
|
if ss -ltn 2>/dev/null | grep -q ":${port} "; then
|
||||||
sleep 1
|
return 0
|
||||||
((i+=1))
|
fi
|
||||||
done
|
sleep 1
|
||||||
return 1
|
((i+=1))
|
||||||
}
|
done
|
||||||
|
return 1
|
||||||
wait_for_explore_stop_log() {
|
}
|
||||||
local logfile="$1"
|
|
||||||
local timeout="${2:-900}"
|
wait_for_explore_stop_log() {
|
||||||
local i=0
|
local logfile="$1"
|
||||||
while (( i < timeout )); do
|
local timeout="${2:-900}"
|
||||||
if [[ -f "$logfile" ]] && grep -Eq "All frontiers traversed/tried out, stopping\\.|Exploration stopped\\." "$logfile"; then
|
local i=0
|
||||||
return 0
|
while (( i < timeout )); do
|
||||||
fi
|
if [[ -f "$logfile" ]] && grep -Eq "All frontiers traversed/tried out, stopping\\.|Exploration stopped\\." "$logfile"; then
|
||||||
sleep 1
|
return 0
|
||||||
((i+=1))
|
fi
|
||||||
done
|
sleep 1
|
||||||
return 1
|
((i+=1))
|
||||||
}
|
done
|
||||||
|
return 1
|
||||||
wait_for_explore_stop_log_with_timer() {
|
}
|
||||||
local logfile="$1"
|
|
||||||
local timeout="${2:-900}"
|
wait_for_explore_stop_log_with_timer() {
|
||||||
local start_ts
|
local logfile="$1"
|
||||||
start_ts="$(date +%s)"
|
local timeout="${2:-900}"
|
||||||
local i=0
|
local start_ts
|
||||||
while (( i < timeout )); do
|
start_ts="$(date +%s)"
|
||||||
if [[ -f "$logfile" ]] && grep -Eq "All frontiers traversed/tried out, stopping\\.|Exploration stopped\\." "$logfile"; then
|
local i=0
|
||||||
return 0
|
while (( i < timeout )); do
|
||||||
fi
|
if [[ -f "$logfile" ]] && grep -Eq "All frontiers traversed/tried out, stopping\\.|Exploration stopped\\." "$logfile"; then
|
||||||
if (( i % 10 == 0 )); then
|
return 0
|
||||||
local now_ts elapsed
|
fi
|
||||||
now_ts="$(date +%s)"
|
if (( i % 10 == 0 )); then
|
||||||
elapsed=$(( now_ts - start_ts ))
|
local now_ts elapsed
|
||||||
echo "[run_all] explore elapsed: ${elapsed}s"
|
now_ts="$(date +%s)"
|
||||||
fi
|
elapsed=$(( now_ts - start_ts ))
|
||||||
sleep 1
|
echo "[run_all] explore elapsed: ${elapsed}s"
|
||||||
((i+=1))
|
fi
|
||||||
done
|
sleep 1
|
||||||
return 1
|
((i+=1))
|
||||||
}
|
done
|
||||||
|
return 1
|
||||||
kill_port_listeners() {
|
}
|
||||||
local port="$1"
|
|
||||||
local pids
|
kill_port_listeners() {
|
||||||
pids="$(ss -ltnp 2>/dev/null | grep ":${port} " | sed -E 's/.*pid=([0-9]+).*/\1/' | sort -u || true)"
|
local port="$1"
|
||||||
if [[ -n "${pids}" ]]; then
|
local pids
|
||||||
echo "[run_all] port ${port} already in use, killing: ${pids}"
|
pids="$(ss -ltnp 2>/dev/null | grep ":${port} " | sed -E 's/.*pid=([0-9]+).*/\1/' | sort -u || true)"
|
||||||
kill ${pids} 2>/dev/null || true
|
if [[ -n "${pids}" ]]; then
|
||||||
sleep 1
|
echo "[run_all] port ${port} already in use, killing: ${pids}"
|
||||||
fi
|
kill ${pids} 2>/dev/null || true
|
||||||
}
|
sleep 1
|
||||||
|
fi
|
||||||
show_rviz_arg="show_rviz:=true"
|
}
|
||||||
if [[ "$NO_RVIZ" == true ]]; then
|
|
||||||
show_rviz_arg="show_rviz:=false"
|
show_rviz_arg="show_rviz:=true"
|
||||||
fi
|
if [[ "$NO_RVIZ" == true ]]; then
|
||||||
|
show_rviz_arg="show_rviz:=false"
|
||||||
if [[ "$MODE" == "mapping" ]]; then
|
fi
|
||||||
start_bg "A_sim" \
|
|
||||||
ros2 launch turtlebot3_gazebo turtlebot3_office_gz.launch.py \
|
if [[ "$MODE" == "mapping" ]]; then
|
||||||
robot_model:="$ROBOT_MODEL" \
|
start_bg "A_sim" \
|
||||||
use_sim_time:="$USE_SIM_TIME" \
|
ros2 launch turtlebot3_gazebo turtlebot3_office_gz.launch.py \
|
||||||
start_slam:=true \
|
robot_model:="$ROBOT_MODEL" \
|
||||||
"$show_rviz_arg" \
|
use_sim_time:="$USE_SIM_TIME" \
|
||||||
gz_partition:="$GZ_PARTITION" \
|
start_slam:=true \
|
||||||
gz_world_name:=default \
|
"$show_rviz_arg" \
|
||||||
world:="$WORLD_PATH"
|
gz_partition:="$GZ_PARTITION" \
|
||||||
else
|
gz_world_name:=default \
|
||||||
start_bg "A_sim" \
|
world:="$WORLD_PATH"
|
||||||
ros2 launch turtlebot3_gazebo turtlebot3_office_gz.launch.py \
|
else
|
||||||
robot_model:="$ROBOT_MODEL" \
|
start_bg "A_sim" \
|
||||||
use_sim_time:="$USE_SIM_TIME" \
|
ros2 launch turtlebot3_gazebo turtlebot3_office_gz.launch.py \
|
||||||
start_slam:=false \
|
robot_model:="$ROBOT_MODEL" \
|
||||||
"$show_rviz_arg" \
|
use_sim_time:="$USE_SIM_TIME" \
|
||||||
gz_partition:="$GZ_PARTITION" \
|
start_slam:=false \
|
||||||
gz_world_name:=default \
|
"$show_rviz_arg" \
|
||||||
world:="$WORLD_PATH"
|
gz_partition:="$GZ_PARTITION" \
|
||||||
fi
|
gz_world_name:=default \
|
||||||
|
world:="$WORLD_PATH"
|
||||||
# --gzweb:gz launch(9002) + 可选 office 内 gzweb-demo 的 Vite(5173)。
|
fi
|
||||||
# --gzweb --no-gzweb-vite:不起 office Vite;页面用 foundation 已在 /opt/gzweb:8000 起的实例(见 run_all_fix.sh)。
|
|
||||||
if [[ "$WITH_GZWEB" == true ]]; then
|
# --gzweb:gz launch(9002) + 可选 office 内 gzweb-demo 的 Vite(5173)。
|
||||||
export GZ_PARTITION
|
# --gzweb --no-gzweb-vite:不起 office Vite;页面用 foundation 已在 /opt/gzweb:8000 起的实例(见 run_all_fix.sh)。
|
||||||
OFFICE_MODEL_ROOT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_office"
|
if [[ "$WITH_GZWEB" == true ]]; then
|
||||||
RESOURCE_PATHS=(
|
export GZ_PARTITION
|
||||||
"${HOME}/.gazebo/models"
|
OFFICE_MODEL_ROOT="${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_office"
|
||||||
"${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/models"
|
RESOURCE_PATHS=(
|
||||||
"${OFFICE_MODEL_ROOT}"
|
"${HOME}/.gazebo/models"
|
||||||
)
|
"${ROOT}/turtlebot3_simulations/turtlebot3_gazebo/models"
|
||||||
for d in "${OFFICE_MODEL_ROOT}"/*/materials/scripts "${OFFICE_MODEL_ROOT}"/*/materials/textures; do
|
"${OFFICE_MODEL_ROOT}"
|
||||||
[[ -d "${d}" ]] && RESOURCE_PATHS+=("${d}")
|
)
|
||||||
done
|
for d in "${OFFICE_MODEL_ROOT}"/*/materials/scripts "${OFFICE_MODEL_ROOT}"/*/materials/textures; do
|
||||||
RESOURCE_PATH_JOINED="$(IFS=:; echo "${RESOURCE_PATHS[*]}")"
|
[[ -d "${d}" ]] && RESOURCE_PATHS+=("${d}")
|
||||||
export GZ_SIM_RESOURCE_PATH="${RESOURCE_PATH_JOINED}"
|
done
|
||||||
# Keep compatibility with components resolving textures via legacy lookup vars.
|
RESOURCE_PATH_JOINED="$(IFS=:; echo "${RESOURCE_PATHS[*]}")"
|
||||||
export GZ_FILE_PATH="${RESOURCE_PATH_JOINED}"
|
export GZ_SIM_RESOURCE_PATH="${RESOURCE_PATH_JOINED}"
|
||||||
export GAZEBO_RESOURCE_PATH="${RESOURCE_PATH_JOINED}"
|
# Keep compatibility with components resolving textures via legacy lookup vars.
|
||||||
|
export GZ_FILE_PATH="${RESOURCE_PATH_JOINED}"
|
||||||
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
export GAZEBO_RESOURCE_PATH="${RESOURCE_PATH_JOINED}"
|
||||||
if [[ ! -d "${ROOT}/gzweb-demo/gzweb-demo/node_modules/gzweb" ]]; then
|
|
||||||
echo "[run_all] gzweb demo dependencies missing, running npm install once..."
|
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
||||||
bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm install"
|
if [[ ! -d "${ROOT}/gzweb-demo/gzweb-demo/node_modules/gzweb" ]]; then
|
||||||
fi
|
echo "[run_all] gzweb demo dependencies missing, running npm install once..."
|
||||||
else
|
bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm install"
|
||||||
echo "[run_all] --no-gzweb-vite: skipping office gzweb-demo npm install; use /opt/gzweb (port 8000) for UI."
|
fi
|
||||||
fi
|
else
|
||||||
|
echo "[run_all] --no-gzweb-vite: skipping office gzweb-demo npm install; use /opt/gzweb (port 8000) for UI."
|
||||||
kill_port_listeners 9002
|
fi
|
||||||
kill_port_listeners 5173
|
|
||||||
|
kill_port_listeners 9002
|
||||||
echo "[run_all] waiting for /clock before websocket..."
|
kill_port_listeners 5173
|
||||||
if wait_for_topic "/clock" 25; then
|
|
||||||
start_bg "D_websocket" gz launch "${ROOT}/websocket.sdf"
|
echo "[run_all] waiting for /clock before websocket..."
|
||||||
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
if wait_for_topic "/clock" 25; then
|
||||||
start_bg "E_gzweb_frontend" bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm run dev:host"
|
start_bg "D_websocket" gz launch "${ROOT}/websocket.sdf"
|
||||||
echo "[run_all] office gzweb-demo Vite: http://localhost:5173"
|
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
||||||
fi
|
start_bg "E_gzweb_frontend" bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm run dev:host"
|
||||||
else
|
echo "[run_all] office gzweb-demo Vite: http://localhost:5173"
|
||||||
echo "[run_all] WARN: /clock not detected in time; starting websocket (and optional frontend) anyway."
|
fi
|
||||||
start_bg "D_websocket" gz launch "${ROOT}/websocket.sdf"
|
else
|
||||||
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
echo "[run_all] WARN: /clock not detected in time; starting websocket (and optional frontend) anyway."
|
||||||
start_bg "E_gzweb_frontend" bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm run dev:host"
|
start_bg "D_websocket" gz launch "${ROOT}/websocket.sdf"
|
||||||
fi
|
if [[ "$NO_GZWEB_VITE" != true ]]; then
|
||||||
fi
|
start_bg "E_gzweb_frontend" bash -lc "cd '${ROOT}/gzweb-demo/gzweb-demo' && npm run dev:host"
|
||||||
|
fi
|
||||||
if wait_for_port 9002 12; then
|
fi
|
||||||
echo "[run_all] websocket server ready on ws://localhost:9002"
|
|
||||||
else
|
if wait_for_port 9002 12; then
|
||||||
echo "[run_all] ERROR: websocket server failed on 9002; check ${LOG_DIR}/D_websocket.log"
|
echo "[run_all] websocket server ready on ws://localhost:9002"
|
||||||
fi
|
else
|
||||||
fi
|
echo "[run_all] ERROR: websocket server failed on 9002; check ${LOG_DIR}/D_websocket.log"
|
||||||
|
fi
|
||||||
echo "[run_all] waiting ${SLEEP_NAV2}s before starting Nav2..."
|
fi
|
||||||
sleep "$SLEEP_NAV2"
|
|
||||||
|
echo "[run_all] waiting ${SLEEP_NAV2}s before starting Nav2..."
|
||||||
if [[ "$MODE" == "mapping" ]]; then
|
sleep "$SLEEP_NAV2"
|
||||||
start_bg "B_nav2" ros2 launch nav2_bringup navigation_launch.py use_sim_time:="$USE_SIM_TIME"
|
|
||||||
else
|
if [[ "$MODE" == "mapping" ]]; then
|
||||||
start_bg "B_nav2" \
|
start_bg "B_nav2" ros2 launch nav2_bringup navigation_launch.py use_sim_time:="$USE_SIM_TIME"
|
||||||
ros2 launch nav2_bringup bringup_launch.py \
|
else
|
||||||
use_sim_time:="$USE_SIM_TIME" \
|
start_bg "B_nav2" \
|
||||||
map:="$MAP_YAML" \
|
ros2 launch nav2_bringup bringup_launch.py \
|
||||||
slam:=false
|
use_sim_time:="$USE_SIM_TIME" \
|
||||||
fi
|
map:="$MAP_YAML" \
|
||||||
|
slam:=false
|
||||||
if [[ "$WITH_EXPLORE" == true && "$MODE" == "mapping" ]]; then
|
fi
|
||||||
start_bg "C_explore" ros2 launch explore_lite explore.launch.py use_sim_time:="$USE_SIM_TIME"
|
|
||||||
last_index=$(( ${#PIDS[@]} - 1 ))
|
if [[ "$WITH_EXPLORE" == true && "$MODE" == "mapping" ]]; then
|
||||||
EXPLORE_PID="${PIDS[$last_index]}"
|
start_bg "C_explore" ros2 launch explore_lite explore.launch.py use_sim_time:="$USE_SIM_TIME"
|
||||||
EXPLORE_LOG="${LOG_DIR}/C_explore.log"
|
last_index=$(( ${#PIDS[@]} - 1 ))
|
||||||
fi
|
EXPLORE_PID="${PIDS[$last_index]}"
|
||||||
|
EXPLORE_LOG="${LOG_DIR}/C_explore.log"
|
||||||
echo
|
fi
|
||||||
echo "[run_all] started. Mode: ${MODE}"
|
|
||||||
echo "[run_all] logs: ${LOG_DIR}"
|
echo
|
||||||
echo
|
echo "[run_all] started. Mode: ${MODE}"
|
||||||
|
echo "[run_all] logs: ${LOG_DIR}"
|
||||||
if [[ "$MODE" == "mapping" ]]; then
|
echo
|
||||||
if [[ "$WITH_GZWEB" == true ]]; then
|
|
||||||
if [[ "$NO_GZWEB_VITE" == true ]]; then
|
if [[ "$MODE" == "mapping" ]]; then
|
||||||
echo "[run_all] UI: foundation /opt/gzweb on port 8000 (no office Vite)."
|
if [[ "$WITH_GZWEB" == true ]]; then
|
||||||
elif wait_for_port 5173 25; then
|
if [[ "$NO_GZWEB_VITE" == true ]]; then
|
||||||
echo "[run_all] office gzweb-demo ready: http://localhost:5173"
|
echo "[run_all] UI: foundation /opt/gzweb on port 8000 (no office Vite)."
|
||||||
else
|
elif wait_for_port 5173 25; then
|
||||||
echo "[run_all] WARN: office gzweb frontend not ready yet, check ${LOG_DIR}/E_gzweb_frontend.log"
|
echo "[run_all] office gzweb-demo ready: http://localhost:5173"
|
||||||
fi
|
else
|
||||||
fi
|
echo "[run_all] WARN: office gzweb frontend not ready yet, check ${LOG_DIR}/E_gzweb_frontend.log"
|
||||||
|
fi
|
||||||
if [[ "${WITH_EXPLORE}" == true && -n "${EXPLORE_PID:-}" ]]; then
|
fi
|
||||||
echo "[run_all] exploration is running (pid=${EXPLORE_PID}), waiting for stop signal (timeout=${EXPLORE_WAIT_TIMEOUT}s)..."
|
|
||||||
if wait_for_explore_stop_log_with_timer "${EXPLORE_LOG}" "${EXPLORE_WAIT_TIMEOUT}"; then
|
if [[ "${WITH_EXPLORE}" == true && -n "${EXPLORE_PID:-}" ]]; then
|
||||||
echo "[run_all] detected exploration stop from log, finalizing explore process..."
|
echo "[run_all] exploration is running (pid=${EXPLORE_PID}), waiting for stop signal (timeout=${EXPLORE_WAIT_TIMEOUT}s)..."
|
||||||
else
|
if wait_for_explore_stop_log_with_timer "${EXPLORE_LOG}" "${EXPLORE_WAIT_TIMEOUT}"; then
|
||||||
echo "[run_all] WARN: explore stop not detected within timeout; forcing stop and saving current map."
|
echo "[run_all] detected exploration stop from log, finalizing explore process..."
|
||||||
fi
|
else
|
||||||
kill "${EXPLORE_PID}" 2>/dev/null || true
|
echo "[run_all] WARN: explore stop not detected within timeout; forcing stop and saving current map."
|
||||||
wait "${EXPLORE_PID}" 2>/dev/null || true
|
fi
|
||||||
echo "[run_all] explore_lite stopped, now saving map."
|
kill "${EXPLORE_PID}" 2>/dev/null || true
|
||||||
fi
|
wait "${EXPLORE_PID}" 2>/dev/null || true
|
||||||
|
echo "[run_all] explore_lite stopped, now saving map."
|
||||||
if [[ "${WITH_EXPLORE}" == true ]]; then
|
fi
|
||||||
echo "[run_all] auto-saving map to ${MAP_BASENAME}.yaml/.pgm ..."
|
|
||||||
ros2 run nav2_map_server map_saver_cli -f "$MAP_BASENAME" --ros-args -p use_sim_time:="$USE_SIM_TIME"
|
if [[ "${WITH_EXPLORE}" == true ]]; then
|
||||||
echo "[run_all] map saved successfully:"
|
echo "[run_all] auto-saving map to ${MAP_BASENAME}.yaml/.pgm ..."
|
||||||
echo " - ${MAP_BASENAME}.yaml"
|
ros2 run nav2_map_server map_saver_cli -f "$MAP_BASENAME" --ros-args -p use_sim_time:="$USE_SIM_TIME"
|
||||||
echo " - ${MAP_BASENAME}.pgm"
|
echo "[run_all] map saved successfully:"
|
||||||
echo "[run_all] mapping workflow completed, exiting now."
|
echo " - ${MAP_BASENAME}.yaml"
|
||||||
exit 0
|
echo " - ${MAP_BASENAME}.pgm"
|
||||||
fi
|
echo "[run_all] mapping workflow completed, exiting now."
|
||||||
|
exit 0
|
||||||
cat <<EOF
|
fi
|
||||||
[run_all] Mapping mode notes:
|
|
||||||
- RViz 'Localization: inactive' is normal during SLAM mapping.
|
cat <<EOF
|
||||||
- You did not enable --explore, so auto-save/auto-exit is disabled.
|
[run_all] Mapping mode notes:
|
||||||
- Press Ctrl+C when you want to stop all.
|
- RViz 'Localization: inactive' is normal during SLAM mapping.
|
||||||
EOF
|
- You did not enable --explore, so auto-save/auto-exit is disabled.
|
||||||
wait
|
- Press Ctrl+C when you want to stop all.
|
||||||
else
|
EOF
|
||||||
echo "[run_all] Localization mode: RViz Localization should become active after initial pose."
|
wait
|
||||||
echo "[run_all] Keep this terminal running; Ctrl+C to stop all."
|
else
|
||||||
wait
|
echo "[run_all] Localization mode: RViz Localization should become active after initial pose."
|
||||||
fi
|
echo "[run_all] Keep this terminal running; Ctrl+C to stop all."
|
||||||
|
wait
|
||||||
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue