Linux Basics for Mini Pupper

This guide covers essential Linux commands and concepts you’ll need when working with the Mini Pupper.

Basic Directory Navigation

# Print current directory
pwd

# List files in current directory
ls

# List with details (permissions, size, date)
ls -la

# Change directory
cd /home/ubuntu

# Go to home directory
cd ~

# Go up one directory
cd ..

# Go to previous directory
cd -

Common Directories

Directory Purpose
/home/ubuntu User home directory
~/ros2_ws ROS2 workspace
/etc System configuration files
/var/log System logs

Package Management

Update System Packages

Always update your package list before installing new software:

# Update package list
sudo apt update

# Upgrade all installed packages
sudo apt upgrade -y

# Update and upgrade in one command
sudo apt update && sudo apt upgrade -y

Install Packages

# Install a single package
sudo apt install <package-name>

# Install multiple packages
sudo apt install package1 package2 package3

# Install without confirmation
sudo apt install -y <package-name>

# Example: Install common tools
sudo apt install -y git vim htop

Remove Packages

# Remove a package
sudo apt remove <package-name>

# Remove package and configuration files
sudo apt purge <package-name>

# Remove unused dependencies
sudo apt autoremove

Search for Packages

# Search for a package
apt search <keyword>

# Show package information
apt show <package-name>

Environment Variables

View Environment Variables

# View all environment variables
env

# View specific variable
echo $HOME
echo $PATH
echo $ROS_DISTRO

Set Environment Variables

# Set variable for current session
export MY_VAR="my_value"

# Use the variable
echo $MY_VAR

Permanent Environment Variables

Add to ~/.bashrc for permanent variables:

# Edit .bashrc
nano ~/.bashrc

# Add at the end of file:
export MY_VAR="my_value"
export ROS_DOMAIN_ID=0

# Apply changes
source ~/.bashrc

Common ROS2 Environment Variables

# Add to ~/.bashrc
export ROS_DOMAIN_ID=0
export ROS_LOCALHOST_ONLY=0
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash

Aliases

Aliases are shortcuts for commonly used commands.

Create Aliases

# Edit .bashrc
nano ~/.bashrc

# Add aliases at the end:
alias ll='ls -la'
alias update='sudo apt update && sudo apt upgrade -y'
alias cb='cd ~/ros2_ws && colcon build'
alias src='source ~/ros2_ws/install/setup.bash'
alias pupper='ssh ubuntu@<minipupper-ip>'

# Apply changes
source ~/.bashrc

Useful Aliases for Mini Pupper

# Add to ~/.bashrc
alias ros2src='source /opt/ros/humble/setup.bash && source ~/ros2_ws/install/setup.bash'
alias bringup='ros2 launch mini_pupper_bringup bringup.launch.py hardware_connected:=True'
alias camera='ros2 launch mini_pupper_driver camera.launch.py'
alias topics='ros2 topic list'
alias nodes='ros2 node list'

Systemctl (Service Management)

View Services

# List all services
systemctl list-units --type=service

# Check status of a service
sudo systemctl status <service-name>

# Example: Check SSH service
sudo systemctl status ssh

Control Services

# Start a service
sudo systemctl start <service-name>

# Stop a service
sudo systemctl stop <service-name>

# Restart a service
sudo systemctl restart <service-name>

# Enable service to start on boot
sudo systemctl enable <service-name>

# Disable service from starting on boot
sudo systemctl disable <service-name>

Create a Custom Service

Create a service file for auto-starting programs:

# Create service file
sudo nano /etc/systemd/system/my-service.service

Example service file:

[Unit]
Description=My Custom Service
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu
ExecStart=/usr/bin/python3 /home/ubuntu/my_script.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable my-service
sudo systemctl start my-service

File Operations

Create and Edit Files

# Create empty file
touch filename.txt

# Create directory
mkdir my_folder

# Create nested directories
mkdir -p parent/child/grandchild

# Edit file with nano
nano filename.txt

# Edit file with vim
vim filename.txt

Copy, Move, Delete

# Copy file
cp source.txt destination.txt

# Copy directory
cp -r source_dir/ destination_dir/

# Move/rename file
mv oldname.txt newname.txt

# Delete file
rm filename.txt

# Delete directory
rm -r directory/

# Delete with confirmation
rm -i filename.txt

File Permissions

# View permissions
ls -la

# Make file executable
chmod +x script.sh

# Change owner
sudo chown ubuntu:ubuntu filename.txt

SSH (Remote Access)

Connect to Mini Pupper

# Basic SSH connection
ssh ubuntu@<minipupper-ip>

# Example
ssh ubuntu@192.168.1.100

SSH Key Setup (Password-less Login)

# Generate SSH key (on your computer)
ssh-keygen -t rsa -b 4096

# Copy key to Mini Pupper
ssh-copy-id ubuntu@<minipupper-ip>

# Now connect without password
ssh ubuntu@<minipupper-ip>

SSH Config File

Create ~/.ssh/config for easier connections:

Host pupper
    HostName 192.168.1.100
    User ubuntu
    IdentityFile ~/.ssh/id_rsa

