So I finally decided to convert my Eee 1000H from XP to Win7, which looked like a seemingly easy task now that it even has Win7 compatible drivers. Oh, how mistaken I was.

Installing went fairly easy (except for errors completely of my own, but those are outside the scope of this post). I mounted the ISO I got from MSDNAA (yes, it's legit), went through the installer, five reboots later and I was in a shiny new Win7 world, complete with sound and partial hotkey functionality.

Then I went to get my fancy new drivers, to get all the functionality working. I started with the my usual driver install order: chipset, VGA, ACPI (called hotkeys on the Asus page), reboot. This is when the problems started. Up flashed a few dialog boxes on bootup, "Can't get WMI AsusManagement object" among others. A little googling later and I find out this means the ACPI driver doesn't recognize the BIOS, and I remember that I saw a BIOS update that said "supports Windows 7", so I thought "Oh, just have to update the BIOS."

Asus has a tool called Asus Update, that allows you to update the BIOS from Windows, so I went to install that, only to find that it didn't recognize my machine as an Eee PC, because the ACPI driver wasn't installed (or, in this case, not working properly). Uh, wait a minute, so you're telling me I can't update my BIOS because the ACPI isn't working, but the ACPI won't work before I update my BIOS? Oh dear...

Usually at this point you find a boot floppy and use a DOS-based BIOS updater, and indeed Asus has one called AfuDOS, but as you well know the Eee has no floppy, and Windows refuses to make an USB Pen an MS-DOS boot disk.

The rescue comes in the form of a very poorly documented feature of the Eee PC BIOS. If you press Alt+F2 at the grey screen when booting, it will go into a mode called EZ-Flash, and look for a BIOS ROM file from an USB device, named after your model ("1000H.ROM" in my case)!

Now, it is VERY important that you format the USB device as FAT16, otherwise it will not work. It will detect the file, but freeze while trying to read it. I have also seen the recommendation that the BIOS file be the only file on the device, but I don't think that should matter too much. However, as you most likely will have to reformat it to make it FAT16 anyway, that is most likely going to be the case.

So, to summarize, if you're getting the "Can't get WMI AsusManagement object" error, do the following:

  • Download the newest BIOS update, rename it "1000H.ROM" (or whatever model your Eee is)
  • Find an USB Device, format it to FAT16 (if it isn't already), and copy the BIOS file to the device
  • Reboot your machine with the device plugged in, and hold Alt+F2 on bootup.
  • If all went well, it should beep a little, and show some messages indicating it's installing the new BIOS, and when you're done, it should tell you to power down. Do so, and when you start back up into Win7, the error should be gone!

And if you're just planning on installing Win7 over XP, but haven't done so yet, update the BIOS before you start the install! You'll save yourself a load of trouble, and be able to install drivers with no problems.

Robots, Image Recognition and Path-finding, oh my!

| No Comments | No TrackBacks

The last few months, I've been doing a school project together with two other students in the course "Image processing and pattern recognition," which had as its goal to control a small micro robot through an obstacle course using nothing but the images taken by a camera in the roof.

The project was done entirely in MATLAB, with some code supplied by the school to control the robot, and some proof-of-concept code written by me in Python. Now, the project is over, and I thought I'd go through the solution we came up with here.

Detecting the robots and obstacles
To find the robot and the obstacles on the field, we decided to use a "base" image of the field when it's empty as a way to discern what's supposed to be there and what isn't. We then take a picture of the field with the robot in the starting position, move the robot forward a little bit, then take another picture.

These two pictures are then subtracted from the base picture and converted to binary images where every pixel value above 2 becomes white, and the rest becomes black. Then we apply a filtering algorithm (morphological opening-then-closing for the ones in the know) that removes whatever noise particles is left and connects certain disconnected pieces of the obstacles. Now we have sufficient grounds to discern what is an obstacle and what is the robot, as well as which direction the robot is facing.

filter-bw.png
Binary image

filter-morph.png
Morphologically filtered image

To find the obstacles, we just look at which pixels in the pictures stay the same (a simple AND operation between the two images), and the object that has moved is then the robot. To find the angle and position of the robot, all you need to do is see how far the moving objects' centers have moved.

Path-finding
Now, the remaining part of the task to be done before we can even start moving the robot towards the goal is to figure out which way it should go, so as to reach the goal AND avoid the obstacles. To do this, we decided to lean on the juggernaut of path-finding known as A*, favourite of game devs.

Before we could apply this, though, we have to convert the field image to a more game-like "tile-set". So we basically go over the image with only the obstacles, split it into tiles of a given size, and check how many white pixels each tile contains. If it crosses a threshold (we got it down so nicely we could use a threshold of 1 pixel), then it is marked as uncrossable (a "wall") in the resulting tile matrix, otherwise it's walkable.

tiles.png
Resulting tile matrix

We then run the A* algorithm over the image, with the current robot position, and the goal position, to get the goal path as a set of nodes per tile to cross. As this isn't exactly the best path to follow (way too many stops and turns), we then apply a further algorithm to smooth the path

Path-smoothing
To do this, we chose to use a method we call "ray-casting" to weed out unnecessary path nodes. Imagine we have a path as detailed in this picture, with the start and end nodes marked as "valid" (green):
path.png

We start with the first node, draw a line (ray) to the next node in the path, then draw two more lines parallel to that at a distance representing the robot's width, as so:
raycasting1.png

We keep doing this for every node of the path, until any of these lines collide. When this happens we know that this node cannot be reached directly from the node we're checking for, and as such we need to mark the previous node as valid.
raycasting3.png

After we have done this for all the nodes, and reached the end node, we are left with a path that has significantly less nodes, as well as more direct paths where there was a stepladder effect previously.
finished_path.png

The last mile
Now, finally, we can move the robot through the path we have created. This is done by sending commands to the robot to rotate, and move a certain distance towards the next node in the path. As the robot isn't entirely precise, we decided to not let it move too far per movement command, so it wouldn't veer off course too much, and would be given a chance to "compensate" as it moves towards the goal.

The movement is tracked by taking a new picture with the camera, and doing the same filtering operations as before to find the new robot position and angle, so that we can guide it closer to the node as it approaches. If all goes as planned, it should eventually reach the goal position, without colliding into any of the obstacles!

How to (re)enable Django's admin docs

| 2 Comments | No TrackBacks
If you've used Django before, you may have remembered that Django's admin pages had a Documentation link in the top right corner. This lead to a site which provided documentation for all Models, Views, Tags and Filters that exist in your project, which is immensely useful for devs and designers alike.

In the newer versions of Django this has seemingly disappeared, and the official documentation makes very little mention of it, as it has been split into its own (as of yet undocumented) app. So, you have to enable it yourself by adding the admindocs app and setting up an url pattern for it.

So, to accomplish this, first open up your settings.py and add 'django.contrib.admindocs' to your INSTALLED_APPS, set a SITE_ID if you haven't done so already, then do the following with your urls.py:

urlpatterns = patterns(
    '',
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/(.*)', admin.site.root), # Standard admin url pattern
    # Other URL patterns go here
)
Note that the admindocs pattern has to go before the standard admin pattern, because Django gives you the first view from the top that matches, and the admin pattern is very hungry. :)

Now when you go into the admin section, you should have a shiny new Documentation link that leads to Django's automatic documentation for your project. Enjoy!

Portable Django project with Buildout

| No Comments | No TrackBacks
The last few days I've been working on a project using Django, and to set up my Django projects, I find the best solution is using Buildout. I think messing around with virtual environments is annoying, makes it harder to deploy the project later, and frankly just wastes my time more than it saves it. (It also happens to be the way I learned to do it while working at Opera, but that's besides the point ;) )

