Fenrir Project - Universal Robotic Platform

This book describes the Fenrir Project develped at the Brno University of Technology, Czech Republic.

Robot is actively used for the Robotics and Computer Vision labs.

Authors

  • Ing. Adam Ligocki, Ph.D.
  • Ing. Petr Šopák
  • Ing. Jakum Minařík

Fenrir Project Overview

The Fenrir Project is an open-source, multi-purpose educational robot designed for a wide range of applications in high schools and universities.

The robot is based on Raspberry Pi 4 and Arduino Nano. The Raspberry Pi provides computational power, ROS2 support, WiFi connection and USB support. The Arduino Nano extends the Raspberry Pi IOs and manages peripherals.

Robot Overview

Visualization - Physical Design

robot renderer

Schematic system Architecture

Overview schematic

Acknowledgments

This work was created with the support of project RP182401001 under the PPSŘ 2025 program.

Hardware Desing

This section provides a detailed description of all hardware components required to build the robot.
It covers 3D-printed parts, electronic components, integrated modules, and custom-designed PCBs.

3D Printed Components

This section lists all parts that need to be 3D-printed and provides recommended printing settings for optimal results.

Recommended Printing Parameters:

  • Printer: Prusa MK4
  • Slicer: PrusaSlicer
  • Filament: Prusament PLA or PETG
  • Infill: 30%
  • Layer height: 0.2 mm
  • Infill pattern: Gyroid

AR Tag Plate - 1x

AR Tag Plate

Battery Holder - 2x

Battery Holder

Camera Mounts - 2x

Camera Mount

Front Leg - 1x

Front Leg

Rear Leg - 1x

Leg Rear

LCD Mount - 1x

LCD mount

Plate Bottom - 1x

Bot Plate

Plate Middle - 1x

Mid Plate

Plate Top - 1x

Top Plate

SRF05 Mount - 3x

srf mount

Stand - 1x

Stand

Wheels - 2x

Wheels

Custom PCBs

This chapter presents the custom PCBs designed for the Fenrir Project.

The robot includes three custom PCBs with the following functionalities:

  • Raspberry Pi Sield (header)

    • Power supply
    • I2C bus
    • SPI bus
    • UART bus
    • Fan cooling
    • Buttons
    • LEDs
  • I2C Sensor Board

    • IMU (Accelerometer + Gyroscope)
    • Barometer
    • Magnetometer
    • ADC
    • Real-Time Clock (RTC)
  • Arduino Nano Board

    • I2C bus
    • Motor Control
    • Motor Encoders
    • Ultrasonic Sensors
    • Line Sensors

For detailed design files, please refer to the pcbs folder in the root of this repository.


Raspberry Pi Shield

ext_schematic

Figure 1. Raspberry Pi Shield schematic.

rpi_ext_render_top

Figure 2. Raspberry Pi Shield 3D render.

I2C Sensor Board

i2c_board_schematic

Figure 3. I2C Sensor Board schematic.

i2c_board_render

Figure 4. I2C Sensor Board 3D render.

Arduino Nano Every Board

arduino_schematic

Figure 5. Arduino Nano Board schematic.

arduino_render

Figure 6. Arduino Nano Board 3D render.

Modules

RoleComponentURL
Main ComputerRPilink
MicrocontrollerArduino Nanolink
2x BatteryPowerbank 10000 mAhlink
CameraRPi Camera v2link
GPSNEO-7M modulelink
2D LiDARRPLiDAR A1M8link
LCDHD44780 20x4 I2Clink
3x UltrasoundSRF-05link
2x Line SensorTCRT5000 modulelink
H BridgeL298N modulelink
Motor with EncoderDG01D‐Elink
IMUMPU6050link
BarometerBME280link
Real Time ClockDS3231link
ADCADS1115link
UWB (not implemented yet)DWM1000link
DC/DC Step UpXL6009link
Power DeliveryUSB-C PD modulelink

Wiring

Wiring Overview

Figure 1. Wiring overview of the Fenrir robot.


