<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>iodinot</title><description>iodinot 的技术笔记与实践记录</description><link>https://iodi.net</link><item><title>NVIDIA Orin NX/Nano 初始化</title><link>https://iodi.net/blog/nvidia-orin-init</link><guid isPermaLink="true">https://iodi.net/blog/nvidia-orin-init</guid><description>Orin NX/Nano 的系统安装、配网及 SSH 初步配置</description><pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Tabs, TabItem } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;不常用的流程及指令容易遗忘，而有些流程是低频却必要的，比如新设备的初始化。本文记录 NVIDIA Orin NX/Nano 系统的安装以及初步配置流程以便查阅。&lt;/p&gt;
&lt;h2&gt;一、 WSL2配置&lt;/h2&gt;
&lt;p&gt;仅供 Windows 用户参考，原生 Ubuntu 用户可直接跳到&lt;a href=&quot;#%E4%BA%8C-%E7%B3%BB%E7%BB%9F%E5%AE%89%E8%A3%85&quot;&gt;系统安装&lt;/a&gt;
在 &lt;code&gt;~/.wslconfig&lt;/code&gt; 下加入如下配置：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[wsl2]
# 刷机需要与设备处于同一物理局域网，所以使用镜像网络。
networkingMode=mirrored

# 可选：仅在开启代理软件的 TUN 模式（如 Clash/Mihomo 虚拟网卡），且导致 WSL2 镜像网络启动异常
# （例如 `ip a` 只有 `lo`）时再配置。将 TUN 网卡加入黑名单后，WSL2 仍可正常克隆物理网卡。
# 这里的 `Mihomo` 是你的 TUN 网卡名称。
ignoredNetworkAdapters=Mihomo

# 关闭自动代理，避免 WSL 内部环境变量与宿主机 TUN 路由互相干扰。
autoProxy=false
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、 系统安装&lt;/h2&gt;
&lt;h3&gt;2.1 GUI 安装&lt;/h3&gt;
&lt;p&gt;SDK Manager下载：&lt;a href=&quot;https://developer.nvidia.com/drive/sdk-manager&quot;&gt;NVIDIA SDK Manager&lt;/a&gt;
之后基本就是傻瓜式操作了，详细教程见 &lt;a href=&quot;https://docs.nvidia.com/sdk-manager/install-with-sdkm-jetson/index.html&quot;&gt;官方文档&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;2.2 CLI安装&lt;/h3&gt;
&lt;p&gt;对 &lt;strong&gt;Jetson Orin NX / Nano&lt;/strong&gt; 而言，NVIDIA 官方当前推荐的命令行刷机路线是 &lt;strong&gt;&lt;code&gt;initrd flashing&lt;/code&gt;&lt;/strong&gt;。依据见 &lt;a href=&quot;https://docs.nvidia.com/jetson/archives/r36.4.4/DeveloperGuide/SD/FlashingSupport.html&quot;&gt;Flashing Support&lt;/a&gt; 与 &lt;a href=&quot;https://docs.nvidia.com/jetson/archives/r36.4/DeveloperGuide/IN/QuickStart.html&quot;&gt;Quick Start&lt;/a&gt;。&lt;/p&gt;
&lt;h4&gt;2.2.1 安装前提&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先下载两个官方包&lt;/strong&gt;：BSP release package 和 sample rootfs，下载入口在 &lt;a href=&quot;https://developer.nvidia.com/embedded/jetson-linux-archive&quot;&gt;Jetson Linux 下载页&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;**Orin NX / Nano 默认记 &lt;code&gt;initrd flash&lt;/code&gt;**而不是 &lt;code&gt;flash.sh&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;2.2.2 环境准备&lt;/h4&gt;
&lt;p&gt;官方准备步骤如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 解压 Jetson Linux BSP 包
tar xf ${L4T_RELEASE_PACKAGE}
# 将 sample rootfs 解压到 Linux_for_Tegra/rootfs
sudo tar xpf ${SAMPLE_FS_PACKAGE} -C Linux_for_Tegra/rootfs/
cd Linux_for_Tegra/
# 安装刷机依赖
sudo ./tools/l4t_flash_prerequisites.sh
# 应用 NVIDIA 提供的二进制组件
sudo ./apply_binaries.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 &lt;code&gt;${L4T_RELEASE_PACKAGE}&lt;/code&gt; 和 &lt;code&gt;${SAMPLE_FS_PACKAGE}&lt;/code&gt; 指的就是刚下载的那两个官方包。&lt;br&gt;
顺序是：&lt;strong&gt;先解包 rootfs，再跑前置依赖，最后 &lt;code&gt;apply_binaries.sh&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;2.2.3 Force Recovery Mode&lt;/h4&gt;
&lt;p&gt;对于 &lt;strong&gt;Jetson Orin Nano Developer Kit&lt;/strong&gt;，Quick Start 给出的进入 Force Recovery Mode 的方式如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;断开电源，确保开发板处于关机状态。&lt;/li&gt;
&lt;li&gt;在 12-pin button header 上短接 &lt;code&gt;REC&lt;/code&gt; 和 &lt;code&gt;GND&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;重新接上电源。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以在主机上直接执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 主机侧确认 Recovery Mode 识别结果
lsusb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果能看到类似下面这一行，才说明板子确实进了恢复模式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Bus 001 Device 025: ID 0955:7523 NVIDIA Corp. APX
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.2.4 命令行刷写&lt;/h4&gt;
&lt;p&gt;Quick Start 给出的 Jetson Orin Nano Developer Kit 官方示例如下：&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--external-device nvme0n1p1&lt;/code&gt;：目标系统写入的外部介质分区。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c tools/kernel_flash/flash_l4t_t234_nvme.xml&lt;/code&gt;：外部介质布局配置文件。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p &quot;-c bootloader/generic/cfg/flash_t234_qspi.xml&quot;&lt;/code&gt;：QSPI 启动介质配置。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--showlogs&lt;/code&gt;：输出详细刷机日志。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--network usb0&lt;/code&gt;：通过 USB 虚拟网卡完成刷机过程中的网络通信。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jetson-orin-nano-devkit internal&lt;/code&gt;：目标板型与刷写模式参数。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;--network usb0&lt;/code&gt; 不能漏。Flashing Support 提到，&lt;code&gt;initrd flash&lt;/code&gt; 过程中工具会通过 &lt;code&gt;IPv6&lt;/code&gt; 地址空间 &lt;code&gt;fc00:1:1::/48&lt;/code&gt; 使用 NFS 和 SSH。&lt;/p&gt;
&lt;h4&gt;2.2.5 启动介质确认&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;第一次启动时，要在 UEFI 菜单里选对刚刷进去的启动介质&lt;/strong&gt;。&lt;br&gt;
比如刷的是 NVMe，启动项也应指向 NVMe。&lt;/p&gt;
&lt;h4&gt;2.2.6 参考资料&lt;/h4&gt;
&lt;p&gt;后面如果又忘了细节，优先翻这几个官方页面和官方论坛贴：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.nvidia.com/jetson/archives/r36.4/DeveloperGuide/IN/QuickStart.html&quot;&gt;NVIDIA Jetson Linux Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.nvidia.com/jetson/archives/r36.4.4/DeveloperGuide/SD/FlashingSupport.html&quot;&gt;NVIDIA Flashing Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forums.developer.nvidia.com/t/recovery-mode-for-jetson-orin-nano-0955-7523-p3767-0003-with-8gb/318754&quot;&gt;NVIDIA Developer Forums: Recovery Mode for Jetson Orin Nano&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forums.developer.nvidia.com/t/failed-to-connect-jetson-orin-nano-dev-kit-to-host-via-usb-c-after-flashing-jetpack-6-2/323030&quot;&gt;NVIDIA Developer Forums: USB-C / Recovery 识别问题讨论&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、初次配网&lt;/h2&gt;
&lt;h3&gt;3.1 Headless下无路由器后台权限获取Nano局域网IP&lt;/h3&gt;
&lt;p&gt;适用范围：板卡已连接工作机同一局域网，但没有显示器、没有路由器后台权限。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# 1. 查看本机 IPv4，确认当前网段（本文示例为 192.168.1.0/24）
ipconfig

# 2. 只扫描开放 22 端口的主机
nmap -p 22 --open 192.168.1.0/24

# 3. 根据扫描结果尝试 SSH，确认目标地址
ssh nvidia@192.168.1.20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nmap -p 22 --open&lt;/code&gt; 用于只保留开放 SSH 端口的主机，候选更少。&lt;/li&gt;
&lt;li&gt;Nano 安装系统后 &lt;code&gt;sshd&lt;/code&gt; 默认开启，因此可先用 &lt;code&gt;22&lt;/code&gt; 端口做一轮筛选。&lt;/li&gt;
&lt;li&gt;本机实测在 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 下可正常筛出 &lt;code&gt;192.168.1.20&lt;/code&gt;，其 MAC 厂商会显示为 &lt;code&gt;Nvidia&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;拿到候选地址后，再用 &lt;code&gt;ssh nvidia@&amp;#x3C;ip&gt;&lt;/code&gt; 做最终确认。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nmap.org/download.html&quot;&gt;Nmap Download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://npcap.com/&quot;&gt;Npcap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文写作时，本机使用 &lt;code&gt;Nmap 7.98 + Npcap 1.87&lt;/code&gt;，&lt;code&gt;nmap -sn 192.168.1.0/24&lt;/code&gt; 可正常执行。&lt;/p&gt;
&lt;h3&gt;3.2 配置 mDNS 访问&lt;/h3&gt;
&lt;p&gt;具体配置过程见&lt;a href=&quot;/blog/nvidia-orin-environment-setup#22-%E6%8A%9B%E5%BC%83%E9%9D%99%E6%80%81-ip%E9%85%8D%E7%BD%AE-mdns-%E8%AE%BF%E9%97%AE&quot;&gt;《NVIDIA Orin 环境配置》&lt;/a&gt;的对应章节，这里不再重复展开。&lt;/p&gt;
&lt;h2&gt;四、SSH 扫盲&lt;/h2&gt;
&lt;p&gt;进入远程开发阶段后，&lt;code&gt;SSH&lt;/code&gt; 基本就是你和 Orin Nano 交互的默认入口。无论是工业研发团队，还是高校计算平台，成熟做法都相当一致：以 &lt;code&gt;SSH&lt;/code&gt; 作为默认控制面，以公钥认证作为默认鉴权手段，再用主机别名和端口转发把日常开发流程固化下来。&lt;/p&gt;
&lt;h3&gt;4.1 第一次连接&lt;/h3&gt;
&lt;p&gt;如果这台 Nano 还没配好 &lt;code&gt;mDNS&lt;/code&gt;，就先用刚扫出来的 IP 登录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh nvidia@192.168.1.20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一次连接时，终端通常会提示你确认主机指纹，输入 &lt;code&gt;yes&lt;/code&gt; 即可。登录成功后，建议先记住下面几条最常用的确认命令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hostname      # 当前主机名
hostname -I   # 当前 IP
whoami        # 当前登录用户
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 用 &lt;code&gt;~/.ssh/config&lt;/code&gt; 给设备起别名&lt;/h3&gt;
&lt;p&gt;如果每次都手动输入 &lt;code&gt;ssh nvidia@192.168.x.x&lt;/code&gt;，很快就会烦。更实用的做法是在开发机的 &lt;code&gt;~/.ssh/config&lt;/code&gt; 里给每台设备起一个固定别名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host nrc17-via-jump
    HostName 192.168.1.20              # Nano 在内网中的地址
    User nvidia                        # Nano 登录用户
    IdentityFile ~/.ssh/id_ed25519     # 登录 Nano 使用的私钥
    IdentitiesOnly yes                 # 只使用指定私钥
    ProxyJump jump-lab                 # 先跳到 jump-lab，再转发到目标主机
    ConnectTimeout 5                   # 避免跳板链路异常时卡太久
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 &lt;code&gt;Host&lt;/code&gt; 后面的名字是你自己定义的别名。这样以后直接执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh nrc17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可登录对应设备。&lt;br&gt;
如果跳板链路不止一层，&lt;code&gt;ProxyJump&lt;/code&gt; 也支持继续写成 &lt;code&gt;jump-a,jump-b&lt;/code&gt; 这种链式形式。&lt;/p&gt;
&lt;h3&gt;4.3 免密登录&lt;/h3&gt;
&lt;p&gt;工程上更推荐把公钥提前配好，避免每次输密码：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 本机生成 ed25519 密钥；如果已有 ~/.ssh/id_ed25519，可跳过
ssh-keygen -t ed25519

