Monday, 28 November 2011

Drive system

In order to drive the tank and power a computer, we need 1 or more batteries that can last a decent period of time.

The first thing that comes to mind is a car battery, but after some research I learned that car batteries are not suitable as they are designed for high amp, short term power to start an engine and would not last very long at all and also these batteries do not like being discharged completely and can become damaged quite easily like this.

We need long lasting energy to power a laptop and the other components onboard and it seems a "VRLA" (or Valve-Regulated Lead-Acid) battery is the most suitable type.
These are the batteries used in electric wheel chairs, garage doors, alarm systems, etc. and prices can vary quite a bit, but there seems to be some affordable varieties on eBay.

Our dad being a very resourceful person managed to find an old lead acid battery in the garage and so we will use this as our first attempt and upgrade if we need to.

We purchased some 12V 15RPM geared motors from eBay and Rob built a little platform that we could use to test out our new equipment.
He made up some little brackets for the motors and found some old plastic wheels, which he used some metal to put a flat side in the hole so it would be keyed like the motors axle.
There is a single caster at one side, the 2 mounted motors on the other, the lead acid battery on top and some terminals to connect all the wires together.

As these motors are geared for torque, not speed, it was moving quite slow, but that will change a little when we get appropriate sized wheels, etc.

This made us think that because we are going for pulling power, not speed, we should test out the load carrying capacity of the rig.
We loaded up an additional full size car battery and it moved all that effortlessly.
After that we loading up more and more until we got to a point where rig stopped moving, but only because the motors were ripping through the plastic wheels.

This made us pretty confident that these 12v motors would be strong enough for any equipment we want to load up, as long as the motors are strongly coupled to the wheels (or in our case, the tracks).

Streaming webcams

I was envisioning a responsive interface with 2 video feeds, one for the direction of travel and another for the direction of the gun.
I figured because the server and client are on a local network, 2 video feeds should not max out the bandwidth of a wifi network and it would be easy.

Well as usual, there is more to the picture. Rob and I bought 2 webcams that are known to work in Linux and I started experimenting with different streaming applications.


VLC never ceases to amaze me, it is so versatile and just works for so many things.
Using X11 forwarding, the VLC GUI provides a very simple way of saying "Stream my /dev/video1 device over HTTP" and then browsing to that ip:port just works! You can also connect another remote VLC to the feed and view it that way.

This GUI action can then be translated into its command line equivalent and you would have a simple scriptable method of streaming a webcam.
The command line you end up with can be a little hard to create as there are a lot of sane defaults the GUI uses that aren't used by default on the commandline.


This is another incredibly complete set of tools for anything media related.
FFMPEG's way of accomplishing this is to configure and start an FFSERVER instance, which accepts HTTP video feeds and provides a simple web server to view it.

I created a couple of different configurations and this is where I first discovered the main problem with my idea.
It seems there is a limitation where 2 webcams cannot be streaming at the same time.

This could be a limitation of the drivers at an operating system level, or because some people have suggested the bus cannot support 2 cams at once.
Either way, it seems we will have to only use one webcam initially and maybe add functionality to switch between the two at a later stage.

The FFMPEG mailing list was very useful for helping me get this working, a big thank you to Belcampo for the help.

MJPG Streamer

This is an interesting project, an MJPEG is a Motion-JPEG, which is essentially a streaming set of jpeg images that make up the frames of a video.

Using MJPGStreamer is simple, just install the package from your software repository and execute a command like this:
mjpg_streamer -i " -d /dev/video0 -o -w /usr/www -p 8081"
That is all you need to get video from the webcam and stream it over HTTP on port 8081.
Notice the optional -w /usr/www - During the installation of the package, it puts some HTML content there so when you start the server it can give you an explanation of what's going on and a demonstration of its features (and there are quite a few!)

I was pretty impressed with its simplicity and it means the client browser does not need any special video codecs installed, as long as the browser can render images.


The last streaming option I experimented with was Streamer.
Streamer is very simplistic, all it does is take a snapshot or video from your webcam and dump it to disk as a file.