The basics

Getting started with Django and Buildout essentially requires two files, the Zope bootstrap.py (available here) and a buildout.cfg for configuring your environment.

A basic buildout.cfg file, utilizing Djangorecipe to install Django, would look something like this:

[buildout]
parts = django

[django]
recipe = djangorecipe
version = 1.1.1
eggs =
	mock
	django-notification
	django-messages
project = my-django-project
This is the configuration for a simple Django project called "my-django-project", which depends on the mock, django-notification and django-messages modules. To build and set up this, you simply enter the following commands:

python bootstrap.py
python bin/buildout
This first runs the bootstrap file, which fetches the necessary modules for running buildout and gives you a buildout binary in the bin/ folder. Then you run the buildout command, which parses the buildout.cfg file, automatically fetching the necessary dependencies, the given Django version (in this case 1.1.1, but you could set it to "trunk" to get the newest development version), and create a version of the Django manager script at bin/django.

This script does exactly what the manage.py script does in a regular django setup, to sync the db you run bin/django syncdb, to start the server you type bin/django runserver, and so on and so forth.

If this is the first time you run the buildout, djangorecipe will also check for the presence of a directory called "my-django-project", and if that doesn't exist, it will create a skeleton Django project with that name, which serves as a great starting point.

All of this greatly simplifies the amount of work needed to start a new django project, you just mock up a tiny buildout config and run buildout, and you have what you need to start easily set up for you.

