Each instrument on the Apache Point Observatory 3.5m telescope has an instrument control computer (ICC) which is the public "face" of the instrument. The ICC receives commands, issue replies and writes data to disk. An ICC may also issue commands (via a separate connection to the hub).
This manual describes how to design an ICC for the APO 3.5m telescope.
The basic architecture at APO is as follows:
A central hub routes all communications. The hub receives commands from commanders (e.g. TUI users) and routes them to actors (e.g. instruments). Actors issue replies, which are sent to all commanders. The hub does not modify commands or replies, except for necessary changes to header information, plus correcting invalid formatting and possibly changing whitespace.
It is important to remember that the 3.5m telescope is a multi-user, remote controlled telescope. There are usually at least two users connected (scientist and telescope operator) and there may well be more (collaborators or scientists waiting their turn). In addition, even people working at the observatory are somewhat remote from the telescope. Thus:
The hub can talk to an ICC using TCI/IP or serial communications. The ICC should live in the computer room, if possible, since it is a warm environment and one capable of safely eliminating excess heat. However, if your ICC is sufficiently rugged and does not generate too much heat, and with approval from APO staff, your ICC may also live in the intermediate level of the telescope enclosure, or even at the instrument.
All communications between the control building and the telescope must be over optical fibers, to protect against lightning damage. We provide optically protected TCP/IP and some RS-232 serial ports. If you use some other protocol then you must provide the optical interfaces and possibly the fiber as well.
Commands are sent to the hub in the following format: actor CmdrID command string
Where:
The hub then strips the actor, assigns a new commander ID (because different users may use the same commander ID) and sends the otherwise-unmolested command to the actor as: CmdrID MsgID command string where MsgID is a historical relic used to make commands and replies process the same that you should ignore.
Each reply from the actor must be tagged with CmdrID (as per the reply format discussed below). The hub uses that number to figure out who sent the command and with what CmdrID, and it includes that information when it broadcasts the reply to all commanders.
The command string must consist of printable ASCII characters. Beyond that, the format is up to the designer of the ICC. However, we do have some suggestions:
One ICC that makes a good model is the DIS ICC. Craig Loomis wrote the DIS ICC with the current hub in mind, and in Python, the preferred language.
The hub has a set of instExpose scripts that provide a unified interface for taking exposure. This offers advantages to both the ICCs and to TUI. The ICCs need only save exposures using the file name and location specified by the instExpose script (rather than trying to figure out where the exposure for this user belongs and what the next sequence number should be). And, of course, TUI takes advantage of the uniform exposure interface to use one code base to control exposures for all instruments.
All instruments should accept stop and/or abort commands while exposing, even if they do no other form of multitasking. Both commands halt the exposure, but stop reads out and saves the partial exposure, whereas abort discards it.
instExpose can support a wide variety of exposure commands. Nonetheless, if you are implementing a new command set from scratch, it will save trouble to emulate DIS or some other modern instrument.
Instruments write data to an NFS-shared disk. The data should be written in FITS format with basic information in the FITS header, including bit depth and image shape. The hub then fills in the FITS header with WCS information, an exposure comment, etc., and notifies commanders that the image is available.
Each command results in one or more replies, ending with a reply saying that the command finished or failed. Actors may also output unsolicited replies, and this can be very useful if an instrument has environmental monitors. The instrument can report a problem right away using an unsolicited reply, rather than waiting until the hub sends a command.
A well chosen set of replies is the very heart of a well-designed ICC. Designing a command set is fairly easy because an instrument designer has a very keen sense of what the instrument should do. A good reply set is less obvious, yet is crucial for informing users as to what is going on inside the instrument. Thus this section starts with a section on overall design criteria before going into details of the reply format.
Replies are the only way users know what an instrument is doing! When a user sends a command to your instrument, the other users basically don't know about it until they see the resulting replies. All users (even the one who sent the reply) rely on the instrument's replies to keep track of what is going on.
Thus an ICC should issue a reply whenever the instrument changes state. When an exposure starts, when readout starts, when filter change starts and finishes, when temperature is read, etc. Be chatty!
Here are some specific guidelines:
For commands that take a long time to execute, issue a reply when the command starts and another when it finishes (successfully or otherwise). Also:
It is helpful to display a summary of overall health and status. One easy way to send this info to TUI is to send a "status word": a set of binary bits, each of which indicates one item of state. Suggested rules (which make the info easy to use):
Actors output replies in the following format: CmdrID MsgID MsgType ReplyData
where:
The hub then processes the header of the reply, resulting in the following being sent to commanders: Prog.User CmdrID Actor MsgType ReplyData
Technically speaking, the hub actually parses the message data and re-assembles it before sending the reply to the commanders. But the message data should not be affected unless it was mis-formatted.
Each reply has an associated type character, as follows:
Solicited replies (triggered by a command) must end with exactly one ":", "f", or "!" reply. Before that, you may issue as many "i" or "w" replies as you like. (You may also issue more than one ">" reply, but it violates the intent of that message code.)
Unsolicited replies (not triggered by a command, thus CmdrID = 0) do not have any such restrictions.
The data in a reply must be in keyword-value format. This consists of one or more keywords separated by semicolons; each keyword may also have one or more comma-separated values. For example: NoValueKeyword; OneValueKeyword=val1; ManyValueKeyword=val1, val2, val3...
Keywords indicate the state of your ICC. Typically the user interface will set up a callback to be triggered by a particular keyword, so its display can be kept up-to-date. For this to work well, keywords should:
Examples:
The picky details about keyword-value format are as follows:
Basics:
Keywords are words. We suggest you stick to legal C identifiers, though the actual rules are a bit broader. Case is ignored.
Values can be any of:
"an \\ example \" string containing \\ and \""
Please use APO standard units for commands and replies. These include: