adding more posts
@ -1,4 +1,10 @@
|
||||
---
|
||||
title: "Contact"
|
||||
date: 2022-08-21T22:12:40+01:00
|
||||
---
|
||||
---
|
||||
|
||||
UK-based, award-winning post-grad electronic engineering student & previous Disney intern
|
||||
|
||||
Multilingual programmer working from [embedded systems](/posts/iot) to holoportation and full-stack web-dev
|
||||
|
||||
I draw sometimes too
|
BIN
content/posts/draught/checkers-board.png
Normal file
After Width: | Height: | Size: 50 KiB |
47
content/posts/draught/index.md
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
title: "Draught"
|
||||
date: 2021-07-13T14:02:40+00:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
![ci](https://github.com/sarsoo/draught/actions/workflows/test.yml/badge.svg)
|
||||
|
||||
Rust is a great language for low-level work. Its memory model and syntactic sugar make it attractive for new projects, eliminating many types of bugs by design.
|
||||
|
||||
Likewise, WebAssembly is an attractive prospect for speeding up client-side web code. Combining the compiled performance, type safety and memory safety of Rust with the mature GUI development ecosystem of HTML/Javascript/CSS extends the possibilities for what can be completed client-side.
|
||||
|
||||
It's these ideas that made me want to explore Rust + WASM - prior to this, I knew little about either beyond the basic tutorials. In my masters AI module, I studied adversarial game models including the [MiniMax algorithm](https://en.wikipedia.org/wiki/Minimax). This algorithm generates a tree of possible moves and compares scores to decide which move should be made. Generating this tree can be expensive as it explodes exponentially, as such it would be a good candidate to try and speed up using compiled Rust over interpreted Javascript.
|
||||
|
||||
![checkers board](checkers-board.png)
|
||||
###### Standard checkers board rendered on an HTML canvas using Rust
|
||||
|
||||
The project took about 3 weeks off and on. Initially, I wanted to model the game board without the off-diagonal pieces that aren't played on. This would have helped reduce the memory footprint of each board which would be ideal when we are going to be handling a lot. Unfortunately, this significantly increased the complexity of modelling piece movements - after some trial and error I resorted to just modelling the whole board.
|
||||
|
||||
The MiniMax algorithm was also a bit of a pain. The algorithm relies on a tree structure for which I used the [IndexTree crate](https://crates.io/crates/indextree). Instead of using pointers between nodes that could rely on unsafe code, this library instead relies on a single backing array of nodes. Working out how to effectively create, populate and traverse the trees while following the borrow checker's rules was an effective learning exercise.
|
||||
|
||||
![screenshot](screenshot.png)
|
||||
###### Javascript UI with a Rust-controlled canvas
|
||||
|
||||
The performance of the game and the AI was pretty impressive. This was also without any Alpha-Beta pruning, a method to reduce the number of tree nodes that need searching. Below are the results of a basic benchmark for expanding the MiniMax tree to given depths both in development mode and release mode.
|
||||
|
||||
| Tree Depth | Dev Mode (Unoptimised) | Release Mode (Optimised) |
|
||||
|------------|------------------------|--------------------------|
|
||||
| 1 | 0.86 ms | 0.1 ms |
|
||||
| 2 | 4 ms | 0.26 ms |
|
||||
| 3 | 30 ms | 2 ms |
|
||||
| 4 | 223 ms | 15 ms |
|
||||
| 5 | 1,798 ms | 116 ms |
|
||||
| 6 | 14,379 ms | 1,006 ms |
|
||||
| 7 | 120,534 ms | 9,028 ms |
|
||||
|
||||
###### Time to generate a move with trees of various depths (Chromium/Linux)
|
||||
|
||||
At first, the AI was intimidatingly good. In fairness I am far from a checkers expert, I don't know how to play particularly "tactically" or anything like that. Something that I found interesting was that increasing the search depth did not necessarily make the AI feel harder to play. Setting the depth to 1 or 2 made the other player very aggressive, taking any piece it could. When increasing the search depth, the player wouldn't necessarily just take any piece when able to, but it was good at blocking moves the human may try to make.
|
||||
|
||||
In order to make the game more fun to play, I introduced a further parameter, the _perfect chance_. Instead of always following the move that the MiniMax algorithm suggested, instead it would sometimes pick a random move instead. This was decided randomly turn-by-turn using a threshold between 0 and 1. This threshold was presented as a difficulty slider within the UI and made the game much more fun to play.
|
||||
|
||||
Ultimately, I was pretty happy with the project and it can now be used as a testbed for trying out new Rust, WASM and Javascript skills that I learn.
|
||||
|
||||
[GitHub Repo](https://github.com/sarsoo/draught)
|
||||
|
||||
[Try it out!](https://draught.sarsoo.xyz/)
|
BIN
content/posts/draught/screenshot.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
content/posts/game-of-life/gameoflife1.png
Normal file
After Width: | Height: | Size: 31 KiB |
17
content/posts/game-of-life/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "Game of Life"
|
||||
date: 2021-06-26T14:14:40+00:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
![ci](https://github.com/sarsoo/game-of-life/actions/workflows/test.yml/badge.svg)
|
||||
|
||||
One of my first exposures to Rust WebAssembly was following the Rust + WASM Book's tutorial. The tutorial explains how to shift expensive logic from an interpreted Javascript environment to a faster, compiled Rust + WebAssembly one.
|
||||
|
||||
![example](gameoflife1.png)
|
||||
|
||||
This would prove a useful base from which to develop my [checkers implementation](/posts/draught).
|
||||
|
||||
[GitHub Repo](https://github.com/sarsoo/game-of-life)
|
||||
|
||||
[Try it out!](https://life.sarsoo.xyz/)
|
11
content/posts/iot/index.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
title: "IoT Coursework"
|
||||
date: 2020-11-24T15:03:40+00:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
My post-grad internet of things coursework concerned coding a smart sensor using a Contiki-based board. Written in C, the software collected light readings into a buffer before processing these data groups using symbolic aggregate approximation or SAX. This piece achieved 95%.
|
||||
|
||||
[GitHub Repo](https://github.com/Sarsoo/IoT-Labs)
|
||||
|
||||
[Read the report here.](report.pdf)
|
BIN
content/posts/iot/report.pdf
Normal file
BIN
content/posts/markov/StateTopology.png
Normal file
After Width: | Height: | Size: 145 KiB |
29
content/posts/markov/index.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "Hidden Markov Model Training"
|
||||
date: 2021-01-05T11:12:40+00:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
![state-topology](StateTopology.png)
|
||||
|
||||
###### Markov model state topology
|
||||
|
||||
The second piece of coursework for my speech & audio processing & recognition module was focused on the machine learning side of the field. One of the main methods we learnt about were __Hidden Markov Models__ and how to train them, this coursework was a test of the theory. My submission achieved 98%.
|
||||
|
||||
![probability density function iterations](iterated-pdfs.png)
|
||||
|
||||
###### Re-estimated probability density function outputs after training
|
||||
|
||||
The provided spec for the model included the __entry, exit__ and __transition__ probabilities, the parameters for each state's __Gaussian output__ function and the observations used for training.
|
||||
|
||||
From here, the coursework tested the ability to calculate and analyse various aspects of the model including __forward, backward, occupation__ and __transition__ likelihoods. A single iteration of __Baum-Welch__-based training was completed resulting in a new set of __transition__ probabilities and __output function parameters__.
|
||||
|
||||
![Occupation likelihoods](occupation-bars.png)
|
||||
|
||||
###### Probability of being in each state at each time step or observation
|
||||
|
||||
The above graph is presenting the __occupation likelihoods__ of each state at each time step or observation. It is the joint probability from the forward and backward likelihoods. From here it looks like the observations were taken from state 2 for 3 time-steps before swapping to state 1 for 4 time-steps and changing back to state 2 for the last one.
|
||||
|
||||
[GitHub Repo](https://github.com/Sarsoo/markov-models)
|
||||
|
||||
[Read the report here.](report.pdf)
|
BIN
content/posts/markov/iterated-pdfs.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
content/posts/markov/occupation-bars.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
content/posts/markov/report.pdf
Normal file
35
content/posts/mddp/index.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "Net-Zero Cable Repair Ship"
|
||||
date: 2021-01-10T18:44:40+00:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
I've just completed one of my post-grad modules which was structured as a multi-disciplinary group design project. A group of engineers of varying disciplines came together to design a subsea fibre-optic cable repair ship which is net-zero carbon.
|
||||
|
||||
As the electronic engineer, my responsibilities included the designs for the onboard batteries and the underwater drone vehicle.
|
||||
|
||||
# Battery
|
||||
|
||||
Ammonia fuel cells were selected for powering the vessel. This was a fantastic option as, not only does it not produce carbon during use, but if generated correctly, this element can be net-zero as well. However, from a current-voltage perspective, there is a most efficient state for the cell to be used in and a dynamic load can make the cells less efficient overall.
|
||||
|
||||
![mission range](mission1.png)
|
||||
###### Power usage and the battery capacity modelled over time during a 12 day mission
|
||||
|
||||
In order to allow the fuel cells to operate in their most efficient state, a battery is included in between the cells and the drive stage in order to handle these peaks. Lithium-ion batteries were selected and analysed from a sustainability perspective.
|
||||
|
||||
The project had a heavy focus on sustainability, the batteries can be somewhat lacking in this regard as a rapidly changing domain. Recycling Lithium-ion batteries isn't done anywhere near as much as it should and key materials are predominantly found in areas with poor environmental and working conditions.
|
||||
|
||||
Specifically for our project scope, the carbon cost of components was considered in order to work out whether the project could achieve its goal of net-zero carbon. The carbon cost describes the equivalent weight of carbon dioxide that is produced in order to create the object. Depending on the definition this can include the cost of just creating the subject while more in-depth analyses consider the whole life of a system. This includes proper end-of-life procedures that allow some carbon cost to be deducted like second-use.
|
||||
|
||||
# Underwater Drone
|
||||
|
||||
Drones are used in subsea cable repair to locate, cut and retrieve each half of the broken cable. A team of specialist conducts the splicing before the ROV returns the cable to the seabed and buries it with its water jet. A design was drawn up to extend the current capabilities of remote underwater vehicles (ROV) to include autonomous operations. This would allow the vehicle to locate the cable on its own.
|
||||
|
||||
![rov range](rov-range.png)
|
||||
###### Operating range of the ROV
|
||||
|
||||
This requires a number of advances including onboard power, a more advanced navigation system and a more flexible launch and recovery system.
|
||||
|
||||
[GitHub Repo](https://github.com/Sarsoo/MDDP-Cableship)
|
||||
|
||||
[Read the report here.](report-extra.pdf)
|
BIN
content/posts/mddp/mission1.png
Normal file
After Width: | Height: | Size: 326 KiB |
BIN
content/posts/mddp/report-extra.pdf
Normal file
BIN
content/posts/mddp/rov-range.png
Normal file
After Width: | Height: | Size: 483 KiB |