Wednesday, August 31, 2005


Flying Lesson #46

With the passage of Katrina, we had wind for the first time since April. I went with the instructor to Cobb County Airport-McCollum Field (RYY) to practice crosswind landings. We also did some VOR tracking.

Logged today: 1.6 hours dual in N4363D, with 5 takeoffs and 5 landings. Cost: $287.


Gas Prices

While driving home from the airport today, I noticed long lines of cars at several gas stations. I wondered why. I knew Katrina was expected to have some effect on gas supplies, but I hadn't heard about a serious crisis.

As I got near my home, I noticed the price for unleaded at the nearby station was $3.19 per gallon. The last time I bought gas, I think it was around $2.50, so that's quite a bump.

I haven't worried much about gas prices up until now. I live three miles from work, and one mile from the grocery store, so I only need to fill my tank once or twice a month. But experts are claiming that $4/gallon is coming, and if a fill-up costs more than $40, I'll definitely take notice.

I don't know what this will mean for aviation fuel prices. I burn about $35 worth of aviation fuel for every hour of flying lessons. Fuel is included in the cost of airplane rental, so I don't really worry about it. Rental prices may rise, or a fuel surcharge may be added.

Later that same day...

I figured all those people waiting in line were crazy. Nothing in the news indicated that we were in any immediate danger of running out of gasoline. But, my car only had a quarter of a tank left, so at 11:00 PM, I decided it might be prudent to go fill up while all those crazy people were going to bed.

The first gas station I visited, one mile away from my apartment, had no gasoline for sale. Uh-oh.

Around the corner was another gas station. Again, the pumps were shut down because the tanks were empty.

So I widened my search. The station three miles away had no gas. I checked another five miles away—no gas. At that point, I decided that I shouldn't waste any more gas looking for gas. I'd just need to conserve what I had, and wait to see what happened over the next few days.

I took an alternate route home, which I knew would take me past a few more stations. Lucky me: the fifth gas station had gas! There were a few people in line ahead of me, but I was able to fill up after a few minutes. And at "only" $2.90/gallon (20 cents cheaper than the prices at most of the places that had no gas).

A guy nearby announced to everyone that filling up his big pickup's tank had cost $110. It made me glad that I don't drive that gas-guzzling Mustang any more.

As I returned home, I passed two more stations which had no gas. So that's six out of seven gas stations without fuel.

I hope this was just temporary insanity on everyone's part. The thought of gas prices rising has never bothered me, but it never occurred to me that availability would be a problem. As I drove around looking for fuel, I thought about what I'd have to do if gas was unavailable for a few days. I could make the three-mile drive to work for a while, but I'd probably need to give up the 40-mile round trips to the airport for flying lessons. I also thought about what would happen if gas were unavailable for a week or more; that would definitely cause a change in my lifestyle.

This is going to make me think a little about each trip I make from now on. I've been keeping track of my car's mileage, so I know how far a tank will take me. I know the difference in mileage I get depending upon whether the air-conditioning is on or off. I may need to start planning my car trips with the same care I plan a cross-country airplane trip.

And I'm going to stop taking gasoline for granted.

Sunday, August 28, 2005


Sudoku Solver

Yesterday I ran across a kind of logic puzzle known as Sudoku. For more information, see the Wikipedia article about it. This type of puzzle is apparently becoming very popular among those who enjoy working puzzles in newspapers.

I have no interest in such puzzles, but I thought it might be fun to write a program that would solve them, and it would be a good chance to learn more about Ruby. So I went at it for a few hours, and wound up with a working program. It implements a simple brute-force depth-first search algorithm—I wasn't interested in doing anything clever. It solves the example puzzle from the Wikipedia article in about five seconds on my iMac G5.

If anybody is interested in playing around with it or improving upon it, it can be downloaded from (Of course, you will need Ruby installed to run it.)

As input, it takes a list of nine nine-character lines. Use the digits '1' through '9' to represent the givens, and the character '.' (period) to represent empty squares. For example, if you want to solve the puzzle from the Wikipedia article, create a file wikipedia_example.txt and give it these contents:


Then run the solve_sudoku.rb program, like this:

ruby solve_sudoku.rb wikipedia_example.txt

and you'll get this output:


I used test-first design, so a set of unit tests is included. This is the kind of very-simple program where I would normally be tempted to just dive in without doing any unit testing, but I'm glad I did this one test-first. I'm still learning Ruby, so I made several dumb syntactic mistakes, and it would have been very difficult to catch them if I'd tried to write the whole thing at once and then debug it.

By the way, using Ruby is a lot of fun. (Yes, Sean, I know you told me so.)

Friday, August 26, 2005


Flying Lesson #45: Second Dual Cross-Country Flight

