Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.apo.nmsu.edu/Telescopes/HardwareControllers/GalilMirrorControllers.html
Дата изменения: Tue Jan 21 21:51:11 2014
Дата индексирования: Sat Apr 9 23:28:42 2016
Кодировка:

Поисковые слова: ngc 253
Galil Mirror Controller

Galil Mirror Controllers

By Russell Owen

Contents

Introduction

This manual describes motion controllers used to control various mirrors and other devices at Apache Point Observatory. The manual describes the basic software and wiring common to all devices. It also describes most or all of the controlled devices, including software and wiring additions. (At the time of this writing, the SDSS engineering camera is not described.)

Each motion controller consists of a Galil DMC-15x0 motion controller, added software described in this manual, and a mixture of stepper motor and servo motor drivers. The stepper motor drivers must include an "on full step" output if you wish to power down the motors after a move (as we do in most cases, to reduce generated heat). One such driver is the Intelligent Motion Systems IMS-483.

These motion controllers take as input the length of each actuator, in microsteps. There is no attempt to deal with "natural" units, such as μm, nor with a "natural" frame of reference, such as piston, tilt and translation of a mirror. This decision was made because the Galil motor controller's built-in programming language is primitive and the number representation has very limited precision.

There are also documentation from Galil which describe the built in command set, wiring and electrical specifications. The newer Galil documentation is divided into two manuals, one for commands, the other for everything else. The older documentation combines everything in one fat manual. The built in Galil command set is not used for normal motion, because the added software provides higher-level commands. But the built in language is worth knowing about, as it can be very handy for engineering.

Commands

The following commands are intended to be used interactively. The behavior of these commands may be altered by device-specific modifications (described elsewhere in this manual):

Engineering Commands:

There are additional commands in the Galil that are only not documented here, as they are intended for internal use. For a complete list, see the source code (preferably the text files, as the code in the Galil has the comments stripped away to save memory).

Axis Variables A, B, C, D...

Motion commands require a position or other parameter for each axis. To execute these commands, first set variables A, B, C, D... to the desired position or other value (see the command for details), then execute the command. To leave an axis unchanged, leave the variable alone. If you set a variable and want to clear it, set it to MAXINT. To clear all variables at once, simply execute any non-motion command, such as STATUS.

XQ #COMPVAR

Computes variables needed for operation, based on user-specified constants. As such, it should be executed whenever you change any user-specified constant. It is also executed automatically at power up.

It is a grave mistake to change any user-specified constants without then executing COMPVAR. At best your changes will be ignored, but you might put the Galil into an inconsistent state resulting in very strange behavior.

Warning: If you change any constants dealing with range of motion, you should also home the system after running COMPVAR.

XQ #HOME

Homes all axes using the algorithm described below. Before calling, set axis variables A, B, C... to any value other than MAXINT (the default) for the axes you wish homed. Homing is prohibited if any axis is moving. An axis must be homed before it can be moved using MOVE or MOVEREL.

If the controller has been homed at least once since last power up, the position error (change from last home position) is reported. This error may be due to lost steps or an actual change in the home position due to inaccuracy in the home switch or positioning mechanism.

Caveats:

XQ #MOVE

Moves to the given absolute position, in microsteps. Before calling, set axis variables A, B, C... to the desired position. Example, moving only axes B and C (all spaces are optional):

B = -5623
C = 25
XQ #MOVE

This command prints the duration of the move for each axis, the target position and, when finished, the actual end position. The command does not return until motion finishes and is verified to have completed successfully.

If correction is enabled, then at the end of the move the encoders are read and a corrective move is made of all eligible actuators.

If MOFF = 1 then the motion will be rounded to the nearest full step, and the motors powered down WTIME seconds after the move completes. If MOFF = 0 then the motion will be to the nearest microstep and the motor current will be left on (motor current may automatically be reduced after a short time by the motor drivers, but the Galil motion controller has nothing to do with such current reduction).

XQ #MOVEREL

Like MOVE except the specified position is an offset, relative to the target position. The default offset is zero.

XQ #SHOWPAR

Displays constant (but settable) parameters. If the system includes additional device-specific enhancements then additional lines showing device-specific parameters may be appended.

Sample output for a 4-axis system with no device-specific enhancements. A leading colon has been removed:

XQ#SHOWPAR
 02.01, 4 software version, NAXES number of axes
 0, 1, 00 DOAUX aux status? MOFF motors off when idle? NCORR # corrections
 00.10, 00.00, 30.00 WTIME, ENCTIME, LSTIME
-000500000, -000500000, -000500000, -000500000 -RNGx/2 reverse limits
 000500000,  000500000,  000500000,  000500000 RNGx/2 forward limits
 000050000,  000050000,  000050000,  000050000 SPDx speed
 000005000,  000005000,  000005000,  000005000 HMSPDx homing speed
 000500000,  000500000,  000500000,  000500000 ACCx acceleration
 000000000,  000000000,  000000000,  000000000 MINCORRx min correction
 000000000,  000000000,  000000000,  000000000 MAXCORRx max correction
 000000050,  000000050,  000000050,  000000050 ST_FSx microsteps/full step
 000005000,  000005000,  000005000,  000005000 MARGx dist betw hard & soft rev lim
 000000000,  000000000,  000000000,  000000000 INDSEP index encoder pulse separation
 0000.0000,  0000.0000,  0000.0000,  0000.0000 ENCRESx encoder resolution (microsteps/tick)
OK

XQ #STATUS

