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

参考资源

相关推荐
feng_you_ying_li3 小时前
liunx之库的原理,核心是静态库(2)
linux
cui_ruicheng3 小时前
Linux网络编程(三):Socket编程预备知识
linux·服务器·网络
小此方3 小时前
Re:Linux系统篇(十六) 进程篇 · 一:深入理解操作系统:从软硬件架构到“先描述,再组织”的管理哲学
linux·驱动开发·硬件架构
Shadow(⊙o⊙)3 小时前
进程分析2.0——进程退出、进程等待-Linux重要经典模块
linux·运维·服务器·开发语言·c++·学习
pengyi8710153 小时前
高匿代理核心原理详解,隐藏真实IP实现无痕网络访问
linux·运维·服务器·网络·tcp/ip
Irissgwe3 小时前
九、Linux信号机制(一)
linux·信号处理·信号·进程信号·信号的产生
皮卡蛋炒饭.3 小时前
数据链路层相关学习
linux·数据链路层
Benszen4 小时前
云计算基础-1: VMware落地部署CentOS 7
linux·centos·云计算
JackSparrow4144 小时前
彻底理解Java NIO(二)C语言实现 I/O多路复用+Reactor模式 服务器详解
java·linux·c语言·后端·nio·reactor模式