Josef “Jeff” Sipek

May 5, 2013

Instrument Flying

Filed under: C182 IFR flying lightroom overcast photography sunset — JeffPC @ 01:41

I was paging through a smart collection in Lightroom, when I came across a batch of photos from early December that I did not share yet. (A smart collection is filter that will only show you photos satisfying a predicate.)

On December 2nd, one of the people I work with (the same person that told me exactly how easy it is to sign up for lessons) told me that he was going up to do a couple of practice instrument approaches to Jackson (KJAX) in the club’s Cessna 182. He then asked if I wanted to go along. I said yes. It was a warm, overcast day…you know, the kind when the weather seems to sap all the motivation out of you. I was going to sit in the back (the other front seat was occupied by another person I work with — also a pilot) and play with my camera. Below are the some of the better shots; there are more in the gallery.

Getting ready to take off:

US-127 and W Berry Rd:

The pilot:

The co-pilot:

On the way back to Ann Arbor, we climbed to five thousand feet, which took us out of the clouds. Since I was sitting in the back, I was able to swivel around and enjoy the sunset on a completely overcast day. The experience totally made my day. After I get my private pilot certificate, I am definitely going to consider getting instrument rated.

The clouds were very fluffy.

April 28, 2013

Change Ringing - The Changes

Filed under: ringing — JeffPC @ 13:00

We have seen what a bell tower set up for change ringing looks like; we have looked at the mechanics of ringing a single bell and what it sounds like if you ring the bells in what is called rounds (all bells ring one after each other in order of pitch, starting with the treble and ending with the tenor).

Ringing rounds is good practice, but ringing would be really boring if that was all there was. Someone at some point decided that it’d be fun for one of the ringers to be a conductor, and direct the other ringers to do the most obvious thing — swap around. So, for example, suppose we have 6 bells, the treble is the first, and the tenor is the last. First, we get rounds by ringing all of them in numerical order:

123456

Then, the conductor makes a call telling two bells to change around. For example, say that the conductor says: 5 to 3. This tells the person ringing bell number 5 that the next hand stroke (I completely skipped over this part in the previous post, but bell strikes come in pairs: hand stroke, and back stroke) he should follow the bell number 3. In other words, the new order will be:

123546

You can see that in addition to the 5 changing place, the 4 had to move too! Now, it is following the 5.

Until the next call, the bells go in this order. Then the conductor may say something like: 3 to 1, or 3 to treble. Just as before, 2 bells move. This time, it is the 2 and the 3, yielding:

132546

Let’s have another call…5 to 3. Now, we have:

135246

This pattern (all odd bells in increasing order, followed by all even bells in increasing order) is called Queens. There are many such patterns.

Ringing traditionally starts in rounds, and ends in rounds. So, let’s have a few calls and return the bells to rounds.

3 to the lead (this means that 3 will be the first bell) 315246
4 to 5 315426
4 to the treble 314526
2 to 4 314256
treble lead 134256
2 to 3 132456
rounds next 123456

There we have it. We’re back in rounds. There was nothing special about the order of these changes. Well, there is one rule: the bells that are changing places must be adjacent. So, for example, if we start in rounds, we can’t do 4 to the treble. Why is that? These bells are heavy, and especially the heavier ones (>10 Wikipedia article: cwt) will not move that far easily. Remember, this is bell ringing, not wrestling.

April 22, 2013

Plotting with ggmap

Filed under: R flying ggmap ggplot gps graphing — JeffPC @ 00:46

Recently, I came across ggmap package for R. It supposedly makes for some very easy plotting on top of Google Maps or OpenStreetMap. I grabbed a GPS recording I had laying around, and gave it a try.

You may recall my previous attempts at plotting GPS data. This time, the data file I was using was recorded with a USB GPS dongle. The data is much nicer than what a cheap smartphone GPS could produce.

> head(pts)
        time   ept      lat       lon   alt   epx    epy mode
