Jetson Orin Nano Super + Ubuntu 22.04 + ROS2 Humble + Autoware Universe
正确安装流程(修正版)
适用平台 : NVIDIA Jetson Orin Nano Super (8GB/16GB)
系统 : Ubuntu 22.04 (Jammy) with JetPack 6.x
ROS版本 : ROS2 Humble Hawksbill
安装方式: 源码编译 (Source Build)
目录
- 系统准备
- [ROS2 Humble 安装](#ROS2 Humble 安装)
- [Autoware 开发环境配置](#Autoware 开发环境配置)
- [源码导入(wget 方式)](#源码导入(wget 方式))
- [rosdep 配置](#rosdep 配置)
- 编译构建
- 常见问题速查
1. 系统准备
1.1 确认环境
bash
# 确认 Ubuntu 22.04
lsb_release -a
# 确认 JetPack 版本
head -n 1 /etc/nv_tegra_release
# 系统更新
sudo apt update && sudo apt upgrade -y
sudo apt install -y git curl wget vim build-essential python3-pip python3-vcstool python3-colcon-common-extensions unzip
1.2 配置 Swap(编译必需!)
bash
# Jetson Orin Nano 内存有限,必须配置 32GB+ Swap
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 验证
free -h
1.3 Git 配置优化
bash
# 增大缓冲区,减少 GnuTLS 错误
git config --global http.postBuffer 524288000
git config --global http.maxRequestBuffer 100M
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
git config --global core.compression 0
2. ROS2 Humble 安装
bash
# 设置 UTF-8 locale
locale # 检查是否支持 UTF-8
sudo apt install -y locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
# 添加 ROS2 软件源
sudo apt install -y software-properties-common
sudo add-apt-repository universe -y
sudo apt install -y curl gnupg lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# 安装 ROS2 Humble
sudo apt update
sudo apt install -y ros-humble-desktop ros-humble-ros-base ros-dev-tools
# 环境配置
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
3. Autoware 开发环境配置
bash
# 克隆 Autoware 主仓库
mkdir -p ~/autoware && cd ~/autoware
git clone https://github.com/autowarefoundation/autoware.git
cd autoware
git checkout 1.8.0 # 使用稳定版本
# 安装开发环境(跳过 NVIDIA,JetPack 已自带)
./setup-dev-env.sh --no-nvidia
常见问题处理
问题 1:apt 锁被占用
bash
# 终止占用进程
sudo kill -9 $(pgrep -f apt) 2>/dev/null
sudo rm -f /var/lib/apt/lists/lock /var/cache/apt/archives/lock /var/lib/dpkg/lock*
sudo dpkg --configure -a
sudo apt update
问题 2:ros2-apt-source 下载超时
bash
# 编辑 ansible task 文件,跳过该任务
FILE=$(find ~/.ansible/collections -path "*/ros2/tasks/main.yaml" 2>/dev/null | head -1)
sed -i '/name: Get ros2-apt-source package/,/mode:/{s/^/# /}' "$FILE"
sed -i '/name: Install ros2-apt-source package/,/become:/{s/^/# /}' "$FILE"
sed -i '/name: Install ros-{{ rosdistro + .*/{n;s/when:.*/when: false/}' "$FILE"
问题 3:gpg 权限错误
bash
sudo chown -R $(whoami):$(whoami) ~/.gnupg
chmod 700 ~/.gnupg
问题 4:acados 等仓库克隆超时
bash
# 批量修改所有 ansible roles 中的 github URL 为 ghproxy
find ~/.ansible/collections -name "*.yaml" -path "*/roles/*" | while read f; do
if grep -q "github.com" "$f"; then
sed -i 's|https://github.com/|https://ghproxy.com/https://github.com/|g' "$f"
fi
done
4. 源码导入(wget 方式)
重要 :Jetson 上 Git 的 GnuTLS 有兼容性问题,HTTPS 克隆频繁超时。
解决方案 :用wget下载 GitHub archive tar.gz,然后解压。
bash
cd ~/autoware
# 创建 src 目录
mkdir -p src
# 用 Python 脚本批量下载所有仓库
python3 << 'PYEOF'
import yaml
import os
import subprocess
import re
repos_file = "repositories/autoware.repos"
with open(repos_file, "r") as f:
repos = yaml.safe_load(f)
failed = []
success = 0
skipped = 0
is_commit = lambda v: bool(re.match(r'^[0-9a-f]{40}$', v))
for path, info in repos["repositories"].items():
url = info["url"]
version = info.get("version", "main")
target = f"src/{path}"
# 已存在则跳过
if os.path.exists(target) and (os.path.exists(os.path.join(target, "CMakeLists.txt")) or os.path.exists(os.path.join(target, "package.xml"))):
print(f"[SKIP] {path}")
skipped += 1
continue
# 清理残留
if os.path.exists(target):
os.system(f"rm -rf '{target}'")
owner_repo = url.replace("https://github.com/", "").replace(".git", "")
owner, repo = owner_repo.split("/")
# 尝试多种 archive URL 格式
urls_to_try = [
f"https://github.com/{owner}/{repo}/archive/refs/tags/{version}.tar.gz",
f"https://github.com/{owner}/{repo}/archive/{version}.tar.gz",
f"https://github.com/{owner}/{repo}/archive/refs/heads/{version}.tar.gz",
]
print(f"
[DOWNLOAD] {path} -> {version}")
os.makedirs(os.path.dirname(target), exist_ok=True)
tar_file = f"/tmp/{repo}_{version.replace('/', '_')}.tar.gz"
downloaded = False
for archive_url in urls_to_try:
print(f" Trying: {archive_url}")
r = subprocess.run(["wget", "--timeout=120", "--tries=3", "-q", "-O", tar_file, archive_url], capture_output=True, text=True)
if r.returncode == 0 and os.path.exists(tar_file) and os.path.getsize(tar_file) > 1024:
downloaded = True
print(f" ✓ Downloaded")
break
else:
print(f" ✗ Failed")
if not downloaded:
print(f" ✗✗✗ All download attempts failed")
failed.append((path, url, version))
continue
# 解压
r2 = subprocess.run(["tar", "xzf", tar_file, "-C", os.path.dirname(target)], capture_output=True, text=True)
if r2.returncode != 0:
print(f" ✗ Extract failed")
failed.append((path, url, version))
os.remove(tar_file)
continue
# 重命名解压后的目录
parent_dir = os.path.dirname(target)
possible_names = [
f"{parent_dir}/{repo}-{version}",
f"{parent_dir}/{repo}-{version.lstrip('v')}",
f"{parent_dir}/{repo}-{version.replace('refs/tags/', '')}",
f"{parent_dir}/{repo}-{version.replace('refs/heads/', '')}",
]
renamed = False
for extracted in possible_names:
if os.path.exists(extracted):
os.rename(extracted, target)
print(f" ✓ Renamed: {os.path.basename(extracted)} -> {os.path.basename(target)}")
renamed = True
break
if not renamed:
# fallback: 找最匹配的目录
dirs = [d for d in os.listdir(parent_dir) if os.path.isdir(os.path.join(parent_dir, d)) and d.startswith(repo)]
if dirs:
os.rename(os.path.join(parent_dir, dirs[0]), target)
print(f" ✓ Renamed (fallback): {dirs[0]} -> {os.path.basename(target)}")
renamed = True
if renamed:
success += 1
else:
print(f" ✗ Rename failed")
failed.append((path, url, version))
# 清理
if os.path.exists(tar_file):
os.remove(tar_file)
print(f"
{'='*60}")
print(f"Skipped: {skipped}, Success: {success}, Failed: {len(failed)}")
if failed:
print("Failed repos:")
for p, u, v in failed:
print(f" - {p} ({v})")
PYEOF
验证导入
bash
# 检查数量
echo "CMakeLists.txt: $(find src -name 'CMakeLists.txt' | wc -l)"
echo "package.xml: $(find src -name 'package.xml' | wc -l)"
# 查看目录结构
ls src/core/
ls src/universe/
ls src/launcher/
5. rosdep 配置
重要:raw.githubusercontent.com 在国内经常超时,需要手动下载 rosdistro 到本地。
bash
# 1. 创建本地 rosdep 目录
mkdir -p ~/.ros/rosdep
cd ~/.ros/rosdep
# 2. 手动下载 rosdistro 文件(wget 比 git 更稳定)
wget --timeout=60 --tries=3 https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
wget --timeout=60 --tries=3 https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
wget --timeout=60 --tries=3 https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/ruby.yaml
# 3. 配置 rosdep 使用本地文件
sudo mkdir -p /etc/ros/rosdep/sources.list.d
sudo tee /etc/ros/rosdep/sources.list.d/20-default.list << 'EOF'
yaml file:///home/jetson/.ros/rosdep/base.yaml
yaml file:///home/jetson/.ros/rosdep/python.yaml
yaml file:///home/jetson/.ros/rosdep/ruby.yaml
EOF
# 4. 更新 rosdep
rosdep update
# 5. 安装依赖
cd ~/autoware
source /opt/ros/humble/setup.bash
rosdep install -y --from-paths src --ignore-src --rosdistro $ROS_DISTRO
6. 编译构建
bash
cd ~/autoware
source /opt/ros/humble/setup.bash
# 编译(限制线程数防止 OOM)
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --parallel-workers 2
# 如果内存还是不够,限制到 1 个线程
# colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --parallel-workers 1
# 编译后配置环境变量
echo "source ~/autoware/install/setup.bash" >> ~/.bashrc
source ~/autoware/install/setup.bash
编译时间
- 首次编译: 4-8 小时(Jetson Orin Nano Super)
- 后续增量编译: 几分钟到几十分钟
防断连建议
bash
# 使用 tmux 保活
sudo apt install -y tmux
tmux new -s build
# 在 tmux 里执行 colcon build
# 按 Ctrl+B 然后 D detach
# 随时恢复: tmux attach -t build
7. 常见问题速查
| 问题 | 原因 | 解决方案 |
|---|---|---|
apt 锁被占用 |
后台 apt 进程未释放 | sudo kill -9 $(pgrep -f apt); sudo rm -f /var/lib/apt/lists/lock |
GnuTLS recv error (-110) |
Git SSL/TLS 握手失败 | 用 wget 下载 tar.gz 替代 git clone |
Failed to connect to github.com port 443 |
Git 连接超时 | 用 wget 下载 archive 替代 |
rosdep update 超时 |
raw.githubusercontent.com 被墙 | 手动下载到 ~/.ros/rosdep/ 本地使用 |
gpg 权限不够 |
.gnupg 目录所有权错误 |
sudo chown -R $(whoami):$(whoami) ~/.gnupg |
编译被 killed |
OOM 内存不足 | 增大 swap 到 64GB,限制 --parallel-workers 1 |
ghproxy 连接超时 |
ghproxy 服务不可用 | 不要用 ghproxy,直接用 wget 下载 |