Studio711.com – Ben Martens

Geek

CascadeSkier Windows Phone 7 App

Three years ago, I wrote a mildly successful Windows sidebar gadget (~6000 users) that shows local temperatures, 24 hour snowfall and total snowfall for all the local resorts. There are other data sources like that, but what sets this apart is that the data is updated hourly thanks to live feeds from the Northwest Avalanche Center. (Thanks again to the NWAC for letting me use their data!) While displaying all that data, the gadget cycles through web cam feeds from each resort. At the bottom of the gadget is a quick news line to keep people informed of local snow news. Version 4.0 just hit the Windows Live gallery yesterday so feel free to download it for free and try it out. If you want more details, check out gadget.studio711.com.

Many of the users asked if I had plans to make a Windows Phone 7 version of that gadget. I said no at first, but with time and a lot of requests, I changed my mind and decided to give it a shot. Microsoft also really encouraged employees to develop their own applications. I’m sure that’s a large part of why employees are all getting new phones (that and because we’ll make good marketers.) Anyway, I’m proud to say that if you go to the Zune Marketplace and flip through the Sports genre, search for “cascadeskier”, or click this link (with the Zune software installed), you’ll see my app!

The development process was interesting:

  • It costs $99/year to be a developer. Microsoft keeps 30% of the generated revenue. This all covers the cost of identity verification and unlimited application submissions.
  • A very nice suite of development tools is available in a single package. It includes Visual Studio 2010 Express, Expression Blend, and a WP7 emulator.
  • Code is written in Silverlight/WPF. It was my first foray into that world but I’m happy with the end result. Data binding was the most painful part, but after I learned some debugging tricks, that got simpler.
  • The application submission process is very nice. Fill out the form, click upload, wait for them to test it and then it shows up in the marketplace. If you fail the tests, you get a document back detailing exactly what tests you fail. If you clean that up and don’t break anything else, you’ll be in the marketplace. Your app will never be declined without an answer. It sounds simple but it’s a huge plus for developers and a big win over the Apple platform.
  • Updates are super simple. The developer uploads a new binary and the Windows Phone software takes care of the rest. It notifies the user that there is a new version available and points them to the download.

  

I have actually submitted two apps already, but I think the second one will be much less popular. I wrote it mostly for myself. It’s called DiamondStats. It’s a simple app that helps you keep track of your baseball or softball stats. It sound silly but I’m a numbers guy and I’m always thinking about stats while I’m playing rec league softball. (Yes, I know that’s bad. I didn’t do it when I was playing competitively in high school.) Having the app is nice because I can just walk back into the dugout, pop in the numbers and then forget about it. I wrote this for my old phone and then rewrote it for the new platform.

I plan to continue to release updates for the CascadeSkier application. Suggestions are already coming in and some of them have been pretty good. I think the first think I want to do is get rid of the start page where you select from a list of resorts. You should jump automatically to your favorite resort and be able to filter out the ones you don’t care about.

At some point I might port it over to Android, but that’s not real high on my list right now. It will very likely never be on iPhone since I won’t be buying a Mac just to write an app for that phone.

If you download it, please send me your feedback!

[UPDATE] You can view the most up to date information about this app at http://cascadeskier.studio711.com

Harry Potter Newspaper

After doing the Halloween video, I decided to give special effects another try. This idea had been floating around in my head for a while and here is the result. It’s not perfect, but I thought it was good enough to share.

If you’re curious, the main effects I used in Premiere Elements 8 were lightning, crop and corner pin. The pinning was almost a frame by frame effort as I manually tracked the movement of the paper. If I had $700 for After Effects I could have used motion tracking and the result would have been much cleaner. I also used a combination of blur and coloring effects to try to match the look of the paper. The strange background in the inset video is the result of using chroma key for a background that wasn’t uniform. I did it as an accident but thought it fit the overall look pretty well.

It’s amazing what you can accomplish with a few hours at the computer. We’ve come a long way since the days that we used to sit in the dorm room with multiple VCRs and audio input sources cabled together to attempt to mix videos.

Windows Mobile Podcast Player

