31days until
Dragon Con 2014

Blog


An interesting (to me) version control scenario

posted Apr 27, 2014, 8:20 AM by Lewis Baumstark

I'm thinking about toying with the idea of maybe doing some hacking on the Arduino IDE.  So I made a local clone of their public Git repository:

git clone git://github.com/arduino/Arduino.git

So far it's pretty basic stuff; from here I can hack on the codebase, commit my own changes, etc.  Importantly, I can keep my local copy of the codebase up-to-date with changes from the official site via a

git pull

as the official site is listed in my config as the origin remote site.  What I can't do is push my changes (via a get push)  to the official site since I don't have write privileges there (and for good reason!)

Since I'm looking at adding new features, I'm going to create (and move to) a new branch (named "windshield" for mysterious reasons) in my local repository:

git checkout -b windshield

Still pretty basic.  From here on, any changes I make will be part of the windshield branch and won't pollute the master branch until I merge them.  This should help with pulling official updates as well.

Now where it gets weird is I want to back up my changes to a different remote repository, one hosted at my workplace (it is, after all, a work-related project).  So first I set a new remote named "uwg" that points to the arduino-windshield project I created at our Gitlab site, and then set the local windshield branch to push its changes to that remote:

git remote add uwg git@code.westga.edu:lewisb/arduino-windshield.git
git branch --set-upstream windshield uwg/windshield

Now, as long as I am working on the windshield branch on my local machine all my commits will go to my work repository when I issue a git push.

My lame attempt to rationalize a plot convenience in Half-Life

posted Feb 23, 2014, 6:32 PM by Lewis Baumstark

Half-Life 1 and 2 rank among my all-time favorite video games.  HL1, especially, has a great story, which is hard to pull off in a first-person shooter.  Being a science fictional setting, there's a lot of fantastic stuff that requires suspension-of-belief: murderous monsters, teleportation portals, alien worlds, futuristic technology, and the fact that all the scientists at Black Mesa have the same face and voice.  Given all that, there was one that actually bugged me: the fact Gordon Freeman, the protagonist, could carry several hundred pounds of weapons and ammo and run sprints without breaking a sweat.  To recap, by the end of HL1, Gordon is carrying:
  • a crowbar
  • a 9mm Glock pistol
  • a .357 Magnum
  • a pump shotgun
  • an MP-5
  • grenades
  • satchel charges
  • trip mines
  • a shoulder-mounted rocket launcher
  • a crossbow
  • a Gauss Gun (fancy-schmancy future laser shootie thingie)
  • a Gluon Gun (more fancy-schmancy future tech); for encumbrance purposes it is notable that the Gluon Gun basically resembles a Ghostbuster's Proton Pack: a heavy backpack with what looks like a fireman's hose running to a hand-held nozzle that sprays an arm-sized stream of death before it.
  • the Hive-hand (organic alien gun that shoots an infinite stream of bees.  OH NO BEES!)
  • Snarks (suicidal exploding alien crabs that chase after people)
  • plus enough ammo to fill a shopping cart

Not content with "it's just a game, stupid" my brain has rationalized how one Navy-Seal-turned-high-energy-physicist could carry all this, and what's more, it's actually a major plot point.

The key is the HEV Suit.  If Gordon Freeman is the archetypal hero of myth, the HEV Suit is his magic armor.  It protects him from injury, aids healing, allows him to run faster, keeps track of vitals and ammo, talks to him in a friendly robo-feminine voice, and even has a handy flashlight.  It is what sets Gordon apart from other actors in the game, what gives him power beyond mere mortals.

And it's why the military is after him.

We are told in the beginning that the HEV suit is merely work clothes, something a third-tier physicist wears while doing the grunt work for the Big Name scientists at Black Mesa, all the while hoping he'll be listed as fifth contributor on a journal paper or three.  That just what we're told.  In reality, it's a prototype military exo-suit, outfitted with advanced technology gleaned from Black Mesa's dalliance with portals.  Specifically, it uses portal-based technology to create extra-dimensional "pants pockets" where Gordon can stash his arsenal without being encumbered.  Doctor Who would be proud, possibly even jealous.

