#! /bin/csh -f # # operate the X-Y-Z goniometer or the kinematic "Bob" stage # # relative moves are in the "lab" frame: x=x-rays y=gravity z=spindle (phi dependent) # absolute moves are in the goniometer frame (independent of the value of phi) # goto Setup Help: cat << EOF usage: sample.com [to|by] x y z [phi] relative moves are in the "lab" frame: x=x-rays y=gravity z=spindle (phi dependent) absolute moves are in the goniometer frame (independent of the value of phi) EOF Return_from_Setup: onintr report get_position: # survey the sample motors from the deltatau set info = `echo -n "#1p\r#2p\r#3p\r#5p\r" | sock_exchange.tcl $pmac 14001 4 "\006" |& awk '{gsub("[\006\r]"," ",$0); print}'` # save current motor positions (in mm and degrees) set pos = `echo "$info" | awk 'NF==4{print $1/16968, $2/16968, $3/16968, $4/8385}'` # ignore actual phi position if user wants to pretend it is somewhere else if($?user_phi) then set pos = `echo $pos $user_phi | awk '{print $1,$2,$3,$5}'` endif if($?kinematic) then set pos = `echo "$info" | awk 'NF==4{print $1/37380, $2/37380, $3/37380, $4/8385}'` endif if($?debug) echo "GOTHERE pos = $pos" set phi = `echo $pos | awk 'NF==4{print $4}'` # see if deltatau responded amicably if($#pos == 4) then if($?move) goto move goto finish endif # didn't work, try XOS set pos = "" # use XOS: pretend to be a gui, get motor state, and then disconnect echo -n "" |\ xos3_exchange.tcl 1 "set_motor_dependency" 20 >&! ${tempfile} if($?user_phi) then set phi = "$user_phi" else set phi = `awk '/^stog_configure_real_motor gonio_phi/{print $5}' ${tempfile}` endif set x = `awk '/^stog_configure_real_motor sample_x/{print $5}' ${tempfile}` set y = `awk '/^stog_configure_real_motor sample_y/{print $5}' ${tempfile}` set z = `awk '/^stog_configure_real_motor sample_z/{print $5}' ${tempfile}` rm -f ${tempfile} >& /dev/null # save motor positions (in mm and degrees) set pos = `echo $x $y $z $phi | awk '{print $1, $2, $3, $4}'` if($?debug) echo "GOTHERE1 pos = $pos" # see if DCSS responded amicably if($#pos == 4) then if($?move) goto move goto finish endif # didn't work, try LabView direct set x = `pxmotor.com Sample X |& awk '$NF~/^[0-9-]/{print $NF}'` set y = `pxmotor.com Sample Y |& awk '$NF~/^[0-9-]/{print $NF}'` set z = `pxmotor.com Sample Z |& awk '$NF~/^[0-9-]/{print $NF}'` if($?user_phi) then set phi = "$user_phi" else set phi = `pxmotor.com Spindle |& awk '$NF~/^[0-9-]/{print $NF}'` endif # save motor positions (in mm and degrees) set pos = `echo $x $y $z $phi | awk '{print $1, $2, $3, $4}'` if($?debug) echo "GOTHERE1 pos = $pos" if($#pos == 4) then if($?move) goto move goto finish endif # didn't work, try LBL/DCS echo -n "" |\ xos_exchange.tcl $control 1 "over out" 1 >! ${tempfile} if($?user_phi) then set phi = "$user_phi" else set phi = `awk '/^stog_configure_real_motor gonio_phi/{print $5}' ${tempfile}` endif set x = `awk '/^stog_configure_real_motor sample_x/{print $5}' ${tempfile}` set y = `awk '/^stog_configure_real_motor sample_y/{print $5}' ${tempfile}` set z = `awk '/^stog_configure_real_motor sample_z/{print $5}' ${tempfile}` rm -f ${tempfile} >& /dev/null # save motor positions (in mm and degrees) set pos = `echo $x $y $z $phi | awk '{print $1/1000, $2/1000, $3/1000, $4}'` if($?debug) echo "GOTHERE1 pos = $pos" # see if XOS responded amicably if($#pos == 4) then if($?move) goto move goto finish endif # didn't work, try something else? set pos = "" # jump ahead if we are out of ideas if(! $?move) goto finish move: if(! $?dX) set dX = 0 if(! $?dY) set dY = 0 if(! $?dZ) set dZ = 0 if(! $?phi) set phi = 0 # convenient to use radians for trig set phi_in_rads = `echo $phi | awk '{print $1*atan2(1,0)/90}'` if ($?debug) echo "GOTHERE phi= $phi ( $phi_in_rads )" # compute relative motor moves in mm set delta = `echo "$dX $dY $dZ $phi_in_rads" | awk '{print -$1*sin($4)-$2*cos($4), -$1*cos($4)+$2*sin($4), $3}'` # the "y" and "z" motors here go in the "opposite" direction if($beamline == 1231) set delta = `echo "$dX $dY $dZ $phi_in_rads" | awk '{print -$1*sin($4)-$2*cos($4), $1*cos($4)-$2*sin($4), -$3}'` if($?kinematic) then # compute relative moves in mm for the three parallel motors set delta = `echo "$dX $dY $dZ $phi_in_rads $leverage" | awk '{third=4/3*atan2(1,0);dX=$1;dY=$2;dZ=$3;phi=$4;leverage=$5} {print (dX*cos(phi) -dY*sin(phi))/leverage +dZ, (dX*cos(phi+third) -dY*sin(phi+third))/leverage +dZ, (dX*cos(phi-third) -dY*sin(phi-third))/leverage +dZ}'` endif if ($?debug) echo "GOTHERE delta = $delta" # add the delta move to the current position set mmgoal = `echo $delta $pos | awk '{print $1+$4,$2+$5,$3+$6}'` if(! $?relative) then # use the absolute coordinates specified on the command line set mmgoal = ( $dX $dY $dZ ) endif if($?kinematic) goto XOS_move # convert mm motor positions into encoder steps set goal = `echo $mmgoal | awk '{print 16968*$1, 16968*$2, 16968*$3}'` if($?kinematic) set goal = `echo $mmgoal | awk '{print 37380*$1, 37380*$2, 37380*$3}'` # command the motors to move! try_again: if($?debug) echo "GOTHERE #1j=$goal[1] #2j=$goal[2] #3j=$goal[3] " echo -n "#1j=$goal[1]\r#2j=$goal[2]\r#3j=$goal[3]\r" | sock_exchange.tcl $pmac 14001 3 "\006" >& /dev/null if($status) goto XOS_move set speed = 1 usleep 300000 while ("$speed" != "0") # now check and see where they are set info = `echo -n "#1p\r#2p\r#3p\r#5p\r#1v\r#2v\r#3v\r" | sock_exchange.tcl $pmac 14001 7 "\006" | awk '{gsub("[\006\r]"," ",$0); print}'` if($#info != 7) then echo "problem with network : $info" #echo "mcf\n8\n" | sock_exchange.tcl $pmac 9999 > /dev/null sleep 2 continue endif set x_reached = "$info[1]" set y_reached = "$info[2]" set z_reached = "$info[3]" set speed = `echo "$info" | awk '{print sqrt($5*$5+$6*$6+$7*$7)}'` if($?debug) echo -n "GOTHERE " if($?debug) echo "$info $speed" echo "$info $speed " | awk '{printf "%.3f %.3f %.3f\n", $1/16968,$2/16968,$3/16968}' if("$speed" != "0") usleep 200000 end #echo "" # see if we made it set delta = `echo "$goal $info" | awk '{printf "%d", sqrt(($1-$4)^2+($2-$5)^2+($3-$6)^2)}'` if(($delta > 100)&&($?RETRY)) then # finite number of retries if("$RETRY" =~ *[0-9]) set RETRY = `echo $RETRY | awk '{printf "%d", $1-1}'` if("$RETRY" == "0") set RETRY = "" if("$RETRY" == "") unset RETRY set delta = `echo "$goal $info" | awk '{print $1-$4, $2-$5, $3-$6}'` echo "sample is $delta counts off the mark" echo "trying again..." echo -n "#1j/\r#2j/\r#3j/\r" | sock_exchange.tcl $pmac 14001 3 "\006" 3 > /dev/null goto try_again endif unset move goto get_position XOS_move: unset move # convert goal position to microns set goal = `echo $mmgoal | awk '{print $1, $2, $3}'` # pretend to be a gui, set motor states, and then disconnect echo "gtos_become_master force\ngtos_start_motor_move sample_x $goal[1]\ngtos_start_motor_move sample_y $goal[2]\ngtos_start_motor_move sample_z $goal[3]" |\ xos3_exchange.tcl 3 "stog_motor_move_completed sample" 30 >& /dev/null #if($status) goto finish if(! $status) goto get_position # didn't work, try LabView direct #echo "moveto Sample X $goal[1]\r\nmoveto Sample Y $goal[2]\r\nmoveto Sample Z $goal[3]\n" | sock_exchange.tcl px 10001 3 >& /dev/null # convert goal position to microns set goal = `echo $mmgoal | awk '{print 1000*$1, 1000*$2, 1000*$3}'` # pretend to be a gui, set motor states, and then disconnect echo "gtos_become_master force\ngtos_start_motor_move sample_x $goal[1]\ngtos_start_motor_move sample_y $goal[2]\ngtos_start_motor_move sample_z $goal[3]" |\ xos_exchange.tcl $control 3 "stog_motor_move_completed sample" 5 > /dev/null #if($status) goto finish goto get_position report: finish: if(! $?pos) set pos if($#pos >= 3) then # compute relative motor position in mm set rel_pos = `echo "$pos" | awk '{$4*=atan2(1,0)/90; print -$1*sin($4)-$2*cos($4), -$1*cos($4)+$2*sin($4), $3}'` # the "y" and "z" motors here go in the "opposite" direction if($beamline == 1231) then set rel_pos = `echo "$pos" | awk '{$4*=atan2(1,0)/90; print -$1*sin($4)-$2*cos($4), $1*cos($4)-$2*sin($4), -$3}'` endif if($?kinematic) then # compute relative position in mm for the three parallel motors set rel_pos = `echo "$pos $leverage" | awk '{$4*=atan2(1,0)/90; third=4/3*atan2(1,0);dX=$1;dY=$2;dZ=$3;phi=$4;leverage=$5} {print (dX*cos(phi) -dY*sin(phi))/leverage +dZ, (dX*cos(phi+third) -dY*sin(phi+third))/leverage +dZ, (dX*cos(phi-third) -dY*sin(phi-third))/leverage +dZ}'` endif set pos = `echo $pos | awk '{printf "%.3f %.3f %.3f", $1,$2,$3}'` else set pos = "unknown" set BAD = "unable to get position" endif if($?mmgoal) then # see if we made it set miss = `echo $mmgoal $pos | awk '{printf "%d", 1000*sqrt(($1-$4)^2+($2-$5)^2+($3-$6)^2)}'` if($miss > 10) set BAD = "move failed by $miss microns" endif if($?BAD) then echo "ERROR: $BAD" endif echo "sample motors are now $pos" if($?report_relative && $?rel_pos) then echo "relative coordinates $rel_pos" endif if ($?BAD) exit 9 exit Setup: if(! $?beamline) then # default to beamline this computer belongs to setenv beamline `beamline.com` if($status) then echo "ERROR: $beamline" exit 9 endif endif #if(! $?beamline) setenv beamline 831 ############################################################# # platform-specific issues set test = `echo "123asdf" | awk '{print $1+0}'` if("$test" != "123") then alias awk nawk set test = `echo "123asdf" | awk '{print $1+0}'` if("$test" != "123") alias awk gawk set test = `echo "123asdf" | awk '{print $1+0}'` if("$test" != "123") then echo "ERROR: awk no good" exit 9 endif endif set test = `echo -n "\r" |& od -c | wc -w` if("$test" != 3) then alias echo /bin/echo set test = `echo -n "\r" |& od -c | wc -w` if("$test" != 3) alias echo '/bin/echo -e' set test = `echo -n "\r" |& od -c | wc -w` if("$test" != 3) alias echo /usr/bin/echo set test = `echo -n "\r" |& od -c | wc -w` if("$test" != 3) alias echo '/bin/echo \!* | awk '\''/^-n/{printf "%s", substr($0,4) ; exit} {print}'\' set test = `echo -n "\r" |& od -c | wc -w` if("$test" != 3) then echo "ERROR: echo command is broken" exit 9 endif endif set test = `echo "string is digit 1" | /usr/bin/tclsh |& wc -l` if($test != 0) then set test = `echo "string is digit 1" | tclsh |& wc -l` if($test != 0) alias tclsh tclsh8.2 set test = `echo "string is digit 1" | tclsh |& wc -l` if($test != 0) alias tclsh tclsh8.3 set test = `echo "string is digit 1" | tclsh |& wc -l` if($test != 0) then setenv LD_LIBRARY_PATH ~jamesh alias tclsh ~jamesh/tclsh8.2 echo "" | tclsh >& /dev/null if("$status") then echo "ERROR: tclsh not available" exit 9 endif endif alias sock_exchange.tcl "tclsh `which sock_exchange.tcl` \!*" endif ###################################################################### set tempfile = /tmp/sample_temp$$ set pmac = pmac2 if("$beamline" != 831) set pmac = bl${beamline}c if("$beamline" == 822) set kinematic if("$beamline" == 822) set leverage = 4.2 set control = $pmac # default to a relative move set relative # interpret command line first #if("$1" != "") set move foreach arg ( $* ) if("$arg" == "by") then set relative continue endif if("$arg" == "relative") then set relative set report_relative continue endif if("$arg" == "to") then unset relative continue endif if("$arg" =~ phi=*) then set user_phi = `echo $arg | awk -F "[=]" '{print $2+0}'` continue endif # other arguments taken as numbers if(! $?dX) then set dX = `echo $arg | awk '$1+0>-20 && $1+0<20{print $1+0}'` continue endif if(! $?dY) then set dY = `echo $arg | awk '$1+0>-20 && $1+0<20{print $1+0}'` continue endif if(! $?dZ) then set dZ = `echo $arg | awk '$1+0>-20 && $1+0<20{print $1+0}'` continue endif if(! $?user_phi) then set user_phi = `echo $arg | awk '{print $1+0}'` continue endif end #if(! $?dX) set dX = 0 if(! $?dY && $?relative) set dY = 0 if(! $?dZ && $?relative) set dZ = 0 if($?dX && $?dY && $?dZ) set move goto Return_from_Setup