I have bad news. My 120GB Zune died. The original 30GB is still alive and well but Tyla uses that. My Zune got daily use in my car. I had all my music on there and I mostly used it to play the many podcasts that I listen to (TWiT, Car Talk, Home Theater Geeks, Windows Weekly, and Preston and Steve.)

I decided to use my phone (HTC Touch Pro 2) until I can get a new Windows 7 Phone which will double as my new Zune. The only problem with using Windows Mobile 6.5 as a podcast player is that the media player app doesn’t save your position when you stop listening. This is critical for podcasts which span multiple drives to work.

I fired up Visual Studio and started coding an app to do this. It’s a bit tricky to keep the phone from locking, but I got it all working. The UI is nothing fancy but I’ve been using it for a few weeks and it works quite well!

If you’re interested in running the app on your phone or getting the source code, it’s all available at http://podcastplayer.codeplex.com/ for free.

Potholes Timelapse Video

Yesterday I posted a timelapse video where the main feature was the GPS points on the topo map. When we drove back from Potholes a few weeks ago, I focused more on the images. I taped a USB webcam to the rear view mirror and had it connected to the laptop which was running an app to capture an image every two seconds. That worked great except that there was a problem with the inverter and the laptop battery died before we even made it back over the pass.

I took the images that we were able to snag, combined them with the GPS data and created another timelapse video. It’s all done with a custom C# program so if you geeks out there have any questions, let me know. Basically it’s a WinForms app with a web browser that loads the Bing maps and then I use Win32API calls to capture an image of the app. I have another app that combines all the image files into a WMV file.

The next thing I want to try is using the little HD video camera to record the images/video and see how that works. I have a suction cup camera mount that should make it easier to mount in the car and using the video camera means that I won’t need to have the laptop running. I plan to give it another try when we drive out to the coast in a couple weeks.

The video is embedded below, but again, it works best when you view in full screen HD quality. The GPS wasn’t able to get a lock on the signal for a while so it starts out with just images and then the location data kicks in. I wasn’t intentionally trying to keep our camping spot a secret since you could just watch the images and figure out where we were.

Camp Muir Timelapse Video

I’ve been playing around with a lot of time lapse ideas lately. I took some pictures for part of the return trip from Potholes which you’ll see soon, but on the hike up to Muir, I distracted myself by thinking how I could combine all the various data I had collected into one display.

In the backpack, the GPS was taking a recording every few seconds. I was also snapping photos every once in a while. To combine the two, I wrote an app to plot out our current location on top of a topo map and show a photo that was taken at that time (if one exists.) With the GPS data, I was also able to show our rate of ascent, the current elevation, the current time, and the latitude and longitude.

I combined that all into one application, wrote each update out to a new image file and then combined the image files into a movie file. It’s embedded below or you can find it on YouTube. It’s best when viewed in HD in full screen mode.

Compass Declination

I was replaced the battery in my fancy Sunnto Vector watch which meant that I had to recalibrate some of the sensors including the compass. Calibrate a compass? We all learn in grade school that magnetic north isn’t exactly the same as true north, but it’s generally close enough that we don’t think about it. In the midwest it’s pretty close to the same, but out towards the coast the difference is significant. Here in Seattle if you follow a compass and walk north, you’ll be heading almost 17 degrees too far to the east!

Even more interestingly, the declination changes from year to year. In Seattle, it is currently decreasing by about a degree every 6 years. I strongly recommend that you click this Wikipedia link to watch an animation of how the magnetic field has changed over the last 400 years.

You probably don’t need to think about this in your day to day activities, but if you spend time outdoors, it’s good to have in the back of your mind in case you find yourself relying a compass in a survival situation.

Computer Build

A couple weeks ago, I mentioned I was about ready to pull the trigger on the new computer. That day finally arrived and I carved out some time to put it together on Wednesday.

The final parts list looks close to what I said in that post.

Core i7-860
GigaByte P55A-UD3
PNY NVidia GTS250 1GB
Corsair XMS3 8GB DDR3 1600
Corsair TX CMPSU-750TX 750W
Nippon Labs Delux 3.5″ Internal All In One Card Reader/Writer
Antec Two Hundred Case

The only thing not in that list is the DVD drive which I took out of the old computer and the hard drives which I had laying around. The OS is on a 160GB drive and the two 250GB drives are in a RAID0 config. Since the whole computer is backed up daily to the Windows Home Server, I’m not concerned about the reduced reliability of RAID0.