Displays the current status of the controller, including whether axes have been homed, the commanded position, current position and a status word for each axis. If an axis has not been homed, the position information for that axis is invalid and will be displayed as all 9s. If the system includes additional device-specific hardware that has to be managed for motion to begin and end (e.g. brakes or clamps) then additional lines of status showing the status of that hardware will be appended.

The meaning of current position depends on whether the axis is a stepper or servo motor, and whether or not it has an auxiliary (optional) encoder:
No Aux. EncoderAux. Encoder
Stepper Motorcommanded positionaux. encoder position
Servo Motormotor encoder pos.aux. encoder position

Sample output for a 3-axis system with no device-specific enhancements. A few leading colons have been removed:

XQ#STATUS
-001497400, -000767250, -001199000 commanded position
-001497400, -000767250, -001199000 actual position
 00065537,  00065540,  00065540 status word
OK

XQ #STOP

Halts the axes and (if MOFF = 1) powers down the motors. Warning: may not halt the motors on a full step.

Engineering Commands

Engineering commands are not intended for use by the TCC. They are more likely to change over time than commands used by the TCC. They may not return OK when finished.

XQ #GOFS

Moves slowly forward to the next full step (as reported by the stepper motor drivers). Before calling, set axis variables A, B, C... to any non-MAXINT value for the axes you wish to move. Axes with servo motors are not moved; no warning is given.

XQ #GOIND

Moves forward at speed HMSPDx to the next index pulse. Before calling, set axis variables A, B, C... to any non-MAXINT value for the axes you wish to move. Axes without an index pulse encoder (INSEPx=0) are not moved; no warning is given.

XQ #GORLIM

Runs into the reverse limit switch at full speed. Before calling, set axis variables A, B, C... to any non-MAXINT value for the axes you wish to move.

Warnings:

Device-Specific Modifications

Galil motion controllers may be modified to support special needs for specific devices. Local modifications consist of several parts:

The following subroutines must be replaced. This can be done by starting your file with DL #LCMPVAR and including all of the other subroutines listed, ending with a backslash on its own line. See existing local modification files for examples of how this is done. In addition to the required routines below, you may add any subroutines you wish, preferably beginning with the letter L to avoid confusion with built-in routines.

#LCMPVAR

Additions to #COMPVAR, which computes variables at power up and reset. You must define #LVERS to the current version of your local modifications. This is also a good place to define any constants or initialize any variables needed by your local modifications. All constant or variable names should begin with "L".

#LGO (was #LMINIT in version 1.5)

Actions to perform just before each motion begins (just before the motors are turned on if MOFF=1). Test for A, B, C... <> MAXINT to see which axes are about to move. Test _PRA <> 0, _PRB<>0... to see if the specified axis is actually being commanded to go anywhere new. The value of _PRx is either the amount of the commanded move or in some cases (such as finding the reverse limit switches) an upper limit. It is important that this code be "restartable"; if #LMINIT is interrupted (e.g. due to a power failure) then a subsequent call to #LMINIT should finish the initialization sequence.

If initialization takes significant time then you should be smart and only initialize if it has not already been done. If you fail to do this you will not only waste time but you will also make the reported time for a #MOVE or #MOVEREL incorrect (because the time estimate only takes into account one initialization, whereas the move calls #LGO twice).

#LSTATUS

Additions to #STATUS, the status display. Display the state of any interesting hardware you've added.

#LSHWPAR

Additions to #SHOWPAR, the show parameters display. Display the value of any interesting constants you've added.

#LMSTIME

Add the time needed to perform the actions in #LMSTOP for each axis to RESx, in seconds. This allows an accurate reporting of the motion end time. Test for A, B, C... <> MAXINT to see which axes are about to move, and don't increase RESx unless the axis is going to be moved (or, more precisely, extra time is required to stop that axis for whatever reason).

#LMSTOP

Actions to perform after a move completes (just before the motors are turned off, if MOFF = 1). It is important that this code be "restartable"; if #LMSTOP is interrupted (e.g. due to a power failure) then a subsequent call to #LMSTOP should finish the end-of-motion sequence.

#LMVTIME (was #LMITIME in version 1.5)

Add the time needed to perform the actions in #LGO for each axis to RESx, in seconds. This allows an accurate reporting of the total motion time. Test for A, B, C... <> MAXINT to see which axes are about to move, and don't increase RESx unless the axis is going to be moved (or, more precisely, extra time is required to initialize that axis for whatever reason). If LGO is smart about only initializing when not already initialized then you should also make #LMVTIME smart in the same way.

#END

This is a placeholder for the end of code. Test routines are appended from this label, overwriting anything that follows. Hence nothing should follow!

Internals

Basics

The controller represents numbers using 6 bytes of integer followed by 2 bytes of fraction, for a range of:

-2147483647.9999 to 2147483647.9999

The Galil keeps track of positions in microsteps, or in the case of servo motors, in motor shaft encoder ticks. I use the term "microstep" for both cases. For stepper motors, the number of microsteps in a full step is determined by the stepper motor driver, and the corresponding value must be set in ST_FSx. A full step is defined as a magnetic detent on the stepper motor; it is also where the motor will go if only one coil is energized. For servo motors there is no concept akin to a "full step" and ST_FSx should be set to 1.

I had some trouble determining if a typical 200 step motor had 200 magnetic detents. Most motor manufacturers said yes, but a few claimed that 200 step motors had only 50 magnetic detents. I then tested several different stepper motors (including one 400 step motor) and found that all "n" step motors I tested had "n" magnetic detents.

