Hello, I'm

Aidan Webb.

I build robots, circuits and the firmware in between.

I'm an Engineering Physics student at UBC, currently working as an instrumentation engineering co-op at ScopeSys. I like projects that feel tangible and have multiple levels of complexity, I think control theory is awesome and I love when software feels low level and applicable.

01. About Me

Hi, I'm Aidan. I'm a third-year Engineering Physics student at UBC. I get really excited when I'm faced with an interesting challenge and I'm always interested in learning new things.

Right now I'm on co-op at ScopeSys Microfluidics, writing firmware and tooling for a pressure-control instrument. Before that I built an autonomous rescue robot for Robot Summer, a 16-bit CPU on an FPGA, and a team of simulated drones.

In my sparetime I like to lift weights, practise gymnastics (I can do a handstand!), play piano, and am slowly working through a few Mandarin textbooks. I'm also fluent in French. Current favourite book: The Name of the Wind.

Some of the tools I've been working with recently:

  • C / C++
  • Python
  • Verilog
  • Zephyr / ESP-IDF
  • ROS
  • KiCad
  • SolidWorks / Onshape
  • Quartus / ModelSim
Portrait of Aidan Webb

02. Where I've Worked

Instrumentation Engineering Co-op @ ScopeSys Microfluidics

May 2026 – Present

  • Implemented an open-loop controller in C on a Zephyr firmware stack, handing off to a tuned PID loop to smooth pressure control ahead of product launch.
  • Developed Python CLI and GUI tooling with real-time telemetry for a multi-channel pressure and vacuum instrument used for nanoparticle confinement.
  • Packaged internal engineering tools into standalone executables with PyInstaller to simplify deployment across lab systems.
  • Designed precision alignment fixtures and motion-control systems for assembling multilayer lab-on-chip devices.

03. Some Things I've Built

2nd of 15 teams Top drone's view of the course with the bottom drone's position and waypoints overlaid

Jan – Apr 2026

Multi-Agent Drone System

For ENPH 353, our simulated robot had to navigate a Gazebo course, find clueboards and read them, fast and without touching the grass or the pedestrians. We flew two drones: one hovering high over the field as a live "satellite", the other flying the course and reading signs with a custom OCR model.

Maximum score, 2nd of 15 teams, over 98% OCR accuracy

  • ROS
  • Gazebo
  • Python
  • OpenCV
  • TensorFlow
Read the full write-up

Strategy

We tried a few ideas before settling: a custom robot through an Onshape-to-URDF pipeline (in Gazebo, cubes are about as good as curves), a robot that jumped between regions (too hard to land, and possibly against the rules), and imitation and reinforcement learning (unstable and thrown off by wind). We ended up with classical control, PID plus state estimation, for all flight, and saved the machine learning for reading signs.

The final design splits global perception from local control. A "mother" drone hovers over the course, stabilized in XY and yaw, and starts the timer. The second drone then uses the mother's downward camera to locate itself and flies a set of waypoints, photographing clueboards as it goes, and stops the timer once the last clue is submitted.

Top drone

A single ROS controller class holds the drone above the field. The course's centre of mass, from the moments of an HSV mask on the down camera, gives the XY error; the IMU gives a world-to-body rotation so world-frame forces can be applied correctly; and the depth camera sets the altitude, averaging the upper percentile of distances so trees don't throw it off. A leaky integrator on the XY error cancels the steady offset from the wind.

Bottom drone

Localization: it subscribes to the top drone's camera, computes a homography from the image to a normalized field frame, and finds its own bright purple top in that frame. That gives a consistent, scale-invariant (u, v) position.

Navigation: a fixed list of waypoints, each with a target position, altitude, yaw and dwell time, run by a small state machine (running, waiting, done). At each waypoint the drone settles, grabs a front-camera frame and reads the sign in-flight, since the model is light enough to run while it moves.

Control: PID on pixel error for XY, PD with gravity compensation on depth for Z, and IMU feedback for yaw and attitude.

Reading the signs

