Friday, September 03, 2010

Shell Scripting for MacOS X: Laundry Timer with Text To Speech Synthesis

I occasionally forget things. Yes, I admit it. In high school, a friend of mine once said that I'd probably forget at home a certain, rear-facing body part if it weren't attached to my body. He was probably right.

In my apartment building, there is a small set of laundry machines: one washer and two dryers. These three machines are to be split between the twelve apartments in the building. It's not a bad amount of machines, except for when people leave things in the machine for extended periods of time. Yes, I have been one of these people. Many apologies to my building mates!

I had a small minute timer that I used to remind me to move the finished laundry. It was nice, super-cheap, portable device that worked very well, at least until it died. Yes, it was ever so slightly tragic, and involved some amount of leaky battery goo. This really shouldn't have been much of a problem, at least in relation to my bad retrieval-of-laundry habits. I could have used one of the other timers in my house, such as the one on the microwave. For a while, that's what I did, except I occasionally missed hearing it, either from being in the wrong room at the wrong time, having headphones on, etc.

This morning, I started trying a slightly different solution. I wrote a simple shell script to tell me when to move my laundry. It started by using the sleep command to wait the proper number of seconds needed for whatever cycle I'd be on (1500 seconds for a wash cycle in my building, 3600 for a dryer load). When the laundry is done, it would use MacOS X's text-to-speech synthesis libraries (via the 'say' command) to verbally announce the machine's completion.

About half an hour of hacking and documentation-searching resulted in the 'laundry' command, along with a better understanding of bash's numeric 'for' loops and math capabilities, among other things.

The 'laundry' command, as it currently exists, takes in a number of minutes as input and then does the following, in order:

  1. prints the current/start time and the amount of time input.
  2. counts down the minutes, waiting as necessary and printing the remaining time along the way.
  3. prints the end time.
  4. over the computer's audio output, it says the word, "Laundry". This is repeated every ten seconds until Ctrl-C is pressed.


For example, given my building's dryers run time of about an hour, I can run the following:

laundry 60


This is roughly what I would see in the terminal (using a smaller wait time of five minutes):


Start Time: Fri Sep 3 20:33:53 EDT 2010
Waiting for 5 minutes (300 seconds).
Press Ctrl-C to exit.
4 minutes left
3 minutes left
2 minutes left
1 minutes left
Done!
End Time: Fri Sep 3 20:33:53 EDT 2010


The complete code is posted below. You can also download it here (use a right-click to save the file). To install it, be sure to mark it as an executable program (via 'chmod +x ~/Downloads/laundry', assuming it's in the common, MacOS X 'Downloads' folder), and also to copy it somewhere in your PATH, such as /usr/local/bin ('sudo mv ~/Downloads/laundry /usr/local/bin'). To note, the last step is purely optional. Not doing so just means you'll have to type in a longer command to run it.


#!/bin/bash
#
# Super-Simple Laundry Timer
# by David Ludwig
#

if [ "$1" == "" ]; then
echo
echo "Usage:"
echo " laundry <time in minutes>"
echo
exit 0
fi

MINUTES=$1
SECONDS=$[$MINUTES * 60]
START_TIME=`date`

echo "Start Time: $START_TIME"
echo "Waiting for $MINUTES minutes ($SECONDS seconds)."
echo "Press Ctrl-C to exit."

for (( i=1; i<=$MINUTES; i++ )); do
sleep 60
MINUTES_LEFT=$[MINUTES - $i]
if [ $MINUTES_LEFT -ne 0 ]; then
echo "$MINUTES_LEFT minutes left"
fi
done

END_TIME=`date`
echo "Done!"
echo "End Time: $END_TIME"

while true; do
say Laundry
sleep 10
done

Wednesday, April 28, 2010

Camera Solitaire Pong

Last weekend I attended a small game jam co-run by a friend of mine, Darren Torpey. The scene was very laid back, and the weekend was fun. I ended up playing around with the openFrameworks C++ toolkit, a multimedia framework of which I had seen a presentation about it a week before. The feature set looked nice, and it was reported to be very easy to use. It had a lot of computer vision features built in, which seemed interesting and was something I hadn't worked with before. I decided to try my hand at writing a pong app using the camera on my laptop. "Camera Solitaire Pong" is the result.

The game is a heavily simplified version of 3rd person 3d pong, whereby the player views tge game world behind their paddle. The world is represented by a boxy corridor. Normally there'd be another paddle at the other end, however I ended up cutting that feature due to time constraints. Instead, the player's goal is to hit a ball of increasing velocity as many times as possible.

Control of the paddle is done through a video camera. The app will attempt to track an object of a player-specified color. Tennis balls work ok, as do many single color objects of similar size. Ultimately I found that a piece of colored duct tape on the hand worked best, and had a good feel (IMO).

The game consists of two screens. The first is a calibration screen, whereby the player clicks on the object they wish to use. Pressing the spacebar brings the player to the second screen, the game screen.

A Mac build is available at: http://alum.wpi.edu/~davidl/Camera_Solitaire_Pong/latest_mac_build

If I get around to it, I'll try porting to Windows. The only Mac specific code in the game involves loading and saving a few variables, such as the calibrated color. I may also try and add a few features to it. I've already tweaked a few settings since the game jam, and added a title and some basic credits.

Here are some screenshots. Clicking on them should bring up larger versions.

Calibration Screen

Game Screen

A big thanks goes out to Laurence Lee, game jam attendee and Berklee College of Music student, for creating several nice sound effects for the game using one of the tennis balls I brought. Special thanks also goes out to Vickie Wu for making tasty food during the event, and to everyone involved in running things or otherwise making for what was a fun weekend!