robotic circumnavigation of earth
Fri, 19 Aug 2011 22:49 categories: blogHas it even been done before? Searching the internet only finds huge manned solar boats.
Swimming around the earth with solar power should be much easier than flying as one doesnt have to worry about the night (really? see below). Another advantage is, that nations tend to try and protect their airspace whereas swimming through international waters should be fine.
The idea is, to have an autonomous robotic vessel, powered by photovoltaic means and two underwater propellers and doing navigation with gps. While shipping around the world, it would be great to have photos from all the exotic coastlines the robot approached. Image analysis could also be used to avoid getting too close to potential obstacles in the water.
There would be two possible routes. Either hoping to get through panama and suez canal together with other ships (and try not to get stuck by the canal sides) or swimming around cape horn and cape of good hope.
Having an uplink to the vessel would be great and certainly very useful but there doesnt seem to be any solution for satellite navigation that doesnt cost a fortune, isnt a huge installation and works around all the globe? Such an uplink would make lots of things much easier and would avoid loosing the robot.
A quick mockup of how such a robot could look like:
Open questions:
- What about corrosion of the propeller/motors due to salt water?
- What about extreme temperatures? will the electronics cope with that?
- Could something cover the solar panels? Ice? Dirt?
- What about the Night? Build in batteries to keep it powered? Would the robot drift away?
- Are there currents too strong for the robot to overcome?
- Will motors wear out?
- Will someone find it and take it away?
- Is it legal?
- Go through suez/panama canal? How to avoid getting stuck there?
- Could it strand on a coast or riverside being stuck in plants or rocks?
- Enough power from solar cells? How large do they have to be?
EDIT:
Apparently people are already into this:
- http://www.engadget.com/2012/03/15/swimming-robots-break-record/
- http://www.bbc.co.uk/news/technology-17367984
- http://liquidr.com/files/2012/03/PacX_World-Record_03_13_12.pdf
- http://www.engadget.com/2011/11/19/wave-glider-robots-set-out-to-explore-the-seven-seas-break-the/
- http://news.cnet.com/8301-13772_3-57327023-52/ocean-faring-robots-set-sail-on-guinness-record-attempt/
- http://liquidr.com/
windows xp on qemu
Thu, 18 Aug 2011 20:33 categories: blogWorks like a breeze - only note to NOT use a qcow diskimage (will be horribly slow) and use the following qemu options to select network and sound hardware that windows knows about out of the box:
To create a disk image use one of the following commands depending on whether
your system has fallocate
support or not:
$ dd if=/dev/zero of=windows.img bs=1 count=1 seek=3000MiB
$ fallocate -l 3000MiB windows.img
If your filesystem supports sparse files, then your image will not immediately occupy its full size on your disk. Then start qemu like this:
$ qemu-system-x86_64 -k en-us -enable-kvm -hda windows.img \
> -cdrom windows_xp.iso -net nic,model=rtl8139 -net user \
> -soundhw ac97 -m 1024
For bare Windows XP you do not need to specify the -m 1024
option. Windows XP
will be quite happy with the default of 128 MiB RAM. But given the amount of
RAM current hosts have available I usually throw in a bit extra.
My roommate akira used this setup to connect to a university distance course which required the students to use the proprietary Adobe Connect software to connect to the classroom. It turns out that with above setup, the speaker and microphone forwarding between the host and the Windows XP guest worked out of the box. Getting a USB webcame to work turned out to be a bit more tricky but can be accomplished by adding the following to the qemu invocation above:
$ qemu-system-x86_64 [...] \
> -readconfig /usr/share/doc/qemu-system-common/ich9-ehci-uhci.cfg \
> -device usb-host,vendorid=0x046d,productid=0x0825,id=webcam,bus=ehci.0
This will attach the hosts usb device with id 046d:0825 (a Logitech webcam in
this case) to the qemu guest. It doesn't even seem to be necessary to unload
the kernel module responsible for the webcame (uvcvideo in this case) from the
host. The guest seems to be able to cooperate well with it. The interesting bit
of above invocation is the -readconfig
argument which points to
/usr/share/doc/qemu-system-common/ich9-ehci-uhci.cfg
which is a hardware
configuration for qemu written by Gerd Hoffmann. It creates a USB 2.0 adapter
with companion USB 1.0 controllers as a multifunction device on one of the
guests PCI slots. This has the advantage that attaching any USB device from the
host to the guest bus ehci.0
will work no matter whether the device is USB
1.0 or 2.0. If you know what you are doing you can always specify -usb
or
-device usb-ehci,id=ehci
, depending on the USB standard of your device and
then attach it to the right bus. But the -readconfig
solution will work out
of the box in both cases. You can read more about qemu and USB in the excellent
documentation which can be found at
/usr/share/doc/qemu-system-common/usb2.txt.gz
or at
docs/usb2.txt
in the qemu git which was also written by Gerd Hoffmann.
In case you want to read data from the guest with the virtual machine switched off you can mount the disk image you created earlier by doing:
mount -o loop,offset=32256 windows.img windows
Or find out the offset with fdisk: switch display units to sectors with 'u' and print the partition table with 'p'. Then do the math for the proper partition offset. With a default windows xp install it will be 63 sectors times 512 bytes = 32256 bytes.
python for-loop scope and nested functions
Sun, 14 Aug 2011 13:57 categories: blogI recently stumbled over some nasty problems with respect to python scopes in for loops and nested functions therein.
Firstly, try out this snippet:
>>> a = []
>>> for i in range(10):
... a.append(lambda: i)
>>> for f in a: f()
While I expected it to print 0-9 it printed 9 ten times. The reason is twofold.
Firstly it might not be very straightforward but the following should not be surprising:
>>> for i in range(10): pass
>>> i
9
This is, the loop variable is not local to the for loop. There is no new scope created for loops in python. There is only scope for classes and functions.
Secondly, python does late binding with function or lambda calls. The following might be a bit more surprising:
>>> i = 0
>>> f = lambda: i
>>> i = 1
>>> f()
1
Since there is no scope for loops, the following will also print 81 nine times:
>>> a = []
>>> for i in range(10):
... j = i**2
... a.append(lambda: j)
>>> for f in a: f()
The problem of course presented itself to me in a much weirder manner which made it take quite some time until I figuered out the root cause of my problem. My problem was, that I indeed expected the first example to print the numbers 0-9 which it doesnt for reasons explained above.
What I was struggeling with, were gtk and dbus callbacks. My code looked like this:
for iface in interfaces:
def on_succes_cb(msg):
print iface
iface.MyDBusMethod(reply_handler=on_success_cb)
This of course printed the last value iface had in this loop on every invocation of the reply_handler. On a sidenote is is surprising to see how sparsely documented the use of reply_handler and error_handler in dbus python is and how seldomly it seems to be used.
Another piece of the same code looked like this:
for func in ["RequestScan", "EnableTechnology", "DisableTechnology"]:
button = gtk.Button(func)
def button_onclick(button, event):
print func
button.connect("button_press_event", button_onclick)
hbox.pack_start(button, False, False, 0)
And of course every time the differently named buttons where clicked it would print "DisableTechnology".
So how to fix it?
Lets see how to fix the first example:
>>> lst = []
>>> for i in range(10):
... lst.append(lambda j=i: j)
>>> for f in lst: f()
What's the difference? The lambda now has it's own local variable j and in contrast to i, the scope of j is local to the lambda. This will now successfully print 0-9.
But this doesnt help me with my above dbus and gtk callback problems as I can't freely change the function signature for the callbacks. So what to do?
The solution Michael 'emdete' Dietrich pointed me to, was to just use a wrapper function around my code which gets the loop variables as its arguments. By doing so, the loop variable gets copied into the function scope and will not be changed there by subsequent loop iterations.
>>> lst = []
>>> for i in range(10):
... def bind(j):
... lst.append(lambda: j)
... bind(i)
>>> for f in lst: f()
or
>>> lst = []
>>> def bind(j):
... lst.append(lambda: j)
>>> for i in range(10):
... bind(i)
>>> for f in lst: f()
I agreed with emdete that the second variant looks cleaner. The first variant would have made sense if loops had their own scope but hey, they havent. Using the second variant also avoids confusing with variable usage etc.
So now my code looks like this:
def bind(iface):
def on_succes_cb(msg):
print iface
iface.MyDBusMethod(reply_handler=on_success_cb)
for iface in interfaces:
bind(iface)
and this:
def bind(func):
button = gtk.Button(func)
def button_onclick(button, event):
print func
button.connect("button_press_event", button_onclick)
return button
for func in ["RequestScan", "EnableTechnology", "DisableTechnology"]:
button = bind(func)
hbox.pack_start(button, False, False, 0)
To me it always appeared unintuitive that scope is limited to functions and not extended to code blocks. But on the other hand it mimics other languages with side effects:
int i;
for(i=0; i<10; i++);
printf("%d\n", i);
There was a big discussion (64 mails) with several possible solutions on the python-ideas list three years ago: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html
But it doesnt seem as if anything caught on. Hence, for the time being one has to create just another function for new scope. Works for me. Still, even though understanding why and how it works I have trouble finding the first example easily understandable. I would still expect it to work differently.
new toy
Mon, 06 Jun 2011 16:41 categories: blogFinally my new toy arrived: Seagate FreeAgent GoFlex Net
- 1.2 GHz Marvell Kirkwood 88F6281
- 128MB RAM
- 256MB NAND
- 1x GbEthernet
- 1x USB 2.0
- 2x SATA
- 2.3 W power consumption
I acquired it for 40 EUR which is quite a bargain for a computer with these specs.
I already found the pin headers for RX and TX so hacking it can start right after I got myself a new serial usb adapter.
In the photo above, there is a 10-pin header. In the upper row, the three pins from the left are GND, TX and RX. With screen I can then use:
screen /dev/ttyUSB0 115200
latex with blogofile
Sat, 04 Jun 2011 23:29 categories: blogI can now finally add latex formulas to this blog :)
I am using this filter.
To test, have some maxwell: