Wishful Coding

Didn't you ever wish your computer understood you?

Open Hardware GPS Navigator

Arduino GPS

I stumbled upon Open Street Map a few times, and it seemed like a good idea, but when I actually need a map, I reach for Google Maps.

Until it occurred to me it would be great to have GPS navigation on my bicycle. There are a few companies like Garmin that make them, but from what I understand they are not tailored for cyclists.

I thought this would be a fun Arduino project. Buy parts, download map, write code, profit… right? The buying part was easy.

I choose the Mega because it has 8K of SRAM instead of 2K in the Uno. My research showed I’d need it. I did not get the GPS shield because the pins conflict with the TFT shield.

Downloading the map was also easy, but several GB of XML and a few KB of SRAM is not a good match. I decided the right thing to do is to convert the XML to an R-tree and store it in a binary file on the SD card on the back of the TFT shield.

I spent a lot of time learning Rust and R-trees at the same time.

R-trees are fairly intuitive on the surface. It is a tree of rectangles that contain smaller rectangles. So to find nodes within a certain rectangle, you just have to descend in the rectangles that overlap with your query.

To insert a node, you just descend in the node that is the best fit, enlarging it if needed. But at some point the node is full and needs to be split.

Splitting nodes is the hard part, and there are several ways to do it, of varying cost, complexity, and efficiency. How you spit determines how good your tree is. Mine is fairly dumb.

After I had a basic R-tree working, I used Osmosis to load my map data into Postgres, from where I loaded it into my R-tree.

I recursively wrote the bounding box and offsets to child nodes to a file and put it on the SD card in the Mega.

This was an interesting moment where I was developing C and Rust in parallel. The C development had much less friction, a lot of hacks, and many occasions where I drew random pieces of memory to the screen.

After some more hacking and debugging, I had my first map on the screen! Only it took a few minutes to draw.

Studying my code and SdFat revealed a few things:

There where a lot of nodes where it would read each subnode from disk, check its bounds, and backtrack. I figured that if I stored the bounding rectangles on the parent node, I’d have to read a lot less.

SD cards read in blocks of 512 bytes. I made no particular effort to align my nodes. I think this could save some buffering.

So I formatted the SD card (mistake!) and adjusted the file format so that nodes are aligned at 512 blocks and contain the rectangles of their children. The result: It’s even slower! What happened?

I put some millis() in my code, and it turned out that seek() calls where taking over 3 seconds. I googled around and found that most operating systems suck at formatting SD cards.

I reformatted the card with the official utility and seek times magically went down to 500ms. Better, but not good enough.

It turns out that the reason is that at the edge of every cluster(4KB), it needs to read the FAT header where the next cluster is, in case the file is fragmented. (Now you know why defragmenting speeds up your PC)

But knowing that my file is contiguous, I could use a low-level function to read raw blocks. This was a major improvement, and allows maps at low zoom levels to be drawn in under a second.

The current status is that it can draw a map based on your location, show your speed and some other metrics, and zoom in and out. Source code lives here

Pepijn de Vos

Recumbent Knee Problems

I was having some knee problems when riding my recumbent bike. So I did some googling and asking around.

Googling told me that it’s best to pedal 90RPM, but not why. Asking around on the Dutch ligfiets group produced a long thread of good info. This post is a collection of that information.

Before I start, I’ll tell you to go see a physiotherapist. Reading things on the internet is not a substitute for professional care. You only have one pair of knees, and I’ve been told cartilage never grows back.

The problem

Gravity, imago, and wiggle room.

On a normal bike your power is limited to your weight. On a recumbent it’s only limited by your muscles. This means you can push harder than is good for you.

Recumbents have the imago of being fast. So you will push harder than is good for you.

On a recumbent you don’t get “gravity asist”. On a normal bike you can cruise along by just lifting and dropping your legs. This doesn’t work so well horizontally.

People are asymetric, but bikes are not. On a normal bike your hips accomodate this asymetry. On a recumbent your hips are less free.

Why 90RPM

