esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%NAME%
#  Macromotor to control the HXP100 Newport hexapode
#  
#%DESCRIPTION%
#Control of the HXP100 Newport hexapode
#%BR% default socket timeout: 5
#%BR% 'scale' parameter: can be set in the config. This is the
#For example, with a scale of 1000, spec value will be divided by 1000
#to be sent to the controller, and the read value will be multiplied by 1000.
#If not provided, is set to 1
#%BR% - Position is understood as the position of the Tool coordinate system in
#the Work coordinate system
#%END%

   global hxp100_SIMUL  hxp100_DEBUG
   global HXP_SOCK_ANSWER HXP_SOCK_ERR HXP_ERR_MSG
   
   global HXP_SOCK HXP_COORD
   #HXP_GROUPNAME = "HEXAPOD"
   #HXP_SOCK = "192.168.254.254:5001"
   HXP_sock0 = "%.13g,0,0,0,0,0"
   HXP_sock1 = "0,%.13g,0,0,0,0"
   HXP_sock2 = "0,0,%.13g,0,0,0"
   HXP_sock3 = "0,0,0,%.13g,0,0"
   HXP_sock4 = "0,0,0,0,%.13g,0"
   HXP_sock5 = "0,0,0,0,0,%.13g"
   HXP_COORD = "Work"
   HXP_DEG[0]= "X"
   HXP_DEG[1]= "Y"
   HXP_DEG[2]= "Z"
   HXP_DEG[3]= "U"
   HXP_DEG[4]= "V"
   HXP_DEG[5]= "W"
   HXP_SLEEP = 0.01
   
   global HXP_rad
   
   global HXP_optzpos
   # optimal Z position to move after a home, in order to have the maximum 
   # possible travel range in X Y Z U V W
   # LD: 13mm
   HXP_optzpos = 13
   
   global HXP_POS
   

#%UU%
#%MDESC% toggle the debug mode
if (!(whatis("__hxp100_debug")  & 2)) rdef __hxp100_debug \'#$*\'
def hxp100_debug '{
  if ((whatis("__hxp100_debug")>>16) <= 3) { # macro length is 3 bytes: comment
     rdef __hxp100_debug "eprint"
     print "hxp100 macro debug mode is ON"
     hxp100_DEBUG = 1
  }
  else {
     rdef __hxp100_debug \'#\$*\'
     print "hxp100 macro debug mode is OFF"
     hxp100_DEBUG = 0
  }
}'

# some programmer help
#%UU%
#%MDESC% toggle debug mode for the present macros.
def hxp100_simul '{
  if (hxp100_SIMUL) { # if present should be true
      hxp100_SIMUL = 0
    print "hxp100 simulation is OFF"
  } else {
    hxp100_SIMUL      = 1
    print "hxp100 simulation is ON"
  }
}
'

#%IU%
#%MDESC%
# MACRO MOTOR: 
# Called by spec after reading the config file
#
def hxp100_config(num,type,p1,p2,p3) '{  
   local  dev hxp_conf lcmd

   __hxp100_debug ">>> hxp100_config: ",num,type,p1,p2,p3

   # called for each macro-hardware controller 
   # p1:unit p2: nbchan
   if (type=="ctrl") {
     __hxp100_debug ">>>                   new controller "
     split(hxp100_ADDR,hxp_conf,":")
     lcmd = sprintf ("ping %s -c 1", hxp_conf[0])
     if (unix(lcmd) != 0) {
       eprintf ("Controller %s not responding, disabling its motors\n", \
		hxp_conf[0])
       return ".error."
     }
     return
   }

   # called for each macro motor channel
   # p1:unit p2:module p3:channel
   if (type=="mot") {
      #nothing
      local myscale 
      myscale = motor_par(num,    "scale")
      if (myscale < 1.0e-8) {
         myscale = 1
      }
      motor_par(num,    "scalefactor",  myscale,       "add")
      __hxp100_debug ">>>                   scalefactor " myscale
      # this one is used only for channels >=6
      #motor_par(num,    "newpos",  0,       "add")
   }
   
   #returns nothing or .error.
}'