Now connect with:

ssh pupper

Process Management

View Running Processes

# List all processes
ps aux

# Interactive process viewer
htop

# Find specific process
ps aux | grep python

Kill Processes

# Kill by PID
kill <pid>

# Force kill
kill -9 <pid>

# Kill by name
pkill python
killall python

Useful Commands

System Information

# Check disk space
df -h

# Check memory usage
free -h

# Check CPU info
lscpu

# Check system uptime
uptime

# Check IP address
ip addr
hostname -I

Network Commands

# Test network connection
ping google.com

# Check open ports
sudo netstat -tulpn

# Download file
wget <url>

# Transfer files
scp file.txt ubuntu@<ip>:/home/ubuntu/

Shell Scripting

Shell scripts allow you to combine multiple commands into a single executable file, making repetitive tasks easier and more consistent.

Creating Your First Shell Script

# Create a new script file
nano my_script.sh

Add the following content:

#!/bin/bash
# This is a comment - describes what the script does

echo "Hello, Mini Pupper!"
echo "Current date: $(date)"
echo "Current user: $USER"

Make it executable and run:

chmod +x my_script.sh
./my_script.sh

Script Structure Best Practices

#!/bin/bash
#
# Script Name: setup_ros.sh
# Description: Sets up ROS2 environment for Mini Pupper
# Author: Your Name
# Date: 2024-01-01
#

# Exit on error
set -e

# Variables
ROS_DISTRO="humble"
WORKSPACE="$HOME/ros2_ws"

# Functions
setup_environment() {
    echo "Setting up ROS2 environment..."
    source /opt/ros/$ROS_DISTRO/setup.bash
    source $WORKSPACE/install/setup.bash
}

check_ros() {
    if [ -z "$ROS_DISTRO" ]; then
        echo "Error: ROS_DISTRO not set"
        exit 1
    fi
}

# Main execution
main() {
    check_ros
    setup_environment
    echo "Setup complete!"
}

# Run main function
main "$@"

Variables and User Input

#!/bin/bash

# Define variables
NAME="Mini Pupper"
VERSION=2

# Read user input
echo "Enter your robot's IP address:"
read IP_ADDRESS

# Use variables
echo "Connecting to $NAME v$VERSION at $IP_ADDRESS"
ssh ubuntu@$IP_ADDRESS

Conditional Statements

#!/bin/bash

# Check if a file exists
if [ -f "/home/ubuntu/ros2_ws/install/setup.bash" ]; then
    echo "ROS2 workspace found!"
    source /home/ubuntu/ros2_ws/install/setup.bash
else
    echo "ROS2 workspace not found. Building..."
    cd ~/ros2_ws
    colcon build
fi

# Check if a command succeeded
if ping -c 1 google.com &> /dev/null; then
    echo "Internet connection available"
else
    echo "No internet connection"
fi