1 1357826674 0.005 42.22712 -83.75227 297.7 9.436 12.755    3
2 1357826675 0.005 42.22712 -83.75227 297.9 9.436 12.755    3
3 1357826676 0.005 42.22712 -83.75227 298.1 9.436 12.755    3
4 1357826677 0.005 42.22712 -83.75227 298.4 9.436 12.755    3
5 1357826678 0.005 42.22712 -83.75227 298.6 9.436 12.755    3
6 1357826679 0.005 42.22712 -83.75227 298.8 9.436 12.755    3

For this test, I used only the latitude, longitude, and altitude columns. Since the altitude is in meters, I multiplied it by 3.2 to get a rough altitude in feet. Since the data file is long and goes all over, I truncated it to only the last 33 minutes.

The magical function is the get_map function. You feed it a location, a zoom level, and the type of map and it returns the image. Once you have the map data, you can use it with the ggmap function to make a plot. ggmap behaves a lot like ggplot2’s ggplot function and so I felt right at home.

Since the data I am trying to plot is a sequence of latitude and longitude observations, I’m going to use the geom_path function to plot them. Using geom_line would not produce a path since it reorders the data points. Second, I’m plotting the altitude as the color.

Here are the resulting images:

If you are wondering why the line doesn’t follow any roads… Roads? Where we’re going, we don’t need roads. (Hint: flying)

Here’s the entire script to get the plots:

#!/usr/bin/env Rscript

library(ggmap)

pts <- read.csv("gps.csv")

/* get the bounding box... left, bottom, right, top */
loc <- c(min(x$lon), min(x$lat), max(x$lon), max(x$lat))

for (type in c("roadmap","hybrid","terrain")) {
	print(type)
	map <- get_map(location=loc, zoom=13, maptype=type)
	p <- ggmap(map) + geom_path(aes(x=lon, y=lat, color=alt*3.2), data=x)

	jpeg(paste(type, "-preview.jpg", sep=""), width=600, height=600)
	print(p)
	dev.off()

	jpeg(paste(type, ".jpg", sep=""), width=1024, height=1024)
	print(p)
	dev.off()
}

P.S. If you are going to use any of the maps for anything, you better read the terms of service.

April 20, 2013

Matthaei Botanical Gardens

Filed under: nature photography — JeffPC @ 21:20

Back in early February, Holly and I went to the Matthaei Botanical Gardens. I took my camera with me. After over two months of doing nothing with the photos, I finally managed to post-process some of them. I have no idea what the various plants are called — I probably should have made note of the signs next to each plant. (photo gallery)

This one didn’t turn out as nicely as I hoped. Specifically, it is a little blurry. Maybe I’ll go back at some point to retake the photo.

This one is just cool.

I think this is some kind of Aloe.

April 19, 2013

IPS: The Manifest

Filed under: ips openindiana package management rsync smf — JeffPC @ 02:28

In the past, I have mentioned that IPS is great. I think it is about time I gave you more information about it. This time, I’ll talk about the manifest and some core IPS ideals.

IPS, Image Packaging System, has some really neat ideas. Each package contains a manifest. The manifest is a file which list actions. Some very common actions are “install a file at path X,” “create a symlink from X to Y,” as well as “create user account X.” The great thing about this, is that the manifest completely describes what needs to be done to the system to install a package. Uninstalling a package simply undoes the actions — delete files, symlinks, users. (This is where the “image” in IPS comes from — you can assemble the system image from the manifests.)

For example, here is the (slightly hand edited) manifest for OpenIndiana’s rsync package:

