1. 项目概述
作为一名长期使用Jetson Nano进行机器人开发的工程师,我深刻理解存储空间不足带来的困扰。特别是那些配备eMMC存储的2GB版本Jetson Nano,仅有14GB左右的可用空间,在运行ROS系统时很快就会捉襟见肘。今天我要分享的是一种既安全又实用的解决方案——将ROS工作空间迁移到U盘上。
这个方法的核心优势在于:
- 不需要重装系统或进行高风险的家目录迁移
- 保留了系统配置和用户环境
- 操作过程可逆,出现问题可以轻松回退
- 特别适合需要频繁编译大型ROS项目的开发场景
重要提示:在进行任何系统级操作前,请确保已经备份重要数据。虽然本文介绍的方法相对安全,但意外总是可能发生。
2. 准备工作与硬件选型
2.1 选择合适的U盘
在开始操作前,选择合适的存储设备至关重要。根据我的实测经验,推荐以下规格:
| 参数 | 推荐值 | 原因 |
|---|---|---|
| 容量 | ≥32GB | 确保足够空间存放工作空间和编译文件 |
| 接口 | USB 3.0 | 提供足够的传输带宽 |
| 速度 | 读取>100MB/s 写入>50MB/s |
避免编译过程成为瓶颈 |
| 品牌 | 闪迪、三星等大厂 | 稳定性和耐用性有保障 |
我曾经尝试使用一款廉价的USB 2.0 U盘,结果catkin_make的编译时间比在eMMC上还要长30%,完全失去了迁移的意义。
2.2 系统环境检查
在开始前,请确认以下准备工作:
- 确保Jetson Nano已连接稳定的电源
- 保持网络连接畅通(部分操作需要下载依赖)
- 关闭所有不必要的应用程序
- 备份当前ROS工作空间(如果有)
可以通过以下命令检查系统基本信息:
bash复制# 查看系统版本
lsb_release -a
# 查看存储使用情况
df -h
# 查看USB设备识别情况
lsusb
3. U盘识别与格式化
3.1 识别U盘设备
插入U盘后,系统通常会自动识别。我们需要确认设备标识符:
bash复制lsblk -f
典型输出如下:
code复制NAME FSTYPE LABEL UUID MOUNTPOINT
mmcblk0p1 ext4 rootfs 5a3d8e1a-... /
mmcblk0p2 ext4 APP 7b2c1d9f-... /media/nvidia/APP
sda
└─sda1 ntfs Data 6A8E-12F4 /media/nvidia/6A8E-12F4
在这个例子中:
mmcblk0开头的设备是内置eMMC存储sda是我们的U盘设备sda1是U盘上的分区
3.2 格式化U盘为ext4
Linux系统下,ext4文件系统性能最佳。格式化命令如下:
bash复制# 卸载已挂载的分区(如果已自动挂载)
sudo umount /dev/sda1
# 执行格式化(会清除所有数据!)
sudo mkfs.ext4 /dev/sda1
格式化过程中常见的两个问题及解决方法:
- 设备忙错误:
code复制umount: /media/nvidia/6A8E-12F4: target is busy
解决方法:
bash复制# 查找占用进程
sudo lsof /dev/sda1
# 终止相关进程
sudo kill -9 [PID]
# 或者强制卸载
sudo umount -l /dev/sda1
- 分区表错误:
有时U盘可能有多个分区或异常分区表,需要先清理:
bash复制sudo fdisk /dev/sda
# 在交互界面中输入:
# d (删除分区)
# w (写入更改)
4. 挂载与权限设置
4.1 创建挂载点并挂载
bash复制# 创建专用挂载目录
sudo mkdir -p /mnt/ros_usb
# 挂载U盘
sudo mount /dev/sda1 /mnt/ros_usb
# 设置权限
sudo chown -R $USER:$USER /mnt/ros_usb
sudo chmod -R 755 /mnt/ros_usb
4.2 验证挂载
bash复制# 测试写入
echo "test" > /mnt/ros_usb/test_file.txt
# 测试读取
cat /mnt/ros_usb/test_file.txt
# 查看挂载详情
df -h /mnt/ros_usb
正确的输出应该显示U盘已正确挂载,并且读写正常。
5. ROS工作空间迁移
5.1 创建新的工作空间结构
bash复制# 创建工作空间目录
mkdir -p /mnt/ros_usb/ros_ws/src
# 初始化工作空间
cd /mnt/ros_usb/ros_ws
catkin_make
5.2 环境变量配置
编辑~/.bashrc文件,添加以下内容:
bash复制# ROS USB Workspace
source /mnt/ros_usb/ros_ws/devel/setup.bash
export ROS_WORKSPACE=/mnt/ros_usb/ros_ws
使配置立即生效:
bash复制source ~/.bashrc
验证环境变量:
bash复制echo $ROS_PACKAGE_PATH
# 应该包含/mnt/ros_usb/ros_ws/src路径
5.3 迁移现有项目(可选)
如果有现有的ROS工作空间需要迁移:
bash复制# 复制源码
cp -r ~/catkin_ws/src/* /mnt/ros_usb/ros_ws/src/
# 重新编译
cd /mnt/ros_usb/ros_ws
catkin_make
# 验证功能
roslaunch [your_package] [your_launch_file.launch]
6. 自动挂载配置
6.1 获取UUID
bash复制sudo blkid /dev/sda1
输出示例:
code复制/dev/sda1: UUID="a1b2c3d4-1234-5678-90ab-cdef12345678" TYPE="ext4"
6.2 配置fstab
编辑/etc/fstab文件,添加以下行:
code复制UUID=a1b2c3d4-1234-5678-90ab-cdef12345678 /mnt/ros_usb ext4 defaults,noatime,errors=remount-ro 0 2
各参数含义:
noatime:减少写入操作,延长U盘寿命errors=remount-ro:出错时以只读方式重新挂载,防止数据损坏
6.3 测试配置
bash复制# 卸载当前挂载
sudo umount /mnt/ros_usb
# 测试自动挂载
sudo mount -a
# 检查结果
df -h /mnt/ros_usb
7. 使用注意事项与优化
7.1 性能优化建议
- 启用写入缓存:
bash复制sudo mount -o remount,sync /mnt/ros_usb
- 定期维护:
bash复制# 检查文件系统
sudo fsck /dev/sda1
# 清理编译缓存
cd /mnt/ros_usb/ros_ws
rm -rf build devel
catkin_make clean
7.2 安全使用指南
- 正确卸载流程:
bash复制# 结束相关进程
sudo fuser -km /mnt/ros_usb
# 卸载设备
sudo umount /mnt/ros_usb
# 物理拔出前等待LED停止闪烁
- 应急处理:
如果启动时因U盘问题卡住,可以:
- 等待90秒系统自动跳过
- 进入恢复模式编辑fstab
- 使用Live CD修复
7.3 监控脚本示例
创建一个监控脚本~/check_usb.sh:
bash复制#!/bin/bash
MOUNT_POINT="/mnt/ros_usb"
LOG_FILE="/var/log/usb_monitor.log"
if ! mountpoint -q "$MOUNT_POINT"; then
echo "$(date) - USB not mounted, attempting remount..." >> $LOG_FILE
sudo mount -a >> $LOG_FILE 2>&1
fi
# 检查剩余空间
df -h $MOUNT_POINT | tail -1 >> $LOG_FILE
设置定时任务:
bash复制crontab -e
# 添加:
*/10 * * * * ~/check_usb.sh
8. 常见问题排查
8.1 挂载失败问题
问题现象:
code复制mount: /mnt/ros_usb: wrong fs type, bad option, bad superblock...
解决方法:
- 检查文件系统类型:
bash复制sudo blkid /dev/sda1
- 修复文件系统:
bash复制sudo fsck /dev/sda1
- 重新格式化(最后手段)
8.2 权限问题
问题现象:
code复制Permission denied when trying to create file
解决方法:
bash复制# 重新设置权限
sudo chown -R $USER:$USER /mnt/ros_usb
sudo chmod -R 755 /mnt/ros_usb
# 检查SELinux状态(如果启用)
getenforce
8.3 ROS环境问题
问题现象:
code复制[rospack] Error: package 'your_package' not found
解决方法:
- 确认环境变量:
bash复制echo $ROS_PACKAGE_PATH
- 重新source:
bash复制source /mnt/ros_usb/ros_ws/devel/setup.bash
- 检查包路径:
bash复制rospack find your_package
经过这样的设置后,你的Jetson Nano应该能够稳定地在U盘上运行ROS工作空间了。在实际使用中,我发现这种配置特别适合以下场景:
- 需要同时维护多个大型ROS项目
- 进行频繁的代码修改和重新编译
- 使用需要大量临时存储空间的算法(如SLAM)
最后一个小技巧:如果你经常需要在不同的Jetson设备间切换工作,可以考虑使用相同的UUID格式化多个U盘,这样fstab配置可以通用,只需简单更换U盘就能在不同设备上保持相同的工作环境。