Academic Projects @ Warwick

Multi-Agent Car Parking using Reinforcement Learning
Undergraduate thesis applying reinforcement learning to simulate and control groups of autonomous vehicles using PPO and Unity ML-Agents.
- Trained agents with IPPO and MAPPO, and implemented DQN from scratch, using TensorFlow/Python.
- Designed a flexible environment modelled as an MDP with independent agents and dynamic goals, implemented in Unity using C#.
- Achieved a 98.1% parking success rate with up to 7 cars, outperforming single-agent baselines.
- Explored collaborative and competitive behaviours with variable communication and density.
- Revealed novel group dynamics such as 'leaky' collaboration and competition-induced cooperation.
- Scaled training on the university's HPC using Slurm.
- Presented at ICUR '22.
- Awarded 85% for the thesis (top 2% / 250 in cohort).
PythonC#UnitySlurmTensorFlow
MiniC Compiler
Implemented a compiler frontend for a simple C-like language using modern C++17 and LLVM.
- Developed lexical analysis and parsing with Flex and Bison.
- Generated LLVM IR through syntax tree traversal.
- Implemented semantic analysis and robust error reporting.
- Awarded first-class honours for the project.
C++LLVM
Physics Simulation Optimisation
Optimised a two-dimensional computational fluid dynamics simulator.
- Implemented low-level optimisation techniques on the C code, making it run in 1/10th of the original time (~80s to ~7s).
- Parallelised via multi-threading with OpenMP and vectorisation with SSE intrinsics, after removing inter-loop dependencies.
- Applied general optimisation techniques such as loop unrolling, loop fusion & fission, precomputing static conditionals, and removing unexecuted code.
COpenMP
Gaussian Mixture Model Clustering with EM Algorithm
Implemented clustering on the Iris dataset using Gaussian Mixture Models and the EM algorithm, improving accuracy over K-Means.
- Achieved 98% max cluster assignment accuracy after 19 EM iterations.
- Used PCA for dimensionality reduction and data visualisation.
- Developed and analysed the E-step, M-step, and label assignment for EM clustering.
PythonPacket Sniffer
Implemented a packet sniffer to detect SYN Flood, ARP Poisoning and URL Blacklist attacks.
- Low-level C implementation of IP and TCP packet header parsing.
- Multi-threaded implementation to handle high load of incoming packets.
- Used a work queue and mutex locks to handle high loads and prevent race conditions.
C
Timetable Scheduler
Implemented a class timetable scheduler in Python.
- Abstracted the problem into a game of 'Tetris'.
- Modelled scheduling around time and cost constraints as a Constraint Satisfaction Problem (CSP), and implemented CSP solving algorithms.
- Found the optimal assignment by implementing informed search algorithms.
Python
TurtleBot Planning, Localisation and Control
Implemented motion planning, control, sensing, and localisation using ROS and Turtlebot3 in the Gazebo simulator.
- Implemented in Python using ROS.
- Developed square path navigation using velocity control and PD controllers.
- Implemented closed- and open-loop obstacle avoidance with laser scan data.
- Applied particle-filter-based localisation with covariance analysis at waypoints.
- Designed wall-following and dynamic adaptation behaviours.
PythonROS
Pong
Implemented the classic 'Pong' game on the screen of an oscilloscope via an ARM controller.
- Implemented core game logic, including game loops and rendering.
- Built an API between the oscilloscope screen and the C code, providing primitive operations (drawing rectangles and other shapes) later combined to form the whole game.
CARM
Derivative Trade Manager
Software Engineering group project sponsored by Deutsche Bank, involving the design and implementation of a full-stack application to manage derivative trades.
- Delivered the project through the full Software Engineering lifecycle (requirements gathering, design, implementation) in a group of 6.
- Backend implemented in Java with an SQL database, frontend built with React (JavaScript), communicating via a REST API.
- Automatically learns, detects and corrects input errors using a Naive Bayes model.
- Scalable implementation via pagination and query indexing.
JavaJavaScriptSQL
Witter
Implemented the backend data store for a 'Witter' application (akin to Twitter).
- Implemented hash tables, search trees, and other data structures from scratch.
- Balanced time and space complexity trade-offs to optimise for scalability.
Java
Scratch Clone
Implemented an interpreter that computes the resulting memory state from an input program in Scratch block format and the initial memory state.
- Implementation used a Monad Transformer and other high-level abstractions.
- Obtained full marks for the implementation, and awarded two Purple λ awards for achieving marks among the year's highest for Functional Programming.
HaskellPLM Parser and Evaluator
Implemented a parser and evaluator for a made-up programming language (Programming Language of the Moment).
- Translated the rules of the language into a Formal Grammar (functions, parameters, variables, basic mathematical operators and positive integers).
- Implemented a parser using JavaCC and an evaluator using Java.
- Obtained full marks for the implementation.
JavaJavaCCPropositional Logic Prover
Implemented a logical evaluator to determine whether an input theorem is a tautology.
- Implemented the resolution algorithm for propositional logic formulas to determine tautology, in a divide-and-conquer fashion.
- Used Prolog for the implementation, making it entirely functional.
Prolog