diff --git a/documentation/trajectoryPlot1.gif b/documentation/trajectoryPlot1.gif new file mode 100644 index 00000000..5e308047 Binary files /dev/null and b/documentation/trajectoryPlot1.gif differ diff --git a/documentation/trajectoryPlot2.gif b/documentation/trajectoryPlot2.gif new file mode 100644 index 00000000..ea5086cf Binary files /dev/null and b/documentation/trajectoryPlot2.gif differ diff --git a/documentation/trajectoryScan.gif b/documentation/trajectoryScan.gif new file mode 100644 index 00000000..ecb4b70c Binary files /dev/null and b/documentation/trajectoryScan.gif differ diff --git a/documentation/trajectoryScan.html b/documentation/trajectoryScan.html new file mode 100644 index 00000000..d9e3b74e --- /dev/null +++ b/documentation/trajectoryScan.html @@ -0,0 +1,1042 @@ + +
The Newport MM4005 and XPS motor controllers are capable of executing complex +coordinated motions. Trajectories can be defined which move any or all of +the axes through any set of complex motions. The controller will coordinate +these motions, keeping each axis very close to the theoretical position during +the entire motion. The controller can output logic pulses during the execution +of the trajectory, permitting external equipment to be synchronized to the +motion. These capabilities are ideally suited to “on-the-fly” data +collection.
+ +At the APS one application of the MM4005 and XPS is to drive the large Newport +diffractometer. This diffractometer has rather long settling times because of +the mass of the moving elements. However, with this trajectory scanning software +one can use SPEC, for example, to compute a set of diffractometer positions for +a scan in HKL space, and then download these positions to the controller. The +entire scan can be executed without stopping, collecting data in a multi-channel +scaler. This can reduce data collection times dramatically relative to +traditional step scanning.
+ +This document describes an EPICS interface to the trajectory capabilities of +the MM4005 and XPS. This interface is completely general for the controllers, it is not +specific to the Newport diffractometer. The interface lets any EPICS channel +access client do the following:
+The EPICS implementation consists of the following:
+trajectoryScan.db. This database
+ contains almost no "logic" with no links between records in the database. The
+ records are simply variables which channel access clients and the State
+ Notation Language (SNL) program use.
+ MM4005_trajectoryScan.st and XPS_trajectoryScan.st.
+ . These programs implement all of the logic for communicating with
+ the controller and with channel access clients via the database.
+ trajectoryScan.adl,
+ trajectoryScanDebug.adl, trajectoryPlot.adl. These screens are
+ used to control the building, execution, readback, debugging and plotting of
+ trajectory scans.
+The MM4005 and XPS are used at the APS to control the large Newport +diffractometer. This device is capable of moving large masses at high speeds. +The trajectory scanning software does not use the EPICS motor record, and so +does not obey any software limits defined in the motor record. It is very +important that:
+The database is loaded with $(P) (prefix) and $(R)
+(record base) macros. For example, $(P) might be
+13IDC: for the name of the IOC, and $(R) might be
+Traj1: for the first trajectory in this IOC. The prefix and
+record bases are
+omitted from the Process Variable (PV) names in this document, but one should be
+aware that, for example, Nelements is really
+$(P)$(R)Nelements or in this case
+13IDC:Traj1:Nelements.
There are 8 motors in the database, and thus 8 similar records for many
+functions. For example, the records defining the trajectory positions are
+M1Traj, M2Traj ... M8Traj. These are referred to in this document
+either as M1Traj ... M8Traj or as MnTraj.
The MM4005 and XPS always define a trajectory in terms of displacements (i.e. +relative positions) of each motor for each element of the trajectory. Each +trajectory element has an execution time associated with it, and hence there is +a velocity defined for each motor (displacement/time) for each trajectory +element. The MM4005 supports trajectories of up to 2000 elements, while the XPS +supports an essentially unlimited number of elements
+ +During execution of the trajectory the MM4005/XPS can output a user-definable +number of logic pulses. The trajectory elements where these output pulses +begin and end can also be selected. On the MM4005 these pulses are evenly spaced in distance +along the trajectory, which is a distance in up to 8-dimensional space. On the XPS +the pulses are evenly spaced in time. +These output pulses are typically used for the channel-advance of a +multi-channel scaler, allowing detector pulses to be collected in hardware, with +no software overhead at each point. At the time that each pulse is output the +controller captures the theoretical and actual (encoder) position of each +motor. These positions can be read back when the trajectory is complete.
+ +It is important to remember that the number of data points in a scan is +determined by the number of output pulses, not by the number of trajectory +elements. For example, a constant velocity theta/2-theta scan over 10 degrees +can be defined with a only 1 trajectory element, but could be used to collect 1000 +data points at .01 degree steps.
+ +The following table lists the EPICS Process Variables (PVs) which are used to +define the trajectory. Some of these are explained in more detail below.
+| PV Name | +Record Type | +Description |
NumAxes |
+ longout | +The number of motors (axes) which are connected to the MM4005 or XPS. |
Nelements |
+ longout | +The number of elements in the trajectory, i.e. the number of valid
+ points in the M1Traj...M8Traj and TimeTraj
+ arrays. Default=1. |
MoveMode |
+ mbbi | +Defines the type of position information contained in
+ M1Traj...M8Traj. 0=Relative,
+ 1=Absolute, 2=Hydrid.
+ Default=Relative. |
M1Traj ... M8Traj |
+ waveform, double | +The displacements or absolute positions of each motor for each element + of the trajectory. No defaults. |
M1Move ... M8Move |
+ bo | +Flag defining whether each motor is to be moved during the trajectory.
+ 0=No, 1=Yes. Default=No. |
Npulses |
+ longout | +Number of synchronization pulses to be output by the MM4005/XPS. + Default=200. |
StartPulses |
+ longout | +The trajectory element number where synchronization pulses will start. + Default=1. |
EndPulses |
+ longout | +The trajectory element number where synchronization pulses should end.
+ Default=Nelements. The SNL program sets
+ EndPulses=Nelements whenever Nelements is
+ changed, since this is what is normally desired. EndPulses
+ can be changed again after changing Nelements if
+ desired. |
TimeMode |
+ bo | +The mode being used to define the time per trajectory element.
+ 0=Total means that the total time for the trajectory is being
+ defined, and the TimeTraj array will be computed by setting
+ the execution time for each element = Time/Nelements.
+ 1=Per Element means that the time per element has already
+ been loaded into the TimeTraj array. This mode permits each
+ element to have a different execution time. Default =
+ Total. |
Time |
+ ao | +Total trajectory execution time. Used when TimeMode=0.
+ Default=10. |
TimeTraj |
+ waveform, double | +The array containing the execution time per trajectory element. This
+ array is computed by the SNL program if
+ TimeMode=Total, and must be loaded by the user
+ if TimeMode=Per Element. |
Accel |
+ ao | +The acceleration time for the trajectory. Default=0.5 seconds. |
M1Name ... M8Name |
+ stringout | +The name of each motor. These are used for the labels on MEDM screens + and by channel access clients. These names are defined when the database + is loaded. These PVs are not otherwise used and are not required for the + trajectory definition. |
The EPICS interface permits the motor positions for each element of the
+trajectory to be defined in one of 3 ways. This flexibility can remove the
+burden of converting absolute positions to displacements from the EPICS channel
+access client and let the SNL program do the calculations. MoveMode
+can have the following 3 values:
Relative.
+ This mode maps directly to the way the MM4005 works internally.
+ Each trajectory element is a
+ displacement or distance for the motor to move during that element.
+ Absolute.
+ In this mode
+ each trajectory element is an absolute motor position to which the controller
+ will move at each point in the trajectory. In practice the SNL program
+ computes an internal trajectory with Nelements-1 elements where
+ InternalTraj[i] = MnTraj[i+1]-MnTraj[i].
+ The SNL program drives all the motors to
+ the first point in the trajectory, waits for them to get there, and then
+ executes the internal trajectory. The disadvantage of
+ Absolute mode is that a new
+ trajectory needs to be downloaded and built each time the absolute position of
+ any motor in the trajectory is changed.
+ Hybrid.
+ In this mode the
+ trajectory is defined in absolute coordinates, as in Absolute
+ mode. Again, an internal trajectory is computed from
+ MnTraj[i+1]-MnTraj[i]. However,
+ when the trajectory is executed the motors are not moved to
+ the position of the first point of the trajectory. Thus,
+ Hybrid mode permits a trajectory to
+ be defined in absolute coordinates, but executed as motions relative to the
+ current positions of the motors when the trajectory is executed. Thus the
+ motors can be moved using the EPICS motor record, and the trajectory executed
+ at a new absolute position without downloading new values to
+ MnTraj or rebuilding the trajectory. Note that when programming TimeTraj in Absolute or
+Hybrid mode TimeTraj[i] is the time to execute the
+move from position MnTraj[i] to MnTraj[i+1].
The MM4005 requires the number of elements in a trajectory to be a multiple
+of 4. This means that Nelements
+should be a multiple of 4 in
+Relative mode and a multiple of 4
+plus 1 in Absolute or
+Hybrid mode. However, this can be an
+inconvenience for EPICS channel access clients. The SNL program works around
+this restriction as follows. If
+Nelements is not a multiple of 4 for
+MoveMode=Relative or a multiple
+of 4 plus 1 for
+MoveMode=Absolute or
+Hybrid, then up to 3 padding elements
+are automatically added to the user defined trajectory to satisfy the
+requirement. The padding elements always have a time of 0.1 seconds. The
+displacements of the motors in these padding elements is computed to maintain
+the same velocity as the last element in the original trajectory. Thus the
+padding elements will cause the trajectory to execute for up to 0.3 seconds
+longer than requested, and the motors will move slightly farther than requested.
+However, there will be no velocity change, and hence no unexpected accelerations
+during the padding elements.
The number of trajectory elements, Nelements is limited as
+follows.
MAX_ELEMENTS in the SNL program, and 9 waveform records
+ (MnTraj and TimeTraj) which are dimensioned
+ NELM in the database. If 2000 points are allowed then the total
+ memory used in the IOC is 2000*9*8*2 = 288,000 bytes. This is a significant
+ amount of memory for an IOC. MAX_ELEMENTS is presently
+ defined to be 2000 in the SNL programs. This value can be changed (up to
+ 2000 for the MM4005) and the SNL program recompiled. The value of
+ NELM can be set to any value up to MAX_ELEMENTS when
+ the database is loaded. The number of output pulses, Npulses is limited as follows.
MAX_PULSES in the SNL program, and 16 waveform records
+ (MnActual and MnError) which are dimensioned
+ NPULSE in the database. If 2000 points are allowed then the total
+ memory used in the IOC is 2000*16*8*2 = 512,000 bytes. This is a significant
+ amount of memory for an IOC. MAX_PULSES is presently defined
+ to be 2000 in the SNL program. This value can be changed (up to 2000 for the MM4005) or
+ and the SNL program recompiled. The value of NPULSE
+ must be set to exactly the value of MAX_PULSES
+ when the database is loaded. +
+
After a trajectory has been defined by setting the values of the PVs +described in the previous section it must be built before it can be executed. +Building the trajectory consists of downloading it to the MM4005 and checking it +for errors such as excess velocities or accelerations.
+The following table describes the EPICS PVs used for building a +trajectory.
+| PV Name | +Record Type | +Description |
Build |
+ busy | +Setting this PV to 1 will build the trajectory, downloading it to the + controller. It will be set back to 0 automatically when the build is + complete. |
BuildState |
+ mbbi | +The trajectory build state. 0=Done,
+ 1=Busy. |
BuildStatus |
+ mbbi | +The trajectory build status. 0=Undefined,
+ 1=Success, 2=Failure. |
BuildMessage |
+ stringout | +Progress messages while the build is in progress and error message if
+ BuildStatus=Failure. |
M1MDVS ... M8MDVS (MM4005 only) |
+ ao | +The maximum change in velocity allowed between trajectory elements. + This value can be set. These values are read from the MM4005 when the SNL + program starts, so the current values can be seen. The acronym is Maximum + Delta Velocity Set. |
M1MDVA ... M8MDVA (MM4005 only) |
+ ao | +The actual maximum change in velocity between trajectory elements.
+ This value is read from the MM4005 after the trajectory is built.
+ MnMDVE gives the specific trajectory element in which this
+ maximum change in velocity occurred. If MnMDVA is greater
+ than MnMDVS then the trajectory build will fail. The acronym
+ is Maximum Delta Velocity Actual. Read-Only. |
M1MDVE ... M8MDVE (MM4005 only) |
+ longout | +The trajectory element number where MnMDVA occurs. The
+ acronym is Maximum Delta Velocity Element. Read-Only. |
M1MVA ... M8MVA (MM4005 only) |
+ ao | +The actual maximum velocity. This value is read from the MM4005 after
+ the trajectory is built. MnMVE gives the specific trajectory
+ element in which this maximum velocity occurred. If MnMVA is
+ greater than the maximum velocity allowed for this motor then the build
+ will fail. The acronym is Maximum Velocity Actual. Read-Only. |
M1MVE ... M8MVE (MM4005 only) |
+ longout | +The trajectory element number where MnMVA occurs. The
+ acronym is Maximum Velocity Element. Read-Only. |
M1MAA ... M8MAA (MM4005 only) |
+ ao | +The actual maximum acceleration. This value is read from the MM4005
+ after the trajectory is built. MnMAE gives the specific
+ trajectory element in which this maximum acceleration occurred. If
+ MnMVA is greater than the maximum acceleration allowed for
+ this motor then the build will fail. The acronym is Maximum Acceleration
+ Actual. Read-Only. |
M1MAE ... M8MAE (MM4005 only) |
+ longout | +The trajectory element number where MnMAA occurs. The
+ acronym is Maximum Acceleration Element. Read-Only. |
Channel access clients should do the following to build a trajectory:
+Build=1
+ Build, wait for it to go to
+ 0=Done.
+ Build=Done check BuildStatus. If it is not
+ 1=Success, then something went wrong.
+ BuildMessage can be used to determine what the error was,
+ although this will probably require a human rather than a program. If the build fails then it is useful to look at the
+trajectoryScanDebug.adl MEDM screen to examine the maximum velocity
+and acceleration values. See if one or more motors is being commanded to move
+too fast.
+
+
After a trajectory has been successfully built it can be executed. The +trajectory execution consists of the following steps:
+MnTraj[0]. This is only
+ done if MoveMode=Absolute.
+ Real or
+ Simulate mode, with the execution time scaled by
+ TimeScale. Poll during execution and post channel access monitors
+ for the current element being executed, for the current positions of the
+ motors and for any errors.
+ The following table describes the EPICS PVs used for executing a +trajectory.
+| PV Name | +Record Type | +Description |
Execute |
+ busy | +Setting this PV to 1 will execute the trajectory, performing the steps + described above. It will be set back to 0 automatically when the execution + is complete. |
ExecState |
+ mbbi | +The trajectory execution state. 0=Done, 1=Move
+ Start, 2=Executing, 3=Flyback. |
ExecStatus |
+ mbbi | +The trajectory execute status. 0=Undefined,
+ 1=Success, 2=Failure, 3=Abort,
+ 4=Timeout. |
ExecMessage |
+ stringout | +Progress messages while the execution is in progress and error message
+ if ExecStatus is not Success. |
SimMode (MM4005 only) |
+ bo | +Simulation mode. 0=Real, 1=Simulate. The
+ MM4005 can execute a trajectory in simulation mode, not actually moving
+ any motors. Default=Real. |
TimeScale (MM4005 only) |
+ ao | +Scaling time for the trajectory execution. Although a trajectory is
+ defined with a particular time per element, the execution time can be
+ scaled from this value. TimeScale can range from .01 (100
+ times faster) to 100 (100 times slower). Default=1.0 |
Abort |
+ bo | +Setting Abort=1 will immediately abort any motion on the
+ controller. It sends the AB command to the MM4005 which turns off the motor
+ power to all motors. To recover from this it is usually necessary to
+ re-home the motors, and to rebuild the trajectory at least twice before it
+ will succeed. Abort is set back to 0 automatically. |
M1Current ... M8Current |
+ + | The current position of each motor. These values are updated and + posted during execution of the trajectory. They are not + continuously updated when the trajectory is not executing because that + could interfere with EPICS motor records. This conflict will be eliminated + in a future release of the MM4005 support for the EPICS motor + record. |
DetOn |
+ ao | +The .VAL field of this PV is written to its
+ .OUT field in order to turn on the detector just before the
+ trajectory is executed. The .VAL and .OUT fields
+ are defined when the database is loaded. This mechanism is a very flexible
+ way to turn on any sort of detector or set of detectors, since any value
+ can be written to any PV. |
DetOff |
+ ao | +The .VAL field of this PV is written to its
+ .OUT field in order to turn off the detector just after the
+ trajectory is executed. The .VAL and .OUT fields
+ are defined when the database is loaded. This mechanism is a very flexible
+ way to turn off any sort of detector or set of detectors, since any value
+ can be written to any PV. |
Channel access clients should do the following to execute a trajectory:
+Execute=1
+ Execute, wait for it to go to
+ 0=Done.
+ Done check ExecStatus. If it is not
+ 1=Success, then something went wrong.
+ ExecMessage can be used to determine what the error was,
+ although this will probably require a human rather than a program. The execution can fail because the velocity or acceleration is too large,
+even if the build succeeded, if TimeScale is less than 1.0.
+
+ +
After a trajectory has been executed it is possible to read back from the +MM4005 or XPS the theoretical and actual positions of the motors when each +synchronization pulse was output. The EPICS interface presents this information +as the actual positions and the following errors (actual position minus +theoretical position) since these are usually of most interest to the user. +Obviously the theoretical position can be computed from the actual position and +the following error.
+Reading back this information from the MM4005 (but not the XPS) is rather slow, +but in many cases this does not +need to be done for each scan. Once it is established that the following errors +are small enough it is possible to execute scans without reading back from the +MM4005 each time. The readback time is determined by the speed of the +communications interface to the MM4005. Each point returned from the MM4005 is +about 200 characters. Using RS-232 at 19,200 baud this requires 0.1 seconds per +point, where the number of points is equal to the number of output pulses. This +is thus 30 seconds for a scan with 300 output pulses.
+The following table describes the EPICS PVs used for reading back a +trajectory.
+| PV Name | +Record Type | +Description |
Readback |
+ busy | +Setting this PV to 1 will read back the results of the + trajectory motion from the MM4005. It will be set back to 0 automatically + when the readback is complete. |
ReadState |
+ mbbi | +The readback state. 0=Done,
+ 1=Busy. |
ReadStatus |
+ mbbi | +The readback status. 0=Undefined,
+ 1=Success, 2=Failure. |
ReadMessage |
+ stringout | +Progress messages while the readback is in progress and
+ error message if ReadStatus is not
+ Success. |
Nactual |
+ longout | +The actual number of pulses output by the MM4005. This value
+ is normally equal to Npulses, but it could be less if a
+ trajectory did not complete. |
M1Actual ... M8Actual |
+ waveform, double | +The actual position of the motor when each pulse was output + by the contoller during the trajectory scan. |
M1Error ... M8Error |
+ waveform, double | +The following error of the motor when each pulse was output + by the controller during the trajectory scan. The following error is defined + as the actual position minus the theoretical position. |
Channel access clients should do the following to read back a trajectory:
+Readback=1
+ Readback, wait for it to go to
+ 0=Done.
+ Readback=Done check ReadStatus. If it is
+ not 1=Success, then something went wrong.
+ ReadMessage can be used to determine what the error was,
+ although this will probably require a human rather than a program. Note that the readback command reads the global trace buffer of the MM4005. +It can be used to read back this trace buffer even if the previous operation was +not a trajectory execution. This can be useful for debugging operations in +general.
++
+ +
The trajectory scanning does not use the EPICS motor records, but rather +talks directly to the controller. In order to keep the motor records in +sync with the actual motor positions the SNL program always returns the motors +to their original positions, i.e. the positions where the motor records think +they are, after a trajectory execution is complete. One should not move any +motors on an MM4005 while a trajectory scan is in progress.
+ +When a motion is aborted with the Abort PV it will be necessary
+to home the motors and synchronize the motor records with the actual positions
+of the motors.
+
+ +
The communication with the MM4005 uses asyn. It can be used with either the
+RS-232 or GPIB interfaces. Debugging can be enabled with the
+asynSetTraceMask and asynSetTraceIOMask commands.
+Communication with the XPS also uses asyn over a TCP/IP socket connection. Debugging
+can be enabled and disabled in the same way.
+
The timeout for communication with the MM4005 is set to 30 seconds, because
+some commands can take a very long time to response. This was found to be necessary to allow for
+the long time it takes the MM4005 to respond to the TB command after a VC
+command is issued when verifying the trajectory. However, it would probably be
+better to determine empirically how long it takes the MM4005 to verify
+trajectories as a function of Nelements and Npulses
+and have the SNL program wait that long after sending the VC command and
+before sending the TB command. These measurements have not been done yet.
The synchronization output pulses from the MM4005 are provided on pin 12 of +the DB-25 Auxilliary Connector. We have found it convenient to make a connector +with a short BNC pigtail coming from this pin. This pulse output from the MM4005 +is an open-collector circuit. The maximum rating is 30V and 40 mA.
+When using the pulse output as the channel-advance input of the Struck 7201 +or SIS 380x multi-scaler some modifications are required. The SIS 380x manual +states that with the LEMO TTL input configuration the inputs are pulled up to ++5V with 1K Ohm resistors in a resistor pack. For our module the factory +configuration was actually a 4.7K Ohm resistor pack. These resistors did pull +the open-collector output up to +5V. However, when driving the cable over a long +distance (~80 feet) the rise time of the signal was quite slow, about 8 +microseconds to go from 0V to the TTL threshold. This slow rise time caused the +SIS 380x to double count the channel advance signal most of the time. By +replacing the 4.7K Ohm resistor pack with a 200 Ohm pull-up resistor pack the +rise time was reduced to about 2 microseconds, and the module does not double +count. 200 Ohms is within the spec of the MM4005, since it will result in a +current of 5V/200 Ohm = 25 mA, which is less than the 40 mA maximum.
++
+
The source files for trajectory scanning are in the synApps +motor module +, in the motorApp/ tree. +
+NewportSrc/MM4005_trajectoryScan.st +NewportSrc/XPS_trajectoryScan.st +Db/trajectoryScan.db +op/adl/trajectoryScan.adl +op/adl/trajectoryScanDebug.adl +op/adl/trajectoryPlot.adl ++ +
The following are the comments from the beginning of
+trajectoryScan.db which describe the macro parameters which must be
+supplied in the dbLoadRecords command in the vxWorks startup
+script.
# Database for Newport MM4005 trajectory scanning. +# +# Mark Rivers +# August 12, 2000 +# +# Note: This database is completely general for the MM4005, it makes no +# assumptions about the motors defined on particular axis. Thus it can be used +# with the Newport diffractometer or any other set of up to 8 motors. +# +# Macro paramters: +# $(P) - PV name prefix +# $(R) - PV base record name +# $(NAXES) - Number of axes to be used. Typically 6 for diffractometer. +# $(NELM) - Maximum number of trajectory elements +# $(NPULSE) - Maximum number of output pulses +# $(DONPV) - Name of PV to turn detector on +# $(DONV) - Value to write to DONPV to turn detector on +# $(DOFFPV) - Name of PV to turn detector off +# $(DOFFV) - Value to write to DOFFPV to turn detector off +# $(C) - Card # (0,1,2...) of the board with the IP slot for the +# generic serial records +# $(IPSLOT) - IP slot (A-D) for the serial I/O module +# $(CHAN) - Channel (0-7) for the serial port +# $(BAUD) - Baud rate for the serial port +# Note: the MM4005 is assumed to be configured with 8 data bits, +# 1 stop bit, no parity. ++
The following is an example of the lines which must be put in the vxWorks
+startup file to load trajectoryScan.db. Note that the command line
+is longer than the vxWorks limit, so the command must be built using
+malloc, strcpy and strcat.
# Database for trajectory scanning with the MM4005/GPD
+# The required command string is longer than the vxWorks
+# command line, must use malloc and strcpy, strcat
+str = malloc(300)
+strcpy(str,"P=13IDC:,R=traj1,NAXES=6,NELM=1000,NPULSE=1000,C=0,IPSLOT=a,CHAN=2,BAUD=19200")
+strcat(str,",DONPV=13IDC:str:EraseStart,DONV=1,DOFFPV=13IDC:str:StopAll,DOFFV=1")
+strcat(str,",M1=Phi,M2=Kappa,M3=Omega,M4=Psi,M5=2-Theta,M6=Nu,M7=Unused,M8=Unused")
+dbLoadRecords("CARSApp/Db/trajectoryScan.db", str)
+
+DONPV and DOFFPV in this example are for the
+Struck/SIS multichannel scaler database (Struck8.db). For this
+database writing a 1 to EraseStart clears and starts the
+multichannel scaler, writing 1 to StopAll stops it. The names
+M1 ... M8 are used to define the MnName records, which
+in turn provide the motor labels on the MEDM displays.
After iocInit is called in the startup script the SNL program
+must be started. Here is an example:
seq &trajectoryScan, "P=13IDC:, R=traj1"+
+
+
The following show the MEDM screens with which the user can view and modify +the trajectory scanning parameters.
+trajectoryScan.adl is the main screen used to define, build,
+execute and read back trajectories. The only thing which cannot be done in MEDM
+is to edit the MnTraj and TimeTraj arrays, since MEDM
+does not provide a method to edit arrays. trajectoryScan.adl is
+called with macro parameters P, R, TITLE, and M1 ... M8. P and
+R are the prefix and record base used when the database was loaded.
+M1 ... M8 are the names of the motors. These are used to label the
+plots in trajectoryPlot.adl. For example
+trajectoryScan.adl in this screen shot was called with
+P=13IDC:, R=traj1, TITLE=GPD_Trajectory_Scan, M1=Phi, M2=Kappa, M3=Omega,
+M4=Psi, M5=2-Theta, M6=Nu, M7=Unused, M8=Unused.
trajectoryPlot.adl is used to plot the requested trajectory in
+position and time (MnTraj, TimeTraj), the readback
+positions (MnActual) and the following errors
+(MnError).
trajectoryScanDebug.adl is used to display detailed information,
+useful for debugging.
+
+
The following IDL function illustrates how an EPICS channel access client can +define, build, execute and read back a trajectory.
function trajectory_demo1, build=build, execute=execute, read=read, $
+ actual, error, counts
+
+;+
+; NAME:
+; trajectory_demo1
+;
+; PURPOSE:
+; This IDL function demonstates how a channel access client can
+; define, build, execute and read back a complex trajectory with the
+; MM4005.
+;
+; The trajectory parameters are as follows:
+; 101 elements, 300 output pulses, 30 second execution time, 1 second
+; acceleration time.
+;
+; Only the Phi and Kappa axes are moved.
+;
+; The Phi trajectory is a sin wave with two complete periods and an
+; amplitude of +-8 degrees.
+;
+; The Kappa trajectory is a sin wave with one complete period and an
+; amplitude of +-20 degrees.
+;
+; The readback includes the Phi, Kappa and Omega actual positions and
+; following errors. Omega is interesting because although it was not
+; moved during the trajectory it has some following error because of
+; the moving mass of the Kappa arm.
+;
+; The function returns counts from an SIS multichannel scaler which is
+; triggered by the output pulses.
+;
+; CATEGORY:
+; EPICS trajectory scanning
+;
+; CALLING SEQUENCE:
+; Result = TRAJECTORY_DEMO1(Actual, Error, Counts)
+;
+; INPUTS:
+; None.
+;
+; KEYWORD PARAMETERS:
+; BUILD: Set this keyword to build the trajecotry
+;
+; EXECUTE: Set this keyword to execute the trajectory
+;
+; READ: Set this keyword to read back the trajectory into
+; Actual and Error
+;
+; NOTE: Any or all of these keywords can be set. If none is set then the
+; function does not do anything.
+;
+; OUTPUTS:
+; Result: This function returns a status indicating whether the
+; selected operations were successful or not. 0=success,
+; anything else is a failure.
+; Actual: An array of [Nactual, 3] containing the actual positions of
+; the Phi, Kappa and Omega axes.
+; Error: An array of [Nactual, 3] containing the following errors of
+; the Phi, Kappa and Omega axes.
+; Counts: An array of [Nactual, 4] containing the counts from the
+; SIS 3801 multi-channel scaler. The EPICS_MED class library
+; is used to communicate with this device.
+;
+; NOTE: The Actual, Error and Counts outputs are only returned if the
+; READ keyword it set.
+;
+; SIDE EFFECTS:
+; This procedure can move the diffractometer. Be careful!
+;
+; EXAMPLE:
+; status = trajectory_demo1(/build)
+; status = trajectory_demo1(/execute)
+; status = trajectory_demo1(/read, actual, error, counts)
+; plot, actual[*,0]
+; plot, error[*,0]
+; plot, counts[*,0]
+;
+; MODIFICATION HISTORY:
+; Written by: Mark Rivers, August 13, 2000
+;-
+
+ prefix = '13IDC:'
+ traj = prefix + 'traj1'
+ phi = traj + 'M1'
+ kappa = traj+'M2'
+ omega = traj+'M3'
+ mcs = prefix + 'str:'
+
+ ; Make sure the MCS is in External channel advance mode
+ t = caput(mcs+'ChannelAdvance', 'External')
+
+ if (keyword_set(build)) then begin
+
+ ; The trajectory definition is hybid mode, meaning the positions are
+ ; definined in absolute coordinates rather than displacements from on
+ ; element to the next. However, the motors do not move to the absolute
+ ; position of the first element before executing the trajectory.
+ MoveMode = 'Hybrid'
+ t = caput(traj+'MoveMode', MoveMode)
+
+ ; 101 elements in the trajectory. We use 4N+1 since we are defining the
+ ; trajectory in Hybrid mode
+ nelements = 101
+ t = caput(traj+'Nelements', nelements)
+
+ ; 300 output pulses during the trajectory
+ npulses = 300
+ t = caput(traj+'Npulses', npulses)
+
+ ; 30 seconds total time to execute the trajectory
+ t = caput(traj+'TimeMode', 'Total')
+ time = 30.
+ t = caput(traj+'Time', time)
+
+ ; 1 second acceleration time
+ accel = 1.
+ t = caput(traj+'Accel', accel)
+
+ ; The Phi and Kappa motors will move.
+ t = caput(phi+'Move', 1)
+ t = caput(kappa+'Move', 1)
+
+ ; The Phi trajectory is a sin wave with two complete periods and an
+ ; amplitude of +-8 degrees
+ phiTraj = 8.*sin(findgen(nelements)/(nelements-1.)*4.*!pi)
+ t = caput(phi+'Traj', phiTraj)
+
+ ; The Kappa trajectory is a sin wave with one complete period and an
+ ; amplitude of +-20 degrees
+ kappaTraj = 20.*sin(findgen(nelements)/(nelements-1.)*2.*!pi)
+ t = caput(kappa+'Traj', kappaTraj)
+
+ ; Trajectory is now defined. Build it.
+ t = caput(traj+'Build', 1)
+ ; Wait for the build to complete. Wait 0.1 second between polls.
+ repeat begin
+ wait, 0.1
+ t = caget(traj+'Build', Build)
+ endrep until (Build eq 0)
+
+ ; Make sure the build was successful
+ t = caget(traj+'BuildStatus', BuildStatus, /string)
+ if (BuildStatus ne 'Success') then begin
+ t = caget(traj+'BuildMessage', BuildMessage)
+ print, 'Build failed, error = ', BuildMessage
+ return, BuildStatus
+ endif
+ endif
+
+ if (keyword_set(execute)) then begin
+ t = caput(traj+'Execute', 1)
+ ; Wait for the execute to complete. Wait 0.1 second between polls.
+ repeat begin
+ wait, 0.1
+ t = caget(traj+'Execute', Execute)
+ endrep until (Execute eq 0)
+
+ ; Make sure the execution was successful
+ t = caget(traj+'ExecStatus', ExecStatus, /string)
+ if (ExecStatus ne 'Success') then begin
+ t = caget(traj+'ExecMessage', ExecMessage)
+ print, 'Execution failed, error = ', ExecMessage
+ return, ExecStatus
+ endif
+ endif
+
+ if (keyword_set(read)) then begin
+ t = caput(traj+'Readback', 1)
+ ; Wait for the readback to complete. Wait 0.1 second between polls.
+ repeat begin
+ wait, 0.1
+ t = caget(traj+'Readback', Readback)
+ endrep until (Readback eq 0)
+
+ ; Make sure the readback was successful
+ t = caget(traj+'ReadStatus', ReadStatus, /string)
+ if (ReadStatus ne 'Success') then begin
+ t = caget(traj+'ReadMessage', ReadMessage)
+ print, 'Read failed, error = ', ReadMessage
+ return, ReadStatus
+ endif
+
+ ; Read the Phi and Kappa actual and error arrays into IDL, return to
+ ; caller
+ t = caget(traj+'Nactual', nactual)
+ t = caget(Phi+'Actual', PhiActual, max=nactual)
+ t = caget(Phi+'Error', PhiError, max=nactual)
+ t = caget(Kappa+'Actual', KappaActual, max=nactual)
+ t = caget(Kappa+'Error', KappaError, max=nactual)
+ t = caget(Omega+'Actual', OmegaActual, max=nactual)
+ t = caget(Omega+'Error', OmegaError, max=nactual)
+ actual = [[PhiActual], [KappaActual], [OmegaActual]]
+ error = [[PhiError], [KappaError], [OmegaError]]
+
+ ; Read the counts from the SIS multichannel scaler
+ med = obj_new('EPICS_MED', mcs, 4)
+ counts = med->get_data()
+ counts = counts[0:nactual-1,*]
+ endif
+
+ return, 0
+end
++
A set of SPEC macros allows SPEC to utilize trajectory scanning with EPICS +and the MM4005. +
The implementation is done at a low level, so that all of SPEC's standard +scans can be done "on-the-fly" utilizing this trajectory scanning software. This +was done by providing replacement macros for:
_ascan # Used by all ascan and dscan macros +mesh +hklscan # Used by hscan, kscan and lscan +_hklmesh +_hklline # Used by hkcircle, hlcircle, klcircle, hkradial, hlradial and klradial +_scanabort +resume +_loop +It adds the following new macros:
traj_index # Converts a SPEC motor index to an MM4005 motor index +traj_build # Builds a trajectory +traj_exec # Executes a trajectory +traj_read_counts # Reads the data from the multi-channel scaler +traj_read_actual # Reads back the actual MM4005 motor positions +traj_scans_on # Enables trajectory scanning +traj_scans_off # Disables trajectory scanning, uses step scanning +The improvement in performance is dramatic. Using step scanning the +overhead per point is about 1 second, so a 500 point scan takes a minimum of 500 +seconds or more than 8 minutes. Using trajectory scanning the total time to +execute a 500 point scan with .002 seconds per point is 3 seconds, including the +time to print and plot the data and write it to the data file. +
It is easy to switch back and forth between traditional step scanning and
+trajectory scanning. traj_scans_on turns on trajectory scanning for
+all subsequent scans. traj_scans_off reverts back to traditional
+step scanning.
+
It is possible to have the motor positions and HKL values which SPEC prints
+on the screen, plots and stores in the SPEC data file be based upon the
+theoretical motor positions during the scan. Alternatively SPEC can use
+values based upon the actual motor positions at each point in the scan.
+Using the actual motor positions is slower, because the values must be read from
+the MM4005 at the end of the trajectory execution. Set the SPEC global variable
+TRAC_USE_ACTUAL=0 to use the theoretical motor positions, and
+TRAJ_USE_ACTUAL=1 to use the actual motor positions.
+