August 31st, 2010

Biking Up A Hill

A little over 10 years ago I planned on doing a charity bike ride for AIDS from San Francisco to Los Angeles. I was required to raise $5k to participate and the company I was working for at the time was supposed to match any donations I collected…but this was 2000 and that all fell apart when the Dot-com bubble popped. I had been doing some training rides though and at one point naively decided to try and bike up a fairly steep hill in Berkeley, CA (the right side of the elevation profile that appears below).

On that occasion I did not make it to my destination and instead turned around and went home. Recently, I decided to gauge my hill climbing ability on a bike and decided to attack that same hill from the other direction. This is roughly the route I took (Google Maps won’t let me embed a map with biking directions):


View Larger Map

I took my GPS along with me and using my handy gpx elevation plotting script, generated the elevation profile of my ride:

Track: GrzlyPkLoop
total distance: 13.93mi
ascent: 1911.3ft
descent: 1912.9ft
minimum elevation: 66.7ft
maximum elevation: 1681.5ft

Elevation Gain Via Google Chart API

I was able to make it to the Tilden Park Steam Train at the top of the hill without stopping, but it took me almost an hour. It’s easy to see why I had such a hard time coming from the other direction as on average it’s twice as steep, 1300′+ elevation gain in ~3mi. On the way down my GPS said I hit 30.8mph but it felt like I was going twice that fast, my eyes were watering and a couple of insects smashed into my face. I don’t understand how people can go 40+mph on a bicycle, anything above 23mph feels less than stable to me.

It’s easy to get lost in the maze of roads scattered about the Berkeley hills, but if I can find a few routes which will gradually increase the steepness, perhaps after a few more rides I will be able to conquer this hill via the route which turned me back 10 years ago.

August 29th, 2010

The Longest Lunch

A couple of months ago, my wife and I stayed over our friends’ house in their redone guest room when I received a phone call a little after 10a. It was another friend who had 1p reservations for 3 at The French Laundry, a 3 Michelin Star restaurant (as of 2010, the only one in California and one of only 6 in the United States, the other 5 being in New York City). Reservations are hard to get, so after talking it over with the friends we stayed with and deciding there might be enough time to make the 2+ hour drive plus a stop at home to change into formal wear, we were off.

We were presented with two 9 course menus, the first with meat:
French Laundry Menu 1

And the other being vegetarian:
French Laundry Menu 2

The 9 courses are separated by lines on the menu (for some courses you have can choose one of two entrées). In addition, the staff brought out a few surprise items in-between courses such as a crème fraiche topped bit of salmon in a crunchy tuile cornet that looked like a mini vanilla orange sherbet ice cream cone and quarter sized cheese danishes. We ate from the omnivore menu splitting up our choices such that all entrées were enjoyed by at least one person in our party. Here’s a photo of the Tartare Of Japanese Bluefin Tuna (can you tell which cubes are tuna and which are watermelon?):
Tartare Of Japanese Bluefin Tuna

And here is a photo of the Crémeux Aux Fruits De La Passion:
Crémeux Aux Fruits De La Passion

The food tasted quite good, so much so that I had no trouble finishing a sea scallop the size of my palm, even though I dislike them quite a bit. Each dish had a creative presentation and the pace and portions were exactly the right size such that I could finish all of them and at the end of the meal was so full I did not need to eat dinner :) The staff was very helpful and polite and at no time during the 4 hour meal did the atmosphere feel pretentious or stuffy.

Our portion of the bill ($616 since my friend had the Foie Gras and some wine and wanted the total bill to be over $1k so we paid extra gratuity) was 3x more than we’ve ever paid for a meal. Was it worth the money? That’s hard for me to say since I’m not a connoisseur of food and can’t say I really appreciate “high end” things in general e.g. I’ve never eaten at a Michelin rated restaurant before. Even taking the quality of the food, the skill in preparation and presentation, I think the answer has to be no. However, this was definitely an experience that I’m glad to have had, even more so since it was a spur of the moment decision!

August 11th, 2010

GPX Elevation Profile Plotting With The Google Chart API

Last month I went on a few training hikes for an upcoming backpacking trip, and on the final two, I took along my GPS. Google Earth provides a wealth of options for visualizing GPS data, but I wanted to get a better understanding of what was going on under the hood. So I exported my tracks and waypoints as .gpx files and threw together a Python script which calculates a few data points as well as outputs a Google Chart URL with the elevation profile.

The first step was to understand the structure of a .gpx file. My Garmin eTrex Legend HCx only populates a subset of the fields in the schema, the important ones being waypoints <wpt>, tracks <trk>, track segments <trkseg> and track points <trkpt>. A track is comprised of a series of track segments, which in turn are made up of a series of track points. Track points have latitude, longitude and elevation information. Waypoints are similar to track points with the addition of name, type, label, but do not belong to a given track.

I created a class called Geopoint to represent the data contained in a track point. Since the GPS does not record track points at fixed intervals, the next step was to figure out how to calculate the distance between two track points. It’s been quite some time since I had to calculate the length of an arc on an approximate sphere, so it was time to consult the wondernet. It turns out there are a number of ways to calculate the distance between two latitude and longitude coordinates with varying degrees of accuracy. The two that I could understand relatively quickly were the Haversine formula and the Spherical law of cosines, both of which operate with radians and the mean radius of the Earth. Once I had both of those coded, I used the average as the distance between points.

In addition, I also added a field to the Geopoint class to hold a Waypoint (subclass of Geopoint which has a label) and looped through all the Waypoints (trail intersections in my case), associating them with the closest Geopoint allowing me to annotate the elevation profile with them.

The rest of the challenge lay in converting the elevation and distance data such that it can be scaled and displayed properly via the Google Chart API. The API is URL based and has a few limitations such as a max size and URL length. I also added a switch to output units in imperial or metric. The code can be found here: gpx.tar.gz. The archive includes the two .gpx files from my training hikes. You can see the output by running the script like so:

./gpxstats.py -i 2010-07-17_redwood_hike.gpx 2010-07-18_tilden_hike.gpx

That will print the data in feet/miles as well as the URL to the elevation profile in Google Charts.

Track: 17-JUL-10
total distance: 12.23mi
ascent: 3576.5ft
descent: 3571.8ft
minimum elevation: 486.2ft
maximum elevation: 1662.6ft
URL length: 1728


Track: TildenSoLoop
total distance: 10.13mi
ascent: 3060.9ft
descent: 3056.8ft
minimum elevation: 588.7ft
maximum elevation: 1703.6ft
URL length: 1653