#%IU%
#%MDESC%
# MACRO MOTOR: 
# Called by spec on motor operation. It manages: 
#%BR%- position
#%BR%- start_one 
#%BR%- get_status 
 def hxp100_cmd(num,key,p1,p2) '{
   local mychan myparam mystr1 myret nn hxp_add hxp_conf myret 

   __hxp100_debug ">>> hxp100_cmd:    ",num, key, todo, p1, p2

   if(num == "..") { return }

   mychan = motor_par(num,"channel")
   hxp_add = hxp100_ADDR
   split(hxp_add,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100 ",hxp_add

 #
 # return the current position
 #
   
   if (key == "position") {
  
      __hxp100_debug ">>> hxp100_cmd:     position acting"
      
#     send request
      myparam = sprintf("%s.%s",HXP_GROUPNAME,HXP_DEG[mychan]) 
      mystr1 = sprintf("GroupPositionCurrentGet(%s, double *)",myparam)
      if (hxp100_SIMUL == 1) {
         __hxp100_debug "... SIMUL sending: " mystr1
      }   
      else {
         __hxp100_debug "... sending: " mystr1
         sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)
      }            

#     get the answer
      myret = hxp100_waitforanswer(6)

#     
      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
	 return ".error"
      }
        
#     if an error, get the error string
      if (HXP_SOCK_ERR != 0){
         p "HXP100: ..... err code: " splitarr[0]  " , " HXP_ERR_MSG 
         return ".error."        
      }
      else{
         local myscale retret
         myscale = motor_par(num,    "scalefactor")
         #added because was found == 0
         if (myscale < 1.0e-8) {
            myscale = 1
         }
         __hxp100_debug "... scaling factor: " myscale         
         __hxp100_debug "... read position: " HXP_SOCK_ANSWER * myscale  
         retret = HXP_SOCK_ANSWER * myscale     
         return retret
      }
   }

#
# start a motion. p1: dial abs. pos., p2: dial rel. pos.
#

   if (key == "start_one") {
      local mystr1 splitarr nn myarg ret myp2

      __hxp100_debug ">>> hxp100_cmd:     start_one acting"

      myparam = sprintf("HXP_sock%d",mychan)
      if (mychan >=6) {
         myparam = sprintf("HXP_sock%d",mychan-6)      
      }
#     divide the sended position with the scale factor
      local myscale
      myscale = motor_par(num,    "scalefactor")
      __hxp100_debug "... scaling factor: " myscale         

      #added because was found == 0
      if (myscale < 1.0e-8) {
         myscale = 1
      }
      myp2 = p2 / myscale
      myarg = sprintf(@myparam,myp2)
      # for X, Y, Z use Tool coordinate system + incremental move
      # for U, V, W (angles) use Work coordinate system + incremental move
      if (mychan <= 2) {
         mystr1 = sprintf("HexapodMoveIncremental(HEXAPOD,Tool,%s)",myarg)
      }
      else {
         mystr1 = sprintf("HexapodMoveIncremental(HEXAPOD,Work,%s)",myarg)      
      }
      
      # all Tool NO
      #mystr1 = sprintf("HexapodMoveIncremental(HEXAPOD,Tool,%s)",myarg) 
         
#      myp2 = p1 / myscale
#      myarg = sprintf(@myparam,myp2)
#      mystr1 = sprintf("HexapodMoveAbsolute(HEXAPOD,%s,%s)",HXP_COORD,myarg)
      if (hxp100_SIMUL == 1) {
         __hxp100_debug "... SIMUL sending: " mystr1
      }
      else {
         __hxp100_debug "... sending: " mystr1
         
         sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)

#        this is a blocking socket
#        next sock_get will answer 
#           - either immediately with an error code
#           - or with no error after a while.         
      }

      myret = hxp100_waitforanswer(6)      

      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
      }
      else{        
#        if an error, get the error string
         if (HXP_SOCK_ERR != 0){
            p "HXP100: ..... err code: " , HXP_ERR_MSG 
         }
      }
      
      #returns nothing
   }