Today's flight was from Dekalb-Peachtree airport (PDK) to Columbus Metropolitan Airport (CSG). On the return flight, we made a landing at Berry Hill Airport (4A0).

I was a little more comfortable with this trip than I was with the first cross-country, although it still felt a lot like doing my income taxes while riding a motorcycle.

Planning this trip wasn't too difficult. The only thing that made it complicated at all is that the Atlanta Class B airspace sits between PDK and CSG. For you non-pilots: "Class Bravo" airspace refers to the type of airspace that surrounds major airports. Each one is shaped a little bit differently, but in general there is a cylindrical volume centered around the airport, starting at ground level, and then there is a larger cylinder stacked on top of that, and another larger cylinder stacked on top of that. (Think of the shape of a wedding cake, turned upside-down.) To fly around a Bravo, the higher-altitude cylinders require you to fly farther out of your way, so it is common for small planes to stay low, beneath the wider cylinders above. To complicate matters, smaller airports can have controlled airspaces of their own beneath the overlying Bravo airspace. If you accidentally enter Bravo airspace without a clearance, the FAA can do Bad Things to you, so staying out of it is really, really important.

So, the challenge is to identify landmarks and navigational aids one can use to stay out of the Class B without unnecessarily lengthening the trip by staying too far out, and determining an altitude that is low enough so that you won't accidentally climb into the Bravo but high enough to avoid obstacles and underlying airports' airspaces. I planned several short legs to take me around the northern side of the airspace. In hindsight, this was a mistake—it would have been a lot easier to have just a couple of long legs, even if it meant the trip would be longer. There's enough to do on a cross-country flight without needing to change course every few minutes.

The weather wasn't bad. It was a little hazy, but ground temperatures were in the 80's, which seems nice in comparison to the 90+ temperatures I've had on all my flights for the past few months.

After we landed at CSG, the instructor expected that we'd need to pay a landing/ramp fee, but this FBO has adopted a new policy of not charging landing fees to people involved in flight training. We wanted to take the club car out to a restaurant for lunch, but someone else already had the car, so we ate the free chili dogs that the FBO provided. I got updated weather information and completed the plan for the return trip.

I went a bit off course on one leg. I didn't hold my heading well, and forgot to update my heading indicator as required, so I ended up about 10 miles from where I was supposed to be. However, I was close enough that I found the checkpoint without too much searching.

Along the way, the instructor threw a few challenges at me, like hood work, a diversion to an alternate airport, and then he got me lost to see whether I could figure out where we were. I got to practice short-field takeoffs and landings at Berry Hill airport, which I've visited before.

I experimented with my own new navigation log format. It worked out fine, but I'll tweak it a little before the next flight. I brought a small clipboard to hold my navlog, but I found that it got in the way too much. On the way out of the airport, I bought a tri-fold kneeboard to help me solve my cockpit-management issues.

It was a long day, but productive. We are making a night cross-country flight next week, and then I'll get to make my first solo cross-country after that.

Logged today: 3.3 hours dual cross-country in N4363D, with 3 takeoffs and 3 landings, and 0.3 hours simulated instrument conditions. Cost: $648.14.

Wednesday, August 24, 2005



A few weeks ago, I was grounded because the President was in town. Pilots are notified of such occurrences by Notices to Airmen, or NOTAMs. For an example of what such a NOTAM looks like, see the NOTAM describing the Temporary Flight Restrictions (TFR) for the Crawford, Texas area during the President's vacation.

This example shows the things I hate most about the FAA's electronic dissemination of information:

This format was in vogue for computer systems in the 1960's and 1970's, but seems pretty archaic today. I know there are some facilities out that rely on ancient equipment that can't handle cutting-edge features like lower-case letters or baud rates above 300, but can't we just give each of those facilities a few hundred bucks to buy a low-end PC?

I'm not complaining about the jargon or abbreviations or technical language—those things have their place. There are several pages of this stuff to wade through every time I get an electronic DUATS briefing, and it just hurts my eyes to read it.


Ground Lesson #15

We couldn't fly, due to a 1,200-foot ceiling. We spent the time reviewing airplane systems and airspace regulations.

Cost: $114

Saturday, August 20, 2005


Apple Extends iMac G5 Warranty

Apple is extending the warranty period on early iMac G5 computers, due to power and video issues.

It's a good thing that Apple is finally admitting they have a problem, but I suspect the effort I'd have to expend to get a refund on what I spent to get my iMac fixed is more than I want to expend.


Intelligent Design

See this article or this article.

And also this one.

Friday, August 19, 2005


Flying Lesson #44

There's really nothing in the lesson plan until my next dual cross-country flight, which we couldn't schedule until next Friday, so I made another solo flight today. It was cut a little short due to precipitation moving into the area, but it was still enjoyable.

