Refactor infrastructure scripts and add mock hardware support
Changes: - Refactor project scripts for better dev/prod workflow separation - Add mock_hardware.py for local development without real hardware - Add Makefile for common commands - Add .env.example for environment variable reference - Split scripts into dev-backend.sh, dev-frontend.sh, prod-backend.sh - Add stop.sh for clean shutdown Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# dev-backend.sh - 本地后端开发启动(Mock 硬件模式)
|
||||
# 用法: ./scripts/dev-backend.sh
|
||||
# 说明: 启动 Flask 后端,使用 Mock 硬件实现,无需真实硬件
|
||||
# ============================================================
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
AGV_APP_DIR="$PROJECT_DIR/agv_app"
|
||||
|
||||
echo "=========================================="
|
||||
echo " 本地开发模式 - Flask 后端 (Mock 硬件)"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo " Mock 硬件模式已启用:"
|
||||
echo " - AGV 控制器: Mock"
|
||||
echo " - 机械臂: Mock"
|
||||
echo " - 摄像头: Mock"
|
||||
echo " - Nav2 导航: Mock"
|
||||
echo ""
|
||||
echo " 访问: http://127.0.0.1:5000"
|
||||
echo " Ctrl+C 停止"
|
||||
echo ""
|
||||
|
||||
# 设置环境变量启用 Mock 模式
|
||||
export MOCK_HARDWARE=1
|
||||
export FLASK_PORT=5000
|
||||
|
||||
cd "$AGV_APP_DIR"
|
||||
exec uv run --locked python app.py
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# dev-frontend.sh - 前端开发启动
|
||||
# 用法: ./scripts/dev-frontend.sh
|
||||
# 说明: 启动 Next.js 开发服务器,API 代理到后端
|
||||
# ============================================================
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
FRONTEND_DIR="$SCRIPT_DIR/../public-frontend"
|
||||
|
||||
echo "=========================================="
|
||||
echo " 前端开发模式 - Next.js"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo " 后端 URL: ${BACKEND_URL:-http://127.0.0.1:5000}"
|
||||
echo " 访问: http://localhost:3000"
|
||||
echo " Ctrl+C 停止"
|
||||
echo ""
|
||||
|
||||
# 确保后端 URL 设置(默认本地)
|
||||
export BACKEND_URL=${BACKEND_URL:-http://127.0.0.1:5000}
|
||||
export NEXT_PUBLIC_BACKEND_URL=${BACKEND_URL}
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
exec npm run dev
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# dev_start.sh - 本地开发环境启动(不启动 ROS2/机械臂硬件)
|
||||
# 用法: ./scripts/dev_start.sh
|
||||
# ============================================================
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
AGV_APP_DIR="$PROJECT_DIR/agv_app"
|
||||
AGV_ROS2_DIR="${AGV_ROS2_DIR:-$HOME/agv_pro_ros2}"
|
||||
ROS_DISTRO="${ROS_DISTRO:-humble}"
|
||||
ROS_SETUP="${ROS_SETUP:-/opt/ros/$ROS_DISTRO/setup.bash}"
|
||||
ROS_WORKSPACE_SETUP="${ROS_WORKSPACE_SETUP:-$AGV_ROS2_DIR/install/setup.bash}"
|
||||
FLASK_PORT="${FLASK_PORT:-5000}"
|
||||
|
||||
echo "=========================================="
|
||||
echo " 本地开发模式 - 仅启动 Flask"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 切换到项目目录
|
||||
source "$ROS_SETUP" 2>/dev/null || true
|
||||
source "$ROS_WORKSPACE_SETUP" 2>/dev/null || true
|
||||
|
||||
cd "$AGV_APP_DIR"
|
||||
|
||||
# 检查是否有运行的 Flask 进程
|
||||
FLASK_PID=$(pgrep -f "python.*app.py" 2>/dev/null || true)
|
||||
if [ -n "$FLASK_PID" ]; then
|
||||
echo "Flask 已在运行 (PID: $FLASK_PID)"
|
||||
read -p "是否重启? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
kill "$FLASK_PID" 2>/dev/null
|
||||
sleep 1
|
||||
else
|
||||
echo "保持现有进程,退出"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 使用前台模式运行(方便看日志和 Ctrl+C 停止)
|
||||
echo "启动 Flask (前台模式,Ctrl+C 停止)..."
|
||||
echo "访问: http://127.0.0.1:$FLASK_PORT"
|
||||
echo ""
|
||||
exec uv run --locked python app.py
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# restart_flask.sh - 语法检查 + 重启 Flask + 验证
|
||||
# 用法: ssh elephant@<AGV_IP> 'bash -s' < scripts/restart_flask.sh
|
||||
# 或在 AGV 上: cd ~/work/smart-inspection && ./scripts/restart_flask.sh
|
||||
# ============================================================
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
AGV_PROJECT_DIR="${AGV_PROJECT_DIR:-$PROJECT_DIR}"
|
||||
AGV_APP_DIR="${AGV_APP_DIR:-$AGV_PROJECT_DIR/agv_app}"
|
||||
AGV_ROS2_DIR="${AGV_ROS2_DIR:-$HOME/agv_pro_ros2}"
|
||||
ROS_DISTRO="${ROS_DISTRO:-humble}"
|
||||
ROS_SETUP="${ROS_SETUP:-/opt/ros/$ROS_DISTRO/setup.bash}"
|
||||
ROS_WORKSPACE_SETUP="${ROS_WORKSPACE_SETUP:-$AGV_ROS2_DIR/install/setup.bash}"
|
||||
LOG_DIR="${LOG_DIR:-/tmp}"
|
||||
FLASK_PORT="${FLASK_PORT:-5000}"
|
||||
FLASK_LOG="$LOG_DIR/agv_flask.log"
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
source "$ROS_SETUP" 2>/dev/null || true
|
||||
source "$ROS_WORKSPACE_SETUP" 2>/dev/null || true
|
||||
|
||||
cd "$AGV_APP_DIR"
|
||||
|
||||
echo "=========================================="
|
||||
echo " 重启 Flask 服务"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 1. 语法检查
|
||||
echo "[1/3] Python 语法检查..."
|
||||
uv run --locked python -m py_compile app.py
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ 语法错误,请先修复"
|
||||
exit 1
|
||||
fi
|
||||
echo " ✅ 语法检查通过"
|
||||
|
||||
# 2. 清缓存 + 重启
|
||||
echo "[2/3] 清理缓存并重启..."
|
||||
find "$AGV_APP_DIR" -name '*.pyc' -delete 2>/dev/null
|
||||
find "$AGV_APP_DIR" -name '__pycache__' -type d -exec rm -rf {} + 2>/dev/null
|
||||
|
||||
pkill -f "python.*app.py" 2>/dev/null || true
|
||||
pkill -f "uv run .*python app.py" 2>/dev/null || true
|
||||
sleep 1
|
||||
nohup uv run --locked python app.py > "$FLASK_LOG" 2>&1 &
|
||||
FLASK_PID=$!
|
||||
echo " Flask PID: $FLASK_PID"
|
||||
|
||||
# 3. 验证
|
||||
echo "[3/3] 验证服务..."
|
||||
sleep 3
|
||||
if ss -tlnp 2>/dev/null | grep -q ":$FLASK_PORT " || netstat -tlnp 2>/dev/null | grep -q ":$FLASK_PORT "; then
|
||||
echo " ✅ 端口 $FLASK_PORT 正常监听"
|
||||
# 测试机械臂摄像头单帧
|
||||
result=$(curl -s --max-time 5 "http://127.0.0.1:$FLASK_PORT/api/camera/arm_refresh" 2>/dev/null | head -c 4)
|
||||
if [ "$result" = "$(echo -en '\xff\xd8\xff\xe0')" ]; then
|
||||
echo " ✅ arm_refresh 返回 JPEG"
|
||||
else
|
||||
echo " ⚠️ arm_refresh 返回异常(机械臂可能未连接)"
|
||||
fi
|
||||
else
|
||||
echo " ❌ 端口 $FLASK_PORT 未监听,查看日志:"
|
||||
tail -10 "$FLASK_LOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " ✅ 重启完成"
|
||||
echo "=========================================="
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# start_flask.sh - 仅启动/重启 Flask 服务(不启动 ROS2)
|
||||
# 适用于: 修改了前端/API 代码后快速重启
|
||||
# ============================================================
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
AGV_PROJECT_DIR="${AGV_PROJECT_DIR:-$PROJECT_DIR}"
|
||||
AGV_APP_DIR="${AGV_APP_DIR:-$AGV_PROJECT_DIR/agv_app}"
|
||||
AGV_ROS2_DIR="${AGV_ROS2_DIR:-$HOME/agv_pro_ros2}"
|
||||
ROS_DISTRO="${ROS_DISTRO:-humble}"
|
||||
ROS_SETUP="${ROS_SETUP:-/opt/ros/$ROS_DISTRO/setup.bash}"
|
||||
ROS_WORKSPACE_SETUP="${ROS_WORKSPACE_SETUP:-$AGV_ROS2_DIR/install/setup.bash}"
|
||||
LOG_DIR="${LOG_DIR:-/tmp}"
|
||||
FLASK_PORT="${FLASK_PORT:-5000}"
|
||||
FLASK_LOG="$LOG_DIR/agv_flask.log"
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
pkill -f "python.*app.py" 2>/dev/null || true
|
||||
pkill -f "uv run .*python app.py" 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
source "$ROS_SETUP" 2>/dev/null || true
|
||||
source "$ROS_WORKSPACE_SETUP" 2>/dev/null || true
|
||||
|
||||
cd "$AGV_APP_DIR"
|
||||
nohup uv run --locked python app.py > "$FLASK_LOG" 2>&1 &
|
||||
echo "Flask started, PID: $!"
|
||||
sleep 2
|
||||
|
||||
if ss -tlnp 2>/dev/null | grep -q ":$FLASK_PORT " || netstat -tlnp 2>/dev/null | grep -q ":$FLASK_PORT "; then
|
||||
echo "✅ 端口 $FLASK_PORT 正常"
|
||||
else
|
||||
echo "⚠️ 端口 $FLASK_PORT 未监听,检查 $FLASK_LOG"
|
||||
fi
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# stop.sh - 停止开发服务
|
||||
# 用法: ./scripts/stop.sh
|
||||
# 说明: 停止 Flask 和 Next.js 开发服务器
|
||||
# ============================================================
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo " 停止开发服务"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 停止 Flask
|
||||
if pgrep -f "python.*app.py" > /dev/null 2>&1; then
|
||||
echo "停止 Flask..."
|
||||
pkill -f "python.*app.py" || true
|
||||
pkill -f "uv run .*python app.py" || true
|
||||
echo " ✓ Flask 已停止"
|
||||
else
|
||||
echo " - Flask 未运行"
|
||||
fi
|
||||
|
||||
# 停止 Next.js
|
||||
if pgrep -f "next dev" > /dev/null 2>&1; then
|
||||
echo "停止 Next.js..."
|
||||
pkill -f "next dev" || true
|
||||
echo " ✓ Next.js 已停止"
|
||||
else
|
||||
echo " - Next.js 未运行"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "完成"
|
||||
Reference in New Issue
Block a user