In part three of this series about my Honda Civic I went over preparing to install the head on the engine with ARP head studs. In this post I’ll go over getting the head installed and the other parts reattached. Continue reading
Honda Part 3: The Hard Part
Last time I posted about my Honda, I left things with the engine mostly apart, and the whole top of the engine sitting in the trunk. We were finally ready to put in a new head gasket, but there were plenty of things to do before that.
Before I start telling you about all of the cleaning and other prep work that it would take the get the engine back together, I should first explain the plan I had for this project. Continue reading
Honda 2: The Teardown
First step with a cool old Japanese car? Gotta take off the sweet forward-opening hood!
With that out of way, we swiftly began tearing down what we found, which mostly consisted of a gazillion vacuum lines connected to the (complex) carburetor and the three control boxes needed to get this 80’s California car to run. Continue reading
So, I bought a Honda
Like many car stories, mine starts like this:
This is why Craigslist is dangerous! One day I get the idea that these things are cute and in a couple days I’ve found a dirt-cheap car, read my fill of the 1stgencivic.com forums, and somehow am still interested in a car with a blown head gasket. Continue reading
Java Tuples
One oft-noted feature of the Java language is it’s lack of a tuple data type. This leads to an abundance of classes that provide the convenience of grouping more than one value into a single object. These classes usually look more or less like this:
public class ObjectPair<A, B> {
private A primary;
private B secondary;
public ObjectPair(A primary, B secondary) {
this.primary = primary;
this.secondary = secondary;
}
public A getPrimary() {
return primary;
}
public B getSecondary() {
return secondary;
}
@Override
public String toString() {
return "(" + primary.toString() + ", " + secondary.toString() + ")";
}
}
Sometimes you’ll see more specific classes like ObjectWithString, but the idea is the same. This approach is fine for many common tasks, but if you find yourself needing multiple cardinalities of tuple, this approach get’s tedious quickly, as you find yourself writing ObjectTriple, ObjectFourTuple, ObjectFiveTuple, and so on. Thinking that it would be smart to have one class that could create a tuple of any length, you might end up being tempted to write a class like this:
public class Tuple<A> {
public static Tuple<A> getTuple(A... args) {
return Tuple(args);
}
private A[] items;
private Tuple(A[] items) {
this.items = items;
}
public A getItem(int index) {
return items[index];
}
}
But this is even worse than what we had before! Not only are we limited to one type of object (which adds the major headache of unsafe casting to a common use of tuples) but we no longer have any idea of how many items our tuple holds. This approach seems to be a real step backwards, as it’s really just a wrapper around an array, which gets rid of any advantage of having a tuple type available.
To make the single-class approach work, we’ll need some way of storing more information in the type of our tuple objects, by taking an idea from functional programming. We define a type that contains information about how long our tuple is, and what type exists at each location. This recursive type is simply defined, but allows us to create tuples of any length:
public abstract class Tuple<T, U extends Tuple> {
public abstract T getItem();
public abstract U getTuple();
public static final <T> Tuple<T, EmptyTuple> getTuple(T item) {
return new SingleItem(item);
}
public static <T, U extends Tuple> Tuple<T, U> getTuple(T item, U tuple) {
return new SingleItemAndTuple<T, U>(item, tuple);
}
public static abstract class EmptyTuple extends Tuple {}
private static class SingleItem extends Tuple<T, EmptyTuple> {
private T item;
public SingleItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public EmptyTuple getTuple() {
return null;
}
}
private static class SingleItemAndTuple<T, U extends Tuple> extends Tuple<T, U> {
public T item;
public U tuple;
public SingleItemAndTuple(T item, U tuple) {
this.item = item;
this.tuple = tuple;
}
public T getItem() {
return item;
}
public U getTuple() {
return tuple;
}
}
}
Now we have all of the tuple type-safety we could want, at the expense of clumsy notation:
class TupleTest {
public static void main(String[] args) {
Tuple<String, Tuple<Integer, Tuple.EmptyTuple>> tuple = Tuple.getTuple("Test", Tuple.getTuple(Integer.valueOf(1)));
System.out.println(tuple.getItem());
System.out.println(tuple.getTuple().getItem());
}
}
Re-enable virtual terminals on Ubuntu 12.04
In the past month I’ve been getting accustomed to Ubuntu 12.04, and all of the changes it brings to the user interface of Ubuntu. One issue I’ve been especially bothered by is the lack of virtual terminals, at least of users of NVIDIA’s proprietary drivers (myself included). The issue seems to stem from the fact that Ubuntu 12.04 makes use of a hardware framebuffer to draw a splash screen on boot, which causes issues with the driver when attempting to switch virtual terminals. I had a hard time finding any solutions to my problem, until I found this post on AskUbuntu which gives a couple suggestions. While the poster suggests going all out and completely disabling graphical boot, he also suggests a less drastic solution, adding a flag to the linux boot options that prevent loading framebuffer modes that interfere with virtual terminals.
To do this, open /etc/default/grub in a text editor and find the line that reads
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
and change it to read
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=normal"
Rebooting your computer should leave the grub menu and boot splashscreen unchanged, while the virtual terminals work perfectly! Of course, your mileage may vary, depending on your system. This works for me on a fully updated install of Ubuntu 12.04, with an NVIDIA 9800 GT.
More Map Scripts
In the last installment”Ž I wrote a script (gdal_slice.py) to cut up geotagged images and save them in a format that GPSdrive will read. I’ve uploaded that script into a new repository on GitHub.
I’ve also uploaded a script I wrote called get_quad.py, which will download USGS topographic maps automatically. This script naturally complements gdal_slice.py; using the two together allows for almost-totally automatic population of GPSdrive’s map database with high quality topographic maps.
usage: get_quad.py [-h] [-q] [-s STATE] (-g | -c COORD COORD)
Get DRG USGS quad for given latitude and longitude from LibreMaps.org
optional arguments: -h, --help show this help message and exit -q, --silent don't produce any output -s STATE, --state STATE Postal abbr. for the state in which the quad falls, so we don't need to look it up -g, --gps get coordinates from GPSd -c COORD COORD, --coords COORD COORD specify latitude N and longitude E (respectively) in decimal degrees; longitude should be negative, as all maps fall in the western hemisphere
Unfortunately, because of the way USGS maps are organized, the script needs to know the state in which the coordinates fall. If the -s flag is not given, this is inferred from the coordinates, but this lookup requires internet access.
Bluetooth Android GPS on OS X
Inspired by this link from the GPSd homepage I set out to use my brand new Android phone as a bluetooth gps. Naturally, I wanted to use it with GPSd, but on OS X. I read through the Linux directions and thought “this shouldn’t be terribly hard on a Mac!” As it turns out, I was right!
The first step was downloading an app to the phone. I used the free GPS over BT, but the steps should work with most other programs like it.
Once that’s up and running, it’s time to pair your computer and phone. Make sure that the GPS to BT program is running at this point!
If everything worked properly, you should see the following:Make sure that it says “A computer serial port was created”. If it doesn’t say this, your computer didn’t pick up on the serial data stream from the GPS program, and you should retry pairing.
Once OS X has created a serial port, you simply need to point GPSd at it. In a terminal, run
ls /dev/tty.*
One of the results should be /dev/tty.[[devicename]]-BluetoothService — this is what to point GPSd at:
sudo gpsd -n /dev/tty.[[devicename]]-BluetoothService
and you should be up and running!
At the moment there is one caveat: you have to re-pair your devices each time you want to fire up the GPS — at the moment OS X seems unable to open the bluetooth serial port on request. Other than that, it works like a charm!
IndieWeb, or how to avoid Digital Sharecropping
Thanks to the DorkbotPDX blog I found my way onto the website of this year’s IndieWebCamp, which took place in Portland June 25 & 26. Although I was saddened that I wasn’t in town for it, the projects that ended up being developed by the camp immediately grabbed my interest.
Although I had never been aware of the term “indie web” (which seems to have been around for almost 15 years, judging by this article from uzine.net), I’ve been building my own independent web presence for more than four years. In the words of the IndieWebCamp home page:
Rather than posting content on many third-party silos of content, we should all begin owning the content we’re creating. Publish short status updates on your own domain, and syndicate to Twitter. Publish photos on your own domain, syndicate to Flickr, etc, etc.
For some good summaries of the ideas and goals of the IndieWebCamp, this article from GigaOm and this post from Mark Hendrickson are a great place to start, while each of the camp’s guests also have their own websites, each with a wealth of information.
While I’ve been using this domain for quite a while, it’s been in use alongside Facebook, Delicious (and Flickr, to a smaller degree) as a part of my web presence. However, since I ditched Facebook five or six months ago, I’ve been relying on this domain for more, and overall I’ve been pleased. However, as the IndieWebCamp is readily willing to admit, there is room for a lot of room for technical innovation in expanding the functionality of the indie web. Towards that end, I see three threads of work that I’m interested in pursuing:
- Using my site for Flickr-like photo sharing. While this might include syndication to Flickr at some point, I mostly want a light-weight DIY solution to photo sharing.
- Similarly, using my site for bookmarking. I really like the service that delicious offers, but I want to own the data and let delicious simply keep a copy of it (see http://adactio.com/journal/4197/ for some ideas).
- Finally, I’m hugely enamored of the work on delivery-agnostic messaging that took place at IndieWebCamp, which you can find details of here. Not only is it a ridiculously simple protocol, but it starts to address some real issues of a distributed social web, in that it allows two-party communication based solely on domain names as unique identifiers, therefore eliminating the middleman in social-web-type communications.
Map Tiles with Python + GDAL
After getting GPSDrive running on OS X I started looking into different sources for maps. The GPSDrive wiki has a couple of interesting pages about this: one on creating maps and one on map sources. The second page pointed me to the LibreMap Project which has a complete collection of  USGS 1:24000 (large scale) topographic maps for the entire US. These files are distributed as high-resolution GeoTIFF files, along with world files, so the maps are fully geotagged. This means that they contain all of the information needed to generate GPSDrive-friendly map tiles, but GPSDrive will not read them directly. The creating maps page gives some (heavily out-of-date) advice on how to use the gdal_slice.sh script distributed with GPSDrive to create map tiles using the tools from GDAL. Sadly, this script is completely unusable on OS X, because of incompatibilities in the command line tools that are used by the shell script. After spending about five minutes trying to tune it to work with the tools that Apple ships, I completely gave up and looked into other approaches.
Luckily, I quickly found out that GDAL ships with Python bindings. I installed GDAL from source using the instructions from their wiki. To make sure it built with Python modules I ran ./configure –with-python. After that make and sudo make install ran without a hitch.
I then set about re-implementing gdal_slice.sh in Python. Once I got a handle on how to use the Python bindings it was fairly easy to write. You can find the script here.
Using gdal_slice.py is very similar to using gdal_slice.sh:
$ ./gdal_slice.py -h Usage: gdal_slice.py [options] FILENAME Options: -h, --help show this help message and exit -o OVERLAP, --overlap=OVERLAP percentage tiles will overlap. should be at least 20% -a, --add write map info to map_koord.txt in current working directory -m, --map use *_map folders for output; use if input image is UTM. Default behavior -t, --topo use *_top folders for output; use if input image is not UTM -v, --verbose enable debugging output
The biggest difference is that gdal_slice.py does not perform any format conversion; it will write maps to TIFF files. Although the file size is decidedly larger than that of PNGs, my version of GDAL is unable to create PNGs, and disk space is (fairly) cheap. If I’m motivated I’ll get around to adding a format option, at least to allow conversion to PNG.
Running gdal_slice.py filename.ext will create a folder named filename_map (or _top, if you use the -t flag) that contains a set of 1280×1024 TIFF files, as well as a map_koord_draft.txt file. Moving this folder into GPSDrive’s map directory, and merging filename_[map|top]/map_koord_draft.txt with map_koord.txt will make the new maps available to GPSDrive. Note that filename.ext must be in the current working directory, as the script handles filenames/paths somewhat naivëly.
So far I’ve only tested this with GeoTIFFs from LibreMaps, but it seems to work great, with the caveat that LibreMaps’ files include the borders of map, and my script doesn’t do any cropping, so you see borders if you’re near the edges of quads. This doesn’t bother me terribly much, but you may need to turn mapsets on and off in the Map Control dialog to see the appropriate images.
Update 7-14-11: I’ve modified the script with an additional flag (-a) that will automatically merge the generated map_koords file with map_koord.txt in the current working directory. This means that if you run the script from inside .gpsdrive/maps with the -a flag the generated tiles will be automatically added to GPSDrive’s database. The script avoids creating duplicate entries in map_koord.txt, as well as alphabetizing all entries.
I’ve modified the documentation here, as well as the links, to reference the latest version.