Note: Sensor and motor numbering follows a left-to-right convention:

  • Ultrasounds 1 - left, Ultrasound 2 - center, Ultrasound 3 - right
  • Line sensors: 1 - left, Line sensor 2 - right
  • Motors: 1 - left, Motor 2 - right
  • Encoders: 1 - left, Encoder 2 - right

Module APinModule BPinTypeLengthNote
Battery 1-PD Module-USB-C - USB-C15cm-
Battery 2-Raspberry Pi-USB-C - USB-C15cm-
Raspberry Pi-Camera-CSI Cable10cm-
Raspberry Pi3v3GPSVCCwire (blue)10cm3V3
Raspberry PiGNDGPSGNDwire (black)10cmGND
Raspberry PiRxGPSTxDwire (purple)10cmUART
Raspberry Pi5VI2C Board5Vwire (red)8cm5V
Raspberry PiGNDI2C BoardGNDwire (black)8cmGND
Raspberry PiSCLI2C BoardSCLwire (yellow)8cmSCL
Raspberry PiSDAI2C BoardSDAwire (green)8cmSDA
Raspberry Pi-LIDAR-USB-A - microUSB10cm-
I2C Board5VLCDVCCwire (red)8cm5V
I2C BoardGNDLCDGNDwire (black)8cmGND
I2C BoardSCLLCDSCLwire (yellow)8cmSCL
I2C BoardSDALCDSDAwire (green)8cmSDA
I2C Board5VArduinoVCCwire (red)15cm5V
I2C BoardGNDArduinoGNDwire (black)15cmGND
I2C BoardSCLArduinoSCLwire (yellow)15cmSCL
I2C BoardSDAArduinoSDAwire (green)15cmSDA
ArduinoUS1Ultrasound 1Vccwire (red)10cm5V
ArduinoUS1Ultrasound 1GNDwire (black)10cmGND
ArduinoUS1Ultrasound 1Echo/Trigwire (blue)10cmsignal
ArduinoUS2Ultrasound 2Vccwire (red)10cm5V
ArduinoUS2Ultrasound 2GNDwire (black)10cmGND
ArduinoUS2Ultrasound 2Echo/Trigwire (blue)10cmsignal
ArduinoUS3Ultrasound 3Vccwire (red)15cm5V
ArduinoUS3Ultrasound 3GNDwire (black)15cmGND
ArduinoUS3Ultrasound 3Echo/Trigwire (blue)15cmsignal
ArduinoLine1Line Sens. 1VCCwire (red)15cm5V
ArduinoLine1Line Sens. 1GNDwire (black)15cmGND
ArduinoLine1Line Sens. 1A0wire (blue)15cmsignal
ArduinoLine2Line Sens. 2VCCwire (red)15cm5V
ArduinoLine2Line Sens. 2GNDwire (black)15cmGND
ArduinoLine2Line Sens. 2A0wire (blue)15cmsignal
Arduino5VEncoder 1-wire (yellow)20cm5V
ArduinoGNDEncoder 1-wire (brown)20cmGND
ArduinoEN1AEncoder 1-wire (red)20cmA
ArduinoEN1BEncoder 1-wire (orange)20cmB
Arduino5VEncoder 2-wire (yellow)20cm5V
ArduinoGNDEncoder 2-wire (brown)20cmGND
ArduinoEN2AEncoder 2-wire (red)20cmA
ArduinoEN2BEncoder 2-wire (orange)20cmB
ArduinoGNDPD ModuleOUT-wire (black)--
ArduinoM1AH-BridgeIN3wire (yellow)20cmPWM A+
ArduinoM1BH-BridgeIN4wire (green)20cmPWM A-
ArduinoM2AH-BridgeIN1wire (yellow)20cmPWM B+
ArduinoM2BH-BridgeIN2wire (green)20cmPWM B-
PD Module+H-Bridge+12Vwire (orange)15cm12V
PD Module-H-BridgeGNDwire (black)15cmGND
H-BridgeOUT1+Motor 1-wire (green)20cm+
H-BridgeOUT1-Motor 1-wire (blue)20cm-
H-BridgeOUT2+Motor 2-wire (green)20cm+
H-BridgeOUT2-Motor 2-wire (blue)20cm-

Bill of Materials

