Friday, January 27, 2012

Using GNU Make's 'define' and '$(eval)' to automate rule creation

About once a week I get an email from someone random asking a question about GNU Make. I do my best to answer and figured it might be helpful for others if I shared these questions and my answers. So, here goes. This one starts with a Princess Leia style appeal:
I stumbled across your name when googling for help on a GNUmake related problem, hope you have the time to look at it as you are my last hope. I have the following problem in my Makefile:
$(LIBDIR)/libfoo.a: $(filter $(OBJDIR)/foo/%,$(OBJECTS))
$(LIBDIR)/libbar.a: $(filter $(OBJDIR)/bar/%,$(OBJECTS))
$(LIBDIR)/libbaz.a: $(filter $(OBJDIR)/baz/%,$(OBJECTS))
        ar -r [email protected] $^
        ranlib [email protected]
so far, so good - it works as expected. The only problem is, that in the real world it's not just foo, bar and baz for me and I hate having to maintain the list manually. What I would like to do is something like this:
$(LIBDIR)/lib%.a: $(filter $(OBJDIR)/%/%,$(OBJECTS))
        ar -r [email protected] $^
        ranlib [email protected]
but now the pattern for filter has two percentage-characters and this seem to confuse GNUmake. I tried to escape it, use $(call …), etc. but nothing really works. Do you have any trick/hint/idea how to solve this??

Thanks for your time, Best Regards,
And my reply:
Thanks for your mail. I can see what you are trying to do. I think the easiest way out of your predicament is as follows:
# Example of manually maintained list
# $(LIBDIR)/libfoo.a: $(filter $(OBJDIR)/foo/%,$(OBJECTS))
# $(LIBDIR)/libbar.a: $(filter $(OBJDIR)/bar/%,$(OBJECTS))
# $(LIBDIR)/libbaz.a: $(filter $(OBJDIR)/baz/%,$(OBJECTS))
# $(LIBDIR)/%.a:
#        ar -r [email protected] $^
#        ranlib [email protected]

# What you'd like to be able to do
# $(LIBDIR)/lib%.a: $(filter $(OBJDIR)/%/%,$(OBJECTS))
#        ar -r [email protected] $^
#        ranlib [email protected]

# The following will work
# Suppose, for example:

LIBDIR  := lib
OBJDIR  := obj
OBJECTS := $(OBJDIR)/foo/hello.o $(OBJDIR)/foo/bar.o $(OBJDIR)/bar/hello.o \

# Extract the names of the first level directories underneath
# $(OBJDIR) and make a unique list (sort removes duplicates) and store
# that in LIBNAMES.  This assumes that there are no spaces in any of
# the filenames in $(OBJECTS) and that each element of $(OBJECTS)
# starts with $(OBJDIR)

LIBNAMES := $(sort $(foreach a,$(patsubst $(OBJDIR)/%,%,$(OBJECTS)),\
$(firstword $(subst /, ,$a))))

# The following function finds all the objects in $(OBJECTS) in a
# particular directory whose name can be found in LIBNAMES.  So, in
# the example here doing $(call find-objects,foo) would return
# obj/foo/hello.o obj/foo/bar.o

find-objects = $(filter $(OBJDIR)/$1/%,$(OBJECTS))

# Now need to define the rule that handles each of the libraries
# mentioned in $(LIBNAMES).  This function can be used with $(eval) to
# define the rule for a single directory

define make-library 
$(LIBDIR)/lib$1.a: $(call find-objects,$1)
        ar -r [email protected] $$^
        ranlib [email protected]

# Now define the rules for all the directories found in $(LIBNAMES)

$(foreach d,$(LIBNAMES),$(eval $(call make-library,$d)))
You will need a version of GNU Make that supports $(eval).

Monday, January 23, 2012

Saturday, January 14, 2012

GAGA-2: Mounting the flight computer

On GAGA-1 the flight computer was screwed in place using nylon bolts that went through the polystyrene walls of the capsule. GAGA-2 is using cable ties.

One concern with cable ties is their performance at low temperature. The CUSF guys had warned me never to use cable ties for load bearing joints. But since we are holding in place a few grams of flight computer the only remaining concern was whether the cable ties would still be locked at low temperature.

So, I locked together a pair of ties and left them in the freezer at -18C overnight.

The next morning they showed no signs of slippage and I was unable to pull them apart. But for double safety I've also superglued the locking part of the cable ties shut in place.

Here's the flight computer inside the capsule:

There are a pair of cable ties around the two board of the flight computer (the Arduino and the custom shield on top containing the radio transmitter and the GPS). Those help keep them together.

Then there are a pair of cable ties that pass through the wall of the inner capsule. Those cable ties are hot glued in place so there are no holes and so they don't move.

Finally the two sets of cable ties are interleaved so that the board is held in place. Once everything is tightened I dropped superglue in all the locking parts. The computer is positioned so that there's no stress on the rather short cable to the GPS antenna.

It doesn't move and I'm pretty happy that it'll stay in place during the flight. The next thing that needs mounting securely is the battery. On GAGA-1 the batteries popped out on landing; I'm not letting that happen this time.

Monday, January 09, 2012

GAGA-2: Distance RTTY Test

As I said in my previous post about GAGA-2 one vital test was the the radio transmitter worked over a long distance. I'd done the same test for GAGA-1 and went back to the same location for a GAGA-2 test.

My father drove off to one end of the reservoir with GAGA-2 transmitting happily from the back of his car (an estate car) and I drove to the other with my radio and a Yagi. It was obvious as I was driving to the listening point across the reservoir that things were going to work because I could still hear GAGA-2 from time to time using a simple whip aerial.