#
# return motor status
#
#
#

   if (key == "get_status") {     
#  send request
      mystr1 = sprintf("GroupStatusGet (%s, int *)",HXP_GROUPNAME) 
      if (hxp100_SIMUL == 1) {
         __hxp100_debug "... SIMUL sending: " mystr1
         return 0
      }
      else {
         __hxp100_debug "... sending: " mystr1
         sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)
      }            

#     get the answer
      myret = hxp100_waitforanswer(6)

      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
         return ".error"
      }
        
#     if an error, get the error string
      if (HXP_SOCK_ERR != 0){
         p "HXP100: ..... err code: " splitarr[0]  " , " HXP_ERR_MSG
         return ".error."        
      }
      else {
#        got a number
         __hxp100_debug "..... status from the controller: " HXP_SOCK_ANSWER
         local statusnum
         statusnum = HXP_SOCK_ANSWER

         local strstatus
         strstatus = hxp100_getstatusstr(HXP_SOCK,HXP_SOCK_ANSWER)
         __hxp100_debug "..... status string from the controller: " strstatus
            
#        controller ready      
         if ((statusnum == 11)  || \
           (statusnum == 13) || \
           (statusnum == 12) || \
           (statusnum == 10)){
           __hxp100_debug "DEVON"
           return 0    
         }
         if ((statusnum == 44) || \
           (statusnum == 43)){
           __hxp100_debug "DEVMOVING"
           return 0x02     
         }
         else{
            p "HXP100: Fault: status read from the controller: " strstatus 
            return 0x20 
         }    
      }
   }

}' 

#%IU%(nbtryy)
#%MDESC% after a sock_put, wait for an answer. 
#%BR% to be used if the answer is a single item.
#%BR%- maximum of 'nbtry' tries of sock_get reading
#%BR%- returns 0 if OK, -1 if NOT OK but responding, -2 if not responding
#%BR%- if responding, sets HXP_SOCK_ANSWER and HXP_SOCK_ERR
def hxp100_waitforanswer(nbtryy)'{
      local myret nn splitarr err
    
      __hxp100_debug ">>> hxp100_waitforanswer():     acting ", nbtryy

      if (hxp100_SIMUL == 1) {
         myret = "0,,EndOfAPI"
         __hxp100_debug "... SIMUL received: " myret
      }
      else {
         myret = sock_get(HXP_SOCK)
         __hxp100_debug "... received: " myret
      }
                  
      while ( (myret == "") && (nbtryy >0) ){
#        still not answering
         __hxp100_debug  "..... not yet answering"       
         myret = sock_get(HXP_SOCK)
	 nbtryy--
      }
      if ( (myret == "") && (nbtryy <=0) ){
         p "HXP100: ..... HXP100 controller not responding"
	 return -2
      }

#     answer is: <error status>,<text>,EndOfAPI      
      nn = split(myret,splitarr,",")
      __hxp100_debug "..... err code: " splitarr[0]
      __hxp100_debug "..... message : " splitarr[1]
      __hxp100_debug "..... end code: " splitarr[2]
            
#     if an error, get the error string
      if (splitarr[0] != 0){
         errstr = hxp100_geterrstr(HXP_SOCK,splitarr[0])
         __hxp100_debug ".....  answers with err code: " splitarr[0]  " , " errstr 
	 HXP_SOCK_ERR = splitarr[0]
         HXP_ERR_MSG = errstr
         return -1      
      }
      else {
	 HXP_SOCK_ERR = splitarr[0]
         HXP_SOCK_ANSWER = splitarr[1]
         return 0
      } 

}'     


#%UU%(<host:socket>,err)
#%MDESC% return the string associated to an error number, for hexapode
#in host:socket adress.
def hxp100_geterrstr(mysock,numb)'{
   local mystr nn2 splitarr2
         
    __hxp100_debug ">>> hxp100_geterrstr():     acting"
   mystr = sprintf("ErrorStringGet (%d,char *)",numb)
   __hxp100_debug "... sending: " mystr
   sock_put(mysock,mystr);sleep(HXP_SLEEP)
   hxp100_waitforanswer(6)
   return(HXP_SOCK_ANSWER) 
}'