# Check command line arguments
if [ $# -eq 0 ]; then
    echo "Usage: $0 <robot_ip>"
    exit 1
fi

Loops

#!/bin/bash

# For loop - iterate over list
for file in *.py; do
    echo "Python file: $file"
done

# For loop - iterate with range
for i in {1..5}; do
    echo "Iteration $i"
done

# While loop
count=0
while [ $count -lt 5 ]; do
    echo "Count: $count"
    ((count++))
done

# Loop through command output
for topic in $(ros2 topic list); do
    echo "Found topic: $topic"
done

Practical Mini Pupper Scripts

Script 1: ROS2 Bringup Script

#!/bin/bash
# bringup.sh - Launch Mini Pupper with ROS2

set -e

# Source ROS2 environment
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash

# Set ROS Domain ID
export ROS_DOMAIN_ID=${1:-30}

echo "Starting Mini Pupper with ROS_DOMAIN_ID=$ROS_DOMAIN_ID"

# Launch bringup
ros2 launch mini_pupper_bringup bringup.launch.py hardware_connected:=True

Script 2: System Health Check

#!/bin/bash
# health_check.sh - Check Mini Pupper system status

echo "=== Mini Pupper Health Check ==="
echo ""

# Check disk space
echo "Disk Space:"
df -h / | tail -1
echo ""

# Check memory
echo "Memory Usage:"
free -h | grep Mem
echo ""

# Check CPU temperature
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
    temp=$(cat /sys/class/thermal/thermal_zone0/temp)
    temp_c=$((temp/1000))
    echo "CPU Temperature: ${temp_c}°C"
fi
echo ""

# Check ROS2 nodes
echo "ROS2 Nodes:"
source /opt/ros/humble/setup.bash
ros2 node list 2>/dev/null || echo "No ROS2 nodes running"
echo ""

# Check important services
echo "Services Status:"
for service in ssh docker; do
    status=$(systemctl is-active $service 2>/dev/null || echo "not found")
    echo "  $service: $status"
done

Script 3: Backup Script

#!/bin/bash
# backup.sh - Backup important files

BACKUP_DIR="$HOME/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/pupper_backup_$DATE.tar.gz"

# Create backup directory
mkdir -p $BACKUP_DIR

# Create backup
echo "Creating backup..."
tar -czf $BACKUP_FILE \
    ~/.bashrc \
    ~/ros2_ws/src \
    ~/minipupper \
    2>/dev/null

echo "Backup created: $BACKUP_FILE"
echo "Size: $(du -h $BACKUP_FILE | cut -f1)"

Running Scripts Effectively

# Run in current shell (variables persist)
source ./my_script.sh
# or
. ./my_script.sh

# Run in subshell (isolated)
./my_script.sh

# Run with bash explicitly
bash my_script.sh

# Run in background
./my_script.sh &

# Run and log output
./my_script.sh > output.log 2>&1

# Run with nohup (continues after logout)
nohup ./my_script.sh &

Converting Scripts to Systemctl Services

When you want a script to run automatically at boot or be managed as a system service, you can convert it to a systemd service.

Step 1: Create the Script

First, ensure your script works correctly:

# Create script
sudo nano /usr/local/bin/pupper_startup.sh
#!/bin/bash
# /usr/local/bin/pupper_startup.sh
# Mini Pupper startup script

# Wait for network
sleep 10

# Set up environment
export HOME=/home/ubuntu
export USER=ubuntu
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
export ROS_DOMAIN_ID=30

# Log startup
echo "$(date): Starting Mini Pupper ROS2" >> /home/ubuntu/pupper_startup.log

# Launch ROS2
cd /home/ubuntu
ros2 launch mini_pupper_bringup bringup.launch.py hardware_connected:=True

Make it executable:

sudo chmod +x /usr/local/bin/pupper_startup.sh

Step 2: Create the Service File

sudo nano /etc/systemd/system/pupper-ros2.service
[Unit]
Description=Mini Pupper ROS2 Bringup Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
Environment="HOME=/home/ubuntu"
Environment="ROS_DOMAIN_ID=30"
WorkingDirectory=/home/ubuntu
ExecStart=/usr/local/bin/pupper_startup.sh
Restart=on-failure
RestartSec=10

# Logging
StandardOutput=append:/home/ubuntu/pupper_ros2.log
StandardError=append:/home/ubuntu/pupper_ros2_error.log

[Install]
WantedBy=multi-user.target

Step 3: Enable and Start the Service

# Reload systemd to recognize new service
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable pupper-ros2.service

# Start the service now
sudo systemctl start pupper-ros2.service

# Check status
sudo systemctl status pupper-ros2.service

Service File Options Explained

Option Description
After= Start after these services
Wants= Weak dependency on these services
Type=simple Main process is the ExecStart command
Type=forking Process forks and parent exits
User= Run as this user
WorkingDirectory= Set working directory
ExecStart= Command to run
ExecStop= Command to stop (optional)
Restart=on-failure Restart if exits with error
RestartSec= Wait time before restart
WantedBy=multi-user.target Start in normal multi-user mode

Example: Web Controller Service

sudo nano /etc/systemd/system/pupper-webcontroller.service
[Unit]
Description=Mini Pupper Web Controller
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/mini_pupper_web_controller/webserver
ExecStart=/usr/bin/python3 /home/ubuntu/mini_pupper_web_controller/webserver/app.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Example: Docker Compose Service

sudo nano /etc/systemd/system/pupper-docker.service
[Unit]
Description=Mini Pupper Docker Compose
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
User=ubuntu
WorkingDirectory=/home/ubuntu/mini_pupper_ros_aws
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down

[Install]
WantedBy=multi-user.target

Managing Your Services

# View all custom services
systemctl list-units --type=service | grep pupper

# View service logs
journalctl -u pupper-ros2.service

# Follow logs in real-time
journalctl -u pupper-ros2.service -f

# View last 50 lines
journalctl -u pupper-ros2.service -n 50

# Restart service
sudo systemctl restart pupper-ros2.service

# Stop service
sudo systemctl stop pupper-ros2.service

# Disable from boot
sudo systemctl disable pupper-ros2.service

# Remove service
sudo systemctl stop pupper-ros2.service
sudo systemctl disable pupper-ros2.service
sudo rm /etc/systemd/system/pupper-ros2.service
sudo systemctl daemon-reload

Debugging Services

If your service doesn’t start:

# Check status and error messages
sudo systemctl status pupper-ros2.service

# View detailed logs
journalctl -u pupper-ros2.service --no-pager

# Test the script manually
sudo -u ubuntu /usr/local/bin/pupper_startup.sh

# Check for syntax errors in service file
systemd-analyze verify /etc/systemd/system/pupper-ros2.service

Quick Reference

Command Description
pwd Print working directory
ls -la List files with details
cd <dir> Change directory
sudo apt update Update package list
sudo apt install <pkg> Install package
export VAR=value Set environment variable
source ~/.bashrc Reload bash configuration
sudo systemctl status <svc> Check service status
chmod +x <file> Make file executable
ssh user@host Remote connection

Summary

These Linux basics will help you:

  • Navigate the file system
  • Install and manage packages
  • Set up environment variables and aliases
  • Manage system services
  • Connect remotely via SSH
  • Manage files and processes