My teammate Derek Wei built the OCR as a library the controller calls with one function, which returns the clue type and value. Blue thresholding and morphological closing find the sign, and its largest contour is warped by homography to a flat 600 × 400 view. The characters are then thresholded, split into the type and clue rows, and cropped to 100 × 100 before classification.

OCR pipeline: input image, clueboard detection, perspective rectification, character segmentation, classification, post-processing

The classifier is a small three-layer CNN trained in Keras on a synthetic set of 36 characters (A–Z, 0–9) rendered in Ubuntu Mono, then noised, augmented, thresholded and eroded to look like the output of the real pipeline, and exported to TensorFlow Lite for fast inference. Validation accuracy was near perfect, but the training data was very close to the real signs, so the real limit was preprocessing: glare and thresholding that thinned, thickened or merged strokes caused far more misreads than the network did.

Featured Robot Summer autonomous rescue robot

Summer 2025

Autonomous Rescue Robot

For ENPH 253's Robot Summer, the course was a burning pet shelter and our robot had two minutes to find stuffed-animal "pets" and carry them to safety. We designed and built a fully autonomous robot from scratch in six weeks.

Custom ESP32 PCBs, PID motor control and state-machine navigation

  • C++
  • ESP32
  • KiCad
  • Onshape
  • Laser cutting
  • Waterjet
Read the full write-up

Mechanical

We started with quick shape prototypes cut on the laser cutter to get a feel for the robot's form, then used the same process for the final chassis and extended it to waterjet-cut parts.

Electrical

The electronics were a crash course in real-world debugging: parasitic capacitance, noise coupling through ground planes, and many hours with a scope and wavegen. I designed ESP32-based boards in KiCad with distributed power regulation and separated analog and digital signal paths.

Software

Firmware was object-oriented C++, with each component behind a clean interface so the navigation logic could treat hardware as a black box. We fused IMU, Hall-effect, IR and magnetometer data for homing and localization, and tuned PID gains wirelessly over WiFi.

Competition course layout
Top-level RTL of the 16-bit CPU

Sep 2024 – Jan 2025

16-bit RISC CPU

A custom RISC processor written in Verilog with ARM-inspired instruction decoding and memory-mapped I/O, deployed to a DE1-SoC FPGA and running hand-written assembly programs.

Verified with self-checking testbenches in ModelSim

  • Verilog
  • Quartus
  • ModelSim
  • FPGA
  • ARM assembly
Read the full write-up

Control

A state-machine controller reads the instruction decoder's output and drives the control signals for the ALU and memory through fetch, decode, execute, memory and writeback.

Instruction set

Arithmetic (ADD SUB), logic (AND MVN CMP), data movement (MOV), memory access (LDR STR) and branching (B BEQ BNE BLT BLE). Load/store support made it possible to run small programs and watch the CPU work on the board's switches and LEDs.

The project left me keen to go further into branch prediction, superscalar designs and vector processors like GPUs.

1st of 94 teams Rendered snowcat from the CAD competition entry

2024

UBCO CAD Design Competition

Our team modelled an entire ski hill in SolidWorks, complete with a working chairlift and snowcat, totalling more than 12,000 parts. It took first place out of 94 teams.

First place, UBCO CAD Design Competition

  • SolidWorks
  • Assemblies
  • Rendering
Watch the walkthrough

Other Noteworthy Projects

Jan 2026 – Ongoing

EEG Brain-Computer Interface

A multi-stage analog front end that picks up alpha and beta brainwaves, with active filtering and 60 Hz notch suppression, feeding a 16-bit ADC read by an ESP32 and streamed to a host.

  • Analog design
  • LTspice
  • KiCad
  • ESP32
  • I²C
2023

Sustainable Design Project

A prototype for a sustainable development design competition, built with an Arduino and 3D-printed parts. A full write-up is on the way; ask me about it in the meantime.

  • Arduino
  • Prototyping
  • 3D printing

04. What's next?

Get In Touch

I'm always happy to chat about hardware, robotics, or co-op and new-grad opportunities. Whether you have a question or just want to say hi, my inbox is open.