# 将本机公钥复制到目标设备
ssh-copy-id nrc17

# 验证免密是否生效
ssh nrc17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一步在多机调试、频繁重连、脚本化部署时尤其省事。&lt;/p&gt;
&lt;h3&gt;4.4 常用的几种 SSH 命令&lt;/h3&gt;
&lt;h4&gt;远程执行命令&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 指定私钥、连接超时和 SSH 端口；登录后在远端执行巡检命令
ssh -i ~/.ssh/id_ed25519 -o ConnectTimeout=5 -p 22 nrc17 \
  &quot;hostname &amp;#x26;&amp;#x26; hostname -I &amp;#x26;&amp;#x26; systemctl is-active ssh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常用参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt;：指定端口，如 &lt;code&gt;ssh -p 2222 nrc17&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt;：指定私钥文件，如 &lt;code&gt;ssh -i ~/.ssh/id_ed25519 nrc17&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-L&lt;/code&gt;：本地端口转发&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-J&lt;/code&gt;：通过跳板机连接，等价于 &lt;code&gt;ProxyJump&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o&lt;/code&gt;：临时指定配置项，如 &lt;code&gt;-o ConnectTimeout=5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;传文件&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 指定私钥、端口和压缩，将本机文件上传到 Nano
scp -i ~/.ssh/id_ed25519 -P 22 -C ./config.yaml nrc17:~/config.yaml

# 递归拉回远端目录
scp -i ~/.ssh/id_ed25519 -P 22 -r nrc17:~/logs ./logs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常用参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-P&lt;/code&gt;：指定端口，注意这里是大写 &lt;code&gt;P&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt;：指定私钥文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt;：递归复制目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt;：启用压缩，适合弱网环境&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o&lt;/code&gt;：透传 SSH 配置项，如 &lt;code&gt;-o ConnectTimeout=5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;端口转发&lt;/h4&gt;
&lt;p&gt;如果某个服务只监听在 Nano 本机回环地址上，可以用 &lt;code&gt;ssh -L&lt;/code&gt; 把端口转到自己的电脑。例如 Nano 上某个 WebSocket 或 Web 服务监听在 &lt;code&gt;8765&lt;/code&gt; 端口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 指定私钥与端口，只建立隧道、不打开 shell，并放到后台运行
ssh -i ~/.ssh/id_ed25519 -p 22 -N -f \
  -L 8765:localhost:8765 \
  nrc17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连上后，本机访问 &lt;code&gt;localhost:8765&lt;/code&gt;，实际就等于访问 Nano 的 &lt;code&gt;localhost:8765&lt;/code&gt;。&lt;br&gt;