Taking it further

Now, for me, this still isn't simple enough. It requires the presence of the bootstrap.py file (which isn't strictly a part of the project, and IMO shouldn't be in source control), and two commands. So I made myself a little Makefile to automate the task of running buildout, and it looks a little something like this:

.DEFAULT_GOAL = development
.PHONY = development clean

bootstrap.py :
	wget http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py

bin/buildout : bootstrap.py
	python bootstrap.py

development : bin/buildout
	python bin/buildout

clean :
	rm -rf bin develop-eggs eggs parts .installed.cfg downloads bootstrap.py
This allows me to simply type in "make" in the directory with the buildout config, and everything will be done automatically, and subsequently type "make clean" if I need to clean out the environment again.

Together with this, I've added a .gitignore file (since I use Git for most of my source control needs), that filters out all the buildout cruft, as well as .pyc files and the SQLite db, if you're using one:

*.egg-info
*.egg
*.pyc
*.db
.installed.cfg
bin/
develop-eggs/
downloads/
eggs/
parts/
These two relatively minor additions allow me to more or less forget about everything that has to do with python virtual environments or even that you need to do special things to make it work. Updating the environment is just a simple "make" away, and the resultant environment stays out of my way in git.

Rebirth of the blog + RenrakuOS

| No Comments | No TrackBacks
Yeah, my VPS got nuked due to the VAServ hack. I didn't really care too much, I didn't have much of importance on the server, so I'm just going to restart my blog. Trying with Movable Type this time, as Wordpress gave me a real headache with its hugeness, maybe I'll actually like this one. =p

Lately I have been mostly involved in developing RenrakuOS, which is an experimental managed OS programmed entirely in .NET (using the python-like language Boo, to be exact). There are a few relevant places to check for RenrakuOS info:
At the current I'm the designated maintainer for Apps and BCL code, as well as the de facto owner of the input subsystem (I make the keyboard actually work).

In addition, my priority for the foreseeable future is to create an initial set of docs describing the design of the OS, as well as what makes it special and different from contemporary OSes. This will be released as a set of blog posts.

About me

I am Daniel E. Bruce, a Python and .NET coder.

Currently working on Renraku OS, in addition to some personal Python web projects, using both Django and Pylons.

More info:

Recent Comments

  • Anonymous: I removed the HotkeyService_1.11.01,and the "Can't get WMI AsusManagement object" read more
  • Thomas Evertsson: Hi damn this one was though. but i succeded. format read more
  • Jamie Hemmer: Thanks very much for sharing this interesting post. I am read more
  • Joop: Hey thanks a lot for your story, i'm in the read more
  • Don Preus: We are a group of volunteers and starting a new read more

GReader shared items

February 2010

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28            
OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.01