It's pretty clear the suits are rare:
  • Early in the game, when Gordon gets his suit, the storage area suggests there are only 2 others (both, however, are missing).
  • The only others we see are on dead adventurers that were sent into the Xen border-world ahead of Gordon.  Perhaps these were the ones missing from the locker room?
Given how powerful the suits are, it's no wonder the military wants them.  And it's quite possible Gordon has the only one left on Earth.  So when the soldier come in and start murdering scientists left and right, they aren't just securing the facility and erasing every trace of Black Mesa's existence.  They're also after control of all the cool weaponized tech -- including Gordon's HEV suit.  I mean, they wouldn't want him getting away and selling it to Aperture Science, now would they?  And in the end, they get it, or at least, the G-Man gets it when Gordon agrees to be his flunkie and go into suspended animation for 20 years while the Combine invade and enslave us all.

Fortunately the other Black Mesa survivors (likely Dr. Kleiner or Dr. Vance) were (conveniently) able to re-build a new HEV prototype just in time for Gordon to re-awaken in HL2.  At that point the world is already conquered by forces with much cooler toys, so Gordon is pursued less because he's wearing a mechanical orange jumpsuit and more because he's a frickin' Buck Rogers, a legendary hero come back from the dead to lead us out of slavery.  If he doesn't hog all the medkits, that is.

Ruby: make a dummy class (for testing purposes) from a module

posted Jan 19, 2014, 6:49 PM by Lewis Baumstark

I'm not ashamed to admit Ruby messes with my head.  I'm pretty much an ice-cold master of C, Java, and (mostly) C#, but I feel I've only scratched the surface of Ruby.

So my trick of the day comes from trying to think up a way to unit test a Ruby module with non-module methods, meaning it has to be mixed-into a class before those methods can be called and tested.  My first pass was simply to write a throw-away Ruby class that mixed-in the module.  But then I though, why not make a function that works for any module?

So I actually wrote two functions:
  1. one that creates a custom class from the module, basically a "class-ified" module
  2. one that creates an object of that class
Here's the code for the first one.  All it does is create the new Class object, passing as its body an include statement for the module.

def dummy_class_from mod
    Class.new { include mod }
end

And the second, which simply calls new on the class created from the previous function:

def dummy_instance_of mod
    dummy_class_from(mod).new
end

Firefly and User Interface Design

posted Dec 16, 2013, 6:10 PM by Lewis Baumstark

People who know me know I'm a fan of Joss Whedon's short-lived TV show Firefly.  I was thinking about one episode in particular today, titled Out of Gas [Spoiler warning: link goes to plot synopsis].  Their spaceship is dead in the water, er, space.  Captain Malcolm "Mal" Reynolds divides the crew into the two short-range shuttles, sending them in different directions in the desperate hope that one will come across help.  In case that happens, Mal is staying with the ship so he can call the other shuttle back.

So what does this have to do with UI design?  Wash, the ship's pilot, recognizes that Mal will need a way to call the shuttles back, so he comes up with the most user-friendly solution he can think of: he jury-rigs a big red button onto the radio.  Mal doesn't have to worry about radio frequencies, tuning, electronic jibber-jabber, etc.  He just has to push the giant, red, candy-like button.  It's beautiful UI: simple, low mental overhead, no fiddling around necessary.

C, Linux, Short Circuits, and Equality Assignment

posted Oct 10, 2013, 7:17 AM by Lewis Baumstark   [ updated Oct 10, 2013, 12:06 PM ]

So I'm reading this post on an apparent 2003 attempt to insert a backdoor into the Linux kernel.  In the post, he shows the bit of code in question:

if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
        retval = -EINVAL;

and, in a parenthetical, asks the C-savvy readers to explain the subtleties of what's going on...with answers at the end of the post.  I haven't read the answers yet, so I'm going to post my analysis, then compare with Dr. Felton's once I finish the article.