set name=pkg.fmri value=pkg://openindiana.org/network/rsync@3.0.9,5.11-0.151.1.7:20121003T221151Z
set name=org.opensolaris.consolidation value=sfw
set name=variant.opensolaris.zone value=global value=nonglobal
set name=description value="rsync - faster, flexible replacement for rcp"
set name=variant.arch value=i386
set name=pkg.summary value="rsync - faster, flexible replacement for rcp"
set name=pkg.description value="rsync - A utility that provides fast incremental file transfer and copy."
set name=info.classification value="org.opensolaris.category.2008:Applications/System Utilities"
dir group=sys mode=0755 owner=root path=usr
dir group=bin mode=0755 owner=root path=usr/bin
dir group=sys mode=0755 owner=root path=usr/share
dir group=bin mode=0755 owner=root path=usr/share/man
dir group=bin mode=0755 owner=root path=usr/share/man/man1
dir group=bin mode=0755 owner=root path=usr/share/man/man5
license 88142ae0b65e59112954efdf152bb2342e43f5e7
	chash=3b72b91c9315427c1994ebc5287dbe451c0731dc
	license=SUNWrsync.copyright pkg.csize=12402 pkg.size=35791
file 02f1be6412dd2c47776a62f6e765ad04d4eb328c
	chash=945deb12b17a9fd37461df4db7e2551ad814f88b
	elfarch=i386 elfbits=32
	elfhash=1d3feb5e8532868b099e8ec373dbe0bea4f218f1
	group=bin mode=0555 owner=root path=usr/bin/rsync
	pkg.csize=191690 pkg.size=395556
file 7bc01c64331c5937d2d552fd93268580d5dd7c66
	chash=328e86655be05511b2612c7b5504091756ef7e61
	group=bin mode=0444 owner=root
	path=usr/share/man/man1/rsync.1 pkg.csize=50628
	pkg.size=165934
file 006fa773e1be3fecf7bbfb6c708ba25ddcb0005e
	chash=9e403b4965ec233c5e734e6fcf829a034d22aba9
	group=bin mode=0444 owner=root
	path=usr/share/man/man5/rsyncd.conf.5
	pkg.csize=12610 pkg.size=37410
depend fmri=consolidation/sfw/sfw-incorporation type=require
depend fmri=system/library@0.5.11-0.151.1.7 type=require

The manifest is very easily readable. It is obvious that there are several sets of actions:

metadata
specifies the FMRI, description, and architecture among others
directories
lists all the directories that need to be created/deleted during installation/removal
license
specifies the file with the text of the license for the package
files
in general, most actions are file actions — each installs a file
dependencies
lastly, rsync depends on system/library and sfw-incorporation

The above example is missing symlinks, hardlinks, user accounts, services, and device driver related actions.

Many package management systems have the ability to execute arbitrary scripts after installation or prior to removal. IPS does not allow this since it would violate the idea that the manifest completely describes the package. This means (in theory), that one can tell IPS to install the base packages into a directory somewhere, and at the end one has a working system.

It all sounds good, doesn’t it? As always, the devil is in the details.

First of all, sometimes there’s just no clean way to perform all package setup at install time. One just needs a script to run to take care of the post-install configuration. Since IPS doesn’t support this, package developers often create a transient Wikipedia article: SMF manifest and let SMF run the script after the installation completes. This is just ugly, but not the end of the world.

Requests?

I’m going to try something new. Instead of posting a random thought every so often, I’m going to take requests. What do you want me to talk about next?

April 19, 2013

Math test

Filed under: latex math — JeffPC @ 01:41

I decided to finally implement some math support. Here’s a test post.

$a^n + b^n = c^n$

$v(t) = \frac{at}{\sqrt{1 + (\frac{at}{c})^2}}$

I hope equation support will come in handy.

February 13, 2013

FAST 2013

Since FAST starts today, yesterday was dedicated to flying out to San Jose.

Once at KDTW, I spent most of my wait there watching planes at the gates as well as watching more planes take off on 22L. Somehow, it was fascinating to watch them land on 22L and see 22R in the background — the same 22R that I got to do touch and go’s on a couple of weeks ago. I think not having to aviate first let me enjoy the sights — planes large and small barrelling down the runway and then *poof* they gently lift off the runway. At about 500 feet the gear retracts. It’s magic!