Each axis may have an optional "auxiliary" encoder. For stepper motors, this is any encoder (since stepper motors are often run with no encoder). For servo motors, this is in addition to the required motor shaft encoder and is used in a situation where there may be slippage between the motor and the actuated part.

This controller can be made to turn off motors on a full step by setting MOFF = 1, in which case motions will always be rounded to the nearest full step. This is useful for reducing overall power dissipation and noise, while leaving a stepper motor with some (not very much) holding torque. If heat is less of an issue and you need stronger holding torque or higher resolution, you may prefer to keep the motor energized all the time. Most stepper motor drivers (including the IMS-483) will automatically reduce current to the motor after a certain period of inactivity.

The following assumptions were made in coding the Galil motion controller:

Homing Algorithm

Axes are homed as follows:

Coding Standards

The Galil's programming language is very primitive. All variables are global, all math is fixed point, subroutines do not accept arguments, parameters must be dealt with one at a time for each axis (there are arrays, but Galil does not use them to set or return information about the axes) there is no formal looping and there are no string variables (a numeric variable can be used to hold 6 bytes of string data). To make the job more tolerable, I developed the following standards:

Constants and Parameters

Various constants (actually variables that are set once and saved) are used to control aspects of motion such as velocity and range of motion. There are some computed constants whose values depend on these user-set constants, so whenever you change a user-specified constant, be sure to run XQ #COMPVAR to update all computed constants.

The safest way to change constants is to edit the file "M1 Constants" or "M2 Constants" and upload the entire file to the Galil (e.g. via copy/paste in any terminal emulator). This assures that computed constants are correctly updated and that the values are saved (using BV).

In addition to these constants, the Galil has a few built-in "parameters" that must also be specified for proper option. The distinction between constants and parameters is purely internal to the Galil; parameters are saved differently (using BN) and some of them are write-only (which is very frustrating). Fortunately, there are only a few parameters and they should never need to be changed once they are set correctly and saved.

In addition to setting these constants and parameters, there are jumpers in the Galil that must be set appropriately to drive stepper motors (one jumper per axis). Galil motor controllers come from the factory configured to drive servo motors, not steppers.

User-Specified Constants

User-specified constants are actually variables that the software does not touch (except in a few special cases noted below). Variables may be set manually, but the best way to make permanent changes is to find the appropriate file of constants for the mirror in question, edit it, and upload the file to the Galil. Doing this assures that a correct and current file of constants is always available to be examined. At the time of this writing there is no permanent archive for files of constants, please contact Russell Owen to examine the files or to make permanent changes.

To examine the value of a variable use MG name. To change a value, use name = value. After you change a value you should propagate it using XQ #COMPVAR. Warning: after changing any user-specified constant you must update the computed constants using XQ #COMPVAR, else all sorts of strange and unpredictable behavior can result.

AUXMAXN
The maximum number of actual positions output from the auxiliary port before a commanded position is output. ("Maximum" because commanded position is output more often if the axis is moving).
DOAUX
If 1 (or nonzero) then status information is automatically emitted from the auxiliary serial port. See Auxiliary Port Status for details.
ENCTIME
Settling time (in seconds) after a move and after WTIME, before the encoders are read. Ignored if NCORR is zero. If ENCTIME > 0 and MOFF = 1 then the motors are turned off while waiting for ENCTIME. See also NCORR, ENCRESx, MINCORRx and MAXCORRx.
LSTIME
Maximum time required to back out of a limit at low speed. This is only used as a time limit, so please be generous.
MOFF
Turn off all motors after each move? 1 (or nonzero) = yes, 0 = no. If 1 (turn motors off) then stepper motor positions are rounded to the nearest full step, and the Galil verifies that each stepper motor driver is reporting "on full step".
NAXES
Number of axes. Valid values are in the range 1-6.
NCORR
Determines how many encoder-based corrections are applied after a move. Correction is only made for actuators with an auxiliary encoder (ENCRESx nonzero) and for which MAXCORRx is nonzero. See also ENCTIME, ENCRESx, MINCORRx and MAXCORRx.
WTIME
Settling time after a move, in seconds. If MOFF = 1 then the motors are left on for WTIME before being turned off. See also ENCTIME.

Axis-specific constants (x = A-F depending on the axis)

Unless otherwise noted, axes-specific constants must be > 0 if the axis exists and are ignored (and possibly overwritten) if the axis does not exist.