#%UU%(<host:socket>,err)
#%MDESC% return the string associated to an status number, for hexapode
#in host:socket adress.
def hxp100_getstatusstr(mysock,numb)'{
   local mystr nn2 splitarr2
         
    __hxp100_debug ">>> hxp100_getstatusstr():     acting"
   mystr = sprintf("GroupStatusStringGet (%d,char *)",numb)
   __hxp100_debug "... sending: " mystr
   sock_put(mysock,mystr);sleep(HXP_SLEEP)
   hxp100_waitforanswer(6)
   return(HXP_SOCK_ANSWER) 
}'

#%UU%(mne)
#%MDESC% Makes an init on the hexapode defined above the motor 'mne'
#It canbe called by providing any motor of the hexapode
def hxp100_init(mne)'{
   local mysock mynum hxp_conf mystr

   __hxp100_debug ">>> hxp100_init ", mne
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_init ", HXP_SOCK , HXP_GROUPNAME

   mystr = sprintf("GroupKill(%s)",HXP_GROUPNAME)
   __hxp100_debug "... sending: " mystr
   if (hxp100_SIMUL != 1) {
      sock_put(HXP_SOCK,mystr)   
      myret = hxp100_waitforanswer(6)      
      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
      }
      else{        
#        if an error, get the error string
         if (HXP_SOCK_ERR != 0){
            p "HXP100: ..... err code: " , HXP_ERR_MSG 
         }
      }
   }
   
   mystr = sprintf("GroupInitialize(%s)",HXP_GROUPNAME)
   __hxp100_debug "... sending: " mystr
   if (hxp100_SIMUL != 1) {
      sock_put(HXP_SOCK,mystr)   
      myret = hxp100_waitforanswer(6)      
      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
      }
      else{        
#        if an error, get the error string
         if (HXP_SOCK_ERR != 0){
            p "HXP100: ..... err code: " , HXP_ERR_MSG 
         }
      }
   }
   
   mystr = sprintf("GroupHomeSearch(%s)",HXP_GROUPNAME)
   __hxp100_debug "... sending: " mystr
   if (hxp100_SIMUL != 1) {
      sock_put(HXP_SOCK,mystr)
      #removed as seems that never answer.better to loop on the status   
      myret = hxp100_waitforanswer(50)      
      if (myret == -2) {
         p "HXP100: ..... HXP controller not responding"
      }
      else{        
#        if an error, get the error string
         if (HXP_SOCK_ERR != 0){
            p "HXP100: ..... err code: " , HXP_ERR_MSG
         }
      }
   }

}'

#%UU%(mne)
#%MDESC% Reads the status
def hxp100_status(mne)'{
   local mysock mynum hxp_conf mystr1

   __hxp100_debug ">>> hxp100_status ", mne
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_status ", HXP_SOCK , HXP_GROUPNAME

  mystr1 = sprintf("GroupStatusGet (%s, int *)",HXP_GROUPNAME) 
  if (hxp100_SIMUL == 1) {
     __hxp100_debug "... SIMUL sending: " mystr1
     return 0
  }
  else {
     __hxp100_debug "... sending: " mystr1
     sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)
  }            

# get the answer
  myret = hxp100_waitforanswer(6)

  if (myret == -2) {
     p "HXP100: ..... HXP controller not responding"
     return ".error"
  }
        
# if an error, get the error string
  if (HXP_SOCK_ERR != 0){
     p "HXP100: ..... err code: " splitarr[0]  " , " HXP_ERR_MSG 
     return ".error."        
  }
  else {
#    got a number
     __hxp100_debug "..... status from the controller: " HXP_SOCK_ANSWER
     local statusnum
     statusnum = HXP_SOCK_ANSWER

     local strstatus
     strstatus = hxp100_getstatusstr(HXP_SOCK,HXP_SOCK_ANSWER)
     __hxp100_debug "..... status string from the controller: " strstatus
            
#    controller ready      
     if ((statusnum == 11)  || \
           (statusnum == 13) || \
           (statusnum == 12) || \
           (statusnum == 10)){
        p "HXP100: DEVON"
        return 0    
     }
     if ((statusnum == 44) || \
           (statusnum == 43)){
       p "HXP100: DEVMOVING"
       return 0x02     
     }
     else{
        p "HXP100: Fault: status read from the controller: " strstatus 
        return 0x20 
     }    
  }

}'