At one point, I saw the plane at the adjacent gate being prepared for its next flight. I both enjoyed seeing and sympathized with one of the crew (I assume the first officer since I suspect the captain wanted to stay warm) walking around the plane visually inspecting it. I know how annoying it is to be outside when it is cold to make sure the plane is safe to fly, yet I find it comforting that the same rules apply not only to Cessna 172s but also to Airbus A320s.

The first leg of the trip took me to KSLC. I brought my copy of the FAR/AIM with me. I read a bunch. I looked out the window a bunch. After we got past Lake Michigan, the sky cleared up allowing me to watch the ground below instead of the layer of overcast. I was very surprised to discover that the snow covered landscape makes it very easy to spot airports. Well, it is easy to spot paved runways that have been plowed.

The approach to KSLC was pretty cool. I never thought about the landscape in Utah before, but it turns out that Salt Lake City is surrounded by some serious mountains. Now, throw in winter weather with overcast and you’ll end up with a sea of white except for a few places where the mountains are peaking through.

Learning to fly in southeastern Michigan doesn’t make you think about mountains — there just aren’t any. Seeing the mountains peeking through the clouds was a scary reminder that there are more things in the sky than just other airplanes and some towers. If one were flying VFR above the clouds (which is a bad idea), where would be a safe place to descend? Obviously not where the mountains peak through, but any other place might be just as bad. The best looking place could have a mountain or a ridge few hundred feet below the cloud tops. Granted, sectional charts would depict all the mountains but it is a dangerous game to play.

I knew we would end up descending through the overcast and so I played a little game I expected to lose. Once we were in the clouds, I tried to keep track of our attitude by just sensing the forces. I knew I would fail, but I thought it would be interesting to try my best. We spent maybe 90 to 120 seconds in the clouds. At the end, I definitely felt like we were in a right bank — Wikipedia article: Spatial disorentation. I knew that we probably weren’t, but without visual information to fix up my perception there was no way for me to know.

We landed. I watched all the airport signs and markings, following our progress on an airport diagram. Once people started getting off the plane, I decided to ask to see the airworthiness certificate. The first officer (I think) found all the paperwork in the cockpit and showed me. It was really cool to see the same form I see every time I fly the 172 but filled out for an A320. (Theirs was laminated!) We chatted for a little bit about what I fly, and how it’s a good plane. It was fun.

It was time to get to my connecting flight. Nothing interesting happened. I spent about half the flight watching the outside and half reading my book.

After arriving to KSJC, I got up from my seat in the small but comfy plane (CRJ2000). I grabbed my backpack from the overhead bin with one hand since the other hand not only had my hoodie draped over but was holding the FAR/AIM. I started filing out. All that was left to do was give the thank-you-for-landing-safely-and-not-killing-me nod to the crew as I exited the plane. The captain or FO happened to be standing in the cockpit door saying good bye to passengers. I nodded as planned. He responded: “good book.” I smiled.

January 19, 2013

Useless reinterpret_cast in C++

Filed under: c++ code gcc programming — JeffPC @ 22:26

A few months ago (for whatever reason, I didn’t publish this post earlier), I happened to stumble on some C++ code that I had to modify. While trying to make things work, I happened to get code that essentially was:

uintptr_t x = ...;
uintptr_t y = reinterpret_cast<uintptr_t>(x);

Yes, the cast is useless. The actual code I had was much more complicated and it wasn’t immediately obvious that ‘x’ was already a uintptr_t. Thinking about it now, I would expect GCC to give a warning about a useless cast. What I did not expect was what I got:

foo.cpp:189:3: error: invalid cast from type "uintptr_t {aka long unsigned int}"
    to type "uintptr_t {aka long unsigned int}"

Huh? To me it seems a bit silly that the compiler does not know how to convert from one type to the same type. (For what it’s worth, this is GCC 4.6.2.)

Can anyone who knows more about GCC and/or C++ shed some light on this?