这种方式并不局限于 &lt;code&gt;foxglove_bridge&lt;/code&gt;，在 Jupyter、TensorBoard 等交互式服务上也普遍采用同样的 SSH 隧道模式。&lt;/p&gt;
&lt;p&gt;常用参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-L [本机端口]:[远端地址]:[远端端口]&lt;/code&gt;：本地端口转发&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt;：只建立隧道，不执行远程命令&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt;：放到后台运行，通常和 &lt;code&gt;-N&lt;/code&gt; 搭配&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt;：指定 SSH 端口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-J&lt;/code&gt;：通过跳板机建立隧道&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.5 关于 &lt;code&gt;ForwardAgent&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ForwardAgent&lt;/code&gt; 能让远端主机借用你本地 &lt;code&gt;ssh-agent&lt;/code&gt; 中已经加载的密钥，在某些需要从 Nano 再访问 Git 仓库的场景里会很方便。但这一项要谨慎使用，建议只对明确受信任的主机单独开启，不要写成 &lt;code&gt;Host *&lt;/code&gt; 的全局默认值。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Host nrc17
    HostName nrc17.local
    User nvidia
    ForwardAgent yes                   # 允许远端借用本机 ssh-agent；仅建议对受信任主机开启
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你并不需要在 Nano 上继续跳转到别的 SSH 服务，那么这一项完全可以不配。&lt;/p&gt;
&lt;h2&gt;五、常用服务与配置文件&lt;/h2&gt;
&lt;p&gt;容易忘的。&lt;/p&gt;
&lt;h3&gt;5.1 系统层&lt;/h3&gt;
&lt;h4&gt;核心服务&lt;/h4&gt;
&lt;p&gt;| 条目                   | 作用                                                                    | 最小示例                                   |
| ---------------------- | ----------------------------------------------------------------------- | ------------------------------------------ |
| &lt;code&gt;ssh.service&lt;/code&gt;          | 远程登录入口。系统刷好以后，后续大多数终端操作都从它开始。              | &lt;code&gt;sudo systemctl enable --now ssh&lt;/code&gt;          |
| &lt;code&gt;avahi-daemon.service&lt;/code&gt; | 提供 &lt;code&gt;.local&lt;/code&gt; 形式的 &lt;code&gt;mDNS&lt;/code&gt; 主机发现，便于在局域网内用主机名访问 Nano。 | &lt;code&gt;sudo systemctl enable --now avahi-daemon&lt;/code&gt; |&lt;/p&gt;
&lt;h4&gt;核心配置文件&lt;/h4&gt;
&lt;p&gt;| 条目                           | 作用                                                                | 最小示例                |
| ------------------------------ | ------------------------------------------------------------------- | ----------------------- |
| &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;         | &lt;code&gt;sshd&lt;/code&gt; 的主配置文件。常改的通常是认证方式、端口与登录策略。         | &lt;code&gt;Port 22&lt;/code&gt;               |
| &lt;code&gt;/etc/avahi/avahi-daemon.conf&lt;/code&gt; | &lt;code&gt;avahi-daemon&lt;/code&gt; 的配置文件。和 &lt;code&gt;mDNS&lt;/code&gt;、主机名发布相关。              | &lt;code&gt;publish-addresses=yes&lt;/code&gt; |
| &lt;code&gt;/etc/hostname&lt;/code&gt;                | 机器主机名。配合 &lt;code&gt;mDNS&lt;/code&gt; 后，常直接对应 &lt;code&gt;nrc17.local&lt;/code&gt; 这种访问方式。 | &lt;code&gt;nrc17&lt;/code&gt;                 |
| &lt;code&gt;/etc/hosts&lt;/code&gt;                   | 本地静态主机名解析表。改主机名或做本地别名映射时经常一起看。        | &lt;code&gt;127.0.1.1 nrc17&lt;/code&gt;       |&lt;/p&gt;
&lt;h4&gt;Ubuntu 常用配置文件&lt;/h4&gt;
&lt;p&gt;| 条目                             | 作用                                                               | 最小示例                                                         |
| -------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- |
| &lt;code&gt;/etc/apt/sources.list&lt;/code&gt;          | &lt;code&gt;apt&lt;/code&gt; 软件源主配置。换镜像、检查发行版源时最常看。                 | &lt;code&gt;deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted&lt;/code&gt; |
| &lt;code&gt;/etc/apt/sources.list.d/*.list&lt;/code&gt; | 第三方仓库配置目录。Jetson、Docker、ROS 这类额外源通常会落在这里。 | &lt;code&gt;docker.list&lt;/code&gt;                                                    |
| &lt;code&gt;/etc/netplan/*.yaml&lt;/code&gt;            | Ubuntu 的网络配置文件。静态 IP、DNS、网卡名映射通常从这里改。      | &lt;code&gt;renderer: NetworkManager&lt;/code&gt;                                       |
| &lt;code&gt;/etc/fstab&lt;/code&gt;                     | 开机自动挂载表。挂载 NVMe 分区、数据盘或外设时常会改。             | &lt;code&gt;UUID=xxxx /data ext4 defaults 0 2&lt;/code&gt;                              |
| &lt;code&gt;/etc/environment&lt;/code&gt;               | 系统级环境变量文件。需要对所有用户生效的环境变量可以写在这里。     | &lt;code&gt;HTTP_PROXY=http://127.0.0.1:7890&lt;/code&gt;                               |
| &lt;code&gt;~/.bashrc&lt;/code&gt;                      | 用户级 shell 初始化文件。别名、&lt;code&gt;PATH&lt;/code&gt;、代理变量等更常写在这里。    | &lt;code&gt;export PATH=$PATH:/usr/local/bin&lt;/code&gt;                               |&lt;/p&gt;
&lt;h4&gt;自定义自启动&lt;/h4&gt;
&lt;p&gt;| 条目                            | 作用                                                                                          | 最小示例                               |
| ------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------- |
| &lt;code&gt;/etc/systemd/system/*.service&lt;/code&gt; | 自定义 &lt;code&gt;systemd&lt;/code&gt; 服务单元目录。后续如果要让节点、脚本或容器开机自启，通常就在这里写服务文件。 | &lt;code&gt;ExecStart=/usr/bin/docker compose up&lt;/code&gt; |&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;.service&lt;/code&gt; 模板&lt;/h4&gt;
&lt;p&gt;后面如果要把脚本、节点或容器做成开机自启，通常会在 &lt;code&gt;/etc/systemd/system/&lt;/code&gt; 下写一个 &lt;code&gt;.service&lt;/code&gt; 文件。最小模板如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[Unit]
Description=My Startup Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=nvidia
WorkingDirectory=/home/nvidia
ExecStart=/usr/bin/bash /home/nvidia/start.sh
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;After&lt;/code&gt; / &lt;code&gt;Wants&lt;/code&gt;：声明启动依赖，常见是等网络起来。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User&lt;/code&gt;：指定以哪个用户身份运行。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WorkingDirectory&lt;/code&gt;：脚本或程序的工作目录。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExecStart&lt;/code&gt;：真正执行的命令。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Restart&lt;/code&gt; / &lt;code&gt;RestartSec&lt;/code&gt;：异常退出后的重启策略。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WantedBy=multi-user.target&lt;/code&gt;：表示在常规多用户启动阶段拉起。&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/thumbnail.BmXBGBUL.png"/><enclosure url="/_astro/thumbnail.BmXBGBUL.png"/></item><item><title>NVIDIA Orin NX/Nano 环境配置与搭建</title><link>https://iodi.net/blog/nvidia-orin-environment-setup</link><guid isPermaLink="true">https://iodi.net/blog/nvidia-orin-environment-setup</guid><description>在 Orin NX/Nano 平台上部署 ROS2 (rstack) 的完整环境配置指南。</description><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;h2&gt;一、 项目概述&lt;/h2&gt;
&lt;p&gt;本项目在 NVIDIA Jetson Orin NX/Nano 平台上部署一系列无人机上位机所需的ROS2包，下称 AADCL_UAV_UGV。为简化开发流程，并支持后续批量配置集群的需求，本项目通过容器化技术（Docker + Compose）部署，并利用 mDNS 协议简化集群组网。&lt;/p&gt;
&lt;h2&gt;二、 基础环境配置&lt;/h2&gt;
&lt;p&gt;本文适用于已预装基础系统的 Jetson Orin Nano。配置前需确保开发板已联网且可通过终端（SSH、屏幕或远程桌面）访问。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前提条件&lt;/strong&gt;：稳定的局域网环境、已知开发板 IP 以及 SSH 客户端。&lt;/p&gt;
&lt;p&gt;首先进行网络配置。&lt;/p&gt;
&lt;h3&gt;2.1 连接 WiFi&lt;/h3&gt;
&lt;p&gt;要把 nano 连上开发/生产环境的局域网，最常用的办法是使用 &lt;code&gt;nmcli&lt;/code&gt; 指令。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;扫描附近的 WiFi&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nmcli device wifi list
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;连接到你的 SSID&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 把 Your_SSID 和 Your_Password 换成实际的
sudo nmcli device wifi connect &quot;Your_SSID&quot; password &quot;Your_Password&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;确认连接成功&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nmcli connection show  # 看到有绿色的一行就说明连上了
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.2 抛弃静态 IP：配置 mDNS 访问&lt;/h3&gt;
&lt;p&gt;在多机协同的环境下，记住每台车/无人机的 IP 地址是非常麻烦的。我们通过配置 mDNS，让你能在局域网内直接用 &lt;code&gt;nrcXX.local&lt;/code&gt; 这种名字访问 nano，不管它的 IP 怎么变。
如上文所说，我们进入了 Orin Nano 的终端，在终端下输入如下指令：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;给 nano 命名&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 比如第 17 号机，就叫它 nrc17
sudo hostnamectl set-hostname nrc17
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置并启动服务 (Avahi)&lt;/strong&gt;：
安装 Avahi 并确保它在运行。注意：&lt;strong&gt;修改主机名后必须重启 Avahi 服务&lt;/strong&gt;才能让新名字在局域网生效。
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt update &amp;#x26;&amp;#x26; sudo apt install -y avahi-daemon
sudo systemctl restart avahi-daemon
sudo systemctl enable avahi-daemon
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证一下&lt;/strong&gt;：在你的开发机（比如笔记本）上执行 &lt;code&gt;ping nrc17.local&lt;/code&gt;。如果能通，以后你只需要记住这个名字就行了。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.3 生产环境对齐：基于 SSH 的 Headless 开发&lt;/h3&gt;
&lt;p&gt;在无人机集群开发中，给每台 Orin Nano 配备显示器是不现实的。更核心的原因在于：&lt;strong&gt;运行图形界面 (GUI) 会消耗昂贵的 CPU/GPU 资源&lt;/strong&gt;，在 Orin Nano 这种算力受限的平台上，每一分资源都应该留给 ROS 管道和 AI 推理。&lt;/p&gt;
&lt;p&gt;因此，建议采用 &lt;strong&gt;Headless&lt;/strong&gt; 开发模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;性能最大化&lt;/strong&gt;：关闭桌面环境可节省数百 MB 显存及 CPU 周期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;环境一致性&lt;/strong&gt;：开发环境与最终飞行场景完全一致，避免图形驱动导致的性能抖动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;远程可视化&lt;/strong&gt;：通过 &lt;code&gt;foxglove_bridge&lt;/code&gt; 等工具建立 WebSocket 通道，将原始数据流高效转发到你的电脑桌面上，使用 Foxglove Studio 进行低延迟的可视化调试。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置你的开发机 (推荐)&lt;/strong&gt;：
为了不用每次都输 IP 甚至不用输密码，建议在你的电脑（Linux/Mac/Win）的 &lt;code&gt;~/.ssh/config&lt;/code&gt; 中加入如下配置：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Host nrc17
    HostName nrc17.local
    User nvidia
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样便相当于用 &lt;code&gt;ssh nrc17&lt;/code&gt; 代替了 &lt;code&gt;ssh nvidia@192.168.1.17&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;免密登录 (可选)&lt;/strong&gt;：
在你的开发机终端执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh-keygen -t ed25519  # 生成你的密钥（如果已经有了就跳过）
ssh-copy-id nrc17      # 把你的公钥“递给”nano
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成后，&lt;code&gt;ssh nrc17&lt;/code&gt; 便可直连（这在 vibe coding 时非常实用）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.4 容器环境：Docker 与 NVIDIA Toolkit&lt;/h3&gt;
&lt;p&gt;为了不把 nano 的原始系统环境搞乱，建议全量使用容器。除了 Docker，最关键的是要安装 NVIDIA 的转发工具（Toolkit），这样容器里的算法才能用到 Orin 的 GPU 算力。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安装 Docker 引擎与 Compose V2 插件&lt;/strong&gt;：
由于 Ubuntu 22.04 的官方源不含 Compose V2 (即 &lt;code&gt;docker compose&lt;/code&gt; 指令)，我们需要添加 Docker 官方软件源：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 1. 安装基础依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# 2. 添加 Docker 官方 GPG 密钥 (使用 .asc 格式最稳妥，避免转换报错)
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 3. 添加 Docker 软件源列表
echo \
  &quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;#x26;&amp;#x26; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | \
  sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null

# 4. 更新并安装 V2 插件
sudo apt-get update
sudo apt-get install -y docker-compose-plugin

# 5. 权限补丁：将当前用户加入 docker 组
sudo usermod -aG docker $USER
# 注意：执行后需重新登录，或输入 `newgrp docker` 立即生效
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置 NVIDIA 软件源并安装 Toolkit&lt;/strong&gt;：
由于 Ubuntu 官方源不含此工具，必须手动添加 NVIDIA 的仓库：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 账户预检
sudo apt-get update &amp;#x26;&amp;#x26; sudo apt-get install -y curl

# 1. 导入 GPG 密钥（如果文件已存在，执行此指令会自动覆盖）
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor --yes -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

# 2. 添加软件源列表
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed &apos;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&apos; | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# 3. 更新并安装
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# 4. 重启 Docker 生效
sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;三、 获取源码：克隆仓库&lt;/h2&gt;
&lt;h3&gt;3.1 选择访问方式&lt;/h3&gt;
&lt;p&gt;本项目仓库位于 &lt;code&gt;gitfub.cv&lt;/code&gt;，支持以下两种访问方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;生产环境（推荐）&lt;/strong&gt;：由于本仓库已设置为&lt;strong&gt;公开&lt;/strong&gt;，在内地环境可&lt;strong&gt;直接裸连&lt;/strong&gt; HTTPS 地址进行克隆，无需登录，也无需配置 SSH Key。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发环境&lt;/strong&gt;：如果你需要向仓库提交代码，建议配置 SSH Key 以获得推送权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 生产环境：快速克隆（HTTPS）&lt;/h3&gt;
&lt;p&gt;直接执行以下指令进行全量同步：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd ~
# 1. 克隆主架构 (仓库公开，内地直接访问)
git clone https://gitfub.cv/iodinot/AADCL_UAV_UGV.git
cd AADCL_UAV_UGV

# 2. 关键：拉取所有依赖的算法源码和硬件驱动
git submodule update --init --recursive

# 3. 补丁：修正 livox_ros_driver2 的 package.xml
[ -f src/drivers/livox_ros_driver2/package_ROS2.xml ] &amp;#x26;&amp;#x26; cp src/drivers/livox_ros_driver2/package_ROS2.xml src/drivers/livox_ros_driver2/package.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是生产环境，下一步可直接跳到 &lt;a href=&quot;#%E4%BA%94-%E5%AE%B9%E5%99%A8%E9%85%8D%E7%BD%AE%E7%BC%96%E6%8E%92%E4%B8%8E%E5%90%AF%E5%8A%A8&quot;&gt;五、 容器配置、编排与启动&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;3.3 开发环境：SSH 配置（仅需提交代码时执行）&lt;/h3&gt;
&lt;p&gt;如果你需要提交代码，请按以下步骤配置 Gitea 访问权限：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;生成密钥对&lt;/strong&gt;：&lt;code&gt;ssh-keygen -t ed25519 -C &quot;your_email&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;添加公钥&lt;/strong&gt;：复制 &lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; 内容，前往 &lt;a href=&quot;https://gitfub.cv/user/settings/keys&quot;&gt;Gitea SSH 设置&lt;/a&gt; 添加。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;克隆地址&lt;/strong&gt;：使用 &lt;code&gt;git@gitfub.cv:iodinot/AADCL_UAV_UGV.git&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;四、 AADCL_UAV_UGV 目录结构&lt;/h2&gt;
&lt;p&gt;代码按照“单一职责”原则划分为五个顶级目录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~/AADCL_UAV_UGV
├── .env                # 机器硬件配置 (单一事实来源)
├── config/             # 算法逻辑配置 (*.yaml)
├── src/
│   ├── main/           # 系统编排层 (TF/Launch)
│   ├── drivers/        # L1 硬件驱动层
│   ├── core/           # L2 核心感知层
│   ├── apps/           # L3 业务应用层
│   └── sim/            # 仿真工具层
├── compose.yaml        # 多容器编排声明
└── README.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此目录结构采用&lt;strong&gt;Scheme C&lt;/strong&gt;的架构标准。对于开发环境，此目录包含必要的也就是可能进行二次开发的代码的源码；对于生产环境，此目录包含必要的配置文件。&lt;/p&gt;
&lt;h2&gt;五、 容器配置、编排与启动&lt;/h2&gt;
&lt;p&gt;先进入刚刚 pull 下来的代码目录（其目录结构见&lt;a href=&quot;#%E5%9B%9B-aadcl_uav_ugv-%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84&quot;&gt;四、 AADCL_UAV_UGV 目录结构&lt;/a&gt;）。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd ~/AADCL_UAV_UGV
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时并不能直接起 docker 容器，还需要编辑配置文件，我们采用 &lt;strong&gt;SSOT (单一事实来源)&lt;/strong&gt; 原则，通过 &lt;code&gt;.env&lt;/code&gt; 文件来管理机器之间的差异。&lt;/p&gt;
&lt;h3&gt;5.1 设备配置文件 (.env)&lt;/h3&gt;
&lt;p&gt;仓库里&lt;strong&gt;已经包含&lt;/strong&gt;了一个 &lt;a href=&quot;/AADCL_UAV_UGV/.env.example&quot;&gt;&lt;code&gt;.env.example&lt;/code&gt;&lt;/a&gt; 模板。它规定了这台车需要哪些硬件参数。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;复制模板&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;参数配置&lt;/strong&gt;：编辑 &lt;code&gt;.env&lt;/code&gt;。由于无人机的外设配置例如飞控串口路径（比如 MAVLink 用的 &lt;code&gt;/dev/ttyTHS1&lt;/code&gt;）和系统 ID 不确定，需要结合实际情况进行修改。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5.2 离线数据集安装 (MAVROS 必备)&lt;/h3&gt;
&lt;p&gt;MAVROS 在启动时需要特殊的地理坐标数据集（Geoids）。如果在启动日志里看到 &lt;code&gt;GeographicLib exception&lt;/code&gt; 报错，请执行以下指令进行一键安装：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir -p ~/AADCL_UAV_UGV/data/geographiclib
# 启动一个临时容器进行下载（约 100MB）
docker run --rm -v ~/AADCL_UAV_UGV/data/geographiclib:/usr/share/GeographicLib robot_stack_base:humble /opt/ros/humble/lib/mavros/install_geographiclib_datasets.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 初次启动系统&lt;/h3&gt;
&lt;p&gt;本项目使用 &lt;strong&gt;Docker V2&lt;/strong&gt;（&lt;code&gt;docker compose&lt;/code&gt;）进行一键编排。&lt;/p&gt;
&lt;p&gt;对于新机器，我们提供两种部署方案：&lt;strong&gt;方案 A（本地构建）&lt;/strong&gt; 适用于需要深度定制底层依赖的场景；&lt;strong&gt;方案 B（云端拉取）&lt;/strong&gt; 适用于追求一键快速部署的情况。&lt;/p&gt;
&lt;h4&gt;方案 A：本地手动构建 (初次耗时 30-50 分钟)&lt;/h4&gt;
&lt;p&gt;这一步会从头安装 ROS2 Humble、PCL、OpenCV 等数 GB 的依赖。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose build l1-hardware
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;方案 B：从 Gitea 容器仓库拉取&lt;/h4&gt;
&lt;p&gt;如果你已熟悉编译流程或只想进行快速部署，直接执行以下指令即可跳过漫长的编译过程（该仓库为公开，内地裸连且无需登录）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 1. 拉取镜像
docker pull gitfub.cv/iodinot/aadcl_uav_ugv/base:latest
docker pull gitfub.cv/iodinot/aadcl_uav_ugv/l3_planner:latest
docker pull gitfub.cv/iodinot/aadcl_uav_ugv/l3_yolo:latest

# 2. 关联标签 (让 compose 能识别)
docker tag gitfub.cv/iodinot/aadcl_uav_ugv/base:latest robot_stack_base:humble
docker tag gitfub.cv/iodinot/aadcl_uav_ugv/l3_planner:latest l3_planner:humble
docker tag gitfub.cv/iodinot/aadcl_uav_ugv/l3_yolo:latest l3_yolo:humble
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;启动全量系统&lt;/h4&gt;
&lt;p&gt;镜像就绪后（无论通过 A 还是 B），执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;启动视觉模块&lt;/strong&gt;：如果你需要跑 YOLO 目标检测。
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose --profile apps up -d l3-yolo-demo
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;启动监控桥接&lt;/strong&gt;：为了用 Foxglove 远程看数据。
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose --profile viz up -d visualization-bridge
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.4 &lt;code&gt;ros2c&lt;/code&gt; 脚本的配置&lt;/h3&gt;
&lt;p&gt;Docker 的环境隔离虽然安全，但调试很不方便：每次查看节点都要用 &lt;code&gt;docker exec&lt;/code&gt; 进入容器。为此，本项目提供了一个增强版 &lt;code&gt;ros2c&lt;/code&gt; (ROS2 in Container) 脚本，支持 &lt;strong&gt;自动容器探测&lt;/strong&gt;，实现透明化的容器操作体验。&lt;/p&gt;
&lt;p&gt;请在 &lt;strong&gt;宿主机（Nano 终端）&lt;/strong&gt; 直接执行以下“一键安装”指令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -sSL https://gitfub.cv/iodinot/AADCL_UAV_UGV/raw/branch/main/scripts/install_ros2c.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其核心功能及实现方案如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;自动容器感知&lt;/strong&gt;：脚本会自动检测 &lt;code&gt;l1_hardware&lt;/code&gt;、&lt;code&gt;l2_capability&lt;/code&gt; 或 &lt;code&gt;l3&lt;/code&gt; 系列正在运行的容器，并将其作为当前执行目标，人员无需关心具体容器 ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;环境全自动注入&lt;/strong&gt;：每次执行均会自动在容器内 source ROS2 Humble 原生路径及项目自身的 &lt;code&gt;install/setup.bash&lt;/code&gt;，彻底解决“找不到消息类型”或“找不到节点”的问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTY 鲁棒性&lt;/strong&gt;：智能判断当前终端是否为交互式，自动处理 &lt;code&gt;-it&lt;/code&gt; 参数，使其无缝支持 SSH 脚本控制、自动流水线调用及手动调试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极简指令入口&lt;/strong&gt;：将复杂的 &lt;code&gt;docker exec -it ... bash -lc \&quot;...\&quot;&lt;/code&gt; 包装为极简的 &lt;code&gt;ros2c [command]&lt;/code&gt;，使开发者在操作容器时获得与原生 ROS 环境一致的操作体验。&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Tab 补全&lt;/strong&gt;：你可以输入 &lt;code&gt;ros2c -c [Tab][Tab]&lt;/code&gt;，系统会自动联想出当前正在运行的容器名称。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;指定容器&lt;/strong&gt;：如果你想针对特定容器执行指令，可以使用 &lt;code&gt;-c&lt;/code&gt; 参数，例如：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ros2c -c l3_yolo_demo node list
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;默认逻辑&lt;/strong&gt;：若不带 &lt;code&gt;-c&lt;/code&gt;，脚本会按 &lt;code&gt;l1 -&gt; l2 -&gt; l3&lt;/code&gt; 的优先级自动寻找第一个活跃容器执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常用指令&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ros2c node list           # 列出所有节点
ros2c topic list          # 列出所有话题
ros2c                     # 不带参数：直接进入默认容器的 Shell
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;六、 集群部署&lt;/h2&gt;
&lt;p&gt;当你有了一台完整配置好的机型（如 &lt;code&gt;nrc17&lt;/code&gt;），为同型号的新机器（如 &lt;code&gt;nrc18&lt;/code&gt;）配置环境时，无需再重复耗时的编译过程。&lt;/p&gt;
&lt;h3&gt;6.1 方案 A：通过容器注册表同步 (推荐)&lt;/h3&gt;
&lt;p&gt;这是最标准且高效的方法。只需在新机器上重复 &lt;a href=&quot;#%E6%96%B9%E6%A1%88-b%E4%BB%8E-gitea-%E5%AE%B9%E5%99%A8%E4%BB%93%E5%BA%93%E6%8B%89%E5%8F%96&quot;&gt;5.3 节中的方案 B&lt;/a&gt; 即可：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;拉取镜像&lt;/strong&gt;：&lt;code&gt;docker pull gitfub.cv/iodinot/aadcl_uav_ugv/base:latest&lt;/code&gt; ...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;打标签&lt;/strong&gt;：&lt;code&gt;docker tag ... robot_stack_base:humble&lt;/code&gt; ...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;启动&lt;/strong&gt;：&lt;code&gt;docker compose up -d&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由于 Gitea 仓库是公开的且内地直连极速，这种方式比拷贝文件更可靠。&lt;/p&gt;
&lt;h3&gt;6.2 方案 B：离线镜像迁移 (离线/无网络场景)&lt;/h3&gt;
&lt;p&gt;如果在无法连接注册表的情况下，可使用 Docker 的导出功能进行物理迁移：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在“母机”导出&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker save robot_stack_base:humble | gzip &gt; ~/AADCL_UAV_UGV_base.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拷贝至新机&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scp ~/AADCL_UAV_UGV_base.tar.gz nvidia@nrc18.local:~
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在新机导入&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker load &amp;#x3C; ~/AADCL_UAV_UGV_base.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;七、 系统功能验证&lt;/h2&gt;
&lt;p&gt;程序跑起来后，需确认各项模块是否正常运行。以下提供三项关键验证指标：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;节点全不全？&lt;/strong&gt;：执行 &lt;code&gt;ros2c node list&lt;/code&gt;，你应该能看到 &lt;code&gt;mavros&lt;/code&gt;、&lt;code&gt;fast_lio&lt;/code&gt; 和 &lt;code&gt;ego_planner&lt;/code&gt; 等一众核心节点都在线。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定位有输出吗？&lt;/strong&gt;：执行 &lt;code&gt;ros2 topic echo /Odometry&lt;/code&gt;。如果屏幕上数据在跳，说明算法已经闭环并在解算定位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视觉有反应吗？&lt;/strong&gt;：如果启动了 YOLO，执行 &lt;code&gt;ros2 topic echo /yolo/detections&lt;/code&gt;。如果有人或物体出现在镜头里，你会看到识别结果。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;附录：硬件网口配置（优化高频点云传输稳定性）&lt;/h3&gt;
&lt;p&gt;Livox MID360 雷达的数据量较大，若直接在默认网口传输，高频点云包可能会干扰 WiFi 或 SSH 链路的稳定性。建议将雷达绑定至独立的物理网口：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;看看雷达插在哪个口了&lt;/strong&gt;：
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nmcli device  # 找一下那个显示“以太网”连接的口，比如叫 enP8p1s0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;给这个口设个固定 IP&lt;/strong&gt;：
注意：雷达不需要网关，我们只要在这个口上配置 &lt;code&gt;192.168.10.x&lt;/code&gt; 网段就行。
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 假设网口名是 enP8p1s0，给 nano 分配 192.168.10.50
sudo nmcli connection add type ethernet con-name lidar-link ifname enP8p1s0 ipv4.method manual ipv4.addresses 192.168.10.50/24
sudo nmcli connection up lidar-link
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查一下生效没&lt;/strong&gt;：执行 &lt;code&gt;ip addr show enP8p1s0&lt;/code&gt;，看到 &lt;code&gt;192.168.10.50&lt;/code&gt; 就说明搞定了。&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="/_astro/thumbnail.GAU7U3Mg.png"/><enclosure url="/_astro/thumbnail.GAU7U3Mg.png"/></item></channel></rss>