#%UU%(mne,string)
#%MDESC%Writes a string
def hxp100_write(mne,mystr)'{
   local mysock mynum hxp_conf mystr1

   __hxp100_debug ">>> hxp100_write ", mystr
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_write ", HXP_SOCK , HXP_GROUPNAME

  if (hxp100_SIMUL == 1) {
     __hxp100_debug "... SIMUL sending: " mystr
     return 0
  }
  else {
     __hxp100_debug "... sending: " mystr
     sock_put(HXP_SOCK,mystr);sleep(HXP_SLEEP)
  }
}'            

#%UU%(mne)
#%MDESC%read the answer
def hxp100_read(mne)'{
  local myret mysock mynum

   __hxp100_debug ">>> hxp100_read "
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

# get the answer
  myret = hxp100_waitforanswer(6)

  if (myret == -2) {
     p "HXP100: ..... HXP controller not responding"
     return ".error"
  }
}'

#%UU%(mne)
#%MDESC%Homing procedure.Needs hexapode motors been defined
#with hxp100_list
def hxp100_home(mne)'{
   local req ii 
   
   req = 0
   
   while (req != 6) {
      p " "
      p "HXP100 home procedure:"
      p "Please choose an action"
      p "   1: home"
      p "   2: status"
      p "   3: sync"
      p "   4: move to optimal Z position"
      p "   5: setting all the hexapode positions to 0"
      p "   6: quit"
      req = getval("choice ?",req)
      if (req == 1) {
         hxp100_init(mne)
      }
      if (req == 2) {
         p " "
         hxp100_status(mne)
      }
      if (req == 3){
         sync
      } 
      if (req == 4){
          
         # send the motion on Z
         local myparam myp2 myarg mystr1 myret
         myparam = "HXP_sock2"
         myp2 = HXP_optzpos
         myarg = sprintf(@myparam,myp2)
         mystr1 = sprintf("HexapodMoveIncremental(HEXAPOD,Work,%s)",myarg)
         if (hxp100_SIMUL == 1) {
            __hxp100_debug "... SIMUL sending: " mystr1
         }
         else {
            __hxp100_debug "... sending: " mystr1
         
            sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)
         }
         myret = hxp100_waitforanswer(6)      

         if (myret == -2) {
            p "HXP100: ..... HXP controller not responding"
         }
         else{        
#           if an error, get the error string
            if (HXP_SOCK_ERR != 0){
               p "HXP100: ..... err code: " , HXP_ERR_MSG 
            }
         }
         
         # wait for end of motion: read the status
         local mystat
         mystat = hxp100_status(mne)
         while(mystat == 0x02) {
            # still moving
            mystat = hxp100_status(mne)                 
         }
         #do a silent sync
         read_motors(6)
                     
      } 
      if (req == 5){
          
          # set all positions to 0
          for (ii=0; ii<6; ii++) {
              mystr = sprintf("set %s 0",HXP[ii])
              p "doing ", mystr
              eval(mystr)    
          }
          
      }          
   }
}'

#%UU%(mne,coord)
#%MDESC% get the coordinate system position
#%BR%- <mne>: provide any macromotor as argument
#%BR%- <coord>: can be Work/Tool/ ...
#%BR% - returns -2 if controler does not respond, or the response string.
def hxp100_coord_get(mne,coord)'{
   local mysock mynum hxp_conf mystr1 myresp

   __hxp100_debug ">>> hxp100_coord_get ", mne , coord
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_coord_get ", HXP_SOCK , HXP_GROUPNAME

  mystr1 = sprintf("HexapodCoordinateSystemGet(%s,%s,double *,double *, double *,double *, double *,double *)",HXP_GROUPNAME,coord) 

  myresp = hxp100_write_and_get(mne,mystr1)

  return myresp

}'


