spec
Software for Diffraction
2.4.8.1. - Controlling Motors
move_all
-
This command sets motors in
motion.
The sequence of events is as follows.
For some motor controllers, spec
first examines the controller
registers of all
nonbusy motors and makes sure the contents agree with the
current positions in program memory.
If there is a discrepancy, the user is asked to choose
the correct position.
Next, spec prepares to move all
motors that are not already at the positions specified in the built-in
A[]
array, interpreted in user units.
A motor will not be moved if
it is currently moving or
if it is marked as protected (via the configuration file)
or unusable
(due to failure of a hardware presence test).
If the target position of any of the motors is outside the software limits,
the entire move is canceled, and the program resets to command level.
Otherwise, the motors are started, and the command returns.
The sequence of commands when using
move_all
should almost always be,
wait(1) # Wait for moving to finish
read_motors(0) # Put current positions of all motors in A[]
(Assign new values to elements of A[] to be moved)
move_all # Move to those positions
If
read_motors()
is called before the motors have stopped, the values in
A[]
will reflect the motor positions before they stopped.
If
read_motors()
is not called at all, or if you do not explicitly assign a value to
each element of
A[]
, then
you will not know for sure where some motors will be going when
move_all
is called.
A
^C
halts moving, as does the
sync
command.
move_cnt
-
This command is similar to
move_all
, described above, but with the following differences.
Just before the motors are started,
the clock/timer is enabled and
programmed to gate the scalers with a
longer-than-necessary count time.
The motors are then started at the base rate set in the
config
file, but are not accelerated to the steady-state
rate.
No backlash correction is done at the end of the move.
When the move is completed, the clock/timer is stopped.
The
move_cnt
command is used in powder-averaging
scans.
(See the powder-mode macros
3.9.5
sync
-
If any motors are moving, they are halted.
The
motor positions maintained by the motor controller
are then compared
with the motor positions currently set in the program.
If there is a discrepancy, the user is asked which should be changed.
The
sync
command is used to place the motor hardware in a known
state and is supposed to
fix any problems in communicating with the controllers.
motor_mne(motor)
-
Returns the string mnemonic of motor number
motor
as given in the
configuration file.
(Mnemonics are, at most, 7 characters long.)
Resets to command level if not configured for
motor
.
motor_name(motor)
-
Returns the string name of motor number
motor
as given in the
configuration file.
(Names are, at most, 15 characters long.)
Returns
"?"
if not configured for
motor
.
motor_num(mne)
-
Returns the motor number corresponding to the motor mnemonic
mne
,
or -1 if there is no such motor configured.
As of spec release 6.05.01,
mne
can be a variable or an expression.
If
mne
is an uninitialized variable,
-1 is returned.
motor_par(motor, par [, val ])
-
Returns or sets configuration parameters for motor
motor
.
Recognized values for the string
par
follow.
Note, not all parameters are meaningful for all motor controllers.
"step_size"
- returns the current step-size parameter.
The units are generally in steps per degree or steps per millimeter.
If
val
is given, then the parameter is set to that value, but only if
changes to the step-size parameter have been enabled using
spec_par("modify_step_size", "yes")
.
"acceleration"
- returns the value of the current acceleration parameter.
The units of acceleration are the time in
milliseconds for the motor to accelerate to full speed.
If
val
is given, then the acceleration is set to that value.
"base_rate"
- returns the current base-rate parameter.
The units are steps per second.
If
val
is given, then the base rate is set to that value.
"velocity"
- returns the current steady-state velocity parameter.
The units are steps per second.
If
val
is given, then the steady-state velocity is set to that value.
"backlash"
- returns the value of the backlash parameter.
Its sign and magnitude determine the direction and extent of the motor's
backlash correction.
If
val
is given, then the backlash is set to that value.
Setting the backlash to zero disables the backlash correction.
"config_step_size"
- returns the step-size parameter contained in the
config
file.
"config_acceleration"
- returns the acceleration parameter contained in the
config
file.
"config_velocity"
- returns the steady-state velocity parameter contained in the
config
file.
"config_base_rate"
- returns the base-rate parameter contained in the
config
file.
"config_backlash"
- returns the backlash parameter contained in the
config
file.
"controller"
- returns a string containing the controller name of the specified motor.
The controller names are those used in spec's
config
files.
"unit"
- returns the unit number of the specified motor.
Each motor controller unit may contain more than one motor channel.
"channel"
- returns the channel number of the specified motor.
"responsive"
- returns a nonzero value if the motor responded to an initial presence
test or appears otherwise to be working.
"active"
- returns a nonzero value if the motor is currently moving.
"disable"
- returns a nonzero value if the motor has been disabled by software.
If
val
is given and is nonzero, then the motor is disabled.
If
val
is given and is zero, the motor becomes no longer disabled.
A disabled motor channel will not be accessed by any of spec's commands,
and, of course, cannot be moved.
Any
cdef()
-defined
macros will automatically exclude the portions of the macro keyed to
the particular motor when the motor is software disabled.
"slop"
- returns the value of the slop parameter.
If
val
is given, sets the slop parameter.
When this parameter is present, discrepancies between hardware
and software motors positions are silently resolved in favor of the the
hardware when the number of steps in the discrepancy is less than the
value of the slop parameter.
(Not yet implemented for all motor controllers.)
"home_slew_rate"
- returns the value of the home-slew-rate parameter.
If
val
is given, sets the parameter.
This parameter is the steady-state velocity used during a home search.
(Only available for selected controllers.)
"home_base_rate"
- returns the value of the home-base-rate parameter.
If
val
is given, sets the parameter.
This parameter is the base-rate velocity used during a home search.
(Only available for selected controllers.)
"home_acceleration"
- returns the value of the home-acceleration parameter.
If
val
is given, sets the parameter.
This parameter is the acceleration used during a home search.
(Only available for selected controllers.)
"dc_dead_band"
- returns the value of the dead-band parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_settle_time"
- returns the value of the settle-time parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_gain"
- returns the value of the gain parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_dynamic_gain"
- returns the value of the dynamic-gain parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_damping_constant"
- returns the value of the damping-constant parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_integration_constant"
- returns the value of the integration-constant parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_integration_limit"
- returns the value of the integration-limit parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_following_error"
- returns the value of the dc-following parameter for certain DC motors.
Sets the parameter if
val
is given.
"dc_sampling_interval"
- returns the value of the sampling-interval parameter for certain DC motors.
Sets the parameter if
val
is given.
"encoder_step_size"
- returns the value of the encoder step size parameter.
Sets the parameter if
val
is given.
"step_mode"
- returns the value of the step-mode parameter.
Sets the parameter if
val
is given.
A zero indicates full-step mode, while a one indicates half-step mode.
"deceleration"
- returns the value of the deceleration parameter.
Sets the parameter if
val
is given.
"torque"
- returns the value of the torque parameter.
Sets the parameter if
val
is given.
Rereading the
config
file resets the values of all the motor parameters to the values in the
config
file.
Little consistency checking is done by spec on the values programmed with
motor_par()
. You must be sure to use values meaningful to your particular motor controller.
In addition, device-dependent values for
par
are available for specific motor controllers.
See the
Hardware Reference
for values for specific controllers.
dial(motor, user_angle)
-
Returns the dial angle for motor
motor
corresponding
to user angle
user_angle
using the current
offset
between user and dial angles
for
motor
.
The value returned is
(user_angle - offset) / sign,
where
sign
is
±1
and is set in the
config
file.
The value is rounded to the motor resolution
as set by the step-size parameter
in the
config
file.
Resets to command level if not configured for motor
motor
.
read_motors(how)
-
Reads the current motor positions from the motor controllers and
places the values in the
A[]
array, depending on the value of the argument
how
.
If bit 1 is set, the function returns dial values, otherwise
user values are returned.
If bit 2 is set, a forced read of all hardware takes place.
(For efficiency, normally most motor controllers are not read if the
position hasn't been changed by a move.)
If bit 3 is set and if there is a discrepancy between the software
and hardware, the software will be silently corrected to match the hardware.
Note, the forced-read and
"silent-sync"
features are not yet implemented
for all motor controllers.
Check the
Hardware Reference
or contact CSS for hardware-specific information.
move_info([motor|keyword|motor, keyword])
-
The
move_info()
function returns information about what would happen
on a subsequent
move_all
command
given the current motor positions and current values in the
A[]
array.
Such a function might be called, for example, within the
user_premove
macro to determine which motors will be moved to allow
extra limit checking involving the relative postions
of motors.
If called with no arguments, returns a two-dimensional associative array
containing the move information. The array is indexed by
motor number and information keyword. The keywords are:
@to_move@ |
nonzero if motor will move |
@error@ |
reason the motor will not move |
@commanded@ |
the commanded position |
@magnitude@ |
magnitude of the move in user units |
@current@ |
current position in user units |
@current_dial@ |
current position in dial units |
@target@ |
target position in user units |
@target_dial@ |
target position in dial units |
@backlash@ |
backlash for this move in user units |
@leftover@ |
remainder due to motor resolution |
If called with a single argument that is one of the
above keywords, the function returns a one-dimensional associative
array indexed by motor number containing values for that keyword for each motor.
If called with a motor number or mnemonic as a single argument, the
function returns a one-dimensional associative array, indexed by
the above keywords containing values for the one motor.
If called with two arguments, motor number and keyword,
the function returns the corresponding single value.
No matter how the function is called,
the internal code will calculate values for all motors.
Thus, if multiple values are needed, it is most efficient and recommended
to call the function once selecting arguments that will
return all the needed values.
The
"to_move"
element will be 1 or 0, indicating whether the motor
would move or not. If there is condition that prevents the move, the
"error"
element will contain one of these strings:
@low limit@ |
move exceeds low limit |
@high limit@ |
move exceeds high limit |
@busy@ |
motor is busy |
@read only@ |
motor is configured as read only |
@protected@ |
motor configuration does not allow moving |
@disabled@ |
motor has been disabled |
@externally disabled@ |
shared motor has been disabled |
@unusable@ |
motor did not respond to presence test |
Otherwise, there will be no
"error"
array element.
The
"target"
and
"target_dial"
values
are the final position after backlash.
The
"magnitude"
value contains the distance to the target position and
does not include the magnitude of the backlash.
The
"leftover"
value is the fractional value that is the difference
between the requested position and the achievable position
given the finite resolution of the motor.
For example, if a motor has 1000 steps per degree, each step corresponds to
0.001 degrees.
If one asks to move the motor to a position of 1.0004 degrees, the motor will
move to 1 degree and the leftover value will be 0.0004 degrees.
The
"commanded"
value is the target position in user units to the full
precision requested.
The other postion-related values are rounded to the motor resolution.
The
"commanded"
position is saved after a move and is available using
special arguments to the built-in
read_motors()
functions.
As mentioned above,
if multiple values are needed, it is better to make a single call of
move_info()
saving the return values in an array, rather than making
multiple calls, as each call involves calculations for
all the motor positions and values, even if only selected values are
returned.
For example,
{
local i, m[]
m = move_info()
for (i = 0; i < MOTORS; i++)
if (m[i]["to_move"]) {
...
}
}
For the most part, the
move_info()
function will reflect what will happen on the next
move_all
command.
However, for shared motors that can be moved by other processes or
for motors that have positions that drift or have jitter,
the status and position may change between the
move_info()
call and the
move_all
call.
chg_dial(motor, dial_angle)
-
Sets the dial position of motor
motor
to
dial_angle
.
Returns nonzero if not configured for
motor
or if the protection flags prevent the user from changing the limits
on this motor.
Resets to command level if any motors are moving.
chg_dial(motor, cmd)
-
Starts motor
motor
on a home or limit search, according to the value of
cmd
as follows:
"home+"
- Move to home switch in positive direction.
"home-"
- Move to home switch in negative direction.
"home"
- Move to home switch in positive direction if current dial position
is less than zero, otherwise move to home switch in negative direction.
"lim+"
- Move to limit switch in positive direction.
"lim-"
- Move to limit switch in negative direction.
Positive and negative direction are with respect to the dial position
of the motor.
(At present, most motor controllers do not implement the home or limit search
feature.)
Returns -1 if not configured for motor
motor
or if the motor
is protected, unusable or moving,
else returns zero.
get_lim(motor, flag)
-
Returns the dial limit of motor number
motor
.
If
flag >
0,
returns the high limit.
If
flag <
0,
returns the low limit.
Resets to command level if not configured for
motor
.
user(motor, dial_angle)
-
Returns the user angle for
motor
corresponding
to dial angle
dial_angle
using the current
offset
between user and dial angles
for
motor
.
The value returned is
sign × dial_angle + offset,
where
sign
is
±1
and is set in the
config
file.
The value is rounded to the motor resolution
as set by the step-size parameter
in the
config
file.
Resets to command level if not configured for
motor
.
chg_offset(motor, user_angle)
-
Sets the offset between the dial angle and the user angle, using
the current dial position and the argument
user_angle
for motor
motor
according to the relation
user_angle = offset + sign × dial_angle
where
sign
is
±1
and is set in the
config
file.
Returns nonzero if not configured for
motor
.
Resets to command level if any motors are moving.
set_lim(motor, low, high)
-
Sets the low and high limits of motor number
motor
.
low
and
high
are in dial units.
It does not actually matter in which order the limits are
given.
Returns nonzero if not configured for
motor
or if the protection flags prevent the user from changing the limits
on this motor.
Resets to command level if any motors are moving.