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).
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.
Just one:
robotd -port NNNN
to run on a port other than the default (which, for no particular reason, is 2468).
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).
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.
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).