Once on the causeway in the left of the picture I hopped out of the car and pointed the Yagi in roughly the right direction. The RTTY signal came in loud and clear. Moving the Yagi from side to side made it easy to figure out where the transmitter was.

Measuring on Google Maps shows that this time the distance was roughly 6km (3.7 miles) with trees and the body of the car in the way (GAGA-2 wasn't even lifted up to window level). That's still about 1/5 to 1/6 of the distance that GAGA-2 will lift up to, but gives confidence that the 10mW transmitter and, most importantly, the new antenna are going to supply clear enough telemetry for the flight.

Here's a shot from the car while transmitting. I was about 6km on the other side of those trees and across the reservoir. Happily there won't be any trees or car between GAGA-2 and the radio on the day.

Friday, January 06, 2012


Last April I sent a weather balloon up into the stratosphere after months of preparation. You can read all the details starting here. I called the flight GAGA-1. Well, it's time for a GAGA-2.

Since last April I've done a number of experiments with expanding foam to see if it would make a viable material for the GAGA-2 capsule. Summary: no. It's too hard to work with, it doesn't insulate that well and I can get a cheap polystyrene capsule that's much smaller than the GAGA-1 capsule.

So, GAGA-2 will aim for a spring time 2012 flight with a number of changes from GAGA-1. First, a much smaller, lighter capsule. Second, video cameras rather than still. Third, no backup GSM based tracker.

Here's the new capsule. It's made from a pair of hollow polystyrene spheres that fit one inside the other.

These are very, very light. Weighing in at a total of 68g (compare that to GAGA-1's capsule that weighed more than 200g).

The inner sphere is covered in the same mylar film that was inside GAGA-1, and the outside is painted the same fluorescent yellow covered that proved so successful when recovering GAGA-1 (it was visible over 400m away through trees).

For comparison here's the GAGA-1 flown capsule next to the newly painted GAGA-2 capsule.

GAGA-2 will use the same parachute (GAGA-1 was actually a bit heavy for the size and the descent should be a little more graceful this time) and rigging as GAGA-1.

The GAGA-1 camera will be replaced by two tiny HD video cameras (this type). One will record the view and the other the balloon hoping to get video of the balloon bursting at altitude. They are much smaller than the GAGA-1 camera and each weights just 18g (whereas the GAGA-1 camera weighed 215g).

New UKHAS guidelines aimed at improved safety ask that "Antenna elements that face down should be flexible - avoid metal rods." GAGA-1's antenna was pretty stiff having been made out of a cut up coat hanger. So in keeping with the guidelines I've made a new antenna of the same 1/4 wave design out of Ikea drinking straws and copper wire salvaged from this project.

The flight computer is the same one that flew on GAGA-1 with a couple of modifications. GAGA-2 will fly without the external temperature sensor, I've added a direct power connection as space is tight and there wasn't room for the large connector used in GAGA-1 and I've added a strap to hold the piece together (GAGA-1 saw some pretty violent shaking while flying). I'm also using a single 9V battery. One of the failures in GAGA-1 was that the AA batteries became dislodged on landing causing the flight computer to lose power.

I've run a couple of battery life tests using standard 9V batteries. A really cheap and nasty Panasonic 6F22 only managed to power the flight computer for about 90 minutes before dying completely. A Duracell 6LR61 ran the flight computer for 17921 seconds (4 hours 58 minutes 41 seconds). On the day I'll actually be using a lithium battery because of their low temperature performance. Specifically, Energizer Advanced Lithium 9V which will work down to -40C (technical data sheet is here).

One important test is to see how the temperature drops inside the capsule (as I did for GAGA-1). So I placed the completed capsule inside the freezer and measured the temperature inside every 15 minutes.

The temperature drop seems acceptable with expected internal temperatures around -10C (ignoring the fact that there will be internal heating from the radio transmitter).

I'm using the same GPS module as GAGA-1 (a Lassen IQ) which is tiny, but this time I'm using an embedded antenna that will be inside the capsule on top of the Mylar film. Tests show that this work well. From a totally cold start I had a GPS lock in 115s in my back garden.

Next steps for GAGA-2 are:

1. Rewire the cameras so they use a larger external battery to get enough filming life. Then freeze them to see if they still operate at low temperatures. Then mount them.

2. Take the capsule out for a transmission test to make sure that the antenna is good enough.

3. Wait for a calm day for launch.

Sunday, January 01, 2012

International Object Sizing Tool

I often take pictures of objects for this blog when I'm making stuff (such as the Cansole or Home-made 7x7 display) and one constant problem is scale. It's hard for people to know what size the objects are. For example, here's a small HD video camera that I'm planning to use on GAGA-2. This shot shows the camera with its insides out:

Tiny, but how small?

To solve the problem I've created the International Object Sizing Tool that can be photographed alongside an object to give an idea of scale. It has five different ways of showing the size of the object: three common coins, a credit card and centimeter and inch scales. Here it is:

The entire thing is credit card sized (itself an international standard) and I've included the Visa logo and a fake card number and name so that you can recognize it as a credit card sized object.

There's an inches scale on the left, a centimeters scale on the top and three correctly scaled coins: a one Euro, a US quarter and a British Pound.

I made the image in OmniGraffle and printed it out and then stuck it to the back of an old credit card (actually an old airline mileage card since it wasn't embossed) that I'd sanded down.

So, how small is that HD video camera?

If you want to make your own one of these, the PDF is here.