RNGx
Full range of motion, in microsteps. This should be approximately 10% less than the range delimited by the limit switches. Homing is done with respect to the reverse limit switch, so test RNGx by first homing and then moving to the positive soft limit. If RNGx is too large the positive limit switch will be touched or even tripped. If RNGx is too small, the full range of motion will not be used. If RNGx is less than 0.8 of the range set by the limit switches, it is possible for homing to fail on the first attempt and require an additional iteration.
MARGx
Margin between the hard and soft reverse limits, in microsteps. Set this just large enough that the reverse limit switch is not touched when homing is finished. Setting this too large needlessly reduces the full range of travel available to the actuator. If MOFF = 1 and you are using a rotary index pulse encoder, you should adjust MARGx so that after the move by MARGx the actuator ends up roughly halfway between index pulses. This gives you the best odds of always ending on the same index pulse after homing. (If you cannot make this adjustment then you may wish to disable the index pulse encoder by setting INDSEPx to 0.)
SPDx
Maximum speed, in microsteps/sec. Stepper motors have less torque the faster they go, and may also resonate at certain speeds, so be conservative. Test your setting to be sure the motor moves reliably and sounds good both loaded and unloaded.
HMSPDx
Maximum speed for finding the home switch, in microsteps/sec. Intuitively it ought to improve accuracy to home at a lower than normal speed than normal (SPDx). However, the Galil keeps track of counts as it decelerates, even if it hits a limit switch, so homing at a lower speed may not actually be important.
ACCx
Acceleration and deceleration of each axis, in microsteps/sec2. I'm not sure what sets the upper limit (besides resolution in the Galil), but in cases of low inertia, I suggest a value at least 10x the speed (SPDx). Stepper motors work better with fast acceleration.
ST_FSx
Step resolution, in microsteps per full step; set to 1 for a servo motor. This value must match the resolution set in the stepper motor driver.
INDSEPx
If this axis has an index pulse encoder and it is used for homing, then set to the separation between index pulses in microsteps. Otherwise 0. Subtlety: if MOFF = 1, you may wish to adjust the position of the reverse limit/home switch position or the index pulse encoder so that during homing the number of microsteps taken to find the full step (after finding the index pulse) is approximately half a full step (on the average over a number of homings). This gives you the best odds of always ending on the same full step after homing.
ENCRESx
Resolution of encremental auxiliary encoder in ticks per microstep; 0 if no auxiliary encoder. See also NCORR, ENCTIME, MINCORRx and MAXCORRx.
MINCORRx
The minimum error that will be corrected. 0 means correct any error, no matter how small. If MOFF=1 then this value is compared to position errors rounded to the nearest full step. The error in question is measured by the auxiliary encoder at the end of the move. See also NCORR, ENCTIME and ENCRESx and MAXCORRx.
MAXCORRx
The maximum error that will be corrected at the end of a move. Larger errors will cause an error message and no corrections will be applied. Set to 0 if no encoder or if there is an encoder but no correction is desired for that actuator. If MOFF=1 then this test is compared to position error rounded to the nearest full step. If MINCORRx > MAXCORRx then no correction is applied and no warning is given for errors > MAXCORRx. The error in question is measured by the auxiliary encoder at the end of the move. See also NCORR, ENCTIME and ENCRESx and MINCORRx.

Computed Constants

There are a number of constants computed by COMPVAR. XQ #COMPVAR should be run whenever you change any user-set constant. It also runs automatically whenever the Galil is powered up. Read the code for the #COMPVAR program (including comments) for more information.

Parameters

Parameters have an effect similar to constants, but they are implemented as commands built into the Galil rather than as variables. To make your changes permanent (restored at power up or by resetting with RS), save parameters to flash memory using BN. Note: BN also saves the state of the digital outputs; this can be very handy, but be sure the outputs are in the desired state before saving.

MT 2, 2, 2, 2, 2, 2
Motor type. See the Galil manual for more information. Warning: changing this changes both the polarity of the step pulse (which is how I determined the value to use) and also the direction of motion of the motor. Please don't change this setting unless you are willing to also reverse the motor direction (by swapping the A/A-bar or the B/B-bar wires).
CN -1, -1, -1
Configures the polarity of the limit switches. See the Galil manual for more information.
MO
Makes sure all motors are off when the Galil first wakes up.

Status Word

The status word is part of the information returned by the STATUS command. The status word always reports current conditions of the controller; unlike some hardware controllers, the bits are not sticky.

With one exception (see below), good status after a move is simply the stop code (details below). Reasonable stop codes are 1 and 4. 1 is expected after a successful XQ motion command (such as XQ#MOVE, XQ#MOVEREL or XQ#HOME) that includes the axis in question. 4 is expected after a successful XQ motion command that does not include the axis in question (because all other axes are told to stop), or after such a command fails with an error message.

Exception: if MOFF=0 (meaning leave motors on after a move), then it is OK for the motors to be on (bit 14 set). However, as of this writing, MOFF=1 for all mirror controllers at APO.

The status word consists of two parts:

The lower 8 bits (1-8) are a numeric stop code from the Galil SC command:

Stop Code
(bits 1-8)

Meaning
HexDec
00Running in independent mode
11Stopped at commanded position in independent mode. This is the expected stop code after a successful XQ#MOVE, XQ#MOVEREL or XQ#HOME involving this axis. See also code 4.
22Stopping or stopped by forward software limit or switch
33Stopping or stopped by reverse software limit or switch
44Stopping or stopped by stop command (ST). This is the expected stop code after XQ#MOVE, XQ#MOVEREL or XQ#HOME involving other axes, but omitting this axis. It is also normal after any XQ motion command fails. See also code 1.
66Stopped by abort input (not used)
77Stopped by abort command (AB)
88Servo error too large (only relevant to servomotors, e.g. 3.5m M3 rotation)
99Stopped after finding transition in home switch (FE).
1010Stopped after homing (HM) or finding index pulse (FI). Despite appearances, this is not a normal stop code after XQ#HOME.
3250Running in contour mode (not used)
3351Stopped at commanded position in contour mode (not used)
6399MC timeout (MC and TW); axis not in position soon enough after motion sequence ended (not used)
64100Running in vector sequence mode (not used)
65101Stopped at commanded position in vector sequence mode (not used)

Bits 9-32 of the status word report conditions represented by individual bits. Bits 9-16 are from the TS command, but some bits have been flipped to make them easier to understand
BitHexMeaning
9100Encoder position latch armed (not used)
10200Home switch activated (ganged to reverse limit)
11400Reverse limit switch activated
12800Forward limit switch activated
131000(undefined)
142000Motor on, i.e. amplifier enabled (should be 0 if MOFF=1 and axis is halted)
154000Error limit exceeded (not used)
168000Axis in motion
1710000Not on full step error (motor should be on a full step, but is not).
1820000Amplifier fault, e.g. short circuit (note: all amplifiers may have this signal ganged together).
1940000Amplifier fault (alternate input)
2080000(unused)
21-32(unused)

Note: as of version 1.9 bit 17 means "On Full Step Error" and is always supposed to be off (though an on full step error is typically not serious). Before that, bit 17 meant something a bit different and was supposed to be on for most axes.

Details of the Interface

Command Input

Every command must be typed in upper case. Commands must be terminated with <cr> or semicolon. The length of any one command must not exceed 80 characters. (There is no limit on the length of a line containing multiple commands separated by semicolons).

All positions are in microsteps and all times are in seconds (hence velocities are in microsteps/sec, etc.).

Replies

The Galil echoes commands, displaying <cr><lf> for <cr>. Prompting is, unfortunately, a bit strange. In the general case (any Galil command except program editing):

For programs (XQ #progname), the following convention is also used:

In summary:

Error Messages

Error messages all begin with a question mark. Most messages also have the name of a subroutine in upper case immediately following the question mark. The message then follows. Logical values are represented as 1=true, 0=false. If the error message refers to one or more axes, it will end with a string of 1s and 0s indicating which axes are at fault. Axes are listed in order (A, B, C...) and a 1 indicates the axis is a problem, 0 indicates the axis is not a problem.

Auxiliary Port Status

If constant DOAUX = 1, regular status updates are emitted from the auxiliary serial port just as fast as the Galil can output them. Each line of status has the following format (note: controllers may append data; see device-specific information for this information):

Notes:

Example with NAXES = 3:

 070,  000000000.0,  000000000.0,  000000000.0,  00, 0,  0001465051.23
 070,  000000000.0,  000000000.0,  000000000.0,  00, 1,  0001465051.83
 070,  000000000.0,  000000000.0,  000000000.0,  00, 1,  0001465052.43
 070,  000000000.0,  000000000.0,  000000000.0,  00, 1,  0001465053.03
 070,  000000000.0,  000000000.0,  000000000.0,  00, 1,  0001465053.63
 070,  000000000.0,  000000000.0,  000000000.0,  00, 1,  0001465054.23

Warnings:

Configuring the auxiliary port:

Wiring

The following inputs and outputs are used by the basic software for stepper motors. Slightly different predefined inputs and outputs are used for servo motors and the "on full step" inputs are ignored. Additional inputs and outputs may be used for device-specific modifications.

Predefined Outputs

Notes:

Predefined Inputs

Notes:

General-Purpose Digital Inputs

Notes:

Device-Specific Information

3.5m Secondary

Overview

The 3.5m secondary mirror controller includes three axial actuators (A, B and C) to tilt and piston the mirror and two transverse actuators (D and E). All actuators have an associated linear encoder that is slightly offset from the actuator.

There are no device-specific modifications or commands.

Mechanical Information

Axes A, B, C (axial actuators)

Axes D, E (transverse actuators)

3.5m Tertiary

Overview

The 3.5m tertiary mirror controller includes three axial actuators (A, B and C) to tilt and piston the mirror. Each consists of a stepper motor driving a screw through a harmonic drive reducer. Three Heidenhain linear encoders are also used to provide position feedback. At one time this Galil also controlled tertiary rotation, but that was split out into the 3.5m Tertiary Rotator Galil. Note that the Galil software was not changed at this time, so this Galil may still claim to control tertiary rotation, but that is a lie. Eventually the software will be made generic.

Mechanical Information

Axes A, B, C (axial actuators)

3.5m Tertiary Rotator

Overview

The 3.5m tertiary rotator controller rotates the tertiary mirror to point to various instrument ports. It also controls mirror the primary covers and eyelids. For historical reasons this Galil also pretends to control actuators A-C (at one time this Galil also controlled the tertiary axial actuators), but now axes A-C do nothing.

The tertiary mirror mount is rotated by DC servo motor and drive reduction gearbox driving a ring gear. The motor rotates the mirror to the approximate desired position, then the ring gear is clamped by a precision clamping mechanism (precision jaws engaging one of a set of precision slots) to accurately set the final mirror rotation angle. An electric clutch between the reduction gearbox and the drive gear is automatically released as the mirror is clamped to avoid back-driving the drive reduction gearbox.

The tertiary rotation motor has a rotary shaft encoder to close the servo feedback loop and provide initial position information. But the position information is inaccurate because of slop in the gearbox and because the motor shaft encoder is decoupled from the ring gear when the clutch is released. Hence an additional encoder driven by the ring gear provides final position information. This is used to correct the rotation angle before closing the clamp. In Galil parlance the motor shaft encoder is the main encoder and the position encoder is the auxiliary encoder.

The rotator motor is axis E and there is no axis D. This is for historical reasons. At one time axes A-C were the tertiary axial actuators, and the it was easier to write the motor to a different bank of opto-isolated inputs.

Warning: the tertiary rotation home position is not at a slot. So after you home you will get an error reporting that the clamp failed to close. That is normal. We tried adjusting MARGE so that home was at the first slot, but this made motion to that slot unreliable.

Finally, the tertiary Galil can control the primary mirror covers and eyelids.

Device-Specific Software

The 3.5m Tertiary Rotator is controlled by device-specific software version 1.4, May 8, 2001.

Constants

LCLTIME
Time to close the clamp (sec)
LOPTIME
Time to open the clamp (sec)
LSLTIME
Time for the at slot sensor to settle (sec)
LEYETIME
Time to open or close an eyelid (sec)
LCVADDT
Additional time to run the primary mirror covers after the switches have fired (sec)
LCVPOLLT
Polling interval for checking the mirror cover switches during mirror cover motion (sec)
LCVMAXT
Maximum time to move a group of primary mirror covers, before the switches fire (sec). The maximum time the mirror cover motors can run is LCVMAXT + LCVADDT + LCVPOLLT.

XQ #LCLCOV

Close all mirror covers. This command will work unless any of the following is true, in which case it will complain and give up:

See also #LOPCOV.

XQ #LCLEYE

Close eyelid A, where A is in the range [1, 7]. Closes all eyelids if A is out of range or has not been set. See also #LOPEYE.

XQ #LOPCOV

Open all mirror covers. This command will work unless any of the following is true, in which case it will complain and give up:

See also #LCLCOV.

XQ #LOPEYE

Open eyelid A, where A is in range [1, 7]. Unlike #LCLEYE, returns an error if A is out of range or has not been set. You may have more than one eyelid open at one time, but you must call this command once for each eyelid.

XQ #STATUS

Displays two extra lines showing the state of various sensors via #LSTATUS. Example:

1 1 1 1 at slot, left, right jaw open, clutch engaged
1 1 0 0 0 cover groups 1 open, 2 open, 1 closed, 2 closed; eyelids closed

(note: only the first line is present in the release version 1.2)

Motion

For any move involving tertiary rotation (axis E), the following occurs:

Before the move, and only if the clamp is presently not fully unclamped:

After the move, and only if the clamp is not already fully clamped:

Auxiliary Status

The auxiliary status includes one extra item of data: the axis E servo error (in microsteps = motor encoder ticks). This value is useful to determine a good value for parameter ERE, the maximum allowed servo error.

Additional Wiring

Predefined Inputs

General-Purpose Digital Inputs

All digital inputs read 0 for true/sensed.
BitDescriptionValue
4at "slot" sensor0 = at slot (not used; see note)
6left jaw fully out0 = out
7right jaw fully out0 = out
8clutch disengaged0 = disengaged (see note)
9mirror covers group 1 open0 = open
10mirror covers group 2 open0 = open
11mirror covers group 2 closed0 = closed
12mirror covers group 1 closed0 = closed
13(amplifier fault; a standard input)
14eyelids all closed0 = closed

Notes:

General-Purpose Digital Outputs

BitDescriptionValue
1power to "at slot" LED and sensor0 = power on (not used; see note)
2air to clamp0 = open, 1 = close
3(unused)
4mirror cover drive enable1 = enable
5mirror cover group 1 open1 = open
6mirror cover group 2 open1 = open
7mirror cover group 2 close1 = close
8mirror cover group 1 close1 = close
9eyelid #1 (top center) open1 = open
10eyelid #2 (top left) open1 = open
11eyelid #3 (NA2) open1 = open
12eyelid #4 (bottom left) open1 = open
13eyelid #5 (bottom right) open1 = open
14eyelid #6 (NA1) open1 = open
15eyelid #7 (S-H) open1 = open
16(unused)

Mechanical Information

Axis E (rotation)

SDSS Primary

Overview

The SDSS primary mirror has six actuators: three axial (A, B, C = Axial A, B, C), one transverse perpendicular to the altitude axis (D = Transverse Vertical) and two parallel to the altitude axis (E, F = Lateral 1, 2). The lateral links are attached to the mirror via arms that contain air-driven force fuses. All other actuators control hard points which are used by the Yorke Brown air support servos.

The lateral link motors are weak and the axial air support pistons are high friction, so the lateral link force fuses must be disabled (air released) while moving the lateral links. To accomplish this, one of the Galil outputs drives an air valve. Note that turning on the air again will not position the mirror correctly; one must relax the system by driving it up and down axially 5-10 times, preferably while at the zenith.

In addition, there are also two proximity sensors on the lateral links; at present these are not in use, but they can be connected to analog inputs on the Galil. They are intended to help set the mirror rotation (by mechanically adjusting the relative lengths of the lateral links).

Device-Specific Software

SDSS primary software v1.6, March 7, 2001.

Constants

LLATTIME
Time required to fully engage or disengage the lateral link air force fuse (sec)

XQ #SHOWPAR

Displays an extra line showing the version of the device-specific software.

XQ #STATUS

Displays an extra line showing the state of the lateral link air force fuse.

Motion

For any move involving the lateral links (axes E or F), the following occurs:

Before the move begins, via #LMINIT:

After the move is finished, via #LMSTOP:

Additional Wiring

General-Purpose Digital Outputs

Notes:

Mechanical Information

Axes A, B, C (axial actuators) and D (transverse vertical)

Axis E, F (transverse lateral links)

SDSS Secondary

Overview

The SDSS secondary mirror has five actuators: three axial (A, B, C = Axial A, B, C) and two transverse (D, E). The axial actuators are stepper motors; each driving a screw through a harmonic drive reducer. They have separate Heidenhain incremental linear encoders that are a few inches from the actuators, and so have systematic error when the mirror is tilted. The transverse actuators are linear actuators (the motor turns a nut that drives a threaded shaft) that tilt the central linear bearing; they are oriented at 45 degrees from vertical and are in tension (when both contract the mirror is raised).

The axial actuators also contain piezoelectric actuators in series, for fine adjustment. Mirror-specific Galil code computes position error and tries to correct it via the piezos. The piezos are centered while the axial actuators is being moved so that the main actuators can get as close as possible to the correct position. It is possible to disable piezo corrections (see LCSTOP and XQ #LPAUSE below) or set the piezo positions manually (see XQ #LMOVE below).

The total time for one piezo correction is roughly LWTTIME = LCORTIME + (8 * LSETMS / 1000) (in seconds). The Galil has to wait for 8 bit flips, two to set the position for each axis plus one to command the piezos to move.

Device-Specific Software

SDSS secondary software v1.3, 2004-04-01.

Constants

LCORFRAC
Fraction of error to attempt to correct. Should be in the range (0.0, 1.0]. If the piezos are driven into oscillation then reducing this may help.
LCORTIME
Maximum time the piezos take to move (sec). This excludes the time required to send a command to the piezo controller (that is computed from LSETMS). Setting LCORTIME too small will cause position errors to be measured before the piezos have stopped moving. That is probably not very serious. Setting LCORTIME too large needlessly slows down each piezo move and each axial actuator move.
LCSTOP
Set to 0 to enable or 1 to disable background corrections. Note that the background process requires up to LWTTIME seconds to halt after being disabled.
LSETMS
Maximum time the Galil takes to set a piezo control bit and the piezo controller takes to recognize that it has been set (ms). Be careful not to set LSETMS too small, because this introduces errors into the communications between the Galil and the piezo controller. Such errors are nearly impossible to detect except by watching the resulting length of the axial actuator. Setting LSETMS too large needlessly slows down each piezo move and each axial actuator move.
LMAXBIN = A90 hex
Maximum position output (binary). The DAQ has 12 bits (4096) and outputs approx. 0-2.7 volts however, the output amplifier saturates at approximately 2V giving a maximum binary output of approximately A90 hex.
LRES = 1.24 microsteps/piezo increment
Resolution of piezos in microsteps/piezo increment; computed as follows:
1 microstep/8 nm resolution of the axial actuator
2.7V/4096 bits resolution of DAQ
3 nm/200e-6V resolution of the piezo actuator

XQ #LMOVE

Move the piezo actuators to the position specified by LDESPOSx, where x = A, B or C (in microsteps) and print status. Pauses automatic piezo corrections (otherwise the piezos would almost immediately move again). Notes:

Example (omitting colons):

LDESPOSA = 100
LDESPOSB = 4000     Out of range, so it will be adjusted
LDESPOSC = -1000
XQ#LMOVE
 1,  1,  1,  1,  1 axis homed
 000000000,  000000000,  000000000,  000000000,  000000000 commanded position
 000000000,  000000000,  000000000,  000000000,  000000000 actual position
 00331268,  00331268,  00331268,  00331268,  00273921 status word
 3 piezo status word
 000000100,  000001676, -000001000 piezo corrections (microsteps)
OK

XQ #LPAUSE

Zero the piezo actuators and pause automatic piezo corrections. Automatic piezo corrections will resume (if LCSTOP=0) after any XQ #... command except XQ #LMOVE or XQ #LPAUSE.

XQ#SHOWPAR

Displays four extra lines of data, as per this example:

 01.00 version of M2-specific additions
-00001676.4874,  00001676.4874 min, max piezo position (microsteps)
 00002705 number of steps of piezo position
 00000001.2400 resolution (microsteps/piezo ctrl bit)

XQ #STATUS

Displays two extra lines showing the piezo status word and and the amount of the most recently applied correction as per this example:

 0 piezo status word
 000000100,  000001676, -000001000 piezo corrections (microsteps)

Auxiliary Port Output

The auxiliary port output includes some extra data about the piezo actuators. The following items are appended to the normal output:

Example:

 126,  000000000.0,  000000000.0,  000000000.0, -000003400.0,  000000000.0, 00,  1,  0001230775.78, -02539, -02539, -02539,  0
 126,  000000000.0,  000000000.0,  000000000.0, -000003400.0,  000000000.0, 00,  1,  0001230776.12, -02539, -02539, -02539,  0
 126,  000841850.0,  000803250.0,  000873850.0, -000003400.0,  000000000.0, 00,  0,  0001230776.45, -02539, -02539, -02539,  0

Piezo Status Word

The piezo status word shows the status of various flags related to piezo correction. The word is displayed as decimal, even though hex is more traditional. Internally, each flag is 0 for cleared and nonzero (usually 1) for set.

Typically at the beginning of a move you will see bit 2 set (pause requested) followed shortly by bit 1 (pause occurred). At the end of the move you will see both bits cleared.

Automatic Motion

For any move involving the axial actuators (axes A, B or C), the following occurs:

Additional Wiring

General-Purpose Digital Outputs

Notes:

Mechanical Information

Axes A, B, C (axial actuators)

Axes D, E (transverse actuators)

Installing A Galil

The Galils must have code loaded into them before they can function as described in this manual. (Without such code, only the low-level commands described in the factory manual will work.)

Warning: a Galil that has not been programmed or has been incorrectly configured may cause motors to run away when it is first powered up. Never allow the Galil to control a motor until it has been properly programmed and that programming has been saved to flash memory and tested.

There are two configuration errors that can cause problems:

Upload Code

You will need the following to upload Galil code:

The procedure is as follows:

  1. Export the code from subversion repository svn://svn.apo.nmsu.edu/galil/tags/. The following commands list the available release versions and export a particular version:
    svn ls svn://svn.apo.nmsu.edu/galil/tags/
    svn export svn://svn.apo.nmsu.edu/galil/tags/v2.01 galil_v2.01
    
  2. Use python to combine the code files into one file for each desired mirror controller, as follows:
    cd <directory of Galil code>
    python combineGalilCode.py "<mirror name>"
    
    where <mirror name> is one of 35m M2, SDSS M1, etc. For the full list, look for files named "Constants <mirror name>.gal". The combined code is written to file: "Combined <mirror name> <date>.gal". For example, the command: 'python combineGalilCode.py "SDSS M2"' might create file: "Combined SDSS M2 2005-01-31.gal".
  3. If the Galil does not presently contain mirror controller code for this mirror then make sure the Galil is not connected to the mirror actuators. If you can't do that, then you must disable the motors. Otherwise they may run away while you load the code. Any one of the following will work:
  4. Connect to the Galil's serial port. Do not use HOST from the TCC, because HOST does not lock out other users, which could corrupt the upload. If the Galil is attached to a terminal server, telnet to that. If the port is busy (e.g. if the tcc is hogging it), you can free it up by one of:
  5. Send the appropriate file to the Galil, e.g. open the combined code file in any text editor and copy and paste the data to your connection. You will observe many lines go by normally, then many lines that may or may not overwrite each other (this seems to depend on the setup of the terminal server and/or your terminal emulator), then a few normal lines again. However, if you see one or more "?" or error messages, this indicates a failed upload.
  6. Issue the following commands. If any fail, the code cannot be used:
  7. When you are satisfied with this upload, save the code ("burn it") using the following commands (which save the configuration, the variables and the program, respectively):
  8. Issue a RS (reset) command to simulate a power cycle.
  9. Execute XQ#STATUS again. This makes sure the code was properly saved to flash memory.
  10. Test the system.

Test The System

  1. Make sure you understand and respect the limitations of the hardware for the mirror in question. For instance some mirrors don't like large tilts, others don't move well in certain directions at certain altitudes.
  2. Make sure the actuators are near their center of travel. For SDSS M2 axial and 3.5m M2 and M3 axial (A,B,C) actuators simply having them at least 1/16" away from the limit switch is adequate, as these actuators move very slowly.
  3. Power up the system in such a way that you can remove power if the motors run away. If the motors run away, turn off power and configure the Galil before proceeding.
  4. Check the limit switches. This is by far the most common source of problems after any engineering activity has occurred around the mirrors.
    1. Issue the "TS" command. This returns a number representing the state of the switches for each axis. Only the numbers for the axes we control matter: 1-6 for M1, 1-5 for M2.
    2. For each axis, convert the number from decimal to binary.
    3. Make sure bits 1-3 are all high (where bit 0 is the first bit). The bits are: home switch, reverse limit switch and forward limit switch.
    4. Fix any limit switch problems before proceeding. Common failures are:
      1. If bit 3 is high and 1 and 2 are low: the forward limit switch is pressed, a connector is off or a wire or switch is broken.
      2. If bits 1 and 2 are high and 3 is low: the reverse limit switch is pressed, a connector is off or a wire or switch is broken.
      3. If only bit 1 or 2 is high and all other bits are low: check the wiring of the reverse limit switch at the connector on the Galil (see the Galil manual for connector pinouts). The reverse limit switch is connected to both the reverse limit input and the home input, and the break must be after the wiring separates. Typically you'll find a pair of resistors at the connector; look there first.
      4. If bits 1, 2 and 3 are all high: both limit switches may be disconnected or the limit switch logic may be inverted (suggesting the Galil has not yet been configured).
  5. Check that the motors turn in the correct direction.
    1. Have somebody watch the actuator or a dial indicator.
    2. Start the motors moving slowly towards the home switch (which on the APO mirrors is also the reverse limit switch):
            A=0
            XQ#GOEDGE
            When you are satisfied that motion is in the correct direction, halt it using:
            ST
            XQ#DONE
            (Note: XQ#DONE is important, as it clears the A,B,C...variables). Then try the next axis.
            
  6. Home the axes. For this level of testing, it is not necessary to have the telescope at the standard altitude. On the other hand, that may save another homing later!
  7. Home them again (at the same altitude). If the errors seem large, something may be wrong.
  8. When you are finished testing, move the actuators well away from their reverse limits. Never leave them near a limit.

Troubleshooting

On Full Step Error

If a move should end on a full step and does not, the Galil will complain. (Almost all APO mirror actuators are expected to end on a full step; the except is 3.5m tertiary rotation, which is a servo motor).

This error may be relatively benign, but should be investigated to be sure. To investigate:

If the error is benign, I suggest you continue to run, ignoring the error messages, until the problem can be fixed.

This problem is fundamentally a counting error between the Galil and the stepper motor driver amplifier. Either the Galil is emitting the wrong number of pulses or the stepper motor driver amplifier is mis-counting the pulses, or there is noise in the wires between them. This is an error in the requested position and has nothing to do with the actual motion of the motor; it cannot be caused by the motor itself getting jammed. Things to check:

Amplifier Fault

One or more motor driver amplifiers is reporting a fault. This is a serious problem. You will not be able to move any actuator for this mirror until you correct it.

An amplifier can report a fault for many reasons, including:

One difficulty with tracking down amplifier faults is that the Galil only has one or two fault inputs (one for 1-4 axis units; two for units with more axes), to conserve inputs. Typically the "fault" signal from several motor amplifiers are "wire-or"ed to a single fault input. Hence it may be difficult to tell which amplifier is causing the fault. In the long run, we ought to have an LED on each fault line or at least a resistor or diode, so one can figure out which line is faulting without taking fancy steps.

Galil Error Light

The error light on the Galil can indicate several different problems. Note that there is an error output bit that tracks the error light (though we don't monitor it as of 2007-07-23).