#%UU%(mne,coord,pos_x,pos_y,pos_z,pos_u,pos_v,pos_w)
#%MDESC% sets the coordinate system position
#%BR%- <mne>: provide any macromotor as argument
#%BR%- <coord>: can be Work/Tool/ ...
#%BR%- <pos_x>, <pos_y>, <pos_z>, <pos_u>, <pos_v>, <pos_w> : the coord.
def hxp100_coord_put(mne,coord,pos_x,pos_y,pos_z,pos_u,pos_v,pos_w)'{
   local mysock mynum hxp_conf mystr1 myresp

   __hxp100_debug ">>> hxp100_coord_put ", mne , coord , pos_x, pos_y, pos_z, pos_u, pos_v, pos_w
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_coord_put ", HXP_SOCK , HXP_GROUPNAME

  mystr1 = sprintf("HexapodCoordinateSystemSet(%s,%s,%f,%f,%f,%f,%f,%f)",HXP_GROUPNAME,coord, \
                    pos_x,pos_y,pos_z,pos_u,pos_v,pos_w) 

  myresp = hxp100_write(mne,mystr1)

}'

#%UU% (mne, string)
#%MDESC% sends the string to the controller
#%BR% - returns -2 if no response
#%BR% - else returns the response
def hxp100_write_and_get(mne,mystr1)'{
   local mynum mysock myret nn splitarr err

   __hxp100_debug ">>> hxp100_write_and_get ", mne , mystr1
      
   mynum = motor_mne(mne)
   mysock = motor_par(mynum,"address")

   split(mysock,hxp_conf,":")
   HXP_GROUPNAME = hxp_conf[2]
   HXP_SOCK = sprintf("%s:%s",hxp_conf[0],hxp_conf[1])   
   __hxp100_debug ">>> hxp100_write_and_get ", HXP_SOCK , HXP_GROUPNAME

  # send the command

  if (hxp100_SIMUL == 1) {
     __hxp100_debug "... SIMUL sending: " mystr1
     return 0
  }
  else {
     __hxp100_debug "... sending: " mystr1
     sock_put(HXP_SOCK,mystr1);sleep(HXP_SLEEP)
  }        
    
  # wait for answer

   if (hxp100_SIMUL == 1) {
      myret = "0,,EndOfAPI"
      __hxp100_debug "... SIMUL received: " myret
   }
   else {
      myret = sock_get(HXP_SOCK)
      __hxp100_debug "... received: " myret
   }
                  
   while ( (myret == "") && (nbtryy >0) ){
#     still not answering
      __hxp100_debug  "..... not yet answering"       
      myret = sock_get(HXP_SOCK)
      nbtryy--
   }
   if ( (myret == "") && (nbtryy <=0) ){
      p "HXP100: ..... HXP100 controller not responding"
      return -2
   }
   else {
      return myret
   }
}'

#%UU% (theta,dy)
#%MDESC% From an original sample positions, a rotation of the sample 
#in the 'Tool' reference induces a circular
#motion in the X,Y plan. We assume that the X axis is made by the 2 following
#points: the center of the circle and the original sample position.
#%BR%To calculate the radius, after this circular motion, you must provide:
#%BR%- theta: angle (in deg) on this circle from the the original sample 
#position.
#%BR%- dy: dy displacement in Y axis, from the original sample position 
#to this new position. 
def hxp100_r(theta,dy)'{
    local myr
    
    __hxp100_debug ">>>hxp100_r: from theta, dx, dy: ", theta, dy     
    myr = fabs(dy)/sin(rad(fabs(theta)))
    __hxp100_debug ">>>hxp100_r: calculates radius : ", myr     
    return myr    
}'
    