RoleQuantityPrice pre oneURL
RPi 4 4GB160 EURlink
RPLidar1130 EURlink
SD Card 32GB112 EURlink
RPi Camera v2118 EURlink
RPi Cooling12 EURlink
RPi Fan13 EURlink
DC Motor212 EURlink
Arduino Every115 EURlink
Line Sensor21 EURlink
H-Bridge12 EURlink
MPU650013 EURlink
HMC5883L13 EURlink
DC/DC step up12 EURlink
SRF0532 EURlink
RTC14 EURlink
ADS1115115 EURlink
BME28018 EURlink
USB PD Module12 EURlink
LCD
Screw terminal 2x 5.0850.3 EURlink
Screw terminal 3x 2.5480.3 EURlink
Screw terminal 2x 2.5450.2 EUR
GPS1 (optional)15 EURlink
DWM 10001 (optional)40 EURlink
Powerbank220 EURlink
Caster33 EURlink
Screw M3x644--
Screw M3x254--
Color Wires---

Software Architecture

This chapter discusses software architecture of the Fenrir Robot.

The Raspberry Pi software and the Arduino firmware is described and the way how both systems communicate with each other.

Raspberry Pi Software

This project runs on a Raspberry Pi (Ubuntu + ROS 2 Humble) and acts as the high-level HW wrapper of the robot. The Pi hosts ROS 2 nodes that handle lidar, camera, I2C sensors (and the Arduino), RGB LEDs, and buttons. In effect, it gathers all the sensory data, publish them via ROS 2 topics, which makes it easy to read and make decisions and later on it accepts topic for motor speeds.

For sensors, the Pi runs specialized ROS 2 nodes: one for the lidar to scan the environment, one for the camera to capture images or video, and drivers for I2C sensors (ADC, IMU, magnetometer, etc.) and the Arduino (which itself controls motors and encoders, line sensors and ultrasounds). There are also nodes (or scripts) to manage RGB LEDs (for status or feedback) and buttons (for user interaction or emergency stop). All sensor inputs are published into the ROS 2 ecosystem so other nodes (e.g. navigation, mapping, control) can subscribe and act on them.

In addition, the repository includes helper scripts for setting up the Raspberry Pi environment (installing required packages, configuring ROS 2, setting up node launch files, calibrations, etc.). These scripts make it easier to initialize a fresh Pi with all dependencies, and to launch the full ROS 2 system smoothly. So overall, the Raspberry Pi side is responsible for integrating sensors, executing high-level logic, and coordinating with the Arduino via I2C, all within the ROS 2 framework on Ubuntu.

Arduino Firmware

The firmware is available here Firmware.

This Arduino Nano program works as a motor controller that talks with a main computer (for example a Raspberry Pi) using I2C communication. The Nano is an I2C slave – it waits for messages from the master and answers when needed. When the master sends data, the Nano updates target speeds or control settings. When the master asks for data, the Nano sends back measurements like encoder counts or wheel speeds. This communication happens using interrupt callbacks, so it does not stop the main program loop. In this way, the Nano can control motors and communicate at the same time.

Arduino handles the ultrasound sensors, line sensors, possible extension for current sensor and controls the motors.

The robot wheels have encoders that measure how fast they rotate. Each encoder gives electrical pulses when the wheel moves. The Nano uses interrupts to count these pulses very quickly without missing them. The number of pulses in a short time tells how fast the wheel is turning. In the main loop, the program reads these counts and calculates the wheel speed. These measured speeds are compared with the target speeds received from the master to see if the motors are running correctly or need adjustment.

To keep the wheels turning at the right speed, the Nano uses a PID controller. In every cycle of the main loop, the program calculates the difference between target and actual speed and adjusts the motor power with PWM signals. The direction pins control forward or backward rotation, and the PWM value sets how strong the motor runs. The main loop repeats this many times per second, keeping the movement smooth and stable. Meanwhile, I2C and encoder interrupts work in the background, so the system always knows the latest speed and can react quickly to commands from the master.

Memory Space