First off, the (current->uid = 0) clause.  Anyone who's passed Computer Science 1 knows this is an assignment, not a test for a equality (the latter uses ==, not = ).  Unfortunately, even experienced programmers could miss the difference on a casual glance through the code.

Second, (current->uid = 0) is not just a statement; in C, assignments are also expressions, meaning they evaluate to a value.  Specifically, they evaluate to whatever the final value on the right-side of the assignment comes out to be.  In this case zero, also known as "false" in C.

Third, a lesser-known property of the && ("Logical AND")  operator is that it is short-circuiting, meaning that the right-side expression is evaluated if and only if the left-side expression evaluates to true.

So, put those together, and we have a flow through the if-statement that goes:
  1. evaluate (options == (__WCLONE|__WALL)).
    1. if true, then evaluate (current->uid = 0)...which always evaluates to false and has the side-effect of setting the value of current->uid to zero (more on this in a moment).
    2. if false, then the if-statement is skipped over
And that's it.  Note that the body of the if-statement, retval = -EINVAL;, is never executed.  It is dead code, dead enough that a smart compiler should  be able to catch it (oversight/ignorance on the part of the mysterious backdoor-injecting coder?).  (Update: The only two compilers to which I have access do not seem to give any feedback on when or where they perform dead-code elimination. Sad panda.) Effectively, the backdoor code is an obfuscated version of the following:

if (options == (__WCLONE|__WALL)) {
    current->uid = 0;
}

Now I know next-to-nothing about the internals of the Linux kernel, but I know enough, in general, of systems administration to know:
  1. what a "uid" is (answer: a user id, the way OS users are represented, internally and numerically, by the system)
  2. that a uid of zero is very likely a special one.  My guess is either the root user account or, perhaps, a special kernel-mode user.
So let's find out.  According to Wikipedia, my first guess was correct; UID 0 is the root (superuser) account.  In other words, the backdoor code has the effect of giving the backdoored program root-level access to the system whenever (options == (__WCLONE|__WALL)) is true.

My intention had been to stop there and see what the remainder of the post had to say, but my curiosity is getting the better of me.  I want to know the context of those "options" and what they really mean.  It appears __WCLONE and __WALL are flags for the wait() system call that indicate to it to wait until child threads have completed; putting a bitwise-OR between then (the | operator) effectively says check if either are true.  So, the bottom(ish) line appears to be "if this thread has child threads, give this thread root access".  Hmmm.

Now to see how close I got...and the answer is pretty much that I nailed it (high-fives self).  Felton does mention that "So the effect of this code is to give root privileges to any piece of software that called wait4 in a particular way that is supposed to be invalid," and I don't know enough about the kernel to understand why (options == (__WCLONE|__WALL)) would be an invalid situation.  Still, an excellent example of how the subtleties of a programming language can be used for evil as well as good.

Why Java Layout Managers are not a Strategy Pattern (any more...)

posted Oct 6, 2013, 9:19 AM by Lewis Baumstark

Apparently I'm all bloggy today.  Fits and spurts, I suppose.

One thing I see occasionally is that Java's AWT/Swing Layout Manager system is an example of the Strategy design pattern.  The more I learn about layout managers (and Strategy), the less I agree.

First off, a review of Strategy.  The relevant highlights are:
  • Strategy makes a family of algorithms interchangeable.
  • Strategy de-couples the Client (user) of an algorithm from the specific implementation of that algorithm.
To me (and I'll welcome someone pointing out where I get this wrong), the heart of the Strategy pattern is the ability to swap-out one implementation for another -- and have the user (client) of the Strategy be none the wiser.

Now, on to layout managers.  In Java, there are two interfaces, LayoutManager and its extended interface LayoutManager2, that specify how layout managers should behave.  Looking at the methods required by LayoutManager only, I'm actually comfortable calling it Strategy.  So any class that implements only LayoutManager (but not LayoutManager2) should be interchangeable with any other that does the same...which basically leaves FlowLayout and GridLayout.  It's important to recognize that both of these layout managers are agnostic of the Components being added to them; as a component is added, the layout manager finds a place for it.

LayoutManager2 breaks this component-agnostic system by incorporating the idea of constraints.  Its addLayoutComponent() method allows implementing classes to associate a constraints object with a specific component in the GUI.  An example is a constraint that says to put a JButton in the NORTH position of a BorderLayout -- the layout manager can't meaningfully position the JButton without this extra object that effectively couples the JButton (part of the layout manager's client, probably a JPanel or similar container) to the client.

As a more visceral example, create a JFrame with a bunch of buttons and labels and such and set its layout manager to FlowLayout.  Then try to set it to BorderLayout or GridBagLayout.  It might technically work, in a trivial sense, but you're missing out on the power of those layout managers if you don't go further and add in constraints.  This violates what I see as the heart of Strategy -- that implementations of the algorithm be interchangeable.

All that said, this is not a critique of layout managers.  Layout managers like GridBagLayout and SpringLayout are powerful and useful.  I just don't think they can be called a Strategy pattern.  My suspicion is that the original idea behind layout managers was that they were intended as a Strategy, but that the hard realities of GUI layout (especially with Java's can't-win goal of platform-independent GUIs) meant the API designers had to break it later on down the line.

Showing Java Processes Launched from Eclipse

posted Oct 6, 2013, 7:43 AM by Lewis Baumstark

As someone who grades student programming assignments, it isn't unusual to get a lot of rogue Java processes running in the background.  Windows Task Manager is not good at distinguishing these from other processes that may be legit (like Eclipse itself); they all show up at "java" or "javaw" instances.

The Debug view (note: different from the Debug perspective) will show all processes (and their sub-threads) launched from within Eclipse, so it is a handy way to find out which student's work is, say, stuck in an infinite loop.  Or didn't set the default JFrame close behavior as EXIT_ON_CLOSE.  People who use the debugger regularly know this.  The Debug View can be added to any perspective, so I put it in the regular Java perspective in order to keep an eye on what's running in the background.

I'd argue the Debug View is poorly-named, which may prevent people from finding it when needed.  So maybe "The Goog" will index this for people trying to find the answer.

1988 Dragon*Con Program Book

posted Jul 21, 2013, 4:02 PM by Lewis Baumstark

A friend who's been going to D*C far longer than I scanned in the 1988 program book.  Geeky nostalgia...

I especially love the ads for vintage computer hardware.

Debugging Arduino Servo Issues

posted May 10, 2013, 5:00 PM by Lewis Baumstark

Corrections/comments are very welcome, especially if I get the technical details wrong. Please email flippy.qa76 AT gmail.com.

If you are using servos with Arduino, sometimes the results can be...not what you expect.  My example is that I was using continuous servos as the drive motors for a mini-sumo 'bot.  The (greatly simplified) control loop for the motors looked like this:

loop()
{
    take distance measurement from ultrasonic sensor
    adjust servos' speeds accordingly (using Servo.write())
}

And I'd get all kinds of wonky behavior, mostly in that it didn't appear the servos were getting any kind of speed updates at all.  It was *supposed* to move straight forward when the sensor detected another object in front, but in most cases it would act as if the opponent wasn't visible.  (And yes, I checked and double-checked that the sensors were working...)

It turns out this is a timing problem.  Before I cut to the punchline, let's look at the issues in play here.

Arduino loop() function timing

The first thing to look at is how often the void loop() function is called.  For sake of simplicity and to get a ballpark figure, we'll assume loop() is empty, i.e., it is running about as fast as possible.  I'm too lazy to run my own tests on a modern Arduino, but this thread post gives us a starting point of roughly 260 KHz for an empty loop.  That means loop() gets called roughly 260,000 times a second or about 3 times every millisecond (ms).  I'm going to make a wild guess and say that loaded with some actual executable code that loop() runs on the order of once every millisecond or so.  Keep this in mind.