#%UU% (theta,rr)
#%MDESC% From an original sample positions, a rotation of the sample 
#in the 'Tool' reference induces a circular
#motion in the X,Y plan. We assume that the X axis is made by the 2 following
#points: the center of the circle and the original sample position.
#%BR%This macro calculates the dx and dy displacement to do on the sample to
# send it back to its original sample position. You must provide:
#%BR%- theta: present angle (deg) on this circle, from the original 
#sample position. 
def hxp100_dxy(theta)'{
   local myarr dx dy
   
    __hxp100_debug ">>>hxp100_dxy: from theta, radius: ", theta, HXP_rad    
   dx = HXP_rad * (1-cos(rad(theta)))
   dy = (-1) * HXP_rad * sin(rad(theta))
   
   myarr[0]=dx
   myarr[1]=dy 
   
    __hxp100_debug ">>>hxp100_r: calculates dx, dy: ", dx, dy     
   return myarr
   
   
}'

#%UU%(radius)
#%MDESC%set the radius 
def hxp100_setradius(rr)'{
   HXP_rad = rr
}'
   
#%UU%()
#%MDESC%shows the radius 
def hxp100_showradius()'{
   return HXP_rad 
}'



#%UU%
#%MDESC%Adjust Z of Tool coordinate by moving the rotation X or Y.
#%BR%Needs that hxp100_list has been run before (for motor names definition).
# rotation put in Work system !!!!
def hxp100_adjustZ'{
   global HXP_adj HXP_userot HXP_rotinc 
   local mystr myresp myarr motrot mycont mywait
   
   p "Procedure for adjusting Z Tool position"
   HXP_userot = getval("   - Rotate on X or Y ? [0:X, 1:Y]",HXP_userot)
   HXP_rotinc = getval("     which increment for rotating (in deg):",HXP_rotinc)    
   p "Interactive procedure starting. You will be able to quit by typing ctrlC"
   
   # define the index in HXP array : [0:x, 1:y, 2:z, 3:rx, 4:ry, 5:rz]
   if (HXP_userot == 0 ) {
       motrot = 3
   }
   else {
      motrot = 4    
   }
   # now loop
   while (1){
      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
      
      mywait = getval("You are now at " HXP_rotinc " - press to continue",mywait)

      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc*(-2))
      p "doing " mystr
      eval(mystr) 

      mywait = getval("You are now at " HXP_rotinc*(-1) " - press to return to zero",mywait)
      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
         
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp
      HXP_adj = getval("which correction on Z (in mm)?",HXP_adj)
      split(myresp,myarr,",")
      mystr = sprintf("hxp100_coord_put(%s,\"Work\",%f,%f,%f,%f,%f,%f)",HXP[0],myarr[1],myarr[2],(myarr[3]+HXP_adj),myarr[4],myarr[5],myarr[6])
      p "doing: " mystr
      eval(mystr)
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp
      sync
      sync      
   }
}'

#%UU%
#%MDESC%Adjust Y of Tool coordinate by moving the rotation X or Z.
#%BR%Needs that hxp100_list has been run before (for motor names definition).
# rotation put in Work system !!!!
def hxp100_adjustY'{
   global HXP_adj HXP_userot HXP_rotinc 
   local mystr myresp myarr motrot mywait
   
   p "Procedure for adjusting Y Tool position"
   HXP_userot = getval("   - Rotate on X or Z ? [0:X, 1:Z]",HXP_userot)
   HXP_rotinc = getval("     which increment for rotating (in deg):",HXP_rotinc)    
   p "Interactive procedure starting. You will be able to quit by typing ctrlC"
   
   # define the index in HXP array : [0:x, 1:y, 2:z, 3:rx, 4:ry, 5:rz]
   if (HXP_userot == 0 ) {
       motrot = 3
   }
   else {
      motrot = 5    
   }
   # now loop
   while (1){
      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
      
      mywait = getval("You are now at " HXP_rotinc " - press to continue",mywait)

      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc*(-2))
      p "doing " mystr
      eval(mystr) 

      mywait = getval("You are now at " HXP_rotinc*(-1) " - press to return to zero",mywait)
      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
         
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp
      HXP_adj = getval("which correction on Y (in mm)?",HXP_adj)
      split(myresp,myarr,",")
      mystr = sprintf("hxp100_coord_put(%s,\"Work\",%f,%f,%f,%f,%f,%f)",HXP[0],myarr[1],(myarr[2]+HXP_adj),myarr[3],myarr[4],myarr[5],myarr[6])
      p "doing: " mystr
      eval(mystr)
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp      
      sync
      sync
   }
}'