I made a dumb-student-pilot mistake when returning to the airport. I was told to report on a three-mile base, but I didn't do exactly what was expected, and the controller didn't realize where I was. As a result, I was on short final behind another plane which had just completed the "stop" part of a stop-and-go. When the controller realized where I was, he ordered the other plane off the runway immediately. I did a go-around. Nobody yelled at me, but after discussing it with my instructor I know the confusion was entirely my fault. My apologies go out to the poor pilot who had to clear the runway. Now I know what a three-mile base is.

Logged today: 1.2 hours solo in N4363D, with one takeoff and one landing. Cost: $125.83.

Wednesday, August 17, 2005


Flying Lesson #43

Again, solo flight in the practice area. I returned to the airport early to do some pattern work, soft-field takeoffs in particular.

I like the solo practice. This is the fun part of flying. I could practice steep turns and ground reference maneuvers all day, not caring whether I'm making "progress" toward any goal. I read one person's account of his long struggle as a student pilot: finances and other problems led to him being a student for a few years, eventually getting his certificate after 120 hours. He said the long wait wasn't really that bad, because once he had his solo endorsement, he could do practically anything that a private pilot can do, except carry passengers. So if all you want to do is fly around a few times a month, there's no rush to get the certificate.

Logged today: 1.8 hours in N4363D, with 5 takeoffs and 5 landings. Cost $188.75.

Monday, August 15, 2005


Cocoa Programming with Python and Ruby

For the past eight or nine years, most of my work has involved writing Windows programs in C++. As a result, I am thoroughly sick of the Windows API, Windows development tools, and the C++ programming language. In my off hours, I play around with UNIX programming and other programming languages, but I generally have to stick to non-GUI programs due to the lack of good graphical libraries on UNIX (yes, it's true—don't tell me how great Tk or wxWindows or GTK+ or any of those other things are—they all suck).

Apple's Cocoa stuff is nice, but I don't like Objective-C much. It's an ugly mixture of C and Smalltalk. So I'd like to play around with Cocoa, but I want a different programming language.

Apple has published a Developer Connection article about developing Cocoa apps with PyObjC, the Python/Objective-C bridge. The author of the article has some additional information in his blog, including some videos demonstrating how to carry out the Interface Builder steps.

PyObjC is something I've wanted to look at for a while, but I haven't had the time. More interesting to me is the RubyCocoa bridge, but I got a bunch of errors when I tried installing it. I'd like to figure out why my system doesn't like it, but again, I need to find some time.


Magic Buttons

Today's The Daily WTF shows somebody's implementation of an onscreen pushbutton that does something different depending upon whether the user single-clicks it or double-clicks it. It reminds me of one of the more frustrating programming assignments I've had.

With a desire to leap-frog the competition, my employer had hired a user-interface designer (or human-factors expert or user-psychologist or something like that) to design our next-generation applications. This guy spent a few months observing users of our existing systems, and generated over a thousand pages of observations and theories about how the applications would best serve the users. After generating this monstrous stack of data, he designed a user interface that he felt would be very efficient and easy-to-use.

This was in 1994, when most people, even those in the computer industry, had never used Mac OS, Windows, OS/2, the X Window System, or any other graphical mouse-driven user interface. This guy had seen them, but did not try to follow their standard conventions. I never knew if this was due to arrogance or ignorance; I suspect both were at play.

His design called for us to use the standard UI button widgets provided by the operating system (OS/2), but they would react as follows:

I had a couple of big problems with this. First, I'd been a Mac user since the 80's, and knew the importance of simplicity and consistency. When I argued that this arrangement was inconsistent with the way that users expected buttons to work, I was told that the users had never seen any graphical user interfaces before, so they wouldn't have any expectations and thus would not be confused by this behavior. It would be a simple matter of training, I was told. This was an enlightening experience—it was the first time I ever suspected that I might know a lot more about software design than my bosses did.

The second big problem was that the UI library we were using to implement the application weren't designed to handle double clicks and right clicks on buttons. (After all, what kind of idiot would need to do that?) So it took all sorts of hacking to implement this functionality on top of that library. Today this wouldn't bother me as much, but back then, as a junior programmer, hacking around the limitations of a library made me very nervous that the whole thing would come crashing down some day.

We finished the application. The results were disappointing. This was the first major GUI application our company had developed, and users hated it. They were confused. It made no sense. So the company curtailed its development of GUIs for a while, deciding that the world wasn't ready for graphical user interfaces yet. It was only when Windows NT 4.0 appeared a few years later that we were able to write any new GUI applications.

The lesson is simple: a button should work like a button. If you want something that doesn't work like a button, don't use a button.

Management eventually listened to the programmers, and the UI designer was let go. That was another first for me: the first time I was glad to see somebody get fired. There hasn't been a second time.