The whole process took me about three hours to finish. I could easily do it again in less than an hour, but I was taking my sweet time to be careful not to destroy my ~$1000 worth of parts. I had about a 45 minute panic attack when it didn’t boot. The fans would spin, a couple lights came on and then it would die. It would continue to repeat that cycle until I shut the power off.

Finally I figured out that there was a second power plug that needed to go into the motherboard. Once I plugged that in, everything worked and I was in business!

I built this computer to handle HD video so while I was building it, I filmed the whole thing. Tonight I edited the video and it was fantastic. I wish I had a before and after demo for you, but previously I’d get maybe 1 frame every second or two and every time I started or paused the video it would take a few seconds to respond. With this computer, it plays back at regular speed and is extremely responsive. Rendering was also a breeze. What used to take a couple hours to render now takes about 20 minutes.

The real test, of course, is whether or not I’d try this again. Initially I would have said no but I think the nervousness has worn off and I might be willing to give it another shot. There was a definite cost savings over buying it prebuilt from Dell and I got higher quality parts.

And Ken, I should have listened to you and gotten a modular power supply. But even with that, I still would have a mess of cables running everywhere. I need to open it back up and break out the zip ties.

I sped up the video so the whole process takes less than 5 minutes. If you go to YouTube you can watch it in HD.

DAWG Part 2

This post assumes that you’ve read at least the radix tree portion of the post from two days ago. Given that tree built from my dictionary of 100,000 words, what word would require the most nodes to be touched? One key is that the children of every node are sorted alphabetically.

So thinking logically about this, it’s probably going to be a long word. It’s probably going to contain a good number of letters that are towards the end of the alphabet. “aadvark” for example, is not going to work because right away we find the string “aa” after looking at only two nods. “zoo” on the other hand takes 26 nodes just to find the z.

I solved this by pumping all 100,000 words through the radix tree and counting how many nodes I touched for each word. The winner was “superstructures". Here are the nodes I touched at each level:

a b c d e f g h i j k l m n o p q r s
a c e f g h i k l m n o p q s t u
a b c d e f g i k l m n p
e
r
a b c e f g h i l m n o p r s
a c e i m o p t
a i o r
a e o u
c
t
u
r
a e
s

Now you have learned your random piece of trivia for the day. I can’t imagine the situation where this would be useful knowledge. Also, this answer would vary depending on the dictionary you use.

PS. I haven’t had a ton to write about so you get stuck with whatever thoughts fly through my brain. Scary, eh? I wonder what normal people think about.

Directed Acyclic Word Graph

If that title wasn’t warning enough, you should know that this is going to be a pretty geeky post. I thought I’d do a little writeup of the project I’ve been toying with for the last couple weeks and I think a handful of you will enjoy it.

It all began when I started thinking about how you would write a program to find all the words on a 5×5 grid of letters (like Boggle.) There are many apps that do this already, but how do they work? How do you take a dictionary of 100,000 words and quickly apply to it to a bazillion possible letter combinations on a 5×5 grid and find all the valid words?

Radix Tree

I started off by reading in all the words and storing them in a radix tree. There is one root node and then the children of that root node are the distinct first letters in your word list. For a full dictionary you’ll probably end up with that first level of the tree having 26 nodes, one for each letter. This pattern continues down the tree so if you grab any node in the tree, the nodes above it correspond to the prefix of a words and all possible routes down through the children correspond to valid suffixes. Take any path from top to bottom and you have a word in the dictionary.

Each node also contains a flag that we’ll call Terminal which is true if that node can end a word and false if it cannot. So in the example on the right, the “n” in “one” would have Terminal = true because “on” is a valid word.

This turns out to be a very quick way to determine if a string of letters is a valid word. But there is a lot of extra data in the tree. For example, in the diagram on the right, the ending letters in “one” and “three” are identical nodes. There’s room for improvement.

Directed Acyclic Word Graph

As I was thinking about ways to compress this tree a little bit, DaveM pointed me to DAWGs (Directed Acyclic Word Graphs.) To create the DAWG, I create an array of pointers to all the nodes in the tree sorted by their depth in the tree. Starting at the leaf nodes (depth = 0) and moving up to the root, I apply the following algorithm

