00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 import serial
00059 import time
00060 import math
00061 import threading
00062 import os
00063
00064 import rospy
00065 import actionlib
00066 from control_msgs.msg import *
00067 from sensor_msgs.msg import *
00068
00069 FJT_ACTION_NAME = "joint_trajectory_controller/follow_joint_trajectory"
00070
00071 Terminator="\r\n"
00072 commands = {"position": "p", "stop": "s", "move": "m", "set_pwm":"set", "get_pwm":"get"}
00073
00074 class Sdhx():
00075
00076 def __init__(self):
00077
00078 if(rospy.has_param("~devicestring")):
00079 rospy.loginfo("Setting port to:")
00080 self.port = rospy.get_param("~devicestring")
00081 rospy.loginfo(self.port)
00082 self.min_pwm0 = rospy.get_param("~min_pwm0")
00083 self.min_pwm1 = rospy.get_param("~min_pwm1")
00084 self.max_pwm0 = rospy.get_param("~max_pwm0")
00085 self.max_pwm1 = rospy.get_param("~max_pwm1")
00086
00087 rospy.loginfo("starting node")
00088 self._ser = None
00089 self.setup()
00090 self.move_lock = False
00091
00092 self._as = actionlib.SimpleActionServer(FJT_ACTION_NAME, FollowJointTrajectoryAction, self.execute_cb, False)
00093 self._as.start()
00094 self._pub_joint_states = rospy.Publisher('joint_states', JointState,queue_size=1)
00095 self._pub_controller_state = rospy.Publisher('joint_trajectory_controller/state', JointTrajectoryControllerState,queue_size=1)
00096
00097 self._joint_states = JointState()
00098 self._joint_states.name = rospy.get_param("~joint_names")
00099 self._joint_states.velocity = [0.0,0.0]
00100 self._joint_states.position = [0.0,0.0]
00101 self._joint_states.effort = [0.0,0.0]
00102 self._oldpos = [0.0, 0.0]
00103
00104 self._controller_state = JointTrajectoryControllerState()
00105
00106 self.pos = [0,0]
00107 self.command_pos = [0,0]
00108
00109 rospy.Timer(rospy.Duration(0.1), self.publish_joint_states)
00110 rospy.Timer(rospy.Duration(10), self.intern_move)
00111 self.lock = False
00112
00113 def setup(self):
00114 self.close_port()
00115 try:
00116 self._ser = serial.Serial(self.port, timeout=0.5)
00117 rospy.loginfo("Port is alive")
00118 self.set_pwm("min_pwm0")
00119 self.set_pwm("min_pwm1")
00120 self.set_pwm("max_pwm0")
00121 self.set_pwm("max_pwm1")
00122 except serial.serialutil.SerialException:
00123 self._ser = None
00124
00125
00126 def set_pwm(self, pwm_to_set):
00127 complement = " "+(str)(pwm_to_set)+" "+(str)(eval("self."+pwm_to_set))+Terminator
00128
00129 self.execute_command("set_pwm", complement)
00130
00131 status, reply = self.get_pwm(pwm_to_set)
00132
00133 if(status and (int)(reply) ==(eval("self."+pwm_to_set))):
00134 status = True
00135 else:
00136 status = False
00137
00138 return status, reply
00139
00140 def get_pwm(self, pwm_to_get):
00141 complement = " "+(str)(pwm_to_get)+Terminator
00142
00143 status, reply = self.execute_command("get_pwm", complement)
00144
00145 while(status and reply and pwm_to_get not in reply):
00146 status, reply = self.execute_command("get_pwm", complement)
00147
00148 if reply:
00149 reply = reply[reply.find(pwm_to_get)+len(pwm_to_get)+3:-1]
00150
00151 return status, reply
00152
00153 def get_pos(self):
00154 status,pos = self.execute_command("position")
00155
00156 if(not pos==None):
00157 self.pos = pos
00158 return status, self.pos
00159
00160 def stop(self):
00161 complement = " "+Terminator
00162 status,reply = self.execute_command("stop", complement)
00163
00164 return status, reply
00165
00166 def move(self,pos_0, pos_1):
00167 status = None
00168 reply = None
00169
00170 if(not self.move_lock):
00171 self.move_lock = True
00172 complement = " "+(str)(pos_0)+","+(str)(pos_1)+Terminator
00173
00174 status, reply = self.execute_command("move", complement)
00175 if status == False:
00176 rospy.logwarn("Trying to reconnect - calling setup()")
00177 self.setup()
00178 self.move_lock = False
00179 self._joint_states.position = [pos_0/100.0/180.0*math.pi, pos_1/100.0/180.0*math.pi]
00180 return status, reply
00181
00182 def close_port(self):
00183 if self._ser:
00184 self._ser.close()
00185 self._ser = None
00186
00187 def intern_move(self, event):
00188 self.move(self.command_pos[0], self.command_pos[1])
00189
00190 def execute_cb(self, goal):
00191
00192 position_proximal = goal.trajectory.points[-1].positions[0]
00193 position_distal = goal.trajectory.points[-1].positions[1]
00194
00195 position_proximal = math.degrees(position_proximal)*100
00196 position_distal = math.degrees(position_distal)*100
00197 self.command_pos = [position_proximal, position_distal]
00198 status, reply = self.move(position_proximal, position_distal)
00199
00200 print "status", status
00201
00202 if(status==True):
00203 self._as.set_succeeded()
00204 else:
00205 self._as.set_aborted()
00206
00207 def publish_joint_states(self, event):
00208
00209 self._joint_states.header.stamp = rospy.Time.now()
00210 self._pub_joint_states.publish(self._joint_states)
00211 self.publish_controller_state()
00212
00213
00214 def update_joint_states(self):
00215 return
00216 if(not self.lock):
00217 self.lock = True
00218 status, pos = self.get_pos()
00219
00220 if status == True and (not pos==None):
00221 try:
00222 actual_pos_proximal = math.radians((float)(pos[0])/100)
00223 actual_pos_distal = math.radians((float)(pos[1])/100)
00224 self._joint_states.position = [actual_pos_proximal, actual_pos_distal]
00225 except ValueError:
00226 pass
00227
00228 self.lock = False
00229
00230
00231 def publish_controller_state(self):
00232 self._controller_state.header.stamp = rospy.Time.now()
00233 self._controller_state.joint_names = self._joint_states.name
00234 self._controller_state.actual.positions = self._joint_states.position
00235 self._controller_state.actual.velocities = self._joint_states.velocity
00236 self._pub_controller_state.publish(self._controller_state)
00237
00238 def execute_command(self, command, complement=Terminator, timeout=1.2):
00239
00240 if not self._ser:
00241 rospy.logerr("Port is not ready")
00242 return (False,None)
00243
00244 t_out = time.time() + timeout
00245
00246 status,result = False,None
00247 try:
00248 self._ser.write(commands[command]+complement)
00249 line_to_parse = self._ser.readline()
00250
00251 if(command == "position"):
00252
00253 while True:
00254 if (time.time() > t_out):
00255 break
00256 elif("P=" not in line_to_parse[0:2]):
00257 self._ser.write(commands[command]+complement)
00258 line_to_parse = self._ser.readline()
00259 else:
00260 break
00261 rospy.sleep(0.01)
00262
00263 line_to_parse = line_to_parse.replace('P=','')
00264 line_to_parse = line_to_parse.strip()
00265 line_to_parse = line_to_parse.split(',')
00266 result = line_to_parse
00267
00268 if(len(result) !=2):
00269 status = False
00270 else:
00271 status=True
00272
00273 elif(command=="stop"):
00274 rospy.loginfo("Stopping the movement")
00275 while True:
00276 if (time.time() > t_out):
00277 break
00278 elif("@Sto" not in line_to_parse):
00279 self._ser.write(commands[command]+complement)
00280 line_to_parse = self._ser.readline()
00281 else:
00282 rospy.loginfo("Movement stopped")
00283 result = True
00284 break
00285 rospy.sleep(0.01)
00286
00287 elif(command=="set_pwm"):
00288 rospy.loginfo("Setting the PWM: "+complement)
00289
00290 elif(command=="get_pwm"):
00291 result = line_to_parse
00292
00293
00294 elif(command == "move"):
00295
00296 while True:
00297 if (time.time() > t_out):
00298 return False,None
00299 elif("@Mov" not in line_to_parse):
00300 self._ser.write(commands[command]+complement)
00301 line_to_parse = self._ser.readline()
00302 else:
00303 break
00304 rospy.sleep(0.01)
00305
00306 result = line_to_parse
00307
00308 status = True
00309
00310 self._ser.flush()
00311
00312
00313
00314
00315
00316
00317 except Exception as e:
00318 rospy.logerr("Caught: " + str(e))
00319 status = False
00320 result = None
00321 return status, result
00322
00323
00324 if __name__ == '__main__':
00325 try:
00326 rospy.init_node('schunk_sdhx')
00327 sdhx = Sdhx()
00328 r = rospy.Rate(10)
00329 while not rospy.is_shutdown():
00330 sdhx.update_joint_states()
00331 r.sleep()
00332 sdhx.close_port()
00333 except serial.serialutil.SerialException:
00334 pass
00335 except OSError:
00336 pass
00337 except TypeError:
00338 pass
00339