create_deploy_test.sh

bash 复制代码
#!/bin/bash
# ============================================================================
# ROS2 工控机部署包创建脚本(验证版)
# 用途:在 ~/deploy 目录创建并验证完整的部署包
# 使用:./create_deploy_verified.sh
# ============================================================================

set +e  # 遇到错误立即退出

# =========================== 配置区域 ===========================
WORKSPACE_DIR="/home/work/ros2_ws"
DEPLOY_DIR=~/deploy
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
PACKAGE_NAME="ros2_deploy_${TIMESTAMP}.tar.gz"

# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# =========================== 工具函数 ===========================
print_header() {
    echo ""
    echo -e "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BLUE}║ $1${NC}"
    echo -e "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

print_step() {
    echo -e "${YELLOW}>>> $1${NC}"
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_info() {
    echo -e "${CYAN}  → $1${NC}"
}

# =========================== 主程序 ===========================
print_header "       ROS2 工控机部署包创建工具(验证版)       "

# 步骤1:清理并创建部署目录
print_step "[1/10] 准备部署目录"
if [ -d "$DEPLOY_DIR" ]; then
    print_info "清理旧的部署目录..."
    rm -rf "$DEPLOY_DIR"
fi
mkdir -p "$DEPLOY_DIR"
print_success "部署目录已创建: $DEPLOY_DIR"
echo ""

# 步骤2:检查工作空间
print_step "[2/10] 检查工作空间"
if [ ! -d "$WORKSPACE_DIR/install" ]; then
    print_error "找不到 install 目录"
    echo "请先编译项目:"
    echo "  cd $WORKSPACE_DIR"
    echo "  colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release"
    exit 1
fi
print_success "工作空间检查通过"
echo ""

# 步骤3:复制 install 目录(核心)
print_step "[3/10] 复制 install 目录"
print_info "正在复制所有编译后的包..."
cp -r "$WORKSPACE_DIR/install" "$DEPLOY_DIR/"
INSTALL_SIZE=$(du -sh "$DEPLOY_DIR/install" | cut -f1)
print_success "install 目录已复制 (大小: $INSTALL_SIZE)"
echo ""

# 步骤4:复制头文件(如果需要在工控机上进行二次开发)
print_step "[4/10] 复制头文件"
if [ -d "$WORKSPACE_DIR/install/n_v_master_supervisor/include" ]; then
    print_info "包含的头文件目录已在 install 中"
    print_success "头文件已包含在 install/*/include/ 中"
else
    print_info "未找到独立的头文件目录(正常情况)"
fi
echo ""

# 步骤5:复制lib库
print_step "[5/10] 检查并复制第三方库"
if [ -d "$WORKSPACE_DIR/lib" ]; then
    print_info "复制第三方库目录..."
    cp -r "$WORKSPACE_DIR/lib" "$DEPLOY_DIR/"
    LIB_SIZE=$(du -sh "$DEPLOY_DIR/lib" | cut -f1)
    print_success "第三方库已复制 (大小: $LIB_SIZE)"
    
    # 检查spdlog
    if [ -d "$DEPLOY_DIR/lib/x86_64-linux-gnu/spdlog" ]; then
        print_info "✓ spdlog 库已包含"
    fi
else
    print_info "未找到独立的 lib/ 目录(库可能已在 install 中)"
fi
echo ""

# 步骤6:复制Python脚本
print_step "[6/10] 复制Python脚本"
PYTHON_SCRIPTS=(
    "position_monitor.py"
    "publish_manual_state.py"
    "publish_manual_state_robust.py"
    "publish_manual_state_robust_operation_figure-8.py"
    "publish_manual_state_robust_operation_line.py"
    "publish_manual_state_robust_operation_rectangley.py"
)

mkdir -p "$DEPLOY_DIR/scripts"
COPIED_SCRIPTS=0
for script in "${PYTHON_SCRIPTS[@]}"; do
    if [ -f "$WORKSPACE_DIR/$script" ]; then
        cp "$WORKSPACE_DIR/$script" "$DEPLOY_DIR/scripts/"
        print_info "✓ $script"
        ((COPIED_SCRIPTS++))
    fi
done
print_success "Python脚本已复制 ($COPIED_SCRIPTS 个文件)"
echo ""

# 步骤7:验证关键文件
print_step "[7/10] 验证关键文件"

# 验证可执行文件
MASTER_SUPERVISOR_PATH="$DEPLOY_DIR/install/n_v_master_supervisor/lib/n_v_master_supervisor/master_supervisor"
if [ -f "$MASTER_SUPERVISOR_PATH" ]; then
    FILE_SIZE=$(du -h "$MASTER_SUPERVISOR_PATH" | cut -f1)
    print_success "可执行文件: master_supervisor (大小: $FILE_SIZE)"
    
    # 检查是否可执行
    if [ -x "$MASTER_SUPERVISOR_PATH" ]; then
        print_info "✓ 可执行权限正常"
    else
        print_error "可执行权限缺失"
        chmod +x "$MASTER_SUPERVISOR_PATH"
        print_info "已修复执行权限"
    fi
    
    # 检查依赖库
    print_info "检查共享库依赖..."
    MISSING_LIBS=$(ldd "$MASTER_SUPERVISOR_PATH" 2>&1 | grep "not found" || true)
    if [ -z "$MISSING_LIBS" ]; then
        print_success "所有库依赖满足"
    else
        print_error "发现缺失的库:"
        echo "$MISSING_LIBS"
    fi
else
    print_error "找不到可执行文件: $MASTER_SUPERVISOR_PATH"
    exit 1
fi

# 验证配置文件
CONFIG_DIR="$DEPLOY_DIR/install/n_v_master_supervisor/share/n_v_master_supervisor/config"
if [ -d "$CONFIG_DIR" ]; then
    CONFIG_COUNT=$(find "$CONFIG_DIR" -name "*.yaml" | wc -l)
    print_success "配置文件目录存在 ($CONFIG_COUNT 个 yaml 文件)"
    find "$CONFIG_DIR" -name "*.yaml" -exec basename {} \; | while read file; do
        print_info "✓ $file"
    done
else
    print_info "配置文件目录: $CONFIG_DIR (未找到)"
fi

# 验证消息包
print_info "检查消息包..."
MSG_PACKAGES=(
    "n_v_msgs"
    "chassis_control_tohw_msgs"
    "chassis_hardware_msgs"
    "amr_decision_msgs"
    "custom_pose_msgs"
    "common_msgs"
    "msg_border_point"
    "msg_obj"
    "msg_v_state"
    "obj_fuse_msgs"
    "safety_diagn_msgs"
)

MSG_COUNT=0
for pkg in "${MSG_PACKAGES[@]}"; do
    if [ -d "$DEPLOY_DIR/install/$pkg" ]; then
        print_info "✓ $pkg"
        ((MSG_COUNT++))
    fi
done
print_success "消息包已包含 ($MSG_COUNT/${#MSG_PACKAGES[@]} 个)"
echo ""

# 步骤8:创建环境设置脚本
print_step "[8/10] 创建环境设置脚本"
cat > "$DEPLOY_DIR/setup_env.bash" << 'EOF'
#!/bin/bash
# ============================================================================
# ROS2 环境设置脚本
# 用途:设置运行环境
# 使用:source setup_env.bash
# ============================================================================

# 获取脚本所在目录
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

echo "=== ROS2 环境设置 ==="

# Source ROS2基础环境
if [ -f "/opt/ros/humble/setup.bash" ]; then
    source /opt/ros/humble/setup.bash
    echo "✓ ROS2 Humble 环境已加载"
elif [ -f "/opt/ros/foxy/setup.bash" ]; then
    source /opt/ros/foxy/setup.bash
    echo "✓ ROS2 Foxy 环境已加载"
else
    echo "⚠ 警告:未找到ROS2环境"
    echo "  请手动执行: source /opt/ros/<distro>/setup.bash"
fi

# Source 工作空间环境
if [ -f "$SCRIPT_DIR/install/setup.bash" ]; then
    source "$SCRIPT_DIR/install/setup.bash"
    echo "✓ 工作空间环境已加载"
else
    echo "✗ 错误:未找到 install/setup.bash"
    return 1
fi

# 设置Python脚本路径
if [ -d "$SCRIPT_DIR/scripts" ]; then
    export PYTHONPATH="$SCRIPT_DIR/scripts:$PYTHONPATH"
    echo "✓ Python脚本路径已设置"
fi

# 设置第三方库路径
if [ -d "$SCRIPT_DIR/lib" ]; then
    # 查找所有可能的lib路径
    for libdir in "$SCRIPT_DIR/lib" "$SCRIPT_DIR/lib/x86_64-linux-gnu/spdlog/lib"; do
        if [ -d "$libdir" ]; then
            export LD_LIBRARY_PATH="$libdir:$LD_LIBRARY_PATH"
        fi
    done
    echo "✓ 第三方库路径已设置"
fi

echo ""
echo "环境设置完成!"
echo ""
echo "可用命令:"
echo "  ros2 run n_v_master_supervisor master_supervisor"
echo "  ros2 launch n_v_master_supervisor <your_launch_file>.launch.py"
echo "  python3 scripts/position_monitor.py"
echo ""
EOF
chmod +x "$DEPLOY_DIR/setup_env.bash"
print_success "setup_env.bash 已创建"
echo ""

# 步骤9:创建快速启动脚本
print_step "[9/10] 创建快速启动脚本"
cat > "$DEPLOY_DIR/run_master_supervisor.sh" << 'EOF'
#!/bin/bash
# ============================================================================
# Master Supervisor 快速启动脚本
# ============================================================================

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

echo "=== 启动 Master Supervisor ==="
echo ""

# 加载环境
source "$SCRIPT_DIR/setup_env.bash"

# 运行节点
echo "正在启动 master_supervisor..."
echo ""
ros2 run n_v_master_supervisor master_supervisor
EOF
chmod +x "$DEPLOY_DIR/run_master_supervisor.sh"
print_success "run_master_supervisor.sh 已创建"

# 创建测试脚本
cat > "$DEPLOY_DIR/test_deployment.sh" << 'EOF'
#!/bin/bash
# ============================================================================
# 部署包测试脚本
# ============================================================================

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

echo "=== 部署包测试 ==="
echo ""

# 加载环境
source "$SCRIPT_DIR/setup_env.bash"

# 测试1:检查节点是否可以找到
echo ">>> 测试1: 检查节点"
if ros2 pkg executables n_v_master_supervisor | grep -q "master_supervisor"; then
    echo "✓ master_supervisor 节点可用"
else
    echo "✗ 未找到 master_supervisor 节点"
fi
echo ""

# 测试2:检查消息类型
echo ">>> 测试2: 检查消息类型"
if ros2 interface list | grep -q "n_v_msgs"; then
    echo "✓ n_v_msgs 消息可用"
    ros2 interface list | grep "n_v_msgs" | head -3
else
    echo "✗ 未找到 n_v_msgs"
fi
echo ""

# 测试3:检查可执行文件
echo ">>> 测试3: 检查可执行文件"
EXEC_PATH="$SCRIPT_DIR/install/n_v_master_supervisor/lib/n_v_master_supervisor/master_supervisor"
if [ -x "$EXEC_PATH" ]; then
    echo "✓ 可执行文件存在且可执行"
    echo "  路径: $EXEC_PATH"
    echo "  大小: $(du -h "$EXEC_PATH" | cut -f1)"
else
    echo "✗ 可执行文件不存在或无执行权限"
fi
echo ""

# 测试4:检查配置文件
echo ">>> 测试4: 检查配置文件"
CONFIG_DIR="$SCRIPT_DIR/install/n_v_master_supervisor/share/n_v_master_supervisor/config"
if [ -d "$CONFIG_DIR" ]; then
    CONFIG_COUNT=$(find "$CONFIG_DIR" -name "*.yaml" | wc -l)
    echo "✓ 找到 $CONFIG_COUNT 个配置文件"
    find "$CONFIG_DIR" -name "*.yaml" -exec basename {} \;
else
    echo "! 配置目录不存在"
fi
echo ""

# 测试5:快速运行测试(--help)
echo ">>> 测试5: 测试可执行文件"
echo "运行: master_supervisor --help"
timeout 3 "$EXEC_PATH" --help 2>&1 || echo "(节点可能不支持 --help 参数,这是正常的)"
echo ""

echo "=== 测试完成 ==="
EOF
chmod +x "$DEPLOY_DIR/test_deployment.sh"
print_success "test_deployment.sh 已创建"
echo ""

# 步骤10:测试可执行文件
print_step "[10/10] 测试可执行文件"
print_info "加载环境并测试运行..."

# 创建临时测试脚本
cat > /tmp/test_master_supervisor.sh << EOF
#!/bin/bash
source /opt/ros/humble/setup.bash 2>/dev/null || source /opt/ros/foxy/setup.bash 2>/dev/null || true
source "$DEPLOY_DIR/install/setup.bash"

# 设置库路径
if [ -d "$DEPLOY_DIR/lib" ]; then
    export LD_LIBRARY_PATH="$DEPLOY_DIR/lib:\$LD_LIBRARY_PATH"
fi
if [ -d "$DEPLOY_DIR/lib/x86_64-linux-gnu/spdlog/lib" ]; then
    export LD_LIBRARY_PATH="$DEPLOY_DIR/lib/x86_64-linux-gnu/spdlog/lib:\$LD_LIBRARY_PATH"
fi

# 测试运行(3秒后自动结束)
timeout 3 "$MASTER_SUPERVISOR_PATH" 2>&1 || true
EOF
chmod +x /tmp/test_master_supervisor.sh

print_info "执行 3 秒快速测试..."
echo "----------------------------------------"
/tmp/test_master_supervisor.sh || true
echo "----------------------------------------"
print_success "可执行文件测试完成"
rm -f /tmp/test_master_supervisor.sh
echo ""

# 生成部署清单
print_step "生成部署清单"
cat > "$DEPLOY_DIR/MANIFEST.txt" << EOF
=================================================================
ROS2 工控机部署包清单
生成时间: $(date '+%Y-%m-%d %H:%M:%S')
=================================================================

1. 目录结构:
$(tree -L 3 -d "$DEPLOY_DIR" 2>/dev/null || find "$DEPLOY_DIR" -type d -maxdepth 3)

2. 可执行文件:
  - master_supervisor: $MASTER_SUPERVISOR_PATH
    大小: $(du -h "$MASTER_SUPERVISOR_PATH" | cut -f1)

3. 配置文件:
$(find "$DEPLOY_DIR/install/n_v_master_supervisor" -name "*.yaml" 2>/dev/null | sed 's/^/  - /')

4. Python脚本:
$(find "$DEPLOY_DIR/scripts" -name "*.py" 2>/dev/null | xargs -n1 basename | sed 's/^/  - /')

5. 消息包:
$(ls "$DEPLOY_DIR/install" | grep -E "msg|Msg" | sed 's/^/  - /')

6. 库文件:
$(find "$DEPLOY_DIR/lib" -name "*.so*" 2>/dev/null | wc -l) 个共享库文件

7. 总大小:
  install/: $(du -sh "$DEPLOY_DIR/install" | cut -f1)
  lib/:     $(du -sh "$DEPLOY_DIR/lib" 2>/dev/null | cut -f1 || echo "N/A")
  scripts/: $(du -sh "$DEPLOY_DIR/scripts" 2>/dev/null | cut -f1 || echo "N/A")
  总计:     $(du -sh "$DEPLOY_DIR" | cut -f1)

=================================================================
EOF
print_success "部署清单已生成: MANIFEST.txt"
echo ""

# 创建README
cat > "$DEPLOY_DIR/README.txt" << 'EOF'
=================================================================
ROS2 工控机部署包使用说明
=================================================================

📦 快速开始:

1. 设置环境:
   source setup_env.bash

2. 测试部署:
   ./test_deployment.sh

3. 运行程序:
   ./run_master_supervisor.sh
   
   或者:
   ros2 run n_v_master_supervisor master_supervisor

4. 运行Python脚本:
   python3 scripts/position_monitor.py

=================================================================

📋 文件说明:

- install/              : 所有编译后的包(C++可执行文件、消息、配置)
- scripts/              : Python脚本
- lib/                  : 第三方库(包括spdlog)
- setup_env.bash        : 环境设置脚本(必须先执行)
- run_master_supervisor.sh : 快速启动脚本
- test_deployment.sh    : 部署测试脚本
- MANIFEST.txt          : 详细的文件清单

=================================================================

⚙️ 工控机要求:

1. 操作系统: Ubuntu 22.04 (ROS2 Humble) 或 20.04 (ROS2 Foxy)
2. CPU架构: 必须与编译机器相同 (x86_64)
3. ROS2环境: 已安装相应版本的ROS2

安装ROS2:
  sudo apt update
  sudo apt install ros-humble-desktop

=================================================================

🔧 故障排查:

问题1: 找不到共享库
  检查: ldd install/n_v_master_supervisor/lib/n_v_master_supervisor/master_supervisor
  解决: 安装缺失的库

问题2: 找不到消息类型
  检查: source setup_env.bash
  验证: ros2 interface list | grep n_v_msgs

问题3: 无法运行
  检查: 确保已经 source setup_env.bash
  验证: echo $ROS_DISTRO

=================================================================
EOF
print_success "README.txt 已创建"
echo ""

# 打包
print_step "打包部署目录"
cd ~
tar -czf "$PACKAGE_NAME" -C "$(dirname "$DEPLOY_DIR")" "$(basename "$DEPLOY_DIR")"
PACKAGE_SIZE=$(du -sh ~/"$PACKAGE_NAME" | cut -f1)
print_success "部署包已创建: ~/$PACKAGE_NAME (大小: $PACKAGE_SIZE)"
echo ""

# 最终总结
print_header "                    部署包创建完成                    "

echo -e "${GREEN}✓ 部署目录: $DEPLOY_DIR${NC}"
echo -e "${GREEN}✓ 打包文件: ~/$PACKAGE_NAME${NC}"
echo ""

echo -e "${CYAN}📋 验证清单:${NC}"
echo -e "  ${GREEN}✓${NC} install/ 目录 (大小: $INSTALL_SIZE)"
echo -e "  ${GREEN}✓${NC} 可执行文件: master_supervisor"
echo -e "  ${GREEN}✓${NC} 消息包: $MSG_COUNT 个"
echo -e "  ${GREEN}✓${NC} Python脚本: $COPIED_SCRIPTS 个"
if [ -d "$DEPLOY_DIR/lib" ]; then
    echo -e "  ${GREEN}✓${NC} 第三方库: 包括 spdlog"
fi
echo -e "  ${GREEN}✓${NC} 配置文件"
echo -e "  ${GREEN}✓${NC} 启动脚本"
echo ""

echo -e "${CYAN}🧪 本地测试:${NC}"
echo -e "  cd $DEPLOY_DIR"
echo -e "  ./test_deployment.sh"
echo ""

echo -e "${CYAN}🚀 部署到工控机:${NC}"
echo -e "  1. 传输: scp ~/$PACKAGE_NAME user@工控机IP:/home/user/"
echo -e "  2. 解压: tar -xzf $PACKAGE_NAME"
echo -e "  3. 测试: cd $(basename "$DEPLOY_DIR") && ./test_deployment.sh"
echo -e "  4. 运行: ./run_master_supervisor.sh"
echo ""

echo -e "${CYAN}📖 详细信息:${NC}"
echo -e "  查看清单: cat $DEPLOY_DIR/MANIFEST.txt"
echo -e "  查看说明: cat $DEPLOY_DIR/README.txt"
echo ""

print_success "所有操作完成!"
相关推荐
苏 凉2 小时前
ONNX Runtime 在 openEuler 上的 CPU 推理性能优化与评测
开发语言·人工智能
子午2 小时前
【垃圾识别系统】Python+TensorFlow+Django+人工智能+深度学习+卷积神经网络算法
人工智能·python·深度学习
CHANG_THE_WORLD2 小时前
Python 推导式详细教程
开发语言·python
ljh5746491192 小时前
用vscode怎么运行conda中的python环境
vscode·python·conda
林鸿群2 小时前
Ubuntu 25.10编译Chromium源码
linux·chrome·ubuntu·chromium·源码编译
民乐团扒谱机2 小时前
【微科普】GN 算法:在网络的脉络中,寻找社群的边界
开发语言·算法·matlab·语言学·语义网络分析
秋邱2 小时前
AR 技术创新与商业化新方向:AI+AR 融合,抢占 2025 高潜力赛道
前端·人工智能·后端·python·html·restful
Stara05112 小时前
LangChain—大语言模型应用开发框架的体系化架构解析
python·langchain·llm·agent·提示工程·rag
yaoxin5211232 小时前
263. Java 集合 - 遍历 List 时选用哪种方式?ArrayList vs LinkedList
java·开发语言·list
骇客野人2 小时前
java对象和JSON对象之间的转换关系
java·开发语言·json