For each pair of nodes at depth x, if the two nodes have the same character and the two nodes have the same terminal flag and the two nodes have identical subtrees then remove node2 from its parent and add node1 to the childlist of the parent of node2.

Done correctly in a large word list, you can throw away a half to two thirds of the nodes in you tree!

Storing the Graph

It takes a while to build and compress the graph so it makes sense to serialize the tree so that I can just read it in from disc and be ready to go. I encoded each node as a 32-bit number. The first 5 bits represent the character (enough to store the 26 letters in the alphabet), 1 bit represents the terminal flag on/off value, and the last 26 bits represent the array index of the list of the node’s children. I flatten the tree into a jagged array where each node has a slot in the array and the value of that slot is a series of 32-bit numbers which represent it’s children with the above encoding scheme. The algorithm looks like this:

Get a list of the nodes in breadth first order.

Foreach each node in the BFS list look at each of the node’s children. If the child does not have a slot in the array, create an array slot and store that index in the child node. Encode the child node into the 32-bit number and append it to the list of the parent node’s children.

So for any array index N, the list of 32 bit numbers in that array slot represent the children of that node.

Writing this out to disc is pretty straightforward. The only special steps I took were to start the file with the length of the array and then when I write each array slot, I start with the number of children at that position. This speeds things up when I read in the file because I can allocate the right sized array.

Putting It to Use

Now it’s time to put the DAWG to use. I begin by generating a random 5×5 board. I use a weighting scheme to favor the more common letters and produce boards with more words. I then start at look at each node and follow this algorithm:

If this spot hasn’t been visited and the current string plus the letter on this spot is a valid substring in the DAWG, mark this spot as visited and search again looking in all 7 directions. If the current string is a valid word in the DAWG, add it to the list of found words.

Once that’s done I sort the found word list for quicker lookup. Now the player can start the game. When they punch in a word, it’s a simple lookup in that sorted list to determine if it’s a valid word. Since I know what all the valid words are, I can tell the user they have found X% of the words and then show the full word list at the end of the game.

Performance

The speed of the DAWG generation and serialization doesn’t really matter since it only happens once, but I can plow through 100K words in roughly 30 seconds. I’m writing this game for my phone which has a 528MHz processor in it. I can read in the DAWG from disc and load the array into memory in about 9 tenths of a second. Generating the random board and finding all the words happens in only 1 tenth of a second!

The next step is to give this game a little nicer GUI and add a timer, but I always get sidetracked playing the game instead of trying to improve it. This might be as good as it gets before I move on to the next hobby project.

Ski Geek

Somehow, every activity I participate in is turned into a geek project. Skiing is no different. This season, I have been carrying around the Garmin GPS that I purchased earlier in the year. It keeps a signal inside my coat and dutifully tracks my position every few seconds.

I can load this into my National Geographic topographical map program and get an interesting view, but I wanted more. I want to know my top speed, how much time I spent in the lift lines, how fast the lift was moving, which lifts I rode the most, etc.

To that end, I’ve started writing a program to analyze the GPS data. The raw statistics are fairly simple and I was able to get a display churned out pretty quickly. Lately I’ve been stuck on trying to automatically figure out when I was on a lift. On the surface, it seems easy: you’re on a lift when you’re going up. That’s not always true. Runs have rises in them and lifts have dips in them. So then I tried to say that any time I’m heading in the same direction for X miles and Y vertical feet then I’m on a lift. Even that has problems. What happens when you get off a lift and keep skiing straight down the backside of the hill? What happens when you get a couple errant GPS points that aren’t in line with the lift? There is enough drift in the data to make it very complicated. If I can’t get the automatic solution figure out, I’m going to have the user tell me where the lifts are the first time and then I’ll save that data. I want to move on to getting either a 2D or 3D map working next. After that I’ll work out a good way to display all the statistics about the day and each individual run.

If you’re interested in seeing the code and/or helping out, it’s all available on codeplex.

The picture below shows the track from my last ski day at Crystal Mt in the National Geographic software. My software will end up looking something like this but with more data and information on the screen.