The reason I considered this program is because I tried a (slightly nasty) hack to get 2 webcams working at the same time.
By saving a snapshot from one, then a snapshot from the other in rapid succession, I was able to craft up a little ajax page that interleaves requests for these images, in effect providing 2 video feeds at once.
The refresh rate was a little slow, but it was the only way I could see how to accomplish 2 feeds at once... even if it wasn't very good!

The problems

The 2 biggest problems were:
  • The limitation of only streaming one webcam at a time
  • Long delays

The proper video streaming options (VLC and FFMPEG) have the nicest videos and a decent framerate, but the video has to buffer up a little first, which results in something in the order of 6-10 second delays - which is not ideal.

If I used Streamer with one webcam, the delay was quite small, but the framerate was not fantastic (1-3 fps). Using 2 webcams was probably <= 1 fps - but using 2 webcams was just a proof of concept.

MJPG seemed to provide a happy middle ground. The framerate and the delay were not ideal, but acceptable and this seems like the most likely solution for us at this stage.

Using the parallel port

Initially the plan for the tank was a NetDuino, but as we are not experts with microcontrollers, it seems like simply sending commands to the NetDuino via USB is not a common use. The USB is more suitable to load programs, not communication. It can definitely be done, but does not seem simple.

The new plan

This made us turn to more basic methods and I discovered the parallel port!
We found an old laptop in the garage that has 1x USB port and 1x parallel port.
So instead of using a small lightweight NetDuino, we plan on using a full blown computer!

The setup will (hopefully) include a Sinatra/Rails webapp running which will control the parallel port, and therefore control the motors for movement, firing, etc.
This webapp should be mobile browser friendly and with the help of a PCMCIA wifi card that has the ability to be put into master mode, the tank should broadcast its own wifi network so there is no reliance on being close to a router (for field tests).
The web interface should also provide a video stream from the webcam(s) so hypothetically you could control it without line of sight.

I did a simple test to see how easy using the parallel port from Ruby was and documented it over at my blog here:

It worked well, and because we intend on using Ruby on the server side it should be quite easy to setup control via a web page :)

Using /dev/port

The method I documented takes advantage of the /dev/port special file.
This provides a map of every IO port on the system and requires privileged access.
The address of the parallel port is pretty standard and google will generally suffice, but you can discover the address of this port by searching through /proc/ioport.

As mentioned in my blog post, there are 8 data pins, and using /dev/port makes turning these pins on and off really easy.
All you have to do is open the file for writing, seek to the address of the parallel port and write 1 byte (8 bits) where each bit corresponds to a pin. If you want to change the state of the port, you simply seek back and overwrite it again.

Here is my example script.

This method requires root access by default and can be dangerous if other parts of the file are tampered with, so linux provides another way of access the IO ports.

Using /dev/parport0

This method uses the Linux IOCTL mechanism.
I'm no expert with this stuff, but I have a much better understanding of how this works now than when I was just using /dev/port.
This method is similar, but there is a permissions system in place that requires the process that wants access to the parallel port to request it from the OS first.

First you need to open /dev/parport0 as a file for writing as usual, then you need issue an IOCTL to claim that port. Once you can claimed it for use, you can then issue other IOCTL commands for reading and writing and once your done, you need to issue an IOCTL to release it back to the OS again.

This is a bit more complicated that the last method, but it seems like the proper way to do it. IOCTL is a very Linux / C thing, but luckily the Ruby IO library contains a basic implementation.

Here is my example script.

As you can probably see, the IOCTL commands are just constants which I needed to look up to find. I found another Ruby example which is much more complete here.

Thursday, 24 November 2011


So I went to watch my girlfriend's dad have a rally drive experience, it was really cool.

When out of nowhere I hear a rumbling noise as I turn around what do I see?

That's right!
A TANK!!!!

So needless to say, I went and further examined it for my knowledge of how a real army tank is made, this tank had been to Vietnam and has now been retired.

I took a bunch of photos, especially of the track system as this is one of the parts we think we will have to custom build from scratch.