DroneMind/voice_drone_assistant/scripts/run_flight_bridge_with_mavros.sh
2026-04-14 09:59:51 +08:00

147 lines
4.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 一键roscore若还没有→ MAVROS串口连 PX4→ flight_intent 伴飞桥(前台,直到 Ctrl+C
#
# 适合「不想自己敲 roslaunch」时直接跑用法与 run_px4_offboard_one_terminal.sh 前两参一致。
#
# 在 voice_drone_assistant 根目录:
# bash scripts/run_flight_bridge_with_mavros.sh
# bash scripts/run_flight_bridge_with_mavros.sh /dev/ttyACM0 921600
#
# 飞控连上后,另开终端发 JSONstd_msgs/String 必须用 YAML 字段 data见 docs/FLIGHT_BRIDGE_ROS1.md
# source /opt/ros/noetic/setup.bash
# rostopic pub -1 /input std_msgs/String \
# "data: '{\"is_flight_intent\":true,\"version\":1,\"actions\":[{\"type\":\"land\",\"args\":{}}],\"summary\":\"降\"}'"
#
# 环境变量(可选):
# ROS_MASTER_URI 默认 http://127.0.0.1:11311
# ROS_HOSTNAME 默认 127.0.0.1
# BRIDGE_PYTHON 若不设则 python3与 mavros 同机即可,不必 conda
# OFFBOARD_PYTHON 未设 BRIDGE_PYTHON 时也试 yanshi 环境(与 offboard 脚本习惯一致)
#
# Ctrl+C结束伴飞桥并停止本脚本拉起的 MAVROS若 roscore 由本脚本启动则一并结束。
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$ROOT"
if [[ ! -f /opt/ros/noetic/setup.bash ]]; then
echo "未找到 /opt/ros/noetic/setup.bash伴飞桥当前仅支持 ROS1 Noetic" >&2
exit 2
fi
# shellcheck source=/dev/null
source /opt/ros/noetic/setup.bash
export ROS_MASTER_URI="${ROS_MASTER_URI:-http://127.0.0.1:11311}"
export ROS_HOSTNAME="${ROS_HOSTNAME:-127.0.0.1}"
DEV="${1:-/dev/ttyACM0}"
BAUD="${2:-921600}"
FCU_URL="${DEV}:${BAUD}"
ROSCORE_PID=""
MAVROS_PID=""
WE_STARTED_ROSCORE=0
master_ok() {
timeout 3 rosnode list &>/dev/null
}
stop_mavros() {
pkill -f '/opt/ros/noetic/lib/mavros/mavros_node' 2>/dev/null || true
}
kill_children() {
if [[ -n "${MAVROS_PID:-}" ]] && kill -0 "$MAVROS_PID" 2>/dev/null; then
kill "$MAVROS_PID" 2>/dev/null || true
wait "$MAVROS_PID" 2>/dev/null || true
fi
if [[ "${WE_STARTED_ROSCORE}" -eq 1 ]] && [[ -n "${ROSCORE_PID:-}" ]] && kill -0 "$ROSCORE_PID" 2>/dev/null; then
kill "$ROSCORE_PID" 2>/dev/null || true
wait "$ROSCORE_PID" 2>/dev/null || true
fi
}
trap 'kill_children; exit 130' INT
trap 'kill_children; exit 143' TERM
resolve_python() {
if [[ -n "${BRIDGE_PYTHON:-}" ]] && [[ -x "$BRIDGE_PYTHON" ]]; then
echo "$BRIDGE_PYTHON"
return
fi
if [[ -n "${OFFBOARD_PYTHON:-}" ]] && [[ -x "$OFFBOARD_PYTHON" ]]; then
echo "$OFFBOARD_PYTHON"
return
fi
for cand in \
"${HOME}/miniconda3/envs/yanshi/bin/python" \
"${HOME}/anaconda3/envs/yanshi/bin/python" \
"${HOME}/mambaforge/envs/yanshi/bin/python"; do
if [[ -x "$cand" ]]; then
echo "$cand"
return
fi
done
command -v python3
}
echo "===== flight_intent 伴飞桥(含 MAVROSfcu_url=${FCU_URL} ====="
if ! master_ok; then
echo "[1/3] 启动 roscore …"
roscore > /tmp/roscore_flight_bridge.log 2>&1 &
ROSCORE_PID=$!
WE_STARTED_ROSCORE=1
for _ in $(seq 1 50); do
master_ok && break
sleep 0.2
done
if ! master_ok; then
echo "roscore 未起来: tail -40 /tmp/roscore_flight_bridge.log" >&2
kill_children
exit 1
fi
echo "roscore 已就绪 (pid=$ROSCORE_PID)"
else
echo "[1/3] 已有 ROS master跳过 roscore"
fi
echo "[2/3] 启动 MAVROS …"
stop_mavros
sleep 1
roslaunch mavros px4.launch fcu_url:="$FCU_URL" > /tmp/mavros_flight_bridge.log 2>&1 &
MAVROS_PID=$!
echo "等待飞控 connected=true超时 60s…"
connected=0
for _ in $(seq 1 60); do
if timeout 4 rostopic echo /mavros/state -n 1 2>/dev/null | grep -qE 'connected: [Tt]rue'; then
connected=1
break
fi
sleep 1
done
if [[ "$connected" -ne 1 ]]; then
echo "仍未连上飞控。检查串口/波特率: tail -60 /tmp/mavros_flight_bridge.log" >&2
echo "可重试: bash $0 ${DEV} 57600" >&2
kill_children
exit 1
fi
echo "MAVROS 已连接飞控"
PY="$(resolve_python)"
export PYTHONPATH="${PYTHONPATH:-}:${ROOT}"
echo "[3/3] 启动伴飞桥Python: $PY)…"
echo " Ctrl+C 退出并清理本脚本启动的 MAVROS$([[ "$WE_STARTED_ROSCORE" -eq 1 ]] && echo +roscore)"
echo " 发意图: 另开终端 source noetic 后 rostopic pub ... 见脚本头注释。"
set +e
"$PY" -m voice_drone.flight_bridge.ros1_node
BRIDGE_EXIT=$?
set -e
kill_children
exit "$BRIDGE_EXIT"