Installation Setup - Forestry-Robotics-UC/fruc_dataset_apparatus GitHub Wiki
Installation and Setup Guide
System Requirements
Minimum Hardware Specifications
| Component | Minimum | Recommended |
|---|---|---|
| CPU | Quad-core (2.0 GHz) | 8-core (3.0+ GHz) |
| RAM | 8 GB | 16 GB+ |
| Storage | 256 GB SSD | 1 TB NVMe SSD |
| USB Ports | 3x USB 3.0 | 4+ USB 3.0+ |
| Ethernet | 1 Gbps | 10 Gbps (optional) |
| GPU (optional) | - | NVIDIA Jetson / RTX |
Operating System
Desktop/Workstation:
- Primary: Ubuntu 22.04 LTS (Jammy Jellyfish)
- Supported: Ubuntu 24.04 LTS (Noble Numbat)
- Runtime: Docker and Docker Compose
- Kernel: 5.15+ recommended
SteamDeck:
- Base OS: SteamOS (Holo)
- Runtime: Podman (pre-installed, no Docker installation needed)
- Setup: Enter Linux desktop mode (see Steam Deck guide)
- Repository: Usually mounted at
/home/deck/fruc_dataset_apparatus
Network Requirements
- Local Network Access: For DDS communication between containers
- Ouster LiDAR Link-Local: 169.254.0.0/16 subnet
- Optional Internet: For Docker image pulls
Pre-Installation Checklist
Before starting, ensure:
- Operating system installed and up-to-date
- System has stable power
- At least 50 GB free disk space initially
- All sensors purchased and available
- USB cables and adapters on hand
- Network connectivity working
- Sudo access or root permission
- Terminal/console access available
Step 1: System Preparation
Update Package Manager
# Update package lists
sudo apt update
# Upgrade installed packages
sudo apt upgrade -y
# Install essential utilities
sudo apt install -y \
curl \
wget \
git \
build-essential \
net-tools \
htop \
openssh-server
System Configuration
Increase File Descriptor Limits
For large-scale recording sessions:
# Edit limits file
sudo nano /etc/security/limits.conf
# Add at end of file:
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
Apply immediately:
ulimit -n 65536
Configure Swap Space (if needed)
For systems with limited RAM:
# Check current swap
free -h
# Create 4GB swap file
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make permanent
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
Step 2: Install Container Runtime
For Desktop/Workstation (Docker)
Option A: Using Official Docker Repository (Recommended)
# Add Docker's official GPG key
sudo apt install -y ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package index
sudo apt update
# Install Docker
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Option B: Using Distribution Packages
sudo apt install -y docker.io docker-compose
For SteamDeck (Podman)
Podman is pre-installed on SteamDeck. No additional installation needed!
Verify that Podman is available:
podman --version
podman-compose --version
Both commands should return version information. If podman-compose is not installed, install it:
sudo pacman -S podman-compose # On SteamOS (pacman-based)
Verify Installation
For Docker (Desktop):
# Check versions (Docker)
docker --version
docker-compose --version
# Test Docker daemon
sudo docker run hello-world # May require sudo initially
# Output should show: "Hello from Docker!"
For Podman (SteamDeck):
# Check versions (Podman)
podman --version
podman-compose --version
# Test Podman daemon
podman run hello-world
# Output should show: "Hello from Podman"
Configure Container Runtime for Non-Root Access
For Docker (Desktop):
# Create docker group (usually already exists)
sudo groupadd docker 2>/dev/null || true
# Add current user to docker group
sudo usermod -aG docker $USER
# Apply group changes (option 1: restart session)
newgrp docker
# Or option 2: command-specific
sudo docker ps
# Test without sudo (after restart)
docker ps
For Podman (SteamDeck):
Podman on SteamDeck typically allows non-root access by default. If you encounter permission issues:
# Check if rootless mode is available
podman ps # This should work without sudo
# If sudo is required, check your user's sudoers configuration
sudo -l
Step 3: Configure Serial Port Access
Check Available Serial Ports
# List serial devices
ls -la /dev/ttyUSB*
ls -la /dev/ttyACM*
# Or use udevadm
udevadm info -n /dev/ttyUSB0
# Use tool to list all devices
dmesg | tail -20 # Check kernel messages for device detection
Grant Serial Port Permission
Method 1: Temporary (this session only)
# Make serial ports accessible
sudo chmod 666 /dev/ttyUSB*
sudo chmod 666 /dev/ttyACM*
Method 2: Permanent (recommended)
# Add user to dialout group
sudo usermod -aG dialout $USER
# Log out and back in for changes to take effect
exit
Method 3: Using tty-perms.sh Script
cd fruc_dataset_apparatus
sudo bash tty-perms.sh
Verify Serial Access
# Check permissions (should show rw for your user)
ls -la /dev/ttyUSB0
# Test with minicom (optional)
sudo apt install -y minicom
minicom -D /dev/ttyUSB0 -b 460800
Step 4: Clone Repository
Clone from Git
# Create workspace directory
mkdir -p ~/Development
cd ~/Development
# Clone the repository
git clone https://github.com/[org]/fruc_dataset_apparatus.git
cd fruc_dataset_apparatus
# Display directory structure
tree -L 2 -a
Or Extract from Archive
# If you have a ZIP or TAR file
unzip fruc_dataset_apparatus.zip
# or
tar -xzf fruc_dataset_apparatus.tar.gz
cd fruc_dataset_apparatus
Initialize Submodules (if applicable)
# If repository uses submodules
git submodule init
git submodule update
# Or combined
git clone --recurse-submodules <repository-url>
Verify Repository Structure
# Check key directories exist
ls -la docker/
ls -la rosbags/
ls -la rviz/
# Verify scripts are present
ls -la launch-system.sh stop-system.sh tty-perms.sh
Step 5: Install Sensor-Specific Prerequisites
RealSense udev Rules
# Navigate to RealSense rules directory
cd realsense-udev-rules/
# Review the installation script
cat README.md
# Install udev rules
sudo bash realsense-udev-install.sh
# Unplug and replug RealSense camera for rules to take effect
# Verify with:
lsusb | grep RealSense
realsense-viewer # If installed
Xsens Serial Configuration
# Check which serial port Xsens is connected to
dmesg | grep -i xsens
dmesg | grep -i ftdi # Xsens uses FTDI chip
# Example output:
# [ 12.345678] usb 1-1: cp210x converter now attached to ttyUSB0
# Remember this port number for later configuration
Ouster LiDAR Network Setup
Configure Link-Local Network
On Ubuntu 22.04+, use netplan:
# Backup original config
sudo cp /etc/netplan/00-installer-config.yaml \
/etc/netplan/00-installer-config.yaml.bak
# Edit netplan configuration
sudo nano /etc/netplan/00-installer-config.yaml
Add Ouster interface configuration:
network:
version: 2
ethernets:
# Existing network (DHCP)
eth0:
dhcp4: true
# Add Ouster link-local (replace eth1 with your interface)
eth1:
dhcp4: no
addresses:
- 169.254.50.1/16 # Host IP in link-local range
optional: true
renderer: networkd
Apply configuration:
sudo netplan apply
# Verify interface is configured
ip addr show eth1
# Should show: inet 169.254.50.1/16 brd 169.254.255.255
Test Ouster Connectivity
# Ping Ouster at default address
ping 169.254.49.182
# Or discover with ARP scan
sudo arp-scan -l | grep -i ouster
# Or use Ouster's discovery tool (if available)
# Install: https://github.com/ouster-lidar/sdk
Emlid GNSS Configuration
For serial connection:
# Check serial device
ls -la /dev/ttyUSB*
# For network connection, note the assigned IP
# Usually available via mDNS: reach.local
ping reach.local
Step 6: Build Docker Containers
Full Build
cd docker/
# Build all containers (takes 15-30 minutes)
docker-compose build
# Or with progress output
docker-compose build --progress=plain 2>&1 | tee build.log
# Check for errors
tail -50 build.log
Build Status Monitoring
# In separate terminal, monitor Docker daemon
watch -n 1 docker ps
# Or check individual build progress
docker-compose build sensor_name --progress=plain
Troubleshoot Build Failures
If a build fails:
# Rebuild with no cache
docker-compose build --no-cache sensor_name
# Check specific Dockerfile for syntax
docker build -f Dockerfile.xsens -t test:latest .
# View detailed error output
docker-compose build xsens --verbose 2>&1 | grep -A 10 "ERROR"
# Try building individual stages
docker build --target base -f Dockerfile.realsense .
Verify Build Success
# List built images
docker images | grep ros2-apparatus
# Expected output:
# REPOSITORY TAG IMAGE ID
# ros2-apparatus-xsens jazzy abc123def456
# ros2-apparatus-realsense jazzy xyz789uvw456
# ros2-apparatus-ouster jazzy ...
# etc.
Step 7: Create Docker Network
Create Link-Local Network (for Ouster)
# Create custom network
docker network create \
--driver bridge \
--subnet=169.254.0.0/16 \
link-local-net
# Verify network
docker network ls | grep link-local
docker network inspect link-local-net
Step 8: Test System
Pre-Recording Diagnostic Test
cd docker/
# Run automated diagnostics (takes ~7 minutes)
bash pre_recording_test.sh
# Expected output shows:
# - Container startup
# - Topic frequencies
# - Data validation
# - Diagnostic results
Manual Sensor Test
cd docker/
# Start containers
docker-compose up -d
# Wait for initialization (30 seconds)
sleep 30
# List active topics
docker exec ros2-apparatus-xsens ros2 topic list
# Check specific sensor
docker exec ros2-apparatus-realsense ros2 topic hz /camera/color/image_raw
# Monitor system resources
docker stats
# Stop when done
docker-compose down
Network Connectivity Test
# Test inter-container communication
docker-compose up -d xsens publisher
# From publisher, check IMU topic
docker exec ros2-apparatus-publisher ros2 topic echo /imu/data --once
docker-compose down
Step 9: Configure Scripts
Make Scripts Executable
chmod +x launch-system.sh
chmod +x gnome-launch-system.sh
chmod +x stop-system.sh
chmod +x gnome-stop-system.sh
chmod +x tty-perms.sh
# Verify
ls -la *.sh | head -5
Test Launch Scripts
# For KDE/KDialog:
./launch-system.sh --help 2>/dev/null || echo "Help not available"
# For GNOME:
./gnome-launch-system.sh --help 2>/dev/null || echo "Help not available"
# Dry-run (don't actually launch)
bash -n launch-system.sh # Syntax check only
Step 10: Initial Recording
First Recording Test
# Start from repository root
cd ~/Development/fruc_dataset_apparatus
# Launch interactive system
./launch-system.sh
# Follow the dialogs:
# 1. Accept default recording name (or enter custom)
# 2. Select few topics for quick test
# 3. Choose "Size" split, enter 1 GB
# 4. Select "fastwrite" compression
# 5. Confirm to start
# Recording will begin...
# Let it run for 60-120 seconds
# Stop via dialog prompt
Verify First Recording
# Check recorded data
ls -lh rosbags/
# View recording metadata
ros2 bag info rosbags/2026-*/
# Playback recording
ros2 bag play rosbags/2026-*/ --loop
# Check topic data
ros2 topic echo /imu/data --once
Post-Installation Configuration
optional: Install Additional Tools
# RealSense viewer
sudo apt install -y realsense-viewer
# Point cloud visualization
sudo apt install -y pcl-tools
# RViz for visualization
sudo apt install -y ros-jazzy-rviz2
# Dev tools
sudo apt install -y vim nano gedit python3-pip
optional: Configure GUI Shortcuts
for desktop environment, create launch shortcuts:
# Create .desktop file
mkdir -p ~/.local/share/applications/
cat > ~/.local/share/applications/fruc-launch.desktop << 'EOF'
[Desktop Entry]
Type=Application
Name=FRUC Recording
Exec=bash -c 'cd ~/Development/fruc_dataset_apparatus && ./launch-system.sh'
Icon=media-record
Categories=Utility;
Terminal=true
EOF
# Make executable
chmod +x ~/.local/share/applications/fruc-launch.desktop
# Refresh desktop
update-desktop-database ~/.local/share/applications/
optional: Set Up Automated Backups
# Create backup script
cat > backups_rosbags.sh << 'EOF'
#!/bin/bash
# Backup rosbags to external drive weekly
BACKUP_DIR="/mnt/backup/rosbags"
SOURCE_DIR="rosbags"
# Check if backup drive is mounted
if [ ! -d "$BACKUP_DIR" ]; then
echo "Backup drive not found!"
exit 1
fi
# Copy recent recordings
rsync -av --delete "$SOURCE_DIR/" "$BACKUP_DIR/"
echo "Backup complete at $(date)"
EOF
chmod +x backups_rosbags.sh
# Add to crontab for weekly execution
crontab -e
# Add: 0 2 * * 0 ~/fruc_dataset_apparatus/backups_rosbags.sh
optional: Enable X11 Forwarding (for Remote Sessions)
# Install X11 server
sudo apt install -y xvfb x11-utils
# In SSH session, forward display
ssh -X user@remote_host
# Or add to ~/.ssh/config
cat >> ~/.ssh/config << 'EOF'
Host remote_host
ForwardX11 yes
ForwardX11Trusted yes
EOF
Final Verification
Comprehensive System Check
# Create verification script
cat > system_check.sh << 'EOF'
#!/bin/bash
echo "=== FRUC Dataset Apparatus System Check ==="
echo ""
echo "1. Docker Status:"
docker ps -a | head -3
echo ""
echo "2. Storage:"
df -h | grep -E "^/dev|^Filesystem"
echo ""
echo "3. Network - Ouster:"
ping -c 1 -W 1 169.254.49.182 && echo "✓ Ouster reachable" || echo "✗ Ouster not found"
echo ""
echo "4. Serial Ports:"
ls -la /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || echo "No serial devices found"
echo ""
echo "5. Repository Structure:"
[ -d docker ] && echo "✓ Docker directory found" || echo "✗ Docker directory missing"
[ -f launch-system.sh ] && echo "✓ launch-system.sh found" || echo "✗ launch-system.sh missing"
[ -d rosbags ] && echo "✓ rosbags directory found" || echo "✗ rosbags directory missing"
echo ""
echo "=== Check Complete ==="
EOF
chmod +x system_check.sh
./system_check.sh
Sensor Connectivity Status
# Summary of sensor status
./docker/pre_recording_test.sh # 7-minute diagnostic
# Or quick check
cd docker
docker-compose up -d
sleep 10
docker-compose exec publisher ros2 topic list -v | head -20
docker-compose down
Troubleshooting Installation
Common Issues
| Problem | Solution |
|---|---|
| Docker daemon not running | sudo systemctl start docker |
| Permission denied on /dev/docker.sock | sudo usermod -aG docker $USER + logout/login |
| Docker compose not found | sudo apt install docker-compose-plugin |
| Ouster not reachable | Check link-local IP configuration with ip addr |
| Serial port permission denied | sudo bash tty-perms.sh or sudo usermod -aG dialout $USER |
| Build fails with dependency error | docker-compose build --no-cache or rosdep update |
| Out of disk space during build | Reduce Docker image size: docker system prune -a |
Check Logs
# Docker daemon logs
sudo journalctl -u docker -f
# Specific container logs
docker logs ros2-apparatus-xsens
# Build logs
docker-compose build 2>&1 | tee build.log
Next Steps
After successful installation:
- Read the User Manual: User Manual
- Test recording: Run
./launch-system.sh - Review scripts: See Scripts Reference
- Explore topics: List active topics with
ros2 topic list - Visualize data: Use Foxglove Bridge on port 9092
- Develop custom tools: See Developer Guide
Online Resources
Last Updated: 2026-03-30
Related Docs: User Manual | Technical Architecture | Developer Guide