00001
00002 import sys
00003 import roslib
00004 roslib.load_manifest('cob_3d_mapping_gazebo')
00005 roslib.load_manifest('cob_script_server')
00006
00007 import rospy
00008 import os
00009 import math
00010 import time
00011
00012 from gazebo.srv import *
00013 from simple_script_server import *
00014
00015 import getopt
00016 import tf
00017
00018 class broadcaster (object):
00019
00020 def __init__(self,in_frame,out_frame):
00021 self.br = tf.TransformBroadcaster()
00022 self.in_frame= in_frame
00023 self.out_frame = out_frame
00024
00025 def set_tf(self,x,y,alpha):
00026 self.x = x
00027 self.y = y
00028 self.alpha = alpha
00029
00030 def Run(self):
00031 self.br.sendTransform((self.x,self.y, 0),
00032 tf.transformations.quaternion_from_euler(0, 0, self.alpha),
00033 rospy.Time.now(),self.out_frame,self.in_frame)
00034
00035
00036
00037
00038
00039 class RecordCylinderScript(script):
00040
00041 def __init__(self,num_steps,intervall):
00042
00043 rospy.init_node("recorder")
00044 self.sss = simple_script_server()
00045
00046
00047
00048 self.do_tf = False
00049 self.do_verbose= True
00050
00051 self.intervall = intervall
00052
00053 self.num_steps = num_steps
00054
00055 self.srv_set_model_state = rospy.ServiceProxy('/gazebo/set_model_state', SetModelState)
00056 self.req_set = SetModelStateRequest()
00057 self.req_set.model_state.model_name = "robot"
00058 self.req_set.model_state.reference_frame = "map"
00059
00060
00061
00062
00063
00064 if do_tf ==True:
00065 self.tf_br = broadcaster("/map","/odom_combined",)
00066
00067
00068
00069
00070
00071
00072 def set_flags(self,do_tf,do_verbose):
00073 self.do_tf = do_tf
00074
00075 self.do_verbose = do_verbose
00076
00077 def set_init_pose(self):
00078 self.sss.move("arm","folded")
00079 self.sss.move("tray","down")
00080
00081 self.req_set.model_state.pose.position.x = -1.5
00082 self.req_set.model_state.pose.position.y = -1.5
00083 self.req_set.model_state.pose.position.z = 0
00084 self.req_set.model_state.pose.orientation.w = 1
00085 self.req_set.model_state.pose.orientation.x = 0
00086 self.req_set.model_state.pose.orientation.y = 0
00087 self.req_set.model_state.pose.orientation.z = 0
00088 self.res_set = self.srv_set_model_state(self.req_set)
00089
00090
00091
00092
00093
00094 def RunCircle(self, center,radius):
00095
00096
00097 print "[RecordCylinderScript]--> Circle Paramters:"
00098 print " Center = ( %f , % f )" % (center[0],center[1])
00099 print " Radius = %f " % radius
00100 print " Steps = %i " % (self.num_steps)
00101
00102 if radius > 1:
00103 print "WARNING DANGEORUS COB_KITCHEN PARAMETER (use radius <= 1)"
00104 raw_input("to continue anyway pres [Enter] to abort [CTRL+C]")
00105
00106 trajectory = self.calc_circle(center,radius)
00107 self.Move(trajectory)
00108
00109 def RunLine(self,start,end,ori):
00110 print "[RecordCylinderScript]--> Line Paramters:"
00111 print " Start = ( %f , % f )" % (start[0],start[1])
00112 print " End = ( %f , % f ) " % (end[0],end[1])
00113 print " Ori = %f" % ori
00114 print " Steps = %i " % (self.num_steps)
00115
00116 trajectory = self.calc_line(start,end,ori)
00117 self.Move(trajectory)
00118
00119
00120 def RunSingle(self,pos,ori):
00121 print "[SinglePose]--> Line Paramters:"
00122 print " Pos = ( %f , % f )" % (pos[0],pos[1])
00123 print " Ori = %f " % (ori)
00124
00125 trajectory =self.calc_single(pos,ori)
00126
00127 self.Move(trajectory)
00128
00129
00130 def calc_single(self,pos,ori):
00131
00132 trajectory = list()
00133 positions_x=list()
00134 positions_y=list()
00135 alpha =list()
00136 positions_x.append(pos[0])
00137 positions_y.append(pos[1])
00138 alpha.append(ori)
00139
00140 trajectory.append(positions_x)
00141 trajectory.append(positions_y)
00142 trajectory.append(alpha)
00143 return trajectory
00144
00145 def calc_line(self,start,end,ori):
00146 positions_x=list()
00147 positions_y=list()
00148 alpha =list()
00149 step = 0
00150 PI = math.pi
00151 phi = 0
00152
00153 direction_x = end[0]-start[0]
00154 direction_y = end[1]-start[1]
00155
00156 while step < self.num_steps:
00157 d_inc = 1*step /self.num_steps
00158
00159 positions_x.append(start[0]+ d_inc * direction_x )
00160 positions_y.append( start[1]+ d_inc * direction_y )
00161 alpha.append(ori)
00162 step = step+1
00163
00164
00165 trajectory = list()
00166 trajectory.append(positions_x)
00167 trajectory.append(positions_y)
00168 trajectory.append(alpha)
00169 print "[RecordCylinderScript]--> Line trajectory calculated"
00170 return trajectory
00171
00172
00173
00174
00175
00176
00177
00178
00179 def calc_circle(self,center,radius):
00180
00181
00182
00183
00184 positions_x=list()
00185 positions_y=list()
00186 alpha =list()
00187 step = 0
00188 PI = math.pi
00189 phi = 0
00190 delta_phi = 2*PI / self.num_steps
00191 while step < self.num_steps:
00192 phi = (step)*delta_phi
00193 positions_x.append( center[0] + radius * math.cos(phi) )
00194 positions_y.append( center[1] +radius * math.sin(phi) )
00195
00196
00197
00198
00199 alpha.append(phi)
00200
00201 step =step+1
00202 trajectory = list()
00203
00204 trajectory.append(positions_x)
00205 trajectory.append(positions_y)
00206 trajectory.append(alpha)
00207 print "[RecordCylinderScript]--> Trajectory calculated"
00208 return trajectory
00209
00210
00211
00212
00213 def Move(self,trajectory):
00214
00215
00216
00217 positions_x = trajectory[0]
00218 positions_y = trajectory[1]
00219 alpha = trajectory[2]
00220
00221
00222 step = 0
00223 for a in positions_x:
00224 if self.do_tf == True:
00225 self.tf_br.set_tf(positions_x[step],positions_y[step],alpha[step])
00226 self.tf_br.Run()
00227
00228
00229
00230 q = tf.transformations.quaternion_from_euler(0,0,alpha[step])
00231
00232
00233 self.req_set.model_state.pose.position.x = positions_x[step]
00234 self.req_set.model_state.pose.position.y = positions_y[step]
00235 self.req_set.model_state.pose.position.z = 0
00236 self.req_set.model_state.pose.orientation.w = q[3]
00237 self.req_set.model_state.pose.orientation.y = 0
00238 self.req_set.model_state.pose.orientation.z = q[2]
00239 self.res_set = self.srv_set_model_state(self.req_set)
00240
00241
00242
00243
00244
00245
00246
00247 print "[RecordCylinderScript]--> Assumed position % i of % i " % (step,self.num_steps)
00248 step = step+1
00249 time.sleep(self.intervall)
00250
00251 def PitchHead(self,command):
00252 if command == "up":
00253 pos = [[-0.2,0,-0.2]]
00254 elif command == "down":
00255 pos = [[0.1,0,0.1]]
00256 else:
00257 rospy.logwarn('pitch direction not valid use [up] and [down] - ptiching to [0 0 0]')
00258
00259 pos = [[0,0,0]]
00260
00261 move_handle = self.sss.move("torso",pos)
00262 time.sleep(6)
00263
00264
00265
00266
00267
00268
00269 def Spawn(self):
00270
00271 print "[RecordCylinderScript]--> Set robot to initial pose"
00272 self.set_init_pose()
00273 if do_verbose == False:
00274 print "[RecordCylinderScript]--> No Verbose Output"
00275 os.system("roslaunch cob_3d_mapping_gazebo spawn_cylinder.launch >/dev/null")
00276 else:
00277 os.system("roslaunch cob_3d_mapping_gazebo spawn_cylinder.launch ")
00278 print "[RecordCylinderScript]--> Spawning Cylinder"
00279
00280
00281
00282
00283
00284
00285 if __name__ == "__main__":
00286
00287 do_tf = False
00288
00289 do_verbose = True
00290
00291 run_circle = True
00292 run_line = False
00293 run_single = False
00294 run_pitch = False
00295 run_spawn = False
00296 run_helix = False
00297
00298
00299 intervall = 0.3
00300 num_steps = 12
00301 radius = 1
00302 center = (0,0)
00303
00304 try:
00305 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
00306 except getopt.error, msg:
00307 print msg
00308 print "for help use --help"
00309 sys.exit(2)
00310
00311 for o, a in opts:
00312 if o in ("-h", "--help"):
00313 print "\n\nUsage:\t rosrun RecordCylinder.py <mode> <options>"
00314 print " -- when run without <options> argument a default circle trajectory is used\n"
00315
00316 print"<mode> \t spawn .......... spawn default cylinder"
00317 print" \t single [x0][y0][orientation] .. set parameters of single pose"
00318 print" \t line [start][end][orientation] .. set parameters of trajectory line"
00319 print" \t circle [x0][y0][r] .. set parameters of trajectory circle"
00320 print" \t helix [x0][y0][r] .. set parameters of helix circle - looks up, then middle, then down"
00321 print" \t pitch [up] | [down] ....... pitch torso up or down "
00322 print"Note: Only one mode can be chosen at a time. "
00323 print"<options> \t V .............. disable verbose output of spawned cylinder"
00324 print" \t tf ............. publish transform in frame /map"
00325 print" \t I [time]........ set rest intervall at every step to time"
00326 print" \t N [#] .......... number of steps on trajectory"
00327 print"Note: multiple options can be used at the same time by just adding the to the command line"
00328
00329 print"-------------------------------------------------------------------------"
00330 print"default values\t V = True , tf = False , I 0.3 , cirlce 0 0 1 , N 12 "
00331 print"Usage example: RecordCylinder.py circle 0 0 1 N 100 I 0.1 tf"
00332 sys.exit(0)
00333
00334
00335
00336
00337 for i in range(len(args)):
00338
00339 arg = args[i]
00340 if (arg in 'V') == True:
00341 print "no verbose activated"
00342 do_verbose = False
00343 continue
00344 elif (arg in 'spawn') == True:
00345 print "spawning default cylinder"
00346 run_circle = False
00347 run_spawn = True
00348 continue
00349 elif (arg in "tf") == True:
00350 print "tf = true"
00351 do_tf = True
00352 continue
00353 elif(arg in "I") == True:
00354 print ("intervall set to %s" % args[i+1])
00355 intervall = (float)(args[i+1])
00356 continue
00357 elif(arg in "N") == True:
00358 print ("number of steps set to %s" % args[i+1] )
00359 num_steps = (float)(args[i+1])
00360 continue
00361 elif(arg in "circle") == True:
00362 print ("circle paramaters set")
00363 center = ((float)(args[i+1]),(float)(args[i+2]))
00364 radius = (float)(args[i+3])
00365
00366 continue
00367 elif(arg in "line") == True:
00368 print ("line paramaters set")
00369 run_line = True
00370 run_circle = False
00371 start = ((float)(args[i+1]),(float)(args[i+2]))
00372 end = ((float)(args[i+3]),(float)(args[i+4]))
00373 ori = (float)(args[i+5])
00374 continue
00375
00376 elif(arg in "single") == True:
00377 print ("single pose paramaters set")
00378
00379 run_circle = False
00380 run_single = True
00381 pos = ((float)(args[i+1]),(float)(args[i+2]))
00382 ori = (float)(args[i+3])
00383 continue
00384 elif(arg in "pitch") == True:
00385
00386 run_circle = False
00387
00388 run_pitch = True
00389 command = (args[i+1])
00390 continue
00391
00392
00393 elif(arg in "helix") == True:
00394 run_circle = False
00395 run_helix = True
00396 continue
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 SCRIPT = RecordCylinderScript(num_steps,intervall)
00411 SCRIPT.set_flags(do_tf,do_verbose)
00412
00413
00414
00415 if run_line == True:
00416
00417 SCRIPT.RunLine(start,end,ori)
00418 elif run_circle == True:
00419 SCRIPT.RunCircle(center,radius)
00420 elif run_single == True:
00421 SCRIPT.RunSingle(pos,ori)
00422 elif run_pitch == True:
00423 SCRIPT.PitchHead(command)
00424 elif run_spawn == True:
00425 SCRIPT.Spawn()
00426 elif run_helix == True:
00427 SCRIPT.PitchHead("up")
00428 SCRIPT.RunCircle(center,radius)
00429 SCRIPT.PitchHead("middle")
00430 SCRIPT.RunCircle(center,radius)
00431 SCRIPT.PitchHead("down")
00432 SCRIPT.RunCircle(center,radius)