23.11.2014 Views

2006 Scheme and Functional Programming Papers, University of

2006 Scheme and Functional Programming Papers, University of

2006 Scheme and Functional Programming Papers, University of

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

could be run indefinitely. This functional method contrasts typical<br />

servo development where files are “followed” after the gimbals<br />

are positioned before each diagnostic run. This technique was<br />

motivated by the use <strong>of</strong> functional programming: Comm<strong>and</strong>s are<br />

created from nested calls <strong>of</strong> functions whose only root variable is<br />

represented by a function, Mz<strong>Scheme</strong>’s current-milliseconds.<br />

6. <strong>Programming</strong> Techniques<br />

This section describes many <strong>of</strong> the reusable techniques that were<br />

developed while working with Mz<strong>Scheme</strong> version 209.<br />

6.1 Senders <strong>and</strong> Displayer<br />

We wrote a simple displayer to show, in sequence, incoming <strong>and</strong><br />

outgoing messages that access remote subsystems. Make-sender<br />

labels the diagnostics (to indicate their origin) <strong>and</strong> sends them to a<br />

program running in a separate Dr<strong>Scheme</strong> workspace (i.e., another<br />

window with a REPL.) Using a separate workspace prevents cluttering<br />

the operations REPL. A socket is implemented so that the<br />

displayer may also be hosted on a separate computer.<br />

The displayer is normally a file that evaluates the following:<br />

(letrec<br />

((uos (udp-open-socket))<br />

(buffer (make-string 256))<br />

(lupe (lambda()<br />

(let-values<br />

(((n ipa port)<br />

(udp-receive! uos buffer)))<br />

(display (substring buffer 0 n))<br />

(newline))<br />

(lupe))))<br />

(udp-bind! uos #f 9999)<br />

(lupe))<br />

The sender to each remote system is created with the function:<br />

(define (make-sender soc ipa port prefix)<br />

(if (equal? prefix "")<br />

(lambda (text)<br />

(udp-send-to soc ipa port text))<br />

(lambda (text)<br />

(udp-send-to soc ipa port text)<br />

(udp-send-to<br />

soc "127.0.0.1" 9999<br />

(format "~a ~a" prefix text)))))<br />

When the sender is created, non-empty text in prefix will cause<br />

all expressions passing through that sender to be displayed with the<br />

contents <strong>of</strong> prefix. The scripting environment also sends received<br />

expressions to the displayer, so that a clear ordering <strong>of</strong> messages is<br />

indicated in the window.<br />

6.2 Simulating Transactions<br />

We wrote a general transaction simulator before implementing ethernet<br />

communications. This simulator was used <strong>of</strong>ten:<br />

(define (sim-transaction sleep-sec text)<br />

(thread<br />

(lambda()<br />

(sleep sleep-sec) ; simulate round-trip<br />

(eval<br />

(eval (read (open-input-string text)))))))<br />

It first sleeps to simulate the expected round-trip delay, then evaluates<br />

the outgoing expression, <strong>and</strong> finally evaluates the result which<br />

is returned from a local simulation <strong>of</strong> the remote function. For example,<br />

the following will simulate stopping the gimbals:<br />

(sim-transaction 1.5 "(list ’do-gimbals-mode<br />

(do-mode corvus<br />

’stop))")<br />

The simulation requires a local definition (a simulation) <strong>of</strong> the<br />

function do-mode <strong>and</strong> the definition <strong>of</strong> the telescope designator<br />

corvus. The callback function do-gimbals-mode is at the core <strong>of</strong><br />

the local s<strong>of</strong>tware that is being tested. Simulating the remote definitions<br />

also guided the creation <strong>of</strong> a clear, executable specification for<br />

the interface. For long delays, such as waiting several minutes for<br />

a telescope to move to a new location, the reference returned from<br />

sim-transaction was available for manipulating the thread.<br />

6.3 Exception H<strong>and</strong>lers<br />

We added exception h<strong>and</strong>lers to the evaluator functions when we<br />

started using the new s<strong>of</strong>tware. During development, it was better<br />

to let <strong>Scheme</strong> h<strong>and</strong>le the exception <strong>and</strong> generate an error message.<br />

The exception h<strong>and</strong>ler is mainly used to prevent programs from<br />

halting due to misspelled or improperly formed expressions that<br />

are generated by new clients.<br />

6.4 Connection Protocol<br />

The communication paradigm relies on application level error control<br />

to compensate for the lack <strong>of</strong> detection <strong>and</strong> recovery provided<br />

by TCP-like protocols. To prevent the applications from halting, the<br />

message evaluators are wrapped in exception h<strong>and</strong>lers which return<br />

any error message to the client. The motion control systems check<br />

messages by content; e.g., a rate <strong>of</strong> a thous<strong>and</strong> degrees per second<br />

is not accepted even if delivered without error. Most systems<br />

are designed to tolerate missed messages; e.g., a second order trajectory<br />

vector can be missed without noticeable errors in tracking.<br />

The clients nearly always use the response from a server to verify<br />

correct delivery; e.g., if a client sends a message to start a computational<br />

process in SORAPS, the response is used for verification.<br />

We started to develop general techniques for error detection,<br />

such as echoing requests along with the responses, but we stopped<br />

for the lack <strong>of</strong> ways to cause or at least experience network errors.<br />

6.5 Casual Polling <strong>of</strong> Remote Systems<br />

Because TCP connections are avoided for practical reasons, we use<br />

an efficient technique for for getting uninterrupted repetitive data<br />

like telemetry. About every 8 seconds, the remote telemetry system<br />

is sent a message that requests data for ten seconds. This keeps the<br />

data flowing, it doesn’t require the client to terminate the messages,<br />

yet it does not require a transaction for every message. A data<br />

message is not repeated after an overlapping request. Generally,<br />

the requests have the form:<br />

(get-data ’callback-function seconds-to-send)<br />

The server is required to send expressions <strong>of</strong> the form:<br />

(callback-function the-data)<br />

A related form is:<br />

(get-data-if-available ’callback-function<br />

within-the-next-n-seconds)<br />

The server is required to send new data only if it is available within<br />

the next n seconds. This can be used when a telescope system is<br />

scanning for an object <strong>and</strong> it needs a camera to report when it<br />

firsts detects the object. The time limit prevents the camera from<br />

unexpectedly sending information at a much later time.<br />

6.6 Message Timing<br />

The arrival time <strong>of</strong> some expressions are stored in global variables.<br />

Typical functions that use these variables determine lateness <strong>and</strong><br />

78 <strong>Scheme</strong> <strong>and</strong> <strong>Functional</strong> <strong>Programming</strong>, <strong>2006</strong>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!