January 19, 2013

Serial Console

Filed under: console grub illumos openindiana serial solaris — JeffPC @ 22:16

Over the past couple of days, I’ve been testing my changes to the crashdump core in Illumos. (Here’s why.) I do most of my development on my laptop — either directly, or I use it to ssh into a dev box. For Illumos development, I use the ssh approach. Often, I end up using my ancient desktop (pre-HyperThreading era 2GHz Pentium 4) as a test machine. It gets pretty annoying to have a physical keyboard and monitor to deal with when the system crashes. The obvious solution is to use a serial console. Sadly, all the “Solaris serial console howtos” leave a lot to be desired. As a result, I am going to document the steps here. I’m connecting from Solaris to Solaris. If you use Linux on one of the boxes, you will have to do it a little differently.

Test Box

First, let’s change the console speed from the default 9600 to a more reasonable 115200. In /etc/ttydefs change the console line to:

console:115200 hupcl opost onlcr:115200::console

Second, we need to tell the kernel to use the serial port as a console. Here, I’m going to assume that you are using the first serial port (i.e., ttya). So, open up your Grub config (/rpool/boot/grub/menu.lst assuming your root pool is rpool) and find the currently active entry.

You’ll see something like this:

title openindiana-8
findroot (pool_rpool,0,a)
bootfs rpool/ROOT/openindiana-8
splashimage /boot/splashimage.xpm
foreground FF0000
background A8A8A8
kernel$ /platform/i86pc/kernel/$ISADIR/unix -B $ZFS-BOOTFS
module$ /platform/i86pc/$ISADIR/boot_archive

We need to add two options. One to tell the kernel to use the serial port as a console, and one to tell it the serial config (rate, parity, etc.).

You’ll want to change the kernel$ line to:

kernel$ /platform/i86pc/kernel/$ISADIR/unix -B $ZFS-BOOTFS,console=ttya,ttya-mode="115200,8,n,1,-" -k

Note that we appended the options with commas to the existing -B. If you do not already have a -B, just add it and the two new options. The -k will make the kernel drop into the debugger when bad things happen. You can omit it if you just want a serial console without the debugger getting loaded.

There’s one last thing left to do. Let’s tell grub to use the same serial port and not use a splash image. This can be done by adding these lines to the top of your menu.lst:

serial --unit=0 --speed=115200
terminal serial

and removing (commenting out) the splashimage line.

So, what happens if you make all these changes and then beadm creates a new BE? The right thing! beadm will copy over all the kernel options so your new BE will just work.

Dev Box

I use OpenIndiana on my dev box. I could have used minicom, but I find minicom to be a huge pain unless you have a modem you want to talk to. I’m told that screen can talk to serial ports as well. I decided to keep things super-simple and configured tip.

First, one edits /etc/remote. I just changed the definition for hardwire to point to the first serial port (/dev/term/a) and use the right speed (115200):

hardwire:\
	:dv=/dev/term/a:br#115200:el=^C^S^Q^U^D:ie=%$:oe=^D:

Then, I can just run a simple command to get the other system:

$ tip hardwire

September 4, 2012

Cycling

I got myself a bike in early May. It has been a long time since the last time I biked, but Holly and I thought that it would be fun to get bikes and ride around. I am a geek and so I have to do some stats tracking. Data collection is pretty easy with a phone since it has a (mediocre) GPS. Here are my findings about various ways to keep track of the data collected while biking.

Map My Ride

While at the bike store, we were told about Map My Ride. When I got home, I checked it out. I liked the elevation over time (for workouts) and over distance (for tracks), the per-week summary conveniently attached right next to the week in the monthly calendar view, and the idea of a leader board for each track. I’d say the major difference between it and the other sites I tried is the split between a route and a workout. A route is just the path, while a workout is a route and timing information. At first that sounded great, but it turns out that this split is utterly useless and lead to data loss for me. (The phone app lets you ride a route and it will associate the route with your workout instead of the default “create a new route from this workout.” Sadly, if you deviate from the route, the whole system gets very confused. It still makes the association and when you view the workout everything looks right, but certain parts of the website believe that you did exactly the route — no more, no less. If you try to edit the route, it obliterates your detailed time information.) I was willing to call that a quirk of the system and work around it (by always making a new route), but then I found out that the Wikipedia article: GPX export functionality exports only the route and not the workout. In other words, it does not let you get the detailed time information out of it. That is a deal breaker. I searched and it turns out that other people “complained” about this before. While I think that many of the people there had the wrong attitude, I couldn’t help but notice that it took the staff over two and a half months to respond with a essentially useless comment. Ow! Since I liked the interface enough, I thought that maybe I could live with using My Tracks on my phone to record the data, export it as GPX, and then import it on the web.

Couple of days later, someone happened to post a way to get a JSON encoded latitude, longitude, elevation, and time for every workout. I quickly grabbed the data, and whipped up a small Python script to spit out a minimal GPX file.

Custom Software

Initially, I resisted the temptation to write my own custom software to read in the GPS data. When I found out that Map My Ride did not let you export time information, I thought to myself how hard could it be? I had some GPX files I created using My Tracks, so I went and hacked together a quick script which spit out a 100 kB HTML file that used HighCharts to display them. A few observations I made during this were…

  1. One has to do something smarter than dumping over 100 kB of data into a HTML file otherwise the browser will have unacceptably slow response times.
  2. Having the GPX file is a great first step, but some post processing needs to be done to account for the variable accuracy of GPS. (I haven’t experimented with better GPS receivers.) If you do not, you will invariably end up with holes in you data (I’ve seen several 30-second intervals without any location updates), and worse yet random jumps from place to place when the GPS receiver changes its mind about where you are. This results in spikes in distance traveled between two location updates leading to huge spikes in speed.
  3. I should have prototyped my algorithms in R. While running the script and refreshing the page took only a couple of seconds, python doesn’t quite lend itself to the same algorithmic tinkering that R does. (Matlab would have worked too.)

Needless to say, after about 3 hours of playing around, I more or less gave up on the idea of making my own visualization.

Endomondo

I first found Endomondo back in January, when I searched the Android Market Place for an application that would record my GPS location over time. Endomondo is a sports tracker. The free app is pretty simple and straight forward. I think the website is less interesting than Map My Ride’s, but that’s to be expected since Map My Ride caters to cycling. Endomondo makes it easier to find what your best kilometer (or mile) is, while Map My Ride has much better elevation graphing and analysis. While Endomondo felt a bit less feature-full, it lets you export your workouts as GPX with all 4 dimensions.

I was just about ready to switch to it fully (instead of importing My Tracks-generated GPX files), when I heard of Strava during bike-to-work week.

Strava

I thought I would give Strava a shot in case it had more features than Endomondo. I was surprised. The user interface is very clean, and it definitely caters to cyclists (even though it supports other activities). You can view the elevation, speed, and power of a ride with either distance or time on the x-axis with a single click. Strava also differentiates between time and time spent moving and understands that bikes have mass. Strava also has the concept of a “segment”. A segment is a certain path and everyone that takes that path at any point in time will be put on a leader board for others to see. It is interesting to see how you compare to other people in the area.

The Strava android app had issues with Samsung Galaxy Nexus (after you start recording, when the screen blanks as part of the power saving configuration, the app exits), but within a week or two an app update fixed the issues.

Conclusion

My recommendation is either Endomondo or Strava based on what you primarily care about. If you prefer many different sports, I feel that Endomondo will probably work out better for you, while if you are more of a cycling or running fiend Strava is the way to go. Then again, you can sign up for both, and decide which one you like more.

Finally, when I want to just a generic GPS track (e.g., for geo-tagging photos from my camera), I use My Tracks and then export as GPX.

Powered by a pile of c