ByteValueLengthR/W
0ultrasound 0 distance [cm]1BR
1ultrasound 1 distance [cm]1BR
2ultrasound 2 distance [cm]1BR
3encoder A [-]4BR
7encoder B [-]4BR
11current probe [-]2BR
13line sensor 0 [-]2BR
15line sensor 1 [-]2BR
17motor 0 speed [-]2BW
18motor 1 speed [cm]1BW
19reserverd1B-

Robot Assembly

This chapter shows how to assemble the robot.

Robot Assembly

Step 1 - Battery holder mount

  • Bottom part
  • Battery holders (2x)
  • Screw M3x6 (4x)

Step 2 - Front Leg mount

  • Front leg
  • Screw M3x6 (2x)

Step 3 - H-Bridge mount

  • H-bridge
  • screw M3x6 (4x)

Step 4 - Standoffs

  • Standoff (4x)
  • Screw M3x6 (4x)

Step 5 - Rear Leg mount

  • Rear leg
  • Screw M3x6 (2x)

Step 6 - Roller Casters mount

  • Roller caster (3x)
  • Screw M2x4 (6x)

Step 7 - Motors mount

  • Motor with 6-wire cable (2x)
  • Screw M3x25

Step 8 - Line Sensors mount

  • Line sensor with 3 wires (2x)
    • vcc (red)
    • gnd (black)
    • signal (blue)

Step 9 - Middle, Switch

  • Middle part
  • Switch
  • USB power delivery module
  • Wires (red & black)

Step 10 - Arduino Board

  • Arduino board
  • Screw M3x6 (4x)

Step 11 - LiDAR Mount

  • LiDAR with UART to USB converter and 4 screws

Step 12 - Ultrasound Module assembly

  • Ultrasound sensor
  • 3 wires
    • vcc (red)
    • gnd (black)
    • signal (blue)

Step 13 - US Modules mount

  • Ultrasound module (3x)
  • Screw M3x6 (6x)

Step 14 - DC/DC Stepup mount

  • DC/DC stepup
  • Screw M3x6 (2x)

Step 15 - Top, LCD

  • Top Part
  • LCD mount
  • LCD
  • Wires
    • vcc (red)
    • gnd (black)
    • sda (green)
    • scl (yellow)

Step 16 - RPi, Camera

  • Raspberry Pi 4
  • RPi camera v2
  • Camera mount
  • 4x screw M2x3

Step 17 - RPi Module mount

  • RPi module

Step 18 - Sensor Board mount

  • Sensor board
    • IMU
    • ADC
    • RTC
    • Magnetometer
    • Barometer

Step 19 - RPi Hat mount

  • RPi Hat

Step 20 - Bottom Module wires alignment

Step 21 - Mid Module wires alignment

Step 22 - Bot & Mid merge

  • Bottom module
  • Mid module
  • Standoff (4x)

Step 23 - Connecting Encoders to Arduino Board

  • Left motor -> encoder 1
  • Right motor -> encoder 2

Step 24 - Connecting US modules

  • Left US -> us_1
  • Center US -> us_2
  • Right US -> us_3

Step 25 - Top Module mount

  • Top module
  • Screw M3x4 (4s)
  • Wires (RPi power -> Arduino Board)
    • 5V (red)
    • gnd (black)

Step 26 - Connecting I2C RPi <-> Aruino Board

  • Wires
    • sda (green)
    • scl (yellow)

Step 27 - Wiring Arduino Board -> H-Bridge

  • Left motor
    • M1A -> N1 (yellow)
    • M1B -> N2 (green)
  • Right motor
    • M2A -> N3 (yellow)
    • M2B -> N4 (green)

Step 28 - Connecting RPi Power to Sensor Board

  • vcc 5V (red)
  • gnd (black)
  • sda (gree)
  • scl (yellow)

Step 29 - Power Up

Step 30 - Wheels

  • Wheel (2x)

Final

SW Installation and Setup

This chapter just briefly describes the installation and setup the entire robot.

RPi Installation

Required HW

  • Raspberry Pi 4B (8GB RAM recommended)
  • Micro SD Card (minimal 16GB, 64GB recommended)
  • SD Card to USB Adapter

Installation

Install RPi-Imager on your Linux PC