#%UU%
#%MDESC%Adjust X of Tool coordinate by moving the rotation Y or Z.
#%BR%Needs that hxp100_list has been run before (for motor names definition).
# rotation put in Work system !!!!
def hxp100_adjustX'{
   global HXP_adj HXP_userot HXP_rotinc 
   local mystr myresp myarr motrot mywait
   
   p "Procedure for adjusting Y Tool position"
   HXP_userot = getval("   - Rotate on Y or Z ? [0:Y, 1:Z]",HXP_userot)
   HXP_rotinc = getval("     which increment for rotating (in deg):",HXP_rotinc)    
   p "Interactive procedure starting. You will be able to quit by typing ctrlC"
   
   # define the index in HXP array : [0:x, 1:y, 2:z, 3:rx, 4:ry, 5:rz]
   if (HXP_userot == 0 ) {
       motrot = 4
   }
   else {
      motrot = 5    
   }
   # now loop
   while (1){
     mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
      
      mywait = getval("You are now at " HXP_rotinc " - press to continue",mywait)

      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc*(-2))
      p "doing " mystr
      eval(mystr) 

      mywait = getval("You are now at " HXP_rotinc*(-1) " - press to return to zero",mywait)
      mystr = sprintf("umvr %s %f",HXP[motrot],HXP_rotinc)
      p "doing " mystr
      eval(mystr)
         
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp
      HXP_adj = getval("which correction on X (in mm)?",HXP_adj)
      split(myresp,myarr,",")
      mystr = sprintf("hxp100_coord_put(%s,\"Work\",%f,%f,%f,%f,%f,%f)",HXP[0],(myarr[1]+HXP_adj),myarr[2],myarr[3],myarr[4],myarr[5],myarr[6])
      p "doing: " mystr
      eval(mystr)
      mystr = sprintf("hxp100_coord_get(%s,\"Work\")",HXP[0])
      myresp = eval(mystr)
      p "get: ",myresp      
      sync
      sync
   }
}'
      
   
#%UU%<mne_x> <mne_y> <mne_z> <mne_rotx> <mne_roty> <mne_rotz>
#%MDESC%Gives the list of motors for the hexapode.
if (whatis("HXP_nb") == 0) {HXP_nb = 0}
def hxp100_list'{
   global  HXP
   local ii myarr nbmot

   #should be 6   
   nbmot = 6
   if (nbmot != 6) {
      p "usage: hxp100_list <mne_x> <mne_y> <mne_z> <mne_rotx> <mne_roty> <mne_rotz>" 
      exit   
   }
   split("$*",myarr)
   for (ii=0; ii<nbmot; ii++) {   
     HXP[ii] = myarr[ii] 
   }  
}'

#%MACROS%
#%IMACROS%
#%LOG%
#$Revision: 1.8 $
#$Log: hxp100.mac,v $
#Revision 1.8  2013/03/19 14:45:26  domingue
#modify hxp100_adjustX and hxp100_adjustY
#
#Revision 1.7  2012/11/21 16:15:31  domingue
#set optimal Z position to 13mm instead of 14mm
#
#Revision 1.6  2012/11/16 09:33:17  domingue
#hxp100_list;hxp100_adjustX ...;improve hxp100_home;
#
#Revision 1.5  2012/07/09 12:49:47  beteva
#added check for controller not responding to avoid endless motors reading
#
#Revision 1.4  2012/06/21 13:03:14  domingue
#set scale to 1 if 0
#
#Revision 1.2  2011/07/18 14:00:30  domingue
#add hxp100_coord_get; hxp100_coord_put; hxp100_write_and_get
#
#Revision 1.1  2011/07/04 07:13:01  domingue
#Initial revision
#
#

#%AUTHOR% mcd june 2011
#%TOC%