[UPDATE (2005/8/31): There is another related Daily WTF, this time about changing button colors. At least I was smart enough to base my button's color on the internal program state, rather than the other way around.]

Sunday, August 14, 2005


Geeks and Flying

In a comment to my last post, Chris asked "I wonder why so many pilots are programmers." I have a few readers that fit that category, which is to be expected based upon the content I generate. In other aviation-related forums, I notice a lot of IT people, so there does seem to be some correlation between interest in computers and interest in flying.

One explanation is simple economics. Flying is an expensive hobby. Programmers make better-than-average money, so you see lots of programmers flying for the same reason you see lots of doctors, dentists, lawyers, and business-people flying.

But there is more to it than that. Aviation is a great area for technophiles to study. Aerodynamics, electronics, radio, radar, GPS, flight computers, satellite maps, composite materials, weather, air-traffic-control systems—there is a lot of science and gadgetry at play. For those with a drive to learn how stuff works, aviation provides a never-ending supply of stuff to study. For those who just like playing with knobs and buttons, there are plenty of those too.

Underlying it all is a fundamental trust in technology and our ability to master it. It doesn't scare or mystify us. Unlike a lot of airline passengers, we don't just cross our fingers and hope somebody sprinkled enough fairy dust on the wings to keep them levitating in the air. We study the machines, we learn how they work, we test their capabilities, and we have the confidence that if something goes wrong, we'll figure out how to handle it.

Finally, being a pilot makes a geek feel really cool.

Saturday, August 13, 2005


Welcome New Readers

According to FeedBurner, the number of people subscribed to my blog feed has leaped from 10 to 16 in the past few days. A 60% increase is nothing to sneeze at, but with such small numbers, I'm not sure whether it is "real" or not.

Determining an exact number of readers for my blog is problematic. I don't know how many of those 16 readers are real people reading my feed, which are bots, and which represent the same person reading from multiple computers. I also don't know how many people are subscribed to the Blogger-supplied feed instead of FeedBurner feed, and I don't know how many people read the blog via a web browser instead of a news aggregator.

Anyway, I wanted to take this opportunity to welcome (or re-welcome) everyone reading my blog. I'd appreciate any comments telling me who you are and why you are interested in this blog.

Friday, August 12, 2005


Flying Lesson #42: More Solo Practice

Today was a day with great visibility, but the typical scattered afternoon thunderstorms were forecast. We looked at the radar, and there were a few little spots of precipitation here and there, but it was clear enough for the instructor to let me go on a solo flight in the practice area.

The plane hadn't been refueled since its previous flight, so I learned how to call the FBO to get a fuel truck to come top off the tanks. The process was as interesting as it sounds.

There were a few dark clouds, but I didn't encounter any weather problems. I practiced imminent stalls, steep turns, slow flight, turns around a point, and S-turns. The airport was pretty quiet when I got back, which was a pleasant surprise—it can get pretty hectic on Friday afternoons.

Logged today: 1.5 hours solo in N9103M, with one takeoff and one landing. Cost: $157.29.

[Update: The instructor called the following day to tell me that I forgot to tie down the plane after parking it. Oops. I did put the wheel chocks in the right place, so the plane wasn't going to roll away.]

Thursday, August 11, 2005


Just When I Thought That I Was Out...

I thought I was finished with the coin acceptor. We can insert 1-Euro and 2-Euro coins, with a better than 95% acceptance rate. One of the hardware guys came over and installed a newer model of the acceptor, and it worked too. I had mentally checked "coin acceptor" off my list of worries.

Then, in the late afternoon, another programmer comes into my office with more coins to test. But they aren't 1-Euro and 2-Euro coins—they are 5-cent, 10-cent, 25-cent, and 50-cent coins. "They told me to test these too. These will work, right?" he asked.

No! Of course they won't work. The documented requirements were that the coin acceptor should accept only 1- and 2-Euro coins, so it accepts those and rejects the rest. It's not supposed to accept anything smaller than 1-Euro.

Or is it? After some checking with the higher-ups, it turns out the answer is "maybe." Apparently somebody promised a French customer that smaller coins would be supported.

It was a surprise, but it won't really a big deal if "maybe" turns to "definitely." Enabling acceptance of the smaller denominations should be easy, and I can probably hand that work off to somebody else. The bigger issue is that this vending machine has never had to deal with amounts smaller than a whole dollar or whole Euro before, so some testing and tweaking will be needed to verify that all the displays and printed reports handle fractional amounts properly. The software has always done its internal accounting in cents, so we don't expect problems, but you never know what problems will arise with something like this.

Technical issues aside, it is going to be annoying if the machine has to accept different sets of Euro coins in different countries. Everybody is going to be confused, and I'm going to be fielding a lot of bug reports saying that such-and-such coin isn't working in such-and-such country. It would actually be easier for me if each country had a different currency.

By the way, if you were wondering, one one-hundredth of a Euro is officially called a "cent," or "Euro cent" if you need to avoid ambiguity. I understand that Europeans use many slang terms to refer to them; I'm using a few terms of my own.


Never Comment-Out Code

I work with a lot of "legacy code," meaning software that was written a long time ago by other people and which has undergone a lot of changes in its history as the requirements have changed and as different people have worked on it. There's a lot of stuff in there that I don't like, but I generally have respect for what other people have done.

However, one thing that drives me bananas is when I see a function like this:

void Application::DisplayErrors()
// This function is no longer used.  Errors are displayed by the ErrorHandler.
//  if ( ! errors.IsEmpty() ){
//    for ( int i = 0; i < errors.Count(); ++i ){
//      Display( errors[i] );
//      }
//    errors.Clear();
//    }

The "//" characters that begin the lines turn them into comments, lines that have no effect. In this example, every line has been "commented out," and a comment added informing the reader that the function doesn't do anything.

I hate it when people do this. If the function doesn't do anything, it should be deleted, not simply rendered harmless. Some programmers want to leave the old code there in case it might be needed again someday, or as some sort of historical record of how the code used to work, but cruft like this just makes programs harder to read and harder to modify.

The problem is not just that the useless function a waste of screen space and reader attention. Somebody reading another portion of the code might see a call to DisplayErrors() and assume that it will cause errors to be displayed. They may even add a call to DisplayErrors() when they implement some new functionality, and then be stumped for a while when errors don't get displayed.

If code isn't needed, have some guts. Delete it. Don't be afraid. You can always get the old code from the version-control system if you need it again. And nobody cares how the code used to work.

(By the way, the brace-indentation style in that example drives me bananas too. But that's a rant for another day.)

Wednesday, August 10, 2005


Using the Rake Build Language

Martin Fowler has a good article about using Rake, the Ruby library that provides similar functionality to that of Make or Ant/NAnt. The ariticle focuses on the value of using a real programming language to control your builds, as opposed to crippled domain-specific languages like Make and Ant.


Flying Lesson #41

The airport was surrounded by thunderstorms, but the airport itself was clear, so the instructor and I went up in the pattern to practice short-field and soft-field takeoffs and landings. We made four trips around the pattern before I decided to call it quits due to the appearance of rain on the base leg.

We were able to land, park the plane, and get inside before the downpour started.

Logged today: 0.7 hours dual in N9103M, with 4 takeoffs and 4 landings. Cost: $164.60.


Kris Eats Crow

Remember last week, when I complained about the unreliability of the coin acceptor, insisting that it must be a hardware problem because I had done everything possible in software to improve the situation?

Well . . .

A Big Meeting had been scheduled to determine what to do to move forward. In preparation, I wanted to gather extensive statistics on exactly how often the coin acceptor rejected coins, which years and countries of origin had the worst rejection rates, and other stuff like that. The coin acceptor vendor had been asking for such information as well, but I'd been putting it off because I'd already decided it was not my problem, and the hardware guys should deal with it.

I had only been given one Euro coin for my testing. So every time I tested the coin acceptor, I'd drop this coin in, then open the machine, wave my hand around in the coin hopper to find the coin, take the coin out, and then close and lock the machine before inserting the coin again. Thus, it took several seconds for each coin insertion test. I decided this was impractical, and begged for some additional coins. I was given ten more coins, five 1-Euro coins and five 2-Euro coins, giving me a total of eleven coins. I was forced to sign a receipt for the coins, as if they were afraid I'd run off to Europe with my 17-Euro fortune.

I started feeding the coins in one after another, and an interesting pattern emerged. The first one was accepted, the second was rejected, the third was accepted, the fourth was rejected, and so on. It wasn't perfect, but in general, acceptances and rejections alternated. Hmmm, that's weird. I had never seen this before, doing only one coin at a time. Now it made sense that the QA guy was seeing a 50% rejection rate on his machine—he was feeding coins in rapidly as well.

On a hunch, I put a coin in, which was accepted, then I waited ten seconds before dropping in another. It was accepted. It turned out that if I waited ten seconds between insertions, I got a 100% acceptance rate. There was apparently a period of a few seconds after acceptance of a coin when the coin acceptor would reject a subsequent coin.

A possible cause hit me right away. After acceptance of a coin, the machine calculates the new customer balance, then sends a new set of enable/disable commands to the coin acceptor telling it which coins it should accept. For example, if the machine is at the maximum balance, acceptance of all coins will be inhibited; if the machine is one Euro below the maximum, then we will accept a one-Euro coin but not a two-Euro coin. I suspected that sending these commands after every coin acceptance was somehow temporarily inhibiting acceptance.

So I changed the application code to make it stop sending all these commands. Sure enough, when I started pumping coins in again, they were all accepted. The coin acceptor was working perfectly.

I shared my findings with others in the company, inviting them to beat me with a baseball bat after wasting their time with my claims of bad hardware. I also shared my findings with the vendor, but they say that the coin acceptor should work fine even if those commands are sent after each acceptance, so I've still got more work to do to get to the bottom of it.

Lesson learned: When testing a coin acceptor, have a lot of coins on hand. I've been investigating this issue for a few weeks, but as soon as I got a handful of coins, the problem became apparent in just a few minutes.

I'd like to place all the blame on the guy who originally wrote this code, but I can't. The clues were there all along, and I just didn't put them together. I'd also like to blame the guy who decided to give me only one coin, but I should have insisted on receiving more coins sooner.

It was only when I got serious about proving it to be a hardware problem that I discovered it was a software problem after all.

(I'd like to balance this post by also describing something incredibly smart that I've done lately. Unfortunately, nothing comes to mind.)

Saturday, August 06, 2005


Today I looked at the iTunes Music Store, and noticed that the #8 top downloaded song is Journey's "Don't Stop Believin'".


I watch a lot of TV, and work with a lot of people younger than I, so I have been pretty good at keeping up with pop culture even as I grow older. But I'm stumped by this. Has something happened recently that brought this oldie back into popular conciousness? Or am I just more out of touch than I thought?

Is it cool for me to admit I saw Journey live? Twice?

Friday, August 05, 2005


Flying Lesson #40: Dual Cross-Country

Today I had my first dual cross-country flight, from PDK to CHA then to RMG and back to PDK. It was a long day, and I'm very tired.

The instructor and I had lunch together at the Downwind restaurant at PDK. The instructor taught me a valuable rule: two pilots flying together should never eat the same thing for lunch. This reduces the possibility of both pilots simultaneously suffering some sort of food-related ailment in the air.

Another instructor joined us for the ride. He wanted to see the other airports and the route for himself before taking his students along. Takeoffs felt a lot different with the extra weight in the back seat—this is the first time I've flown with anyone back there.

The first part of the flight didn't follow the plan. We had thunderstorms north and northwest of PDK, so after studying the radar before the flight the instructor improvised a path around them. The flight to CHA was uneventful after that. Visibility wasn't bad, and I had no problems finding the checkpoints after we got around the storms.

The FBO at CHA was a pretty nice place. The instructors watched TV in the lounge while I did the planning for the return trip to PDK, using updated weather data. It took me a lot longer than it should have to finish that plan, due to fatigue and a few dumb mistakes I'd made last night when pre-filling some of the lines (some of the headings I'd written down were 90 degrees off). Radar showed a couple more lines of storms between CHA and PDK, but there was a hole that looked navigable, so we set off on the return trip. Visibility was bad (around 3-4 miles), but we didn't encounter any rain or turbulence. When we got to RMG, the instructor pulled to power to simulate a forced engine-out landing, and I didn't handle it well. So we did two more approaches to that airport, with the instructor pulling the power each time, and I kept turning too wide to make the runway without power. Finally, I just made a normal landing, and then we departed for PDK. I don't know why I screwed up so badly; it must have been fatigue.

We got back to PDK at a little before 8:30 PM. I got to see the airport's lights for the first time, which was pretty cool. However, it was still officially a "daytime" flight, because of the FAA's rules about when night really begins.

My planning worked pretty well. It was surprising how the checkpoints kept showing up right in front of me and passing under the plane right at the minute they were expected. I actually had trouble finding a couple of them because, while they were right in front of me, they didn't become visible until they were under the nose of the plane. The only thing I really did wrong in planning was to place my first checkpoint for each leg to far away from the airport. The instructor suggested always having a first checkpoint within sight of the airport, so that no matter what runway you end up taking off from or what sort of pattern the controllers make you fly, you'll always be able to get to that first checkpoint and then know the exact course to the next one.

While the plan was a good one, I had some trouble following it and recording progress. The nav log form has too many columns and numbers on it, making it hard for me to figure out where to read and write things while flying while also shuffling the charts and other pieces of paper in my lap. It functions both as a worksheet and as an in-flight reference, and is just too busy. The computer user-interface designer in me wants to design my own forms.

I felt overwhelmed throughout the flight, even while "relaxing" at the office in Chattanooga. There was a lot of new experience thrown at me today. None of it was unexpected, but actually doing it all for the first time was surprisingly nerve-wracking. I was continuously scanning for traffic, looking for checkpoints, checking and re-checking the chart, checking and re-checking the nav log, writing things down, doing arithmetic in my head, switching radio frequencies, and so on. I know it will get easier with practice.

A couple of days ago, I read another student pilot's account of his cross-country training. He thought it was pretty easy. Of course, he didn't fly in any controlled airspace, never filed a flight plan, didn't use flight following, never communicated with an approach controller or flight service specialist, had unlimited visibility for each flight, just did a touch-and-go at each airport, and flew an identical route for all his dual and solo cross-country flights. I suppose it would be pretty easy under those circumstances, but I think he got cheated out of some valuable training. I'm not going to complain that mine was more difficult.

Logged today: 3.2 hours dual cross-country in N4363D, with 3 takeoffs and 3 landings. Cost: $631.95.


Cross-Country Flight Planning

Tomorrow is my first cross-country flight, so I've spent the last couple of hours doing the planning for the trip. It's a little like doing one's income taxes, except it is more tedious and cheating doesn't help you. There are software applications that automate this task, but we student pilots are expected to do it the old-fashioned way, with pencil and paper.

You start by drawing your flight path on the chart (what most people would call a "map"). The naive thing to do would be to just draw a straight line from my home airport, Atlanta/Dekalb-Peachtree (PDK) to the destination airport, Chattanooga (CHA). The problem with taking that approach is that there is a whole lot of nothing between PDK and CHA. Without any landmarks, I wouldn't know how far along I am or how far off course I might be. I could rely on radio navigation systems, but the point of VFR cross-country training is to learn to use pilotage (comparing what you see with what's on the chart) and dead reckoning (calculating where you should be based upon heading, speed, and time). So I picked a few mountains, lakes, and airports to fly over, all spaced closely enough together that I'd be unlikely to be unable to find the next one or find my way back to the last one at any time.

One annoying thing about a trip from Atlanta to Chattanooga is that you have to fly across the edges of the chart. The northern part of the area is on one side of the paper and the southern part is on the other side, so you have to flip back and forth to see the whole flight path, and go through a few geometric contortions to measure course and distance across the edge. Luckily, I have a second copy of the chart, so I could just lay the two opposite sides next to one another.

Once you have all the "checkpoints" picked out, you draw straight lines between them. Then you fill out a large tabular form called a "navigation log," which has one row for the path between each pair of checkpoints. For each pair of checkpoints, you use the chart and the plotter (a combination ruler-protractor) to fill in the following columns:

Then, for each airport to be visited, you write down all the associated radio frequencies (ATIS, tower, ground, approach, flight service) so they will be at hand when you need them.

That's all I've done tonight. Tomorrow morning, when I get updated weather forecast information, I'll have to fill in the following columns for each checkpoint:

I'll describe the calculations. Consider an example: say you are flying from your home airport to another airport that is 240 nautical miles due north, and your airplane flies at 120 knots. If there was no wind, then the calculations would be easy: you head due north, the flight will take two hours, and so you'll burn two hours' worth of fuel. However, what if there is a 30 mile wind coming from the west? You wouldn't want to point the plane due north, because the wind would blow you 60 miles to the east during the two hours in the air. Instead, you'll need to point the nose left of true north to offset the drift. If you point the nose to the left, you'll be heading into the wind a bit, so your speed over the ground (groundspeed) will decrease.

Doing a quick calculation with the E6B flight computer (you'll have to trust me that it was quick), we find that we would have to point the nose 14 degrees left of due north to maintain a true-north course. This is called the wind-correction angle (WCA). The true heading will be 346 (360 minus 14). Our groundspeed would be only 117 knots, so the trip would take two hours and three minutes instead of just two hours. That extra three minutes isn't much in this example, but if the wind was stronger or coming from more of a northerly direction, it could have a significant effect on groundspeed and fuel usage.

We've figured out the true heading (TH), but we haven't really figured out which way to point the plane yet. The magnetic north pole is not at the same place as the geographic north pole, so if we want to use a compass we have to take into account the difference between magnetic north and true north. This is called variation, and for the area between PDK and CHA, the variation is about three degrees west. So we add three degrees to our true heading to get the magnetic heading (MH), which would theoretically be the heading we want our compass to show.

But wait, that's still not it. A compass is affected by electromagnetic fields in the plane and other imperfections, so we have to factor in the compass's deviation. There is a small card attached to the compass in the plane that gives the deviation, so we can't really write down the final compass heading (CH) until we get into the plane.

So, we do all those steps for every checkpoint in the navigation log. I've got six checkpoints for my trip up to CHA, and six different points for the return trip, where we'll do a touch-and-go at Rome (RMG) to make it a three-leg cross-country trip. In addition to these checkpoints, I also have to calculate the "top-of-climb" and "top-of-descent" points for each leg, which are the points where I'll reach my desired cruise altitudes and start my descents, respectively. I have a total of nineteen rows in my navigation log.

After you fill in all the rows, then you add things up to get the total distance, total estimated time enroute, and total fuel consumption. If total fuel consumption is greater than total fuel capacity, then you have a problem.

When I've finished all these calculations, we'll get in the plane and know exactly what headings to fly and how fast we'll get to the destinations, right? Wrong. The calculations are all based on forecast winds, which won't match the real winds, and on ideal aircraft performance. So while flying, I'll be keeping track of what time we reach each checkpoint, and calculate the actual groundspeeds. If we get blown off course I'll have to adjust my wind-correction angles accordingly.

After my trip, I'll post the nav log to give everyone a better idea of what it looks like. Tonight, I need to get some sleep.

Wednesday, August 03, 2005


Ground Lesson #14

We had good weather today. In preparation for our upcoming cross-country flight, the instructor wanted me to plan a short three-leg trip. We would fly it as if it was a real cross-country flight, except we wouldn't land anywhere and I would just simulate the calls to the flight service station and approach controllers.

After doing all the planning (calculating courses, wind correction, groundspeeds, fuel burn, etc.), we found out that no planes were available today. The plane I would have been flying was found with a dead battery this morning, and they hadn't been able to replace it yet. The other planes were in use or undergoing maintenance.

So, we spent the rest of the lesson time going over to the maintenance hanger and looking at some partially disassembled airplanes. One Warrior undergoing a 100-hour inspection had the cowling removed, so we looked at all the stuff inside the engine. The instructor also removed a couple of the inspection panels on the undersides of the wings so that I could see the internal structures and the aileron control linkages. There was also a Seminole jacked up for work on its landing-gear.

Cost for today: $114

Tuesday, August 02, 2005



Two years ago, when I first worked on my company's vending-machine product, I was assigned to add some reports. The machine has a small printer inside that can be used to print information on sales, inventory, events, and other data stored in the machine. The reports I implemented have some sections that look something like this:

Count Value
$1 Bills: 23 $23
$5 Bills: 15 $75
$10 Bills: 8 $80
---- -----
Total: 46 $178

See those "----" and "-----" lines used above the sums? Eeearrgh! Those are ugly and amateurish. Every time I see those, I cringe. I'm ashamed. I have some excuses: we were working fourteen-hour days, I wasn't familiar with the codebase, and I always intended to go back and fix them when I had time. But still: eearrgh!

During a demo, one of the vice presidents actually suggested that I help the "junior programmer who did these reports" figure out how to draw nice-looking lines. When I sheepishly told him that I was the one who had done it, he didn't believe me.

Today I had to make some modifications to those reports, so I took the opportunity to finally undo my two-year-old sin. The reports now have honest-to-goodness solid horizontal lines, drawn using Windows GDI calls instead of an ASCII approximation, like this:

  Count Value
$1 Bills: 23 $23
$5 Bills: 15 $75
$10 Bills: 8 $80
Total: 46 $178

It made me feel good. As is usual with the really annoying long-term problems like this, it only took about five minutes to fix it.

I wonder which of my current mistakes I'll be fixing in August 2007.


Mighty Mouse

Apple finally has a multi-button mouse. Of course, it does a whole lot more than a typical multi-button mouse.

If they make a Bluetooth version, I may buy one. But I'm not spending $50 on a corded mouse, no matter how much it looks like an iPod.

Monday, August 01, 2005


A Euro Is a Euro Is a Euro (Or Not)

Even after setting lower security levels on our coin acceptors, we still have about a 20% rejection rate on valid coins, meaning that about 1 out of 5 times that we put a coin in, it falls out the coin return slot. I notified the coin-acceptor vendor of our problems, who passed along the information to the manufacturer.

The manufacturer responded quickly, which was nice. The problem, he says, is that Europe has fifteen different factories that manufacture Euro coins, with varying quality, materials, and manufacturing tolerances. (The factories in Belgium and Italy are the worst, he said.) Because of the variations in weights and electromagnetic properties, programming their coin acceptor to handle every possible valid coin has been challenging. He asked whether I could send him some of our troublesome coins so that they could improve their coin acceptor.

He noted that the one-Euro and two-Euro coins are the most problematic, because they are made of two different metals. Our vending machines are designed to accept exactly two different denominations of coins: I'll let the reader guess what those are.

It was interesting information, but not very helpful. My company's options seem to be (a) just ship machines with these coin acceptor and deal with all the complaints, or (b) find a better coin acceptor. This seems like a hardware issue to me, but I'm still stuck with it.

By the way, my entire job isn't about dealing with coin acceptors (although it does seem that way to me sometimes). I'm sharing all the details of one isolated task, as an example of all the crap that we go through when a new product is launched. I won't rant about the problems with our supposedly-uninterruptible power supply, or getting our user interface translated into a couple of foreign languages, or connecting a modem to the European telephone system, or redesigning sales reports for different currencies, or interfacing with retailers' cash register systems, or . . .


Optimization by Hacking on GCC

Today's ridiculous fish demonstrates how Real Programmers optimize their applications: they customize the compiler.

This page is powered by Blogger. Isn't yours?