#%TITLE% ID.MAC
#%NAME%
# ESRF Insertion Devices
#%CATEGORY%
# Accelerator
#
#%DESCRIPTION%
#%PRE%
# This macro set allows to access axes on insertion devices as motors in SPEC.
#
# Since version 4.0 (Jul 2006) this macro file allows also to
# define new style macro motors on an insertion device.
#
# To define new style macro motors you must define:
#
# an id controller in config:
#
# MOTORS DEVICE ADDR <>MODE NUM <>TYPE
# YES id //aries/id/id/28 4 Macro Motors
#
# motors in config referring to that controller. Channel assignment
# will decide on the motor role as follow:
#
# Channel
# 0 - GAP
# 1 - TAPER
# 2 - REVOLVER GAP 1 (Not Implemented yet)
# 3 - REVOLVER GAP 2 (Not Implemented yet)
#
# Module holds the "mechanics" number starting from 1.
# Example: gap and taper motors on first undulator should
# share the same module=1... and channel=0 for gap
# channel=1 for taper)
#
#%PRE%
#%SETUP%
# In the current setup your computer must have access to aries (where the
# data base is running) The macros will only work for authorized users.
# You need to ask for permission to the machine group
#
# For getting id parameters. Type idsetup once to get information
# then define motors in setup file and in config as you can see below
# in example (not necessary if using macro motors)
#
#%EXAMPLE%
# %DL%
# %DT%idsetup%DD% Without parameters returns the list of axes found
# in the beamline frontend
#%PRE%
# Devname: //aries/id/id/61 for 2 carriages
# 2 axes in the system
# 1 - U46 : carriage: id/meca/61m1 ; type: TAPER
# 2 - U48 : carriage: id/meca/61m2 ; type: TAPER
#
#%PRE%
# %DT%idsetup u46 1 gap t48 2 taper%DD% defines two motors u46 and
# t48 (that should be defined in config) to move axes
# 1 and 2 (as shown by idsetup without parameters). The
# first one will do movements on the gap of the first axis
# the second one on the taper of the second axis.
# active axes and move to the desired one.
# %DT%mv u46 23%DD% Will move u46 gap to position 23
# %DT%mv t48 0.2%DD% Will move taper t48 to position 0.2
# %XDL%
#%UU% [parma]
#%MDESC%
#
def id_config (mne, type, unit, module, channel) '{
if (mne == "..") {
print "Using ID Macros Motor on", id_ADDR, "(ctrl unit", unit, ")"
global IDDEV IDAXIS
global IDALLPOS IDMOVE IDERROR
global IDMOVEPOS IDMOVETAPPOS
global IDMECA IDMECADEV IDNOMECA
local _id_
if (split(SPECBL, _id_, "id") != 2 && split(SPECBL, _id_, "ID") != 2 ) {
printf("ID Error: Not ID beamline or Wrong SPECBL variable.\n")
return ".error."
}
IDDEV = id_ADDR
list_init IDAXIS
if (id_getallinfo(id_ADDR) != 0 ) {
printf("ID Error getting info from Front End device server\n")
return ".error."
}
}
else {
if (type == "mot") {
local type[]
type[0]="gap"
type[1]="taper"
type[2]="revolver1"
type[3]="revolver2"
if (channel>1) {
printf("ID Warning: revolver type ID not supported yet.\n")
return ".error."
}
if (module < 1 || module > list_n(IDAXIS)) {
printf("ID Error: Wrong axis (%d) selected\n",module)
return ".error."
}
}
}
}
'
#%IU% (<mne>, <cmd>, <p1>, <p2>)
#%MDESC%
# Macro motor main macro.
def id_cmd (mne, cmd, p1, p2) '{
if (mne == "..") {
if (cmd == "preread_all") {
if (esrf_io(IDDEV, "DevRead", IDALLPOS) == -1) {
IDERROR = 1
}
}
else if (cmd == "prestart_all") {
for (i=0 ; i<list_n(IDAXIS) ; i++) {
IDMOVE[i] = 0
}
}
else if (cmd == "start_all") {
local i axis argin argout
for (i in IDMOVE) {
if (IDMOVE[i] != 0) {
IDMOVE[i]--
axis=i+1
argin[0] = list_getpar(IDAXIS, axis, "dev")
argin[1] = list_getpar(IDAXIS, axis, "ident")
argin[2] = IDMOVE[i]
argin[3] = IDMOVEPOS[i]
argin[4] = IDMOVETAPPOS[i]
esrf_io(IDDEV,"DevWrite",argin,argout)
}
}
}
}
else {
local iddev axis channel mecadev
iddev = motor_par(mne, "address")
axis = motor_par(mne, "module")
channel = motor_par(mne, "channel")
mecadev = list_getpar (IDAXIS, axis, "dev")
if (cmd == "get_status") {
local idstat
idstat = esrf_io(IDDEV, "DevTrigMotion", mecadev)
if (idstat == 2 ) {
id_getallpos()
return 0x02
}
else {
return 0
}
}
else if (cmd == "start_one") {
# p1 : target position in dial units for absolute motion.
# p2 : magnitude in dial units for relative motion.
if (channel == 0 ) {
IDMOVE[axis-1] |= 0x1
IDMOVEPOS[axis-1] = p1
}
if (channel == 1) {
IDMOVE[axis-1] |= 0x2
IDMOVETAPPOS[axis-1] = p1
}
}
else if (cmd == "position") {
local pos
pos = IDALLPOS[(axis-1)*2+channel+0]
return pos
}
}
}
'
#%UU% [mnemonic axe-number gap/taper [mnemonic2 axe-number2 gap/taper ...]]
#%MDESC%
# Macro to setup the insertion device parameters. It uses the
# SPECBL variable to get information from the frontend device
# server
# If called with no parameters it will get information from frontend
# device server and show to the user info about: present axes ant types.
# It can then be called with parameters to configure pseudo motors.
#
def idsetup '{
global ID_ON
global IDDEV
global IDNOMECA IDMECA IDMECADEV
global IDAXIS
global IDALLPOS ID_OLDPOS
global ID_ARGIN ID_ARGOUT
global ID_MOVETHIS ID_NOTREAD
global IDMOVE IDMOVEPOS IDMOVETAPPOS ID_MOVINGANY
global ID_TIMEOUT
local _idno param _onoff idno idhost idroot isid
local i
ID_TIMEOUT=15
# Checks if you are in a BM or ID.
if (split(SPECBL,_idno,"id") != 2 && split(SPECBL,_idno,"ID")!=2) {
if (split(SPECBL,_idno,"d") != 2 && split(SPECBL,_idno,"D")!=2) {
printf("Wrong SPECBL variable\n")
printf("Sorry")
exit
} else {
isid = 0
}
} else {
isid = 1
}
# Setup IDDEV: names of insertion device and front end
# device servers.
if (whatis("IDDEV") & 0x8000000) {
sscanf(_idno[1],"%d",idno)
idhost = "aries"
if ( isid ) {
IDDEV = sprintf("//%s/id/id/%d",idhost,idno)
}
}
if ( isid ) {
list_init IDAXIS
if (id_getallinfo(IDDEV) != 0 ) {
printf("***********************************************\n")
printf("Error getting info from Front End device server\n")
printf("***********************************************\n")
}
else {
# No arguments -> display infos.
if (!$#) {
id_showinfo()
}
else if ("$1" != "silent") {
_onoff = ID_ON
idoff
nmot = split("$*", param)/3
for (i=0 ; i<list_n(IDAXIS) ; i++) {
list_setpar(IDAXIS, i+1, "tapmne", "")
list_setpar(IDAXIS, i+1, "gapmne", "")
list_setpar(IDAXIS, i+1, "def", 0)
}
for (i=0 ; i<nmot ; i++) {
local axis idmne tapergap
idmne = param[i*3]
axis = param[i*3 + 1] - 1
tapergap = param[i*3 + 2]
if (axis < 0 || axis >= list_n(IDAXIS)) {
printf("Wrong axis (%d) selected\n", axis + 1)
} else {
id_axedef(axis, idmne, tapergap)
}
}
if (whatis("ID_ON") & 0x8000000) idon
if (_onoff) idon
setup_tail("id")
}
}
}
}
'
#%UU%
#%MDESC%
def idunsetup 'idoff'
#%UU%
#%MDESC%
# This macro undefines all macros related with the beamline
# insertion device.
#
def idoff '{
local i
ID_ON = 0
for(i=0;i<list_n(IDAXIS);i++) {
cdef("","",list_getpar(IDAXIS,i+1,"gapmne"),"delete")
cdef("","",list_getpar(IDAXIS,i+1,"tapmne"),"delete")
}
cdef("","","_id","delete")
cdef("","","_id2","delete")
}
'
#%UU%
#%MDESC%
# Makes all the definitions active
#
def idon '{
local idmne i
ID_ON = 1
cdef("_id_prompt")
cdef("prompt_mac", "id_prompt()\n", "_id")
cdef("user_getpangles","id_getallpos()\n","_id",0x10)
cdef("user_checkall", "id_premove()\n", "_id",0x10)
cdef("user_checkall", "id_moveall()\n", "_id2",0x20)
cdef("user_motorsrun", "id_poll\n", "_id2",0x20)
for(i=0;i<list_n(IDAXIS);i++) {
local _def
_def = list_getpar(IDAXIS,i+1,"def")
if (_def & 0x1) {
idmne = list_getpar(IDAXIS,i+1,"gapmne")
cdef("user_getpangles",sprintf("id_getpos(%d,%s,1)\n",i,idmne),idmne,0x01)
cdef("_id_prompt",sprintf("id_getpos(%d,%s,1)\n",i,idmne),idmne,0x21)
cdef("user_checkall",sprintf("id_moveone(%d,%s,1)\n",i,idmne),idmne,0x01)
}
if (_def & 0x2) {
idmne = list_getpar(IDAXIS,i+1,"tapmne")
cdef("user_getpangles",sprintf("id_getpos(%d,%s,2)\n",i,idmne),idmne,0x01)
cdef("_id_prompt",sprintf("id_getpos(%d,%s,2)\n",i,idmne),idmne,0x21)
cdef("user_checkall",sprintf("id_moveone(%d,%s,2)\n",i,idmne),idmne,0x01)
}
}
if (whatis("blmenu") & 0x2){
blmenuadd("Insertion Device motors","ID info","idbody","_idblmenu_")
}
}
'
#%IU%
#%MDESC%
def idbody(mode) '{
if (mode == 1) {
if (ID_ON) {
idoff
} else {
idon
}
}
if (mode == 2) {
idsetup
}
return(sprintf("%s",ID_ON?"On":"Off"))
}
'
#%IU%
#%MDESC%
# Polls in the state of the front end
#
def id_poll '{
local idstat argin moving
moving = 0
for (i=0;i<IDNOMECA;i++) {
if (ID_MOVETHIS[i]) {
idstat=esrf_io(IDDEV,"DevTrigMotion",IDMECADEV[i])
if (idstat == 2 ) {
err_accum=0
moving=1
}
else {
if (!ESRF_ERR) {
ID_MOVETHIS[i] = 0
}
else {
if ( (err_accum++) > 3 ) {
print "Error on polling insertion device.Giving up"
ID_MOVETHIS[i] = 0
}
}
}
}
}
if (moving) return(1)
}
'
#%IU% (<axis>, <idmne>, <tapergap>)
#%MDESC%
# Sets the "def" and "tapmne" or "gapmne" fields in IDAXIS.
# <axis> : axis number.
# <idmne> : ID motor mnemonic.
# <tapergap> : can be {"1"|"TAPER"|"taper"|"t"|"Taper"}
#
def id_axedef(axis, idmne, tapergap) '{
local _def
_def = list_getpar(IDAXIS, axis+1, "def")
if (tapergap == "1" || tapergap == "TAPER" || tapergap == "taper" || tapergap == "t" || tapergap == "Taper") {
list_setpar(IDAXIS, axis+1, "tapmne", idmne)
list_setpar(IDAXIS, axis+1, "def", _def |= 0x2)
}
else {
list_setpar(IDAXIS, axis+1, "gapmne", idmne)
list_setpar(IDAXIS, axis+1, "def", _def |= 0x1)
}
}
'
#%IU% (<devname>)
#%MDESC%
# Gets all info from frontend device server
# Fills IDNOMECA IDMECA IDMECADEV
def id_getallinfo(devname) '{
local helloval configval
if (esrf_io(devname,"tcp") == -1 ) {
return(-1)
}
if (esrf_io(devname,"DevHello",helloval) == -1 ) {
return(-1)
}
if (esrf_io(devname,"DevReadConfig",configval) == -1) {
return(-1)
}
IDNOMECA = helloval[2]
axis = 0
mecaix = 0
for (i=0;i<IDNOMECA;i++) {
local mecaname
IDMECA[i] = helloval[3+i]
IDMECADEV[i] = configval[mecaix]
mecaname = configval[mecaix+1]
mecaix += 2
for (j=0;j<IDMECA[i];j++) {
list_add(IDAXIS,sprintf("_%d",axis+1))
list_setpar(IDAXIS,axis+1,"dev",IDMECADEV[i])
list_setpar(IDAXIS,axis+1,"meca",mecaname)
list_setpar(IDAXIS,axis+1,"title",configval[mecaix + 1])
list_setpar(IDAXIS,axis+1,"type",configval[mecaix + 2])
list_setpar(IDAXIS,axis+1,"num",j+1)
list_setpar(IDAXIS,axis+1,"ident",configval[mecaix])
mecaix += 5
axis++
}
}
}
'
#%IU% ()
#%MDESC%
# Print out main info from frontend device server
#
def id_showinfo() '{
printf("Devname: %s for %d carriage\n",IDDEV,IDNOMECA)
printf("%d axes in the system\n",list_n(IDAXIS))
for (i=0;i<list_n(IDAXIS);i++) {
printf("%2d - %8s :",i+1,list_getpar(IDAXIS,i+1,"meca"))
printf(" carriage: %s ; type: %s \n", list_getpar(IDAXIS,i+1,"dev"), list_getpar(IDAXIS,i+1,"title"))
}
}'
#%IU% ()
#%MDESC%
# Reads position for all axes
#
def id_getallpos() '{
global IDERROR
if (ID_NOTREAD) return(0)
if (esrf_io(IDDEV,"DevRead",IDALLPOS) == -1) {
IDERROR=1
return(-1)
} else {
IDERROR=0
}
}
'
#%IU% (axis,idmne,gaptap)
#%MDESC%
# Assigns position to each motor
#
def id_getpos(axis,idmne,gaptap) '{
local motnum
if (IDERROR)
return(-1);
if (ID_NOTREAD) return(0)
motnum = motor_num(idmne)
if (motnum == -1 ) {
printf("Internal macro error on \"id\" macros.\n")
printf("Contact your spec administrator!\n")
return(-1)
}
if (gaptap == 1) {
A[motnum] = IDALLPOS[axis*2]
}
if (gaptap == 2) {
A[motnum] = IDALLPOS[axis*2+1]
}
if (ID_ATPROMPT) {
chg_dial(motnum,A[motnum])
chg_offset(motnum,A[motnum])
}
ID_OLDPOS[motnum] = A[motnum]
return(0)
}
'
#%IU% (<axis>, <idmne>, <gaptap>)
#%MDESC%
# Flags whether axes should be moved or not.
#
def id_moveone(axis, idmne, gaptap) '{
local idnum
idnum = motor_num(idmne)
if (fabs(A[idnum] - ID_OLDPOS[idnum]) > (1.0 / motor_par(idnum,"step_size"))) {
_bad_lim = 0
_chk_lim idnum A[idnum]
if (!_bad_lim) {
if (gaptap == 1 ) {
IDMOVE[axis] |= 0x1
IDMOVEPOS[axis] = A[idnum]
}
if (gaptap == 2) {
IDMOVE[axis] |= 0x2
IDMOVETAPPOS[axis] = A[idnum]
}
ID_MOVINGANY = 1
ID_NOTREAD = 0
}
else {
A[idnum] = ID_OLDPOS[idnum]
}
}
else {
# movement too small
}
}
'
#%IU% ()
#%MDESC%
#
def id_prompt() '{
global ID_ATPROMPT
ID_ATPROMPT=1
id_getallpos()
_id_prompt
ID_ATPROMPT=0
ID_NOTREAD=0
}
'
#%IU% ()
#%MDESC%
#
def id_premove() '{
local ii
ID_MOVINGANY = 0
ID_NOTREAD = 1
for (ii=0 ; ii<list_n(IDAXIS) ; ii++) {
local _def
IDMOVE[ii] = 0
_def = list_getpar(IDAXIS, ii+1, "def")
if (_def & 0x1) {
mnum = motor_num(list_getpar(IDAXIS, ii+1, "gapmne"))
if (mnum != -1 ) {
IDMOVEPOS[mnum] = ID_OLDPOS[mnum]
}
}
if (_def & 0x2) {
mnum = motor_num(list_getpar(IDAXIS, ii+1, "tapmne"))
if (mnum != -1 ) {
IDMOVETAPPOS[mnum] = ID_OLDPOS[mnum]
}
}
}
}
'
#%IU% ()
#%MDESC%
# Move all axes that were previously flagged to move
#
def id_moveall() '{
local i axis j
if (ID_MOVINGANY) {
axis = 0
for (i=0;i<IDNOMECA;i++) {
ID_MOVETHIS[i]=0
ID_ARGIN[3] = 0
ID_ARGIN[4] = 0
for (j=0;j<IDMECA[i];j++) {
if (IDMOVE[axis]) {
local _def
_def = list_getpar(IDAXIS,axis+1,"def")
ID_MOVETHIS[i]++
ID_ARGIN[0] = IDMECADEV[i]
ID_ARGIN[1] = list_getpar(IDAXIS,axis+1,"ident")
if (IDMOVE[axis] == 3) { # both
ID_ARGIN[2] = 2
ID_ARGIN[3] = IDMOVEPOS[axis]
ID_ARGIN[4] = IDMOVETAPPOS[axis]
}
if (IDMOVE[axis] == 2) { # only taper
ID_ARGIN[2] = 1
ID_ARGIN[4] = IDMOVETAPPOS[axis]
}
if (IDMOVE[axis] == 1) { # only gap
ID_ARGIN[2] = 0
ID_ARGIN[3] = IDMOVEPOS[axis]
}
}
axis++
}
if (ID_MOVETHIS[i]) {
esrf_io(IDDEV,"DevWrite",ID_ARGIN,ID_ARGOUT)
}
}
}
}
'
#%MACROS%
#%IMACROS%
#%AUTHOR% V.Rey - BLISS - (Original 11/1996)
# $Revision: 5.0 $ / $Date: 2012/05/03 12:33:32 $
#%TOC%
|