第1章 开发环境搭建¶
本章目标
从零开始搭建 RoboMaster 视觉组的完整开发环境。完成本章后,你将拥有一个可以编译、调试、运行视觉自瞄程序的 Linux 工作环境,并理解每个工具在自瞄系统中的角色。
预计用时: 1-2 天(建议集中完成,不要分太多天)
前置知识: 无,本章面向零基础
1.1 Ubuntu 安装¶
这是什么¶
Ubuntu 是一个基于 Linux 的操作系统。RoboMaster 视觉开发几乎全部在 Linux 下完成,Windows 和 macOS 无法直接运行 ROS2 和大部分视觉算法框架。
为什么需要¶
- ROS2(视觉组的核心框架)原生支持 Linux,在其他系统上运行需要大量额外配置
- OpenCV、CUDA 等视觉/推理库在 Linux 下编译最稳定
- 自瞄程序最终部署在嵌入式 Linux(如 Jetson / Radxa)上,开发环境和部署环境一致能避免大量兼容问题
- Linux 下编译速度和调试体验远优于其他系统
三种安装方案对比¶
| 特性 | 双系统 | WSL2 | 虚拟机 |
|---|---|---|---|
| 性能 | 原生,最好 | 接近原生 | 损耗约 10-20% |
| 显卡支持 | 直接使用 | 有限(GPU 直通实验性) | 需要显卡直通 |
| 安装难度 | 较高(涉及分区) | 最低(Windows 内置) | 中等(需下载虚拟机软件) |
| 和 Windows 共存 | 需重启切换 | 同时使用 | 同时使用 |
| USB 设备支持 | 直接支持 | 需要额外配置 | 需要 USB 转发 |
| 推荐场景 | 主力开发 | 日常学习/轻量开发 | 不想动 Windows 分区 |
| 推荐指数 | ★★★★★ | ★★★★☆ | ★★★☆☆ |
新手建议
如果你是 Windows 用户,且是第一次使用 Linux,强烈建议先用 WSL2 或虚拟机入门。等你熟悉了基本操作之后,再考虑装双系统作为主力环境。如果你是 macOS 用户,虚拟机或远程服务器是更现实的方案。
双系统是指在同一台电脑上同时安装 Windows 和 Ubuntu,开机时可以选择进入哪个系统。
准备工作:
- 一个 8GB 以上的 U 盘(制作启动盘会格式化 U 盘,请提前备份)
- 至少 100GB 的空闲磁盘空间(建议 200GB+)
- 下载 Ubuntu 22.04 LTS 镜像:官方下载页
重要提醒
分区操作有风险,操作不当可能丢失 Windows 数据。请务必提前备份重要文件!
步骤 1:制作启动盘
推荐使用 Rufus(Windows 下)制作启动 U 盘:
- 插入 U 盘,打开 Rufus
- 选择下载好的
.iso镜像文件 - 分区类型选 GPT,目标系统选 UEFI
- 点击"开始",等待完成
步骤 2:为 Ubuntu 腾出磁盘空间
在 Windows 下操作:
- 右键"此电脑" → "管理" → "磁盘管理"
- 选择一个较大的分区(建议 D 盘),右键 → "压缩卷"
- 输入压缩大小(建议至少 100000 MB,即约 100GB)
- 压缩后会出现一块"未分配"空间,不需要做任何操作
步骤 3:从 U 盘启动安装
- 插入 U 盘,重启电脑
- 开机时按 F2/F12/Del(不同品牌不同)进入 BIOS 启动菜单
- 选择 U 盘启动
- 选择 "Install Ubuntu"
- 在安装类型时选择 "Install Ubuntu alongside Windows Boot Manager"(与 Windows 共存)
- 设置用户名、密码,等待安装完成
步骤 4:验证安装
安装完成后重启,你会看到一个启动菜单(GRUB),可以选择进入 Ubuntu 或 Windows。
WSL2(Windows Subsystem for Linux 2)是微软官方提供的在 Windows 中运行 Linux 的方案,安装最简单,适合入门。
步骤 1:启用 WSL2
以管理员身份打开 PowerShell,执行:
# 启用 WSL(Windows 10 2004+ / Windows 11 原生支持)
wsl --install
# 如果上面的命令不可用,手动启用:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# 设置 WSL2 为默认版本
wsl --set-default-version 2
执行完毕后 重启电脑。
步骤 2:安装 Ubuntu 22.04
安装完成后会自动弹出 Ubuntu 终端,设置你的用户名和密码。
步骤 3:验证
步骤 4:安装图形界面(可选,视觉开发推荐)
WSL2 默认只有命令行。要使用图形界面(比如运行有 GUI 的调试工具),执行:
WSL2 的图形支持
Windows 11 和 Windows 10 21H2+ 已内置 WSLg,原生支持 Linux GUI 应用。如果你的系统版本较旧,需要手动安装 VcXsrv 作为 X Server。
虚拟机方案是在 Windows/macOS 中通过虚拟化软件创建一个完整的 Linux 系统,推荐使用 VirtualBox(免费)或 VMware Workstation Player(个人免费)。
步骤 1:安装虚拟机软件
- VirtualBox 下载(免费,跨平台)
- VMware Workstation Player 下载(Windows/Linux 免费)
步骤 2:创建虚拟机
- 打开虚拟机软件,选择"新建虚拟机"
- 选择下载好的 Ubuntu 22.04
.iso镜像 - 分配资源:
- 内存:建议 至少 4GB(8GB 更佳)
- CPU 核心:建议 至少 2 核
- 磁盘:建议 至少 80GB
- 显存:建议 128MB
- 网络选择 桥接模式(方便后续 SSH 和远程连接)
步骤 3:安装 Ubuntu
虚拟机从 ISO 启动后,安装过程和双系统类似:
- 选择 "Install Ubuntu"
- 选择 "Erase disk and install Ubuntu"(这只会影响虚拟磁盘,不影响真实硬盘)
- 设置用户名密码,等待安装完成
步骤 4:安装增强功能
macOS 无法原生运行 ROS2 和大部分 Linux 专用视觉工具。以下是两种可行方案:
方案 A:SSH 连接远程 Linux 服务器(推荐)
如果你有实验室的 Linux 服务器或旧电脑,直接 SSH 连接是最省事的方案。macOS 自带终端和 SSH 客户端,打开"终端"即可使用。后续的 SSH 章节会详细介绍连接方法。
方案 B:虚拟化 Ubuntu(本地运行)
- UTM(免费,推荐用于 Apple Silicon Mac):UTM 官网
- Parallels Desktop(付费,体验最好):Parallels 官网
UTM 安装步骤:
- 从 UTM 官网 下载并安装 UTM
- 打开 UTM,点击"创建新虚拟机",选择"虚拟化"
- 选择下载好的 Ubuntu 22.04 ISO 镜像
- 分配资源:内存建议 至少 4GB,磁盘建议 至少 80GB
- 网络选择 桥接模式
- 按提示完成 Ubuntu 安装
安装后建议安装增强功能以支持共享剪贴板和自适应分辨率:
Parallels Desktop 安装步骤更简单:
- 从 App Store 购买并安装 Parallels Desktop
- 打开后选择"文件 → 新建",导入 Ubuntu 22.04 ISO
- Parallels 会自动完成安装并配置好共享文件夹、剪贴板、显示器适配
Mac 用户建议
如果你日常使用 macOS,方案 A(SSH 远程服务器)是最推荐的,省去本地虚拟化的性能和配置麻烦。如果需要本地运行,UTM 是免费且够用的选择。Parallels 体验最流畅但需付费。无论哪种方案,所有编译和运行都在 Linux 侧完成,macOS 侧主要用来编辑代码和管理文件。
安装后必做的配置¶
无论你用哪种方式安装,进入 Ubuntu 后都要做以下基础配置:
# 1. 更新软件源和已安装的包
sudo apt update && sudo apt upgrade -y
# 2. 安装基础开发工具
sudo apt install -y build-essential git cmake vim curl wget
# 3. 设置 Git 使用中文显示(避免中文文件名显示为八进制)
git config --global core.quotepath false
1.2 基本终端命令¶
这是什么¶
终端(Terminal)是 Linux 下与计算机交互的文字界面。在 Linux 中,几乎所有操作都可以通过终端命令完成,而且很多操作只能通过终端完成。
为什么需要¶
- ROS2、CMake、Git 等工具的主要操作方式都是命令行
- 远程连接嵌入式设备(如 Jetson)时只能用终端
- 命令行操作比图形界面更高效、更可复现
- 团队的部署脚本、CI 流程都基于命令行
终端小知识
打开终端的快捷键:Linux 下按 Ctrl + Alt + T,macOS 下按 Cmd + Space 打开 Spotlight 搜索 Terminal。你看到的 username@hostname:~$ 叫做"命令提示符"(prompt),其中 ~ 代表你的家目录(/home/你的用户名)。
文件和目录操作¶
# pwd — 显示当前所在目录(Print Working Directory)
pwd
# 输出示例:/home/student
# ls — 列出当前目录下的文件(List)
ls # 列出文件名
ls -l # 详细列表(显示权限、大小、日期)
ls -la # 包含隐藏文件(以 . 开头的文件)
ls -lh # 文件大小显示为 KB/MB 而非字节
# cd — 切换目录(Change Directory)
cd /home/student # 切换到绝对路径
cd Documents # 切换到当前目录下的 Documents 子目录
cd .. # 返回上一级目录
cd ~ # 回到家目录(等同于直接输入 cd)
cd - # 回到上一次所在的目录
# mkdir — 创建目录(Make Directory)
mkdir my_project # 创建单个目录
mkdir -p src/vision/include # 递归创建多层目录(-p 表示自动创建父目录)
# cp — 复制文件(Copy)
cp file.txt backup.txt # 复制文件
cp -r src/ src_backup/ # 复制目录(-r 表示递归复制)
# mv — 移动/重命名文件(Move)
mv old_name.txt new_name.txt # 重命名
mv file.txt ~/Documents/ # 移动文件到另一个目录
# rm — 删除文件(Remove)⚠️ Linux 下没有回收站!
rm file.txt # 删除文件
rm -r build/ # 删除目录及其所有内容
rm -rf build/ # 强制删除,不提示确认(危险!慎用!)
# touch — 创建空文件或更新文件时间戳
touch new_file.txt
rm -rf 的教训
rm -rf / 会删除整个系统的所有文件,rm -rf ~ 会删除你所有的个人文件。在使用 rm 命令时 务必确认路径。很多程序员都经历过误删文件的惨痛教训。养成好习惯:删除前先 ls 确认目录内容。
查看文件内容¶
# cat — 显示文件全部内容(Concatenate)
cat CMakeLists.txt
# head / tail — 查看文件开头/末尾几行
head -20 log.txt # 前 20 行
tail -20 log.txt # 后 20 行
tail -f /var/log/syslog # 实时追踪文件末尾(看日志常用,Ctrl+C 退出)
# less — 分页查看大文件
less large_file.txt # 空格翻页,q 退出,/关键词 搜索
# wc — 统计行数、单词数
wc -l CMakeLists.txt # 统计行数
搜索和查找¶
# grep — 在文件中搜索文本(Global Regular Expression Print)
grep "target" src/main.cpp # 在文件中搜索 "target"
grep -r "Target" src/ # 在整个目录中递归搜索
grep -rn "class" src/ # 显示行号(-n)
grep -rni "armor" src/ --include="*.cpp" # 只在 .cpp 文件中搜索,忽略大小写
# find — 查找文件
find . -name "*.cpp" # 查找所有 .cpp 文件
find . -name "CMakeLists.txt" # 查找所有 CMakeLists.txt
find /usr -name "libopencv*" # 查找 OpenCV 库文件
# which — 查找命令的位置
which python3 # 查看 python3 安装在哪里
which cmake
权限管理¶
# 查看文件权限
ls -l main.sh
# 输出:-rw-r--r-- 1 user group 1024 Jul 15 10:00 main.sh
# ^^^^^^^^^^^
# 权限说明:r=读(4), w=写(2), x=执行(1)
# 三组分别代表:文件所有者 / 同组用户 / 其他用户
# chmod — 修改文件权限(Change Mode)
chmod +x run.sh # 给脚本添加可执行权限
chmod 755 run.sh # 所有者 rwx,其他人 rx
chmod 644 config.txt # 所有者 rw,其他人只读
# chown — 修改文件所有者(需要 sudo)
sudo chown student:student my_file
软件包管理¶
# apt — Ubuntu 的软件包管理器(Advanced Package Tool)
# 更新软件源列表(获取最新的包信息)
sudo apt update
# 升级所有已安装的软件包
sudo apt upgrade -y
# 安装软件包
sudo apt install -y git cmake vim
# 卸载软件包
sudo apt remove package_name
# 搜索软件包
apt search opencv
# 查看已安装的包
dpkg -l | grep opencv
sudo 是什么
sudo 代表 "Super User DO",即以管理员权限执行命令。安装软件、修改系统配置等操作需要 sudo。第一次使用时会要求输入密码,密码不会显示任何字符(连 * 都没有),输入完毕直接回车即可。
macOS 上的包管理器是 Homebrew,功能类似于 Ubuntu 的 apt:
brew update # ≈ apt update
brew upgrade # ≈ apt upgrade
brew install vim # ≈ apt install vim
brew uninstall vim # ≈ apt remove vim
brew list # ≈ dpkg -l(查看已安装的包)
brew search opencv # ≈ apt search opencv
Homebrew 安装的软件默认在 /opt/homebrew/(Apple Silicon)或 /usr/local/(Intel),和 apt 的 /usr/ 路径不同,但使用逻辑非常相似。
进程管理¶
# 查看进程
ps aux # 查看所有进程
ps aux | grep my_program # 查找特定进程
# 结束进程
kill PID # 发送终止信号(PID 是进程编号)
kill -9 PID # 强制终止(正常 kill 无效时使用)
# 后台运行程序
./my_program & # & 让程序在后台运行
nohup ./my_program & # 后台运行,关闭终端也不会停止
# 查看系统资源
top # 实时查看 CPU 和内存使用(q 退出)
htop # 更好看的 top(需要安装:sudo apt install htop)
常用快捷键¶
| 快捷键 | 功能 |
|---|---|
Tab |
自动补全命令或文件名(按两次显示所有候选) |
Ctrl + C |
终止当前正在运行的程序 |
Ctrl + Z |
挂起当前程序(用 fg 恢复) |
Ctrl + R |
搜索历史命令 |
Ctrl + A |
光标跳到行首 |
Ctrl + E |
光标跳到行尾 |
Ctrl + L |
清屏(等同于 clear) |
上/下箭头 |
浏览历史命令 |
!! |
重复上一条命令(常配合 sudo:sudo !!) |
1.3 Git 安装与使用¶
这是什么¶
Git 是一个分布式版本控制系统,用于追踪文件的变化历史。你可以把它理解为代码的"时光机"——可以回到任何一个历史版本,可以看到谁改了什么,可以多人同时修改同一个项目而互不冲突。
为什么需要¶
- 视觉组代码由多人协作开发,Git 是协作的基础
- 自瞄系统代码经常需要修改和调试,有了 Git 就不怕改坏——随时可以回退
- 赛前和赛中的代码可能不同,Git 分支可以同时维护多个版本
- 几乎所有开源项目(OpenCV、ROS2、rm_vision)都托管在 GitHub/Gitee 上
安装和配置¶
# 验证安装
git --version
# 输出示例:git version 2.34.1
# 配置用户信息(每次 commit 都会包含这些信息)
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
# 推荐配置
git config --global core.quotepath false # 中文文件名正常显示
git config --global core.editor vim # 设置默认编辑器
git config --global init.defaultBranch main # 默认分支名用 main
核心概念¶
在学习命令之前,先理解 Git 的三个区域:
┌──────────────┐ git add ┌──────────┐ git commit ┌──────────────┐
│ 工作区 │ ──────────> │ 暂存区 │ ──────────> │ 本地仓库 │
│ Working Dir │ │ Stage │ │ Repository │
└──────────────┘ <────────── └──────────┘ └──────────────┘
git checkout git reset
基本操作¶
# ============ 创建仓库 ============
# 方式1:在本地创建新仓库
mkdir my_project && cd my_project
git init
# 方式2:克隆远程仓库(最常用)
git clone https://github.com/your-team/rm_vision.git
cd rm_vision
# ============ 日常工作流 ============
# 查看当前状态(最常用的命令!)
git status
# 修改文件后,查看改了什么
git diff # 查看未暂存的修改
git diff --staged # 查看已暂存的修改
# 添加文件到暂存区
git add src/main.cpp # 添加单个文件
git add src/ # 添加整个目录
git add . # 添加所有修改(慎用!确认没有不需要的文件)
# 提交到本地仓库
git commit -m "feat: 添加装甲板识别模块"
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# 提交信息要有意义,描述你做了什么
# 查看提交历史
git log # 完整日志
git log --oneline # 简洁版(一行一条)
git log --oneline --graph # 带分支图形的简洁版
git log -5 # 只看最近 5 条
# ============ 远程仓库操作 ============
# 查看远程仓库信息
git remote -v
# 推送到远程仓库
git push origin main # 推送 main 分支到 origin 远程
# 从远程拉取更新
git pull origin main # 拉取并合并远程 main 分支
分支操作¶
分支是 Git 最强大的功能之一。在视觉组中,你通常不会直接在 main 分支上开发,而是创建一个自己的分支。
# 查看分支
git branch # 查看本地分支
git branch -a # 查看所有分支(包括远程)
# 创建并切换到新分支
git checkout -b feature/my-armor-detector
# 等同于:
# git branch feature/my-armor-detector
# git checkout feature/my-armor-detector
# 在新分支上开发、提交...
git add .
git commit -m "feat: 实现基础装甲板检测"
# 切换回主分支
git checkout main
# 合并分支到 main
git merge feature/my-armor-detector
# 删除已合并的分支
git branch -d feature/my-armor-detector
提交信息规范¶
好的提交信息能让团队快速理解每次修改的内容。推荐遵循以下格式:
常用的类型:
| 类型 | 含义 | 示例 |
|---|---|---|
feat |
新功能 | feat: 添加能量机关识别 |
fix |
修复 bug | fix: 修复 PnP 解算崩溃问题 |
docs |
文档 | docs: 更新 README 安装说明 |
refactor |
重构 | refactor: 拆分装甲板分类器 |
chore |
构建/工具 | chore: 更新 CMake 配置 |
处理冲突¶
当两个人同时修改了同一个文件的同一部分,合并时会产生冲突:
解决步骤:
- 打开冲突文件,找到
<<<<<<<标记 - 手动决定保留哪些内容(可能需要两种修改都保留)
- 删除所有
<<<<<<<、=======、>>>>>>>标记 git add解决后的文件git commit完成合并
1.4 VSCode 安装与配置¶
这是什么¶
Visual Studio Code(VSCode)是微软开发的免费代码编辑器,是目前最流行的代码编辑器之一。它轻量、快速,通过插件可以支持几乎任何编程语言和工具。
为什么需要¶
- C/C++ 开发需要语法高亮、自动补全、跳转定义等功能,记事本做不到
- CMakeLists.txt 的语法高亮和智能提示能避免很多配置错误
- Remote SSH 插件让你可以在本地编辑远程服务器/嵌入式设备上的代码
- 集成终端和调试器让你无需切换多个窗口
安装¶
# 方式1:通过官方仓库安装(推荐)
sudo apt install -y wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -o root -g root -m 644 packages.microsoft.gpg /etc/apt/trusted.gpg.d/
sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/trusted.gpg.d/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt update
sudo apt install -y code
# 方式2:通过 snap 安装(更简单)
sudo snap install code --classic
直接从 VSCode 官网 下载 Windows 安装包安装即可。
如果你使用的是 WSL2,VSCode 安装后会自动支持 WSL 远程连接。在 WSL 终端中输入:
VSCode 会自动安装 WSL 远程扩展并在 WSL 环境中打开当前目录。
或者从 VSCode 官网 下载 .dmg 安装包,拖入 Applications 文件夹即可。
必装插件¶
安装完 VSCode 后,需要安装以下插件。在 VSCode 左侧栏点击"扩展"图标(或按 Ctrl+Shift+X),搜索并安装:
C/C++ 开发核心:
| 插件名称 | 功能 | 重要程度 |
|---|---|---|
| C/C++ | 代码高亮、智能补全、调试 | ★★★★★ |
| CMake | CMakeLists.txt 语法支持 | ★★★★★ |
| CMake Tools | CMake 项目管理和构建 | ★★★★★ |
| C/C++ Extension Pack | 包含上述多个 C++ 相关插件 | ★★★★☆ |
远程开发:
| 插件名称 | 功能 | 重要程度 |
|---|---|---|
| Remote - SSH | SSH 远程连接开发 | ★★★★★ |
| Remote - SSH: Editing | SSH 远程编辑配置文件 | ★★★★☆ |
| Remote - WSL | WSL 远程连接 | ★★★★★(WSL 用户必装) |
效率提升:
| 插件名称 | 功能 | 重要程度 |
|---|---|---|
| GitLens | 增强 Git 功能,查看每行代码的修改历史 | ★★★★☆ |
| Chinese (Simplified) | VSCode 中文界面 | ★★★☆☆ |
| Clang-Format | 代码格式化 | ★★★☆☆ |
批量安装命令(在 VSCode 终端中执行):
code --install-extension ms-vscode.cpptools
code --install-extension ms-vscode.cmake-tools
code --install-extension twxs.cmake
code --install-extension ms-vscode-remote.remote-ssh
code --install-extension eamodio.gitlens
VSCode 基本使用¶
# 在终端中用 VSCode 打开目录或文件
code . # 打开当前目录
code src/main.cpp # 打开指定文件
code /path/to/project # 打开指定目录
# 快捷键速查
# 功能 Linux / Windows macOS
# 快速打开文件 Ctrl+P Cmd+P
# 命令面板 Ctrl+Shift+P Cmd+Shift+P
# 打开/关闭终端 Ctrl+` Cmd+`
# 打开/关闭侧边栏 Ctrl+B Cmd+B
# 跳转到定义 F12 F12
# 全局搜索 Ctrl+Shift+F Cmd+Shift+F
# Git 面板 Ctrl+Shift+G Cmd+Shift+G
# 启动调试 F5 F5
配置 C++ 开发环境¶
在项目根目录创建 .vscode/settings.json:
{
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.cStandard": "c17",
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.configureOnOpen": true,
"editor.formatOnSave": true,
"files.associations": {
"*.hpp": "cpp",
"*.h": "cpp"
}
}
1.5 SSH 远程连接¶
这是什么¶
SSH(Secure Shell)是一种加密的远程连接协议,让你可以在本地电脑上操控远程服务器。在视觉组中,你需要通过 SSH 连接到嵌入式设备(如 Jetson Nano / Radxa Rock)上运行自瞄程序。
为什么需要¶
- 自瞄程序最终运行在装在机器人上的嵌入式设备上,你不可能每次都把显示器接到设备上
- 赛场上的调试和部署全部通过 SSH 完成
- SSH 也是 VSCode Remote SSH 的底层技术,实现本地编辑远程代码
SSH 密钥对生成¶
SSH 登录有两种方式:密码登录和密钥登录。密钥登录更安全且可以免密,是推荐方式。
# 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
# 执行后会出现:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/student/.ssh/id_ed25519): ← 直接回车用默认路径
# Enter passphrase (empty for no passphrase): ← 直接回车设为空密码(方便后续免密)
# Enter same passphrase again: ← 再次回车
# 查看生成的密钥
ls ~/.ssh/
# id_ed25519 ← 私钥(绝对不能泄露!不能发给任何人!)
# id_ed25519.pub ← 公钥(可以随意分发)
私钥安全
id_ed25519 是你的私钥,永远不要发送给任何人、上传到 GitHub、或放在共享目录里。如果私钥泄露,别人可以冒充你登录所有你配置过的服务器。只把公钥(.pub 文件)配置到目标服务器上。
免密登录配置¶
将公钥复制到远程服务器:
# 一行命令完成免密配置(推荐)
ssh-copy-id username@remote_host_ip
# 例如:
ssh-copy-id radxa@192.168.1.100
# 输入一次密码后,以后就不用再输入了
# 测试连接
ssh radxa@192.168.1.100
ssh-copy-id 失败怎么办
如果 ssh-copy-id 不可用(比如目标设备是 Windows 或嵌入式精简系统),可以手动复制:
SSH Config 文件¶
当你管理多个远程设备时(比如多台机器人),每次输入完整 SSH 命令很麻烦。通过配置 ~/.ssh/config 文件,可以用简单别名快速连接。
写入以下内容:
# 机器人的嵌入式设备
Host robot1
HostName 192.168.1.100
User radxa
Port 22
IdentityFile ~/.ssh/id_ed25519
Host robot2
HostName 192.168.1.101
User radxa
Port 22
IdentityFile ~/.ssh/id_ed25519
# 实验室开发服务器
Host dev-server
HostName 10.0.0.50
User student
Port 22
IdentityFile ~/.ssh/id_ed25519
配置之后,连接就变得非常简单:
SSH 文件传输¶
# scp — 安全复制文件到远程/从远程复制
scp local_file.txt robot1:~/ # 上传文件到远程家目录
scp -r ./build/ robot1:~/rm_vision/ # 上传整个目录
scp robot1:~/log.txt ./ # 从远程下载文件
# rsync — 更强大的同步工具(增量传输,速度更快)
rsync -avz --progress ./build/ robot1:~/rm_vision/build/
SSH 常用调试技巧¶
# 查看详细连接信息(排查问题时使用)
ssh -v robot1
# -v 是 verbose 模式,会显示连接的每一步细节
# 保持连接活跃(防止长时间无操作后断开)
# 在 ~/.ssh/config 中添加:
# ServerAliveInterval 60
# ServerAliveCountMax 3
# 端口转发(将远程端口映射到本地,常用于查看远程的 Web 界面)
ssh -L 8080:localhost:80 robot1
# 然后在本地浏览器访问 http://localhost:8080 即可访问远程的 Web 服务
1.6 CMake 基础¶
这是什么¶
CMake 是一个跨平台的构建系统生成器。你编写 CMakeLists.txt 来描述项目如何编译,CMake 会自动生成 Makefile(或其他构建系统),然后你用 make 来实际编译。
为什么需要¶
- C++ 项目没有像 Python 那样的统一包管理器,编译配置是一个独立的步骤
- 自瞄系统包含多个源文件、多个库(OpenCV、ROS2 等),手动编译命令会非常长
- CMake 是行业标准,ROS2、OpenCV、rm_vision 都用 CMake 构建
- 掌握 CMake 是读懂和修改视觉组代码的前提
一个最简单的例子¶
先理解整个构建流程:
创建一个最小项目:
main.cpp:
CMakeLists.txt:
# 指定 CMake 最低版本要求
cmake_minimum_required(VERSION 3.10)
# 定义项目名称和使用的语言
project(hello_cmake LANGUAGES CXX)
# 添加可执行文件目标
# 语法:add_executable(目标名 源文件...)
add_executable(my_program main.cpp)
构建和运行:
# 1. 创建并进入构建目录(out-of-source build,保持源码目录干净)
mkdir build && cd build
# 2. 运行 CMake,生成 Makefile
cmake ..
# 输出示例:
# -- The CXX compiler identification is GNU 11.4.0
# -- Configuring done
# -- Generating done
# -- Build files have been written to: /home/student/hello_cmake/build
# 3. 编译
make
# 或者用 cmake --build . (更通用的写法)
# 4. 运行
./my_program
# 输出:Hello, RoboMaster!
为什么要在 build 目录中构建?
在源码目录外构建(out-of-source build)是一个好习惯。这样编译生成的中间文件不会污染源码目录,清理时只需删除 build 目录即可。rm_vision 和几乎所有 CMake 项目都采用这种方式。
CMakeLists.txt 详细语法¶
添加多个源文件¶
cmake_minimum_required(VERSION 3.10)
project(armor_detector LANGUAGES CXX)
# 方式1:逐个列出源文件
add_executable(detector
src/main.cpp
src/armor_detector.cpp
src/classifier.cpp
)
# 方式2:用 GLOB 自动收集(不推荐用于大项目,新增文件不会自动发现)
file(GLOB SOURCES "src/*.cpp")
add_executable(detector ${SOURCES})
# 方式3:推荐做法——显式列出
set(SOURCES
src/main.cpp
src/armor_detector.cpp
src/classifier.cpp
)
add_executable(detector ${SOURCES})
头文件搜索路径¶
# 告诉编译器去哪里找头文件(#include "xxx.h")
target_include_directories(detector PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# 现在可以在 src/main.cpp 中使用:#include "armor_detector.hpp"
链接第三方库(OpenCV 为例)¶
# 查找 OpenCV 库
find_package(OpenCV REQUIRED)
# 链接到目标
target_link_libraries(detector ${OpenCV_LIBS})
# 现在可以在代码中使用 #include <opencv2/opencv.hpp>
完整的项目结构¶
一个中等规模的视觉项目通常有这样的结构:
my_project/
├── CMakeLists.txt # 顶层 CMake 配置
├── include/ # 头文件目录
│ └── armor_detector.hpp
├── src/ # 源文件目录
│ ├── main.cpp
│ └── armor_detector.cpp
├── config/ # 配置文件
│ └── params.yaml
└── build/ # 构建目录(不加入 Git)
对应的 CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(armor_detector LANGUAGES CXX)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找依赖库
find_package(OpenCV REQUIRED)
# 创建可执行文件
add_executable(detector
src/main.cpp
src/armor_detector.cpp
)
# 设置头文件搜索路径
target_include_directories(detector PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# 链接库
target_link_libraries(detector ${OpenCV_LIBS})
常用 CMake 命令速查¶
cmake .. # 基本配置(使用默认编译器)
cmake -DCMAKE_BUILD_TYPE=Release .. # 指定 Release 模式(优化,无调试信息)
cmake -DCMAKE_BUILD_TYPE=Debug .. # Debug 模式(有调试信息,适合调试)
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. # 生成 compile_commands.json(VSCode 需要)
cmake --build . # 编译(等同于 make,跨平台通用)
cmake --build . -j8 # 用 8 个线程并行编译(更快)
cmake --build . --target clean # 清理编译产物
make -j$(nproc) # 用所有 CPU 核心编译(Linux 最常用的写法)
# macOS 替代:make -j$(sysctl -n hw.logicalcpu)
make clean # 清理编译产物
1.7 Docker 简介¶
这是什么¶
Docker 是一个容器化平台,可以把应用程序及其所有依赖打包成一个"容器"(Container)。你可以把容器理解为一个极轻量级的虚拟机——它有自己的文件系统、网络环境和运行空间,但共享宿主机的操作系统内核,启动只需几秒。
传统方式: Docker 方式:
┌──────────────┐ ┌──────────────────────────┐
│ 虚拟机 A │ ← 很重 │ 容器 1 │ 容器 2 │ ... │ ← 很轻
│ 完整 OS │ │ ROS2 │ OpenCV │ │
│ 应用程序 │ │ 应用 │ 应用 │ │
├──────────────┤ ├──────────────────────────┤
│ 虚拟机 B │ │ Docker 引擎 │
│ 完整 OS │ ├──────────────────────────┤
│ 应用程序 │ │ 宿主机 OS │
├──────────────┤ └──────────────────────────┘
│ 宿主机 OS │
└──────────────┘
为什么视觉组需要 Docker¶
环境地狱
想象一下这个场景:新队员加入,需要配环境。ROS2 Humble 需要 Ubuntu 22.04,OpenCV 需要特定版本,还有各种编译依赖。按照教程装了一天,最后编译还是报错,因为某个库版本不兼容。这种情况在 C++ 开发中非常常见,俗称"环境地狱"(Dependency Hell)。
Docker 解决了以下问题:
| 问题 | 没有 Docker | 有 Docker |
|---|---|---|
| 新队员配环境 | 跟着文档装 1-2 天,可能失败 | docker pull 一条命令,几分钟搞定 |
| 不同队员环境不一致 | "在我电脑上能跑啊" | 所有人用同一个镜像,100% 一致 |
| ROS2 版本切换 | 卸载重装,可能搞坏系统 | 换一个镜像,互不影响 |
| 比赛现场部署 | 紧急配环境,手忙脚乱 | 赛前打包好镜像,现场直接运行 |
安装 Docker¶
# 卸载旧版本(如果有)
sudo apt remove -y docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# 添加 Docker 仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 将当前用户添加到 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 需要重新登录终端(或重启)才能生效
# 临时方案:在当前终端执行
newgrp docker
# 验证安装
docker run hello-world
# 看到 "Hello from Docker!" 就说明安装成功了
Docker 基本命令¶
# ============ 镜像操作 ============
# 查看本地镜像
docker images
# 从 Docker Hub 拉取镜像
docker pull ubuntu:22.04
# 删除镜像
docker rmi ubuntu:22.04
# ============ 容器操作 ============
# 运行一个容器(交互模式)
docker run -it ubuntu:22.04 /bin/bash
# -i: 交互模式
# -t: 分配伪终端
# 执行后进入容器的 bash,exit 退出并停止容器
# 运行一个容器(后台模式)
docker run -d --name my_container ubuntu:22.04 sleep infinity
# -d: 后台运行
# --name: 给容器起名字
# 查看正在运行的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 进入正在运行的容器
docker exec -it my_container /bin/bash
# 停止/启动/删除容器
docker stop my_container
docker start my_container
docker rm my_container
# ============ 镜像构建 ============
# 根据 Dockerfile 构建镜像
docker build -t my_vision_env .
# 保存/加载镜像(用于离线传输到嵌入式设备)
docker save my_vision_env > vision_env.tar
docker load < vision_env.tar
Dockerfile 示例¶
在项目根目录创建 Dockerfile:
# 基础镜像
FROM ubuntu:22.04
# 设置非交互模式(避免安装过程中的交互提示)
ENV DEBIAN_FRONTEND=noninteractive
# 安装基础依赖
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
libopencv-dev \
&& rm -rf /var/lib/apt/lists/*
# 设置工作目录
WORKDIR /workspace
# 复制项目文件
COPY . .
# 编译项目
RUN mkdir build && cd build && cmake .. && make -j$(nproc)
# 默认启动命令
CMD ["./build/my_program"]
视觉组通常不用自己写 Dockerfile
rm_vision 项目通常会提供预构建好的 Docker 镜像或 Dockerfile,你只需要 docker pull 或 docker build 即可。了解 Docker 基本概念和命令是为了能看懂项目的使用说明并进行简单的定制。
1.8 在自瞄系统中的应用¶
前面介绍了七个工具/概念。下面用一张表总结它们在自瞄系统开发中的具体应用场景:
| 工具 | 在自瞄系统中的具体用法 |
|---|---|
| Ubuntu | 运行 ROS2 节点、编译 OpenCV、训练/推理模型;嵌入式设备上也运行 Ubuntu |
| 终端命令 | cat 查看日志,grep 搜索错误,chmod 赋予脚本权限,top 监控 CPU 占用 |
| Git | 管理自瞄代码版本,团队协作开发不同模块(检测、跟踪、通信) |
| VSCode | 编写和调试 C++ 代码,Remote SSH 编辑嵌入式设备上的代码 |
| SSH | 连接 Jetson/Radxa 部署程序、查看运行日志、赛场调试 |
| CMake | 编译整个自瞄系统,管理 OpenCV、ROS2、串口库等依赖 |
| Docker | 快速搭建一致的开发/部署环境,避免环境问题 |
典型开发流程示例¶
下面是一个完整的视觉组日常工作流程,展示每个工具如何串联使用:
# === 1. 早上到实验室,开始工作 ===
# 打开终端,拉取团队最新代码
cd ~/rm_vision
git pull origin main
# 查看今天有哪些更新
git log --oneline -5
# === 2. 创建自己的开发分支 ===
git checkout -b feature/new-armor-classifier
# === 3. 用 VSCode 打开项目,开始写代码 ===
code .
# 在 VSCode 中编写新的分类器代码...
# VSCode 的 C++ 插件提供自动补全和跳转定义功能
# CMake Tools 插件可以一键编译(Ctrl+Shift+P → CMake: Build)
# === 4. 本地编译测试 ===
cd build
cmake .. && make -j$(nproc)
# 运行测试
./rm_vision_node --test
# 用 grep 在日志中查找关键信息
cat output.log | grep "armor"
cat output.log | grep -i "error" # 忽略大小写搜索
# === 5. 提交代码 ===
cd ~/rm_vision
git add src/new_classifier.cpp include/new_classifier.hpp
git commit -m "feat: 实现新的装甲板颜色分类器"
# === 6. 推送到远程仓库 ===
git push origin feature/new-armor-classifier
# === 7. 部署到机器人上测试 ===
# 用 SSH 连接到机器人的嵌入式设备
ssh robot1
# 在嵌入式设备上拉取代码并编译
cd ~/rm_vision
git pull
cd build && cmake .. && make -j4
# 运行自瞄程序
./rm_vision_node
# 查看运行日志
tail -f output.log
# === 8. 如果使用 Docker ===
# 在嵌入式设备上用 Docker 运行(环境一致性有保障)
docker pull your-team/rm_vision:latest
docker run --rm --privileged \
-v /dev/video0:/dev/video0 \
your-team/rm_vision:latest
在 VSCode 中远程调试嵌入式设备¶
VSCode 的 Remote SSH 让你可以像编辑本地文件一样编辑远程设备上的代码:
- 按
Cmd+Shift+P(macOS)/Ctrl+Shift+P(Linux),输入Remote-SSH: Connect to Host - 选择你配置好的
robot1(来自~/.ssh/config) - VSCode 会自动连接到远程设备并安装服务端
- 打开远程设备上的
~/rm_vision目录 - 现在你可以在本地 VSCode 中编辑远程文件,使用远程终端编译和运行
本章小结¶
恭喜你完成了开发环境搭建!
现在你已经拥有了:
- 一个可以运行的 Linux 环境
- 基本的终端操作能力
- Git 版本控制工具
- VSCode 代码编辑器及必要插件
- SSH 远程连接能力
- CMake 构建系统的基础知识
- Docker 容器化的基本概念
这些是视觉组开发的基础设施。接下来的章节将正式进入 C++ 编程学习。
练习¶
动手实践是最好的学习方式。请完成以下练习:
- 安装 Ubuntu 22.04(任意方式),成功进入桌面/终端
- 在终端中用
mkdir、cd、ls创建并浏览一个目录结构 - 在 GitHub 上注册账号,创建一个仓库,用 Git 完成 clone → 修改 → add → commit → push 全流程
- 安装 VSCode 及 C/C++ 相关插件,成功打开一个 C++ 文件并看到语法高亮
- 生成 SSH 密钥对,配置免密登录到另一台机器(可以和队友互相配置)
- 编写一个 CMakeLists.txt,编译一个包含两个
.cpp文件的项目 - 安装 Docker,运行
docker run hello-world