robotd - a multithreaded TCP/IP robot control daemon

The scenario: you have some physical process which you would like to observe from a range of angles. You may not be able to be in close proximity to the process, so you would like to be able to observe it remotely. Not only this, but you would like other people to be able to perform the same operations, perhaps in parallel and at any time, without interfering with each other.

You might think these requirements are impossible to meet - and indeed, if the users require instant access to the image, they probably are. However, with some simple software and well-behaved hardware, it is possible to provide this service via a Linux box or two, some cheap hardware, and the Internet.

robotd is a multithreaded TCP/IP daemon which allows asynchronous parallel movement requests to be serialised and synchronised with the image acquisition process. It provides a user-friendly command-line interface, or, with the addition of a web server (not necessarily running on the same machine) a simple web interface which anyone can use to acquire an image.

The distribution (available at http://ieee.uow.edu.au/documents/contrib/robotd.tar.gz) only provides an example implementation which is able to control a single axis of the robot. This implementation works with an 8255 parallel I/O card connected to a stepper motor controller and a reed swich circuit (for elementry position feedback, used to find the home position). Naturally, you will need a copy of my 8255 parallel I/O card driver for Linux if you will be using a card such as the PC-14. This is available at http://ieee.uow.edu.au/documents/contrib/PIO.tar.gz, is Copyright (C) 2000 Daniel Franklin and the UoW IEEE Student Branch, and is licenced under the terms of the GNU General Public License version 2.0.

robotd supports extensive logging via the standard Unix syslog facility (logs go in the daemon logfile).

Show us yer code!

What follows is a description of the operation of the daemon, cut straight from the documentation distributed with the program.

The server has at least two active threads at any time, and possibly more. One thread sits listening to a TCP port, spawning a command-parsing thread each time a new connection is established with a client. The other thread sits watching the queue, ready to process any incoming request.

When a client connects, a welcome message is sent to it by the command-parsing thread. This thread now waits for intelligible commands. If it gets a command which it recognises (which may have an optional argument of basically any ordinal type) the request is enqueued, and a signal (SIGUSR1) is sent to the queue manager. Any command-parser thread connected to any client can add requests to the queue.

The queue manager initially sits waiting on SIGUSR1. When it gets the signal, it goes through each job in the queue and processes them sequentially - this allows for additional jobs to be enqueued while the queue manager is processing the current job. After each job is processed, the queue handler pauses for half a second, to allow the camera to stabilise after the move (get rid of the usleep if you don't need this). Then it signals the command-parsing thread (again with SIGUSR1) and waits a further half-second (giving the client time to take a picture or whatever). When the queue finally empties, the manager again waits on SIGUSR1. Note that although the queue handler is sent a signal whenever a job is enqueued, it only makes a difference if we are sitting in a sigwait (), i.e. if the queue is currently empty.

The command-parsing thread is blocked until a job it has placed in the queue has been completed. When it receives the SIGUSR1 from the queue handler, it awaits the next command. Thus the client application knows when the robot has been moved to the desired position, and can be sure that it will be there for at least half a second. For the camera, this is the cue for the CGI script to call the video-capture software and generate a JPG for the returning HTTP stream. A `noop' action is also supported, to enable the user to just take a picture at the current position (the last position moved to before the noop) safe in the knowledge that the camera is not moving.

Command-line options

Just one:

robotd -port NNNN

to run on a port other than the default (which, for no particular reason, is 2468).

Commands

The iDavros is only a single-axis actuator (it can rotate the camera through -170:+170 degrees). Thus its command vocabulary is rather small. It could be readily extended to a multi-axis - perhaps with a choose active joint command, or adding an extra argument to indicate the joint to be moved.

The current vocabulary is as follows:

quit: should be fairly obvious. Terminates the session.
help: provides a short help message, not unlike this one.
home: moves the joint to the home position (zero degrees).
moveto theta: tries to move the joint to absolute position theta degrees.
move theta: tries to move the joint by theta degrees.
does nothing, but pauses for 1/2 second before and after.
getpos: returns the current position of the robot.

Values are bounds-checked (the angle is software-limited to the range described above).

Example Application

A typical example of where this robot daemon is useful is a webcam mounted on a mechanical turntable (possibly with an electronic zoom as well). The UoW IEEE Student Branch iDavros robotic webcam (IEEE Digital Automated Versatile Robotic Observation System) which is available here uses this system. You can get the CGI script (in Perl of course) here. If there are any glaring security holes please tell me - I'm not the world's greatest Perl programmer by any means :-) The script has functions for accessing all of the functionality of the robot, but only uses noop, getpos and moveto at present. You will (naturally) need to change the script to point to the host running robotd (could be localhost).

Some digital photographs of the system are available:

If you want to perform video acquisition, it is suggested that you should use a 2.3 / 2.4 Linux kernel, which have much improved video support compared to 2.2. The IEEE webcam currently uses 2.3.99-pre9 on the web server (bleeding edge on the server - are you MAD??) with a PixelView PlayTV Pro digital video capture card. The software used is the `streamer' program (part of the xawtv package), which captures an image to a file.

Future Plans

The camera we have also supports electronic zoom, and is equipped with autofocus, so we should be able to add basic zoom/wideangle support. This should be a trivial addition to the robot server. Hardware will be somewhat more difficult :-)

On the documentation front I need to draw up the schematics. It's pretty easy to control a stepper motor from a parallel I/O device. For the moment it is left as an exercise for the reader.

Additional commands which may be supported in the future include different measures of angular distance (e.g. radians, grad).


Send me some e-mail: my address is d.franklin@computer.org