### Ensemble Trajectory Scan Database and Sequencer Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Example startup script lines for loading the trajectoryScan.db and starting the sequencer for an Ensemble system. This follows the Asyn driver setup. ```bash # Database for trajectory scanning with the Ensemble dbLoadRecords("$(MOTOR)/motorApp/Db/trajectoryScan.db", "P=13BMC:,R=traj1,NAXES=6,NELM=2000,NPULSE=2000") iocInit ``` -------------------------------- ### Configure MAXv Trajectory Scan Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Example startup script lines for loading the trajectoryScan.db and starting the sequencer for a MAXv system. This configuration uses different parameters for the seq command. ```bash # Database for trajectory scanning with the MAXv dbLoadRecords("$(MOTOR)/motorApp/Db/trajectoryScan.db", "P=13BMC:,R=traj1,NAXES=6,NELM=2000,NPULSE=2000") iocInit # MAXV trajectory scan seq &MAX_trajectoryScan, "P=xxx:,R=traj1:,M1=m1,M2=m2,M3=m3,M4=m4,M5=m5,M6=m6,M7=m7,M8=m8,PORT=none" ``` -------------------------------- ### Configure XPS Trajectory Scan Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Example startup script lines for loading the trajectoryScan.db and starting the sequencer for an XPS system. Ensure dbLoadRecords and seq commands are on single lines. ```bash # Database for trajectory scanning with the XPS dbLoadRecords("$(MOTOR)/motorApp/Db/trajectoryScan.db", "P=13BMC:,R=traj1,NAXES=6,NELM=2000,NPULSE=2000") iocInit dbpf("13BMC:traj1DebugLevel","1") seq(&XPS_trajectoryScan, "P=13BMC:,R=traj1,M1=m33,M2=m34,M3=m35,M4=m36,M5=m37,M6=m38, IPADDR=164.54.160.124,PORT=5001,GROUP=GROUP1, P1=PHI,P2=KAPPA,P3=OMEGA,P4=PSI,P5=2THETA,P6=NU") ``` -------------------------------- ### Ensemble Asyn Substitutions File Example Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Example content for the AeroAsyn.substitutions file used in Ensemble trajectory scanning setup. It defines patterns for motor records. ```st file "$(MOTOR)/db/asyn_motor.db" { pattern {P, N, M, DTYP, PORT, ADDR, DESC, EGU, DIR, VELO, VBAS, ACCL, BDST, BVEL, BACC, MRES, PREC, DHLM, DLLM, INIT} {xxxL:, 17, "m$(N)", "asynMotor", AeroE1, 0, "motor $(N)", mm, Pos, .1, 0, .2, 0, 1, .2, 1.25E-5, 7, 0, 0, "SCURVE 100"} } ``` -------------------------------- ### Configure MM4005 Trajectory Scan Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Example startup script lines for loading the trajectoryScan.db and starting the sequencer for a vxWorks system with MM4005. Note the different database path and sequencer parameters. ```bash # Database for trajectory scanning with the MM4005 dbLoadRecords("$(CARS)/CARSApp/Db/trajectoryScan.db", "P=13IDC:,R=traj1,NAXES=6,NELM=2000,NPULSE=2000") iocInit # Trajectory scanning with MM4005 seq(&MM4005_trajectoryScan, "P=13IDC:, R=traj1, M1=m25,M2=m26,M3=m27,M4=m28,M5=m29,M6=m30,M7=m31,M8=m32,PORT=serial13") ``` -------------------------------- ### Configure Ensemble Trajectory Scan Setup Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Configuration steps for Ensemble system trajectory scanning, including Asyn driver setup and motor configuration. This sets up the communication infrastructure. ```bash dbLoadTemplate("AeroAsyn.substitutions") drvAsynIPPortConfigure("tcp1","164.54.51.77:8000", 0, 0, 0) EnsembleAsynSetup(1) EnsembleAsynConfig(0, "tcp1", 0, 1, 50, 1000) drvAsynMotorConfigure("AeroE1","motorEnsemble",0,1) ``` -------------------------------- ### Example Ensemble Trajectory Scan Initialization Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html This is an example of how to initialize an Ensemble Trajectory Scan sequence with specific motor configurations. ```shell seq &EnsembleTrajectoryScan, "P=15iddLAX:,R=traj1:,M1=aero:c0:m1,M2=none,M3=none,M4=none,M5=none,M6=none,M7=none,M8=none,PORT=tcp1" ``` -------------------------------- ### TRAJECTORY_SCAN Procedure Example Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html This example demonstrates how to call the TRAJECTORY_SCAN procedure to define, execute, and optionally read back motor positions and errors. Ensure the 'READ' keyword is set if you need actual and error data. ```IDL ; 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, NMOTORS] containing the actual positions of ; each axis. ; ERRORS: An array of [Nactual, NMOTORS] containing the following errors of ; each axis. ; NOTE: The ACTUAL and ERROR outputs are only returned if the READ keyword it set. ; ; SIDE EFFECTS: ; This procedure can move the motors. Be careful! ; ; EXAMPLE: ; positions = [[1,2,3],[.1, .2, .3], [0,3,4]] ; status = TRAJECTORY_SCAN('13IDC:traj1', positions, /read, actual, errors) ; plot, actual[*,0] ; oplot, errors[*,0] ; ``` -------------------------------- ### Clone Repository Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Create a new clone of the existing repository to start a new module. This command is used for duplicating the project structure. ```bash [~/epics/motor-split/Newport]$ git clone file://motorNewport4 motorNewport5 Cloning into 'motorNewport5'... remote: Counting objects: 18380, done. remote: Compressing objects: 100% (5465/5465), done. remote: Total 18380 (delta 12722), reused 17041 (delta 12482) Receiving objects: 100% (18380/18380), 6.05 MiB | 378.00 KiB/s, done. Resolving deltas: 100% (12722/12722), done. [~/epics/motor-split/Newport]$ ``` -------------------------------- ### Create EPICS IOC Application with Specific Architecture Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Generates a new EPICS IOC application, prompting for the target architecture and application name. This allows for customization of the IOC setup. ```bash makeBaseApp.pl -i -t ioc Newport ``` -------------------------------- ### Clone Motor Module with All Drivers Source: https://github.com/epics-modules/motor/blob/master/README.md This command clones the motor module and includes all driver submodules, suitable for a full installation. ```bash git clone --recursive https://github.com/epics-modules/motor.git ``` -------------------------------- ### IDL Trajectory Setup and Execution Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html This IDL code configures and executes a motor trajectory. It handles different move modes (Absolute, Relative, Hybrid) and allows building, executing, and reading back trajectory data. The code includes error checking for build and execution status. ```IDL t = caget(traj+'NumAxes', maxAxes) MoveMode = 'Absolute' if (keyword_set(relative)) then MoveMode = 'Relative' if (keyword_set(hybrid)) then MoveMode = 'Hybrid' t = caput(traj+'MoveMode', MoveMode) if (n_elements(build) eq 0) then build=1 if (n_elements(execute) eq 0) then execute=1 if (keyword_set(build)) then begin dims = size(positions, /dimensions) nelements = dims[0] naxes = dims[1] if (n_elements(npulses) eq 0) then npulses = nelements t = caput(traj+'Nelements', nelements) t = caput(traj+'Npulses', npulses) ; Default is 1 second per element if (n_elements(time) eq 0) then time = nelements * 1.0 if (n_elements(time) eq 1) then begin t = caput(traj+'TimeMode', 'Total') t = caput(traj+'Time', time) endif else begin t = caput(traj+'TimeMode', 'Per element') t = caput(traj+'TimeTraj', time) endelse if (n_elements(accel) eq 0) then accel = 1. t = caput(traj+'Accel', accel) ; The first naxes motors will move. for i=0, maxAxes-1 do begin axis = traj + 'M' + strtrim(i+1,2) if (i lt naxes) then begin t = caput(axis+'Move', 1) pos = positions[*,i] t = caput(axis+'Traj', pos) endif else begin t = caput(axis+'Move', 0) endelse endfor ; 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', busy) endrep until (busy 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', busy) endrep until (busy 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', busy) endrep until (busy 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 actual and error arrays into IDL, return to ; caller t = caget(traj+'Nactual', nactual) actual = dblarr(nactual, maxAxes) errors = dblarr(nactual, maxAxes) for i=0, maxAxes-1 do begin axis = traj + 'M' + strtrim(i+1,2) t = caget(axis+'Actual', temp, max=nactual) actual[0,i] = temp t = caget(axis+'Error', temp, max=nactual) errors[0,i] = temp endfor endif return, 0 end ``` -------------------------------- ### MAXvConfig Call with SSI Encoder Source: https://github.com/epics-modules/motor/blob/master/docs/motor_release.html Example of calling MAXvConfig with the third argument set to enable SSI based absolute encoder values for a specific axis. ```c MAXvConfig(0, config0, 0x00) ``` -------------------------------- ### Copy Application and IOC Files Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Copy blank application and IOC files into the new module directory. Use 'cp -riT' for recursive, interactive, and no-target-directory-clobbering copy. Be cautious not to overwrite source files. ```bash [~/epics/motor-split/Newport]$ cp -riT motorNewportBlank motorNewport5 cp: overwrite ‘motorNewport5/newportApp/src/Makefile’? n [~/epics/motor-split/Newport]$ rm motorNewport5/newportApp/src/newport.dbd ``` -------------------------------- ### Configure Remote Repository and Push Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Remove the existing remote origin and add a new one pointing to the GitHub repository. Then, push the local master branch to the remote origin. ```bash [~/epics/motor-split/Newport/motorNewport5]$ git remote -v origin file://motorNewport4 (fetch) origin file://motorNewport4 (push) [~/epics/motor-split/Newport/motorNewport5]$ git remote rm origin [~/epics/motor-split/Newport/motorNewport5]$ git remote add origin git@github.com:kmpeters/motorNewport.git [~/epics/motor-split/Newport/motorNewport5]$ git remote -v origin git@github.com:kmpeters/motorNewport.git (fetch) origin git@github.com:kmpeters/motorNewport.git (push) [~/epics/motor-split/Newport/motorNewport5]$ git push -u origin master X11 forwarding request failed on channel 0 Counting objects: 3651, done. Delta compression using up to 8 threads. Compressing objects: 100% (1810/1810), done. Writing objects: 100% (3651/3651), 907.40 KiB | 0 bytes/s, done. Total 3651 (delta 1488), reused 3535 (delta 1427) remote: Resolving deltas: 100% (1488/1488), done. ``` -------------------------------- ### Soft Channel Motor Record Configuration Source: https://github.com/epics-modules/motor/blob/master/docs/motorRecord.html Example configuration for a soft channel motor record used for angular position commands. ```epics grecord(motor,"$(user):rotary") { field(DTYP,"Soft Channel") field(OUT,"$(user):convertDriveValue.A PP MS") field(RDBL,"$(user):convertReadbackValue.VAL NPP MS") field(URIP,"Yes") field(STOO,"$(user):linear.STOP PP MS") field(DINP,"$(user):linear.DMOV NPP MS") field(MRES,"0.001") field(RRES,"1.000") field(PREC,"3") field(DHLM,"45") field(DLLM,"-45") field(TWV,"5") field(RTRY,"0") field(EGU,"deg.") } ``` -------------------------------- ### Applying a Patch to Update Build Files Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module This snippet demonstrates how to download, modify, and apply a patch file to update Makefiles, RELEASE, and CONFIG_SITE files for module integration. It also includes staging and committing these changes. ```bash wget https://raw.githubusercontent.com/kmpeters/motor/motor-split-testing/modules/betterVendor.patch sed -e 's/vendor/newport/g' -e 's/Vendor/Newport/g' -e 's/VENDOR/NEWPORT/g' betterVendor.patch > betterNewport.patch git apply betterNewport.patch git add .gitignore Makefile configure/RELEASE iocs/newportIOC/configure/CONFIG_SITE iocs/newportIOC/configure/RELEASE iocs/newportIOC/iocBoot/iocNewport/st.cmd iocs/newportIOC/newportApp/src/Makefile iocs/Makefile find . -name "*.local" -exec git add -f {} \; git commit -m "Applied patch to update Makefiles, RELEASE and CONFIG_SITE files" ``` -------------------------------- ### Add and Commit makeBaseApp Files Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Stage and commit the files added from makeBaseApp. This command prepares the changes for version control. ```bash [~/epics/motor-split/Newport]$ cd motorNewport5/ [~/epics/motor-split/Newport/motorNewport5]$ git add Makefile configure/ iocs/newportIOC/Makefile iocs/newportIOC/configure/ iocs/newportIOC/iocBoot/Makefile iocs/newportIOC/iocBoot/iocNewport/Makefile iocs/newportIOC/iocBoot/iocNewport/st.cmd iocs/newportIOC/newportApp/ newportApp/Db/Makefile newportApp/Makefile [~/epics/motor-split/Newport/motorNewport5]$ git commit -m "Added files from makeBaseApp" [master d38b1a1] Added files from makeBaseApp 27 files changed, 490 insertions(+) create mode 100644 Makefile create mode 100644 configure/CONFIG create mode 100644 configure/CONFIG_SITE create mode 100644 configure/Makefile create mode 100644 configure/RELEASE create mode 100644 configure/RULES create mode 100644 configure/RULES.ioc create mode 100644 configure/RULES_DIRS create mode 100644 configure/RULES_TOP create mode 100644 iocs/newportIOC/Makefile create mode 100644 iocs/newportIOC/configure/CONFIG create mode 100644 iocs/newportIOC/configure/CONFIG_SITE create mode 100644 iocs/newportIOC/configure/Makefile create mode 100644 iocs/newportIOC/configure/RELEASE create mode 100644 iocs/newportIOC/configure/RULES create mode 100644 iocs/newportIOC/configure/RULES.ioc create mode 100644 iocs/newportIOC/configure/RULES_DIRS create mode 100644 iocs/newportIOC/configure/RULES_TOP create mode 100644 iocs/newportIOC/iocBoot/Makefile create mode 100644 iocs/newportIOC/iocBoot/iocNewport/Makefile create mode 100644 iocs/newportIOC/iocBoot/iocNewport/st.cmd create mode 100644 iocs/newportIOC/newportApp/Db/Makefile create mode 100644 iocs/newportIOC/newportApp/Makefile create mode 100644 iocs/newportIOC/newportApp/src/Makefile create mode 100644 iocs/newportIOC/newportApp/src/newportMain.cpp create mode 100644 newportApp/Db/Makefile create mode 100644 newportApp/Makefile [~/epics/motor-split/Newport/motorNewport5]$ git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # nothing to commit, working directory clean ``` -------------------------------- ### OMS MAXv Error Message Example Source: https://github.com/epics-modules/motor/blob/master/docs/motor_release.html This message appears in the console or IOC errlog when a MAXv card experiences a watchdog timeout or reboot. ```text ***MAXv card #Disabled*** Watchdog Timeout CTR = ``` ```text ***VME58 card #Disabled*** Reboot Detected. ``` -------------------------------- ### Create Base EPICS Support Application Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Scaffolds a new EPICS support application using the makeBaseApp.pl script. This is the first step in creating a new driver module. ```bash makeBaseApp.pl -t support newport ``` -------------------------------- ### Hard Motor Record Configuration Source: https://github.com/epics-modules/motor/blob/master/docs/motorRecord.html Example configuration for a hard motor record using Oms58 device support for linear position commands. ```epics grecord(motor,"$(user):linear") { field(DTYP,"OMS VME58") field(VBAS,"1.0") field(VELO,"25.0") field(OUT,"#C0 S0 @") field(MRES,"0.001") field(PREC,"3") field(DHLM,"1000") field(DLLM,"-1000") field(RTRY,"0") field(TWV,"1") field(EGU,"mm.") } ``` -------------------------------- ### Enabling Trajectory Scan Debugging (asyn) Source: https://github.com/epics-modules/motor/blob/master/docs/trajectoryScan.html Debugging for communication with MM4005 and XPS controllers can be enabled using asyn trace commands. ```C asynSetTraceMask and asynSetTraceIOMask commands ``` -------------------------------- ### Clone Motor Repository Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Initial step to obtain the motor module source code from GitHub. ```bash git clone https://github.com/epics-modules/motor.git ``` -------------------------------- ### Calculate Speed Base (SBAS) and Velocity Base (VBAS) Source: https://github.com/epics-modules/motor/blob/master/docs/motor_notes.txt Synchronizes the minimum speed (SBAS) and minimum velocity (VBAS) based on the UREV field. ```C pmr->sbas = pmr->vbas / fabs(pmr->urev); pmr->vbas = fabs(pmr->urev) * pmr->sbas; ``` -------------------------------- ### Using Deferred Moves with asyn Motors Source: https://github.com/epics-modules/motor/blob/master/docs/motor_release.html Configure a BO record to control the deferred move flag for asyn motors. This allows moves to be queued and executed simultaneously. ```text DTYP=asynUInt32Digital, OUT=@asynMask(port,1,1)DEFER, ZNAM="Go", ONAM="Defer" ``` -------------------------------- ### Initial/Retry Move Logic - Preferred Direction and Within Backlash Distance Source: https://github.com/epics-modules/motor/blob/master/docs/motor_notes.txt This logic is used when the preferred direction is true and the current position is within the backlash distance plus one step. It sets local velocity/acceleration to backlash values and calculates the local move position. ```Pseudocode ELSE IF [Preferred Dir. == True], AND, [the current position is within the backlash distance plus 1 step. {|DIFF| < |BDST| + |MRES|} { (use_rel == true, AND, (sign(DIFF - BDST) != sign(DIFF)), OR [use_rel == false, AND, ([(LDVL + RDBD) > (DVAL - BDST)] == (DVAL > LDVL))] } ] Set local vel/acc to backlash values. IF use relative moves indicator is true. Set local move position = relpos * FRAC IF use relative moves indicator is true. Set local move position = relpos * FRAC = (DIFF/MRES) * FRAC = ((DVAL - DRBV)/MRES) * FRAC ELSE Set local move position = currpos + (FRAC * (newpos - currpos)) If FRAC = 1 = currpos + newpos - currpos = newpos = DVAL/MRES ENDIF ``` -------------------------------- ### Driver Initialization: Oms/Oms58 Error Check Source: https://github.com/epics-modules/motor/blob/master/docs/RELEASE.txt An explicit error check and corresponding error message ('Oms[58] driver uninitialized.') now result at record initialization if a required driver is not initialized. This is not an issue with Newport controllers due to their initialization particulars. ```c Added pointer to initialized indicator to driver table structure in motordrvCom.h ``` ```c Added error checks in oms_init() and oms_end_trans() in both devOms.c and devOms58.c ``` ```c - initialized pointer to local initialized indicator in driver table. - set initialized indicator ON in init(). ``` -------------------------------- ### Create EPICS IOC Application Source: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module Generates a new EPICS IOC application structure. This command is used to create the necessary files and directories for an IOC. ```bash makeBaseApp.pl -t ioc newport ```