sudo apt install rpi-imager

Run RPi-Imager

rpi-imager

Select Device (Raspberry Pi 4)

Select OS - Others General Purpose OS -> Ubuntu -> Ubuntu Server 22.04.5 LTS (64b)

Select target device (SD Card)

Click Next -> Edit Settings

Setup user, password, WiFi and SSH

Confirm and wait until writing is finished.

Now put the SD card into the RPi and power on.

In case of problems, please visit Official Documentation

OS Configuration

Connect to the Raspberry Pi

ssh <user>@<ip_address>

Run first installation script and reboot afterwards. The script may require user input for confirmation on restarting services Optionaly run script to disable services for faster boot.

sudo bash first_start.sh
sudo bash slow_startup.sh #optional
sudo reboot now

The script will:

  • run system update and upgrade some system packages
  • modify the boot firmware config
  • create a swapfile (can be removed on systems with more RAM)
  • add the user to following groups - video, tty, dialout

The slow_startup.sh will disable this services:

  • network wait
  • snap and related services
  • cloud init and related services

After rebooting the system, run the second script.

sudo bash installation.sh

The script will:

  • update system and install necessary packages
  • install Python packages
  • install ROS 2 and Colcon
  • clone fenrir-project repository
  • build ROS 2 packages
  • add services to the system and enable them at startup

If user name is different than "robot", paths in scripts and service files need to be changed, along with the user for one of services.

#in repository
fenrir-project/software/raspberry_pi/prp_root.service 
fenrir-project/software/raspberry_pi/prp_user.service 
#or after install
/etc/systemd/system/prp_root.service
/etc/systemd/system/prp_user.service

The ROS_DOMAIN_ID can be changed in the *.service files and optionally (but preferably) in ~/.bashrc.

Starting services

Start the necessary services for ROS 2 nodes:

sudo systemctl start prp_root.service
sudo systemctl start prp_user.service

Cloning SD card

Prequisitions:

  • Linux OS
  • SD card reader
  • A SD card with configured system
  • An empty SD card of the same size

Example of how to clone a SD card and rename hostname

# Insert the SD card with the existing system
lsblk # Identify the SD card and its partitions (e.g., /dev/sdc1 and /dev/sdc2)

# Unmout the SD card
sudo umount /dev/sdc*

# Create an image of the SD card with the system
sudo dd if=/dev/sdc of=~/Documents/prp/robot.img bs=4M status=progress  
sudo eject /dev/sdc

# Swap the SD card with an empty one
lsblk # Identify SD card and its partitions (e.g., /dev/sdc1 and /dev/sdc2)
sudo dd if=~/Documents/prp/robot.img of=/dev/sdc bs=4M status=progress # apply image to the SD card
sudo sync

# Mount the SD card's partitions
sudo mkdir /media/jakub/card1
sudo mount /dev/sdc1 /media/jakub/card1
sudo mkdir /media/jakub/card2
sudo mount /dev/sdc2 /media/jakub/card2

# Replace the old hostname for new one
sudo sed -i 's/prp-red/prp-green/g' /media/jakub/card1/user-data /media/jakub/card2/etc/hostname /media/jakub/card2/etc/hosts

# Unmount SD card and remove created folders
sudo umount /media/jakub/card1
sudo umount /media/jakub/card2
sudo rmdir /media/jakub/card1/
sudo rmdir /media/jakub/card2/

ROS_DOMAIN_ID can be rewritten in files:

~/.bashrc
/etc/systemd/system/prp_user.service
/etc/systemd/system/prp_root.service

Arduino Programming

HW Required

  • Host PC with Arduino Studio IDE installed see here.
  • Arduino Nano "Every" (Original or clone; Every need for more external interrupts)
  • USB cable to connect Arduino with PC
  • Arduino PCB for Fenrir Project

Programming

Open the software/arduino_nano/main/main.ino file in the Arduino IDE.

Connect the Arduino Every to the

Try to build the firmware using the "Verify" button in left top.

If build goes ok, try to upload the firmware using the "Upload" button in left top.

Using the ctrl+shift+M open terminal and check if microcontroller communicates.