Jetson Orin Nano Super + Ubuntu 22.04 + ROS2 Humble + Autoware Universe

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)


目录

  1. 系统准备
  2. [ROS2 Humble 安装](#ROS2 Humble 安装)
  3. [Autoware 开发环境配置](#Autoware 开发环境配置)
  4. [源码导入(wget 方式)](#源码导入(wget 方式))
  5. [rosdep 配置](#rosdep 配置)
  6. 编译构建
  7. 常见问题速查

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 下载

参考资源

相关推荐
栩栩云生19 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1120 小时前
linux基础IO
linux·运维·服务器
BelongPanda1 天前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯1 天前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_777998341 天前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器
yunwei371 天前
eBPF 教程:检查 exec 后真正安装的可执行镜像
linux·开源
雷工笔记1 天前
Ubuntu迁移记录
笔记·ubuntu
笑锝没心没肺1 天前
yum update 报错:GPG key retrieval failed: [Errno 14] HTTPS Error 404 - Not Found
linux·运维·服务器
AAA@峥1 天前
CentOS Stream8 基于 Packstack 搭建 OpenStack 云平台全流程实战
linux·centos·openstack
汤永红1 天前
gtk-x11-2.0.so.0
linux·运维·服务器