Servo timing

This page provides an excellent overview of the timing signals used to control servos.  The TL;DR version is that a servo expects to receive a command to move (or in the case of continuous servos, to change speed) every 20 ms.

Now compare this to the loop() function timing.  The ratio is 20:1, meaning loop() executes about 20 times for every time a servo expects a command.  Obviously the actual frequency of loop() depends on the code in it, but it's fair to say it can send commands to a servo faster than a servo can react to them.

Hardware-level effects

Next, consider what actually happens when a Servo::write() method is called.  As way of background, the Servo library uses one of the AtMega's built-in timers to create the pulse signals sent to a servo connected to an Arduino.  This timer is a piece of hardware that periodically generates an interrupt -- a signal that pauses the normal Arduino program to run a special interrupt service routine or ISR.  When  the ISR is finished, the Arduino program picks back up wherever it left off.  When you use the Servo library, it uses the ISR to send the appropriate control pulses to all the attached servos.

The thing to understand here is that Servo::write() does not immediately affect the attached servo.  Instead, it simply records the position (or speed) the servo should have when the ISR runs again.  In other words, you can write() a value to a servo and have other things in your program happen before the servo actually responds.  Worse, loop() could run a bunch of times before this happens, so you could actually write() to a servo a bunch of times, with different values, before it responds (taking only the most-recent).

One more thing to check -- how does the timer's period hold up to our assumption that we're sending servo commands every 20 ms?  The answer is in Servo.h, the header file for the Servo library, where you will see the line:

#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds

Notice REFRESH_INTERVAL is in microseconds (1/1,000,000ths of a second).  Doing the math, 20,000 microseconds equals...20 ms.  Digging into the ISR code for the timer, it turns out that the ISR (which runs a MUCH more often than once every 20 milliseconds) checks to see if 20 ms have elapsed since the last "refresh" of the servos.  If it has, then and only then will it send a new control signal to the attached servos.

I don't care, just tell me what I need to do to get my Arduino sketch working

Fine, fine.  In the end, you just need to make sure that you only call write() on a Servo object once every 20 ms or so.  Maybe a little longer to give the servo's hardware some time to do it's thing -- remember, the servo itself has some control logic that takes a little while to work.

From a code standpoint, this could be as easy as putting delay(20) at the end of loop().  This will work if there isn't really anything else other than servo control going on.  On the other hand, if you're trying to interleave several independent tasks, you may need to set a "timer" of your own.  The outline of that code looks something like this:

// "timer" variable, in milliseconds.  remembers the last time an update happened
// MUST be of type unsigned long!
unsigned long lastUpdate = 0;

// time between updates (20 ms for servo control) 
unsigned long updatePeriod = 20; // in milliseconds

void loop()
{
    // millis() returns the number of milliseconds since the Arduino turned on
    unsigned int now = millis();

    // check to see if updatePeriod milliseconds have elapsed since lastUpdate
    // if so, update the new position and reset lastUpdate
    if( (now-lastUpdate) >= updatePeriod)
    {
        servo.write(newPosition);
        lastUpdate = millis(); // reset our countdown timer
    }

    // can do other stuff here without servo delays getting in the way
}

In practice, I found that performing Servo::write()'s works a little better with a longer period than 20 ms, simply because the servo hardware can't move that fast.  Depending on the particulars of your application, anywhere from 50 ms to 200 ms could be more appropriate -- you'll just have to experiment to find out.

Trailer Hitch Install: the Prequel

posted Apr 20, 2013, 8:03 AM by Lewis Baumstark

The fam and I will be headed to the beach in early June.  Now that we are 3, this means we have 10 times the stuff to carry, so I bought a trailer hitch and cargo rack for our CR-V to expand our carrying capacity.  Hopefully I'll be able to install the hitch this weekend.

I purchased the hitch from www.etrailer.com and wanted to give them a shout-out for the excellent install instructions and videos they had for my hitch (and presumably, most other hitches).

1-10 of 88