The end goal is reducing strain on your knees, so it is obvious that a lighter gear means less strain.

In this regard the human body is like a combustion engine. There is a speed at which it produces the most power, and a speed where it is the most efficient.

90RPM is the speed where you can produce the most power. 60RPM is the speed where you are the most efficient. Approximately, depending on you and your bike.

Rules of thumb

  • Keep a constant pace, vary your speed and gear.
  • Don’t fight headwind and hills. Reduce gear.
  • Shift to first gear when stopping.
  • Reduce gear when slowing down.
  • Accelerate slowly.
  • First accelerate, then gear up.
  • Keep your speed at least above 60RPM.
  • Pedal lighly, ride slowly.

How much is 90RPM

Three half revolutions per second. Not that much when you get used to it.

A cheap way to find out is to install a metronome app on your phone, and set it to 90bpm. Now make a whole revolution per 1/4, or one leg per 1/8, assuming a 4/4 measure.

If you’re doing it right it’ll feel like you’re just moving your legs, instead of pushing the bike.

Once you get a feeling for it, let your mind go. I cycle much more naturally and relaxed when I’m not watching every move. It’s not helpful to stick to exactly 90RPM in a non-constant environment. Your body will interrupt you when conditions change significantly.

Other helpful things

Adjust the lenght of your bike real precise. It can be a matter of millimeters, due to the limited hip movement mentioned earlier. Too long and you knees will over-strech, too short and you push less efficiently. From what I heard, the former manifests as pain in the back of your knee, the latter as pain in the kneecap.

Some people report that shorter cranks make it easier to pedal fast. This might be especially true if you’re short.

Some people use oval gears, claiming they provide a more constant feeling. The idea is that the gear is small at the dead spot and large when perpendicular to your legs.

Consider SPD pedals and shoes. At a high RPM a lot of energy goes towards keeping your feet on the pedals. Using SPD pedals make it easy to pedal fast, and as a bonus allow you to pull as well as push.

Pepijn de Vos

Chromebook Arch Chroot

I just bought an Asus C300 Chromebook. They have a really good money/value ratio. Decent hardware for a fraction of the price of an Ultrabook.

I figured that if it’s more powerful than the Raspberry Pi, it’s powerful enought to be my work laptop. The only thing that remains is to put Linux on it.

I read that you can dual-boot or use Crouton to create a Debian chroot. I think Chrome+terminal is enough for my needs, but I prefer Arch over Debian.

Luckily, it turns out to be rather easy to get an Arch chroot. These steps only work for Intel Chromebooks. Basically follow these steps on the wiki.

First thing to do is to get in developer mode, otherwise you can’t access the shell. Press esc+refresh+power and follow the steps on the screen. This will take a few minutes and wipe out your drive.

Next open Crosh with ctrl+alt+t and open a full Bash console with shell.

Enabling developer mode disables OS verification, which is nice if you want to run your own OS. However, if you just want a chroot, it’s safer to turn verification back on.

sudo crossystem dev_boot_signed_only=1

Next download the Arch bootstrap archive from any mirror. Not the ISO, mind you. Chrome OS doesn’t understand gzip to my surprise, but this is not an issue.

I had some issues with the cursor getting stuck. This can be fixed by installing Secure Shell

Now we need to extract the bootstrap archive to a proper location. Most of the partitions are mounted with the ro and noexec flags, which foiled my initial attempt at entering the chroot. However, /usr/local allows writing and execution.

cd /usr/local
tar xf /home/user/blablabla/Downloads/archlinux-bootstrap-yyyy.mm.dd-x86_64.tar.gz
sudo vim root.x86_64/etc/pacman.d/mirrorlist
sudo root.x86_64/bin/arch-chroot /usr/local/root.x86_64/
pacman-key --init
pacman-key --populate archlinux
pacman -Syu

And that’s all there is to it. You can now install anything you want inside the chroot. I went ahead and installed vim and git. I’m now writing this post in my Arch chroot.

Pepijn de Vos