00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 import time
00019 import datetime
00020 import os
00021 import sys
00022 import types
00023 import thread
00024 import commands
00025 import math
00026 import threading
00027
00028
00029 import pygraphviz as pgv
00030
00031
00032 import rospy
00033 import actionlib
00034
00035
00036 from std_msgs.msg import String,ColorRGBA
00037 from std_srvs.srv import Trigger
00038 from sensor_msgs.msg import JointState
00039 from geometry_msgs.msg import *
00040 from trajectory_msgs.msg import *
00041 from move_base_msgs.msg import *
00042 from control_msgs.msg import *
00043 from tf.transformations import *
00044
00045
00046 from cob_actions.msg import SetStringAction, SetStringGoal
00047 from cob_sound.msg import *
00048 from cob_script_server.msg import *
00049 from cob_light.msg import LightMode, LightModes, SetLightModeGoal, SetLightModeAction
00050 from cob_mimic.msg import SetMimicGoal, SetMimicAction
00051 from actionlib.msg import TestAction, TestGoal
00052 from actionlib import GoalStatus
00053
00054 graph=""
00055 graph_wait_list=[]
00056 ah_counter = 0
00057 graph = pgv.AGraph()
00058 graph.node_attr['shape']='box'
00059 last_node = "Start"
00060
00061
00062
00063
00064 class script():
00065 def __init__(self):
00066
00067 filename = os.path.basename(sys.argv[0])
00068 self.basename, extension = os.path.splitext(filename)
00069 rospy.init_node(self.basename)
00070 self.graph_pub = rospy.Publisher("/script_server/graph", String, queue_size=1)
00071
00072
00073 def Initialize(self):
00074 pass
00075
00076
00077 def Run(self):
00078 pass
00079
00080
00081
00082
00083 def Start(self):
00084 self.Parse()
00085 global ah_counter
00086 ah_counter = 0
00087 self.sss = simple_script_server()
00088 rospy.loginfo("Starting <<%s>> script...",self.basename)
00089 self.Initialize()
00090 self.Run()
00091
00092 rospy.loginfo("Wait for script to finish...")
00093 while ah_counter != 0:
00094 rospy.sleep(1)
00095 rospy.loginfo("...script finished.")
00096
00097
00098
00099
00100 def Parse(self):
00101 rospy.loginfo("Start parsing...")
00102 global graph
00103
00104 self.sss = simple_script_server(parse=True)
00105 self.Initialize()
00106 self.Run()
00107
00108
00109
00110 rospy.set_param("/script_server/graph", graph.string())
00111 self.graph_pub.publish(graph.string())
00112 rospy.loginfo("...parsing finished")
00113 return graph.string()
00114
00115
00116
00117
00118 class simple_script_server:
00119
00120
00121
00122 def __init__(self, parse=False):
00123 global graph
00124 self.ns_global_prefix = "/script_server"
00125 self.wav_path = ""
00126 self.parse = parse
00127 rospy.sleep(1)
00128
00129
00130
00131
00132
00133
00134
00135 def init(self,component_name,blocking=True):
00136 return self.trigger(component_name,"init",blocking=blocking)
00137
00138
00139
00140
00141
00142
00143 def stop(self,component_name,mode="omni",blocking=True):
00144 ah = action_handle("stop", component_name, "", False, self.parse)
00145 if(self.parse):
00146 return ah
00147 else:
00148 ah.set_active(mode="service")
00149
00150 rospy.loginfo("<<stop>> <<%s>>", component_name)
00151 if component_name == "base":
00152 if(mode == None or mode == ""):
00153 action_server_name = "/move_base"
00154 elif(mode == "omni"):
00155 action_server_name = "/move_base"
00156 elif(mode == "diff"):
00157 action_server_name = "/move_base_diff"
00158 elif(mode == "linear"):
00159 action_server_name = "/move_base_linear"
00160 else:
00161 message = "Given navigation mode " + mode + " for " + component_name + " is not valid, aborting..."
00162 rospy.logerr(message)
00163 ah.set_failed(33, message)
00164 return ah
00165 client = actionlib.SimpleActionClient(action_server_name, MoveBaseAction)
00166 else:
00167 parameter_name = self.ns_global_prefix + "/" + component_name + "/action_name"
00168 if not rospy.has_param(parameter_name):
00169 message = "Parameter " + parameter_name + " does not exist on ROS Parameter Server, aborting..."
00170 rospy.logerr(message)
00171 ah.set_failed(2, message)
00172 return ah
00173 action_server_name = rospy.get_param(parameter_name)
00174 client = actionlib.SimpleActionClient(action_server_name, FollowJointTrajectoryAction)
00175
00176
00177 rospy.logdebug("calling %s action server",action_server_name)
00178
00179 if blocking:
00180
00181 rospy.logdebug("waiting for %s action server to start",action_server_name)
00182 if not client.wait_for_server(rospy.Duration(1)):
00183
00184 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
00185 rospy.logerr(message)
00186 ah.set_failed(4, message)
00187 return ah
00188 else:
00189 rospy.logdebug("%s action server ready",action_server_name)
00190
00191
00192 client.cancel_all_goals()
00193 ah.set_succeeded()
00194 return ah
00195
00196
00197
00198
00199
00200
00201 def recover(self,component_name,blocking=True):
00202 return self.trigger(component_name,"recover",blocking=blocking)
00203
00204
00205
00206
00207
00208
00209 def halt(self,component_name,blocking=True):
00210 return self.trigger(component_name,"halt",blocking=blocking)
00211
00212
00213
00214
00215
00216
00217
00218
00219 def trigger(self,component_name,service_name,blocking=True):
00220 ah = action_handle(service_name, component_name, "", blocking, self.parse)
00221 if(self.parse):
00222 return ah
00223 else:
00224 ah.set_active(mode="service")
00225
00226 rospy.loginfo("<<%s>> <<%s>>", service_name, component_name)
00227 parameter_name = self.ns_global_prefix + "/" + component_name + "/service_ns"
00228 if not rospy.has_param(parameter_name):
00229 message = "Parameter " + parameter_name + " does not exist on ROS Parameter Server, aborting..."
00230 rospy.logerr(message)
00231 ah.set_failed(2, message)
00232 return ah
00233 service_ns_name = rospy.get_param(parameter_name)
00234 service_full_name = service_ns_name + "/" + service_name
00235
00236 if blocking:
00237
00238 try:
00239 rospy.wait_for_service(service_full_name,1)
00240 except rospy.ROSException, e:
00241 error_message = "%s"%e
00242 message = "...service <<" + service_name + ">> of <<" + component_name + ">> not available,\n error: " + error_message
00243 rospy.logerr(message)
00244 ah.set_failed(4, message)
00245 return ah
00246
00247
00248 try:
00249 trigger = rospy.ServiceProxy(service_full_name,Trigger)
00250 if blocking:
00251 rospy.loginfo("Wait for <<%s>> to <<%s>>...", component_name, service_name)
00252 resp = trigger()
00253 else:
00254 thread.start_new_thread(trigger,())
00255 except rospy.ServiceException, e:
00256 error_message = "%s"%e
00257 message = "...calling <<" + service_name + ">> of <<" + component_name + ">> not successfull,\n error: " + error_message
00258 rospy.logerr(message)
00259 ah.set_failed(10, message)
00260 return ah
00261
00262 if blocking:
00263
00264 if not resp.success:
00265 message = "...response of <<" + service_name + ">> of <<" + component_name + ">> not successfull,\n error: " + resp.message
00266 rospy.logerr(message)
00267 ah.set_failed(10, message)
00268 return ah
00269
00270
00271 rospy.loginfo("...<<%s>> is <<%s>>", component_name, service_name)
00272 ah.set_succeeded()
00273 return ah
00274
00275
00276
00277
00278
00279
00280
00281
00282 def trigger_action(self,component_name,action_name,blocking=True):
00283 ah = action_handle(action_name, component_name, "", blocking, self.parse)
00284 if(self.parse):
00285 return ah
00286 else:
00287 ah.set_active(mode="action")
00288
00289 rospy.loginfo("<<%s>> <<%s>>", action_name, component_name)
00290
00291
00292
00293
00294
00295
00296
00297 action_full_name = "/" + component_name + "/" + action_name
00298 action_client = actionlib.SimpleActionClient(action_full_name, TestAction)
00299
00300 if blocking:
00301
00302 if not action_client.wait_for_server(rospy.Duration(1)):
00303 message = "ActionServer %s is not running"%action_full_name
00304 rospy.logerr(message)
00305 ah.set_failed(4, message)
00306 return ah
00307
00308
00309 if blocking:
00310 rospy.loginfo("Wait for <<%s>> to <<%s>>...", component_name, action_name)
00311 goal_state = action_client.send_goal_and_wait(TestGoal())
00312 if not (action_client.get_state() == GoalStatus.SUCCEEDED):
00313 message = "...state of <<" + action_name + ">> of <<" + component_name + ">> : " + GoalStatus.to_string(action_client.get_state())
00314 rospy.logerr(message)
00315 ah.set_failed(10, message)
00316 return ah
00317 else:
00318 action_client.send_goal(TestGoal())
00319
00320
00321 rospy.loginfo("...<<%s>> is <<%s>>", component_name, action_name)
00322 ah.set_succeeded()
00323 return ah
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 def string_action(self,component_name, data, blocking):
00334 action_name = "set_string"
00335 ah = action_handle(action_name, component_name, "", blocking, self.parse)
00336 if(self.parse):
00337 return ah
00338 else:
00339 ah.set_active(mode="action")
00340
00341 rospy.loginfo("<<%s>> <<%s>>", action_name, component_name)
00342 action_full_name = "/" + component_name + "/" + action_name
00343 action_client = actionlib.SimpleActionClient(action_full_name, SetStringAction)
00344
00345 if blocking:
00346
00347 if not action_client.wait_for_server(rospy.Duration(1)):
00348 message = "ActionServer %s is not running"%action_full_name
00349 rospy.logerr(message)
00350 ah.set_failed(4, message)
00351 return ah
00352
00353
00354 goal = SetStringGoal()
00355 goal.data = data
00356 if blocking:
00357 rospy.loginfo("Wait for <<%s>> to <<%s>>...", component_name, action_name)
00358 goal_state = action_client.send_goal_and_wait(goal)
00359 if not (action_client.get_state() == GoalStatus.SUCCEEDED):
00360 message = "...state of <<" + action_name + ">> of <<" + component_name + ">> : " + GoalStatus.to_string(action_client.get_state())
00361 rospy.logerr(message)
00362 ah.set_failed(10, message)
00363 return ah
00364 else:
00365 action_client.send_goal(goal)
00366
00367
00368 rospy.loginfo("...<<%s>> is <<%s>>", component_name, action_name)
00369 ah.set_succeeded()
00370 return ah
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 def move(self,component_name,parameter_name,blocking=True, mode=None):
00382 if component_name == "base":
00383 return self.move_base(component_name,parameter_name,blocking, mode)
00384 else:
00385 return self.move_traj(component_name,parameter_name,blocking)
00386
00387
00388
00389
00390
00391
00392
00393
00394 def move_base(self,component_name,parameter_name,blocking, mode):
00395 ah = action_handle("move", component_name, parameter_name, blocking, self.parse)
00396 if(self.parse):
00397 return ah
00398 else:
00399 ah.set_active()
00400
00401 if(mode == None or mode == ""):
00402 rospy.loginfo("Move <<%s>> to <<%s>>",component_name,parameter_name)
00403 else:
00404 rospy.loginfo("Move <<%s>> to <<%s>> using <<%s>> mode",component_name,parameter_name,mode)
00405
00406
00407 if type(parameter_name) is str:
00408 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + parameter_name
00409 if not rospy.has_param(full_parameter_name):
00410 message = "Parameter " + full_parameter_name + " does not exist on ROS Parameter Server, aborting..."
00411 rospy.logerr(message)
00412 ah.set_failed(2, message)
00413 return ah
00414 param = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00415 else:
00416 param = parameter_name
00417
00418
00419 if not type(param) is list:
00420 message = "No valid parameter for " + component_name + ": not a list, aborting..."
00421 rospy.logerr(message)
00422 print "parameter is:",param
00423 ah.set_failed(3, message)
00424 return ah
00425 else:
00426
00427 DOF = 3
00428 if not len(param) == DOF:
00429 message = "No valid parameter for " + component_name + ": dimension should be " + str(DOF) + " but is " + str(len(param)) + ", aborting..."
00430 rospy.logerr(message)
00431 print "parameter is:",param
00432 ah.set_failed(3, message)
00433 return ah
00434 else:
00435 for i in param:
00436
00437 if not ((type(i) is float) or (type(i) is int)):
00438
00439 message = "No valid parameter for " + component_name + ": not a list of float or int, aborting..."
00440 rospy.logerr(message)
00441 print "parameter is:",param
00442 ah.set_failed(3, message)
00443 return ah
00444 else:
00445 rospy.logdebug("accepted parameter %f for %s",i,component_name)
00446
00447
00448 pose = PoseStamped()
00449 pose.header.stamp = rospy.Time.now()
00450 pose.header.frame_id = "/map"
00451 pose.pose.position.x = param[0]
00452 pose.pose.position.y = param[1]
00453 pose.pose.position.z = 0.0
00454 q = quaternion_from_euler(0, 0, param[2])
00455 pose.pose.orientation.x = q[0]
00456 pose.pose.orientation.y = q[1]
00457 pose.pose.orientation.z = q[2]
00458 pose.pose.orientation.w = q[3]
00459
00460
00461 if(mode == None or mode == ""):
00462 action_server_name = "/move_base"
00463 elif(mode == "omni"):
00464 action_server_name = "/move_base"
00465 elif(mode == "diff"):
00466 action_server_name = "/move_base_diff"
00467 elif(mode == "linear"):
00468 action_server_name = "/move_base_linear"
00469 else:
00470 message = "Given navigation mode " + mode + " for " + component_name + " is not valid, aborting..."
00471 rospy.logerr(message)
00472 ah.set_failed(33, message)
00473 return ah
00474
00475 rospy.logdebug("calling %s action server",action_server_name)
00476 client = actionlib.SimpleActionClient(action_server_name, MoveBaseAction)
00477
00478 rospy.logdebug("waiting for %s action server to start",action_server_name)
00479 if not client.wait_for_server(rospy.Duration(1)):
00480
00481 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
00482 rospy.logerr(message)
00483 ah.set_failed(4, message)
00484 return ah
00485 else:
00486 rospy.logdebug("%s action server ready",action_server_name)
00487
00488
00489 client_goal = MoveBaseGoal()
00490 client_goal.target_pose = pose
00491
00492 client.send_goal(client_goal)
00493 ah.set_client(client)
00494 ah.wait_inside()
00495 return ah
00496
00497
00498 def compose_trajectory(self, component_name, parameter_name):
00499
00500 param_string = self.ns_global_prefix + "/" + component_name + "/joint_names"
00501 if not rospy.has_param(param_string):
00502 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",param_string)
00503 return (JointTrajectory(), 2)
00504 joint_names = rospy.get_param(param_string)
00505
00506
00507 if not type(joint_names) is list:
00508 rospy.logerr("no valid joint_names for %s: not a list, aborting...",component_name)
00509 print "joint_names are:",joint_names
00510 return (JointTrajectory(), 3)
00511 else:
00512 for i in joint_names:
00513
00514 if not type(i) is str:
00515 rospy.logerr("no valid joint_names for %s: not a list of strings, aborting...",component_name)
00516 print "joint_names are:",param
00517 return (JointTrajectory(), 3)
00518 else:
00519 rospy.logdebug("accepted joint_names for component %s",component_name)
00520
00521
00522 if type(parameter_name) is str:
00523 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + parameter_name
00524 if not rospy.has_param(full_parameter_name):
00525 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
00526 return (JointTrajectory(), 2)
00527 param = rospy.get_param(full_parameter_name)
00528 else:
00529 param = parameter_name
00530
00531
00532 if not type(param) is list:
00533 rospy.logerr("no valid parameter for %s: not a list, aborting...",component_name)
00534 print "parameter is:",param
00535 return (JointTrajectory(), 3)
00536
00537 traj = []
00538 for point in param:
00539
00540 if type(point) is str:
00541 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + point
00542 if not rospy.has_param(full_parameter_name):
00543 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
00544 return (JointTrajectory(), 2)
00545 point = rospy.get_param(full_parameter_name)
00546 point = point[0]
00547
00548 elif type(point) is list:
00549 rospy.logdebug("point is a list")
00550 else:
00551 rospy.logerr("no valid parameter for %s: not a list of lists or strings, aborting...",component_name)
00552 print "parameter is:",param
00553 return (JointTrajectory(), 3)
00554
00555
00556
00557 if not len(point) == len(joint_names):
00558 rospy.logerr("no valid parameter for %s: dimension should be %d and is %d, aborting...",component_name,len(joint_names),len(point))
00559 print "parameter is:",param
00560 return (JointTrajectory(), 3)
00561
00562 for value in point:
00563
00564 if not ((type(value) is float) or (type(value) is int)):
00565
00566 rospy.logerr("no valid parameter for %s: not a list of float or int, aborting...",component_name)
00567 print "parameter is:",param
00568 return (JointTrajectory(), 3)
00569
00570 rospy.logdebug("accepted value %f for %s",value,component_name)
00571 traj.append(point)
00572
00573 rospy.logdebug("accepted trajectory for %s",component_name)
00574
00575
00576 timeout = 3.0
00577 try:
00578 start_pos = rospy.wait_for_message("/" + component_name + "/joint_states", JointState, timeout = timeout).position
00579 except rospy.ROSException as e:
00580 rospy.logwarn("no joint states received from %s within timeout of %ssec. using default point time of 8sec.", component_name, str(timeout))
00581 start_pos = []
00582
00583
00584 traj_msg = JointTrajectory()
00585
00586 traj_msg.joint_names = joint_names
00587 point_nr = 0
00588 traj_time = 0
00589
00590 param_string = self.ns_global_prefix + "/" + component_name + "/default_vel"
00591 if not rospy.has_param(param_string):
00592 default_vel = 0.1
00593 rospy.logwarn("parameter %s does not exist on ROS Parameter Server, using default of %f [rad/sec].",param_string,default_vel)
00594 else:
00595 default_vel = rospy.get_param(param_string)
00596
00597 param_string = self.ns_global_prefix + "/" + component_name + "/default_acc"
00598 if not rospy.has_param(param_string):
00599 default_acc = 1.0
00600 rospy.logwarn("parameter %s does not exist on ROS Parameter Server, using default of %f [rad^2/sec].",param_string,default_acc)
00601 else:
00602 default_acc = rospy.get_param(param_string)
00603
00604 for point in traj:
00605 point_nr = point_nr + 1
00606 point_msg = JointTrajectoryPoint()
00607 point_msg.positions = point
00608
00609
00610
00611
00612
00613
00614 point_msg.velocities = [0]*len(joint_names)
00615 point_msg.accelerations = [0]*len(joint_names)
00616
00617
00618 if start_pos != []:
00619 point_time = self.calculate_point_time(component_name, start_pos, point, default_vel, default_acc)
00620 else:
00621 point_time = 8*point_nr
00622
00623 start_pos = point
00624 point_msg.time_from_start=rospy.Duration(point_time + traj_time)
00625 traj_time += point_time
00626 traj_msg.points.append(point_msg)
00627 return (traj_msg, 0)
00628
00629 def calculate_point_time(self, component_name, start_pos, end_pos, default_vel, default_acc):
00630 try:
00631 d_max = max(list(abs(numpy.array(start_pos) - numpy.array(end_pos))))
00632 t1 = default_vel / default_acc
00633 s1 = default_acc / 2 * t1**2
00634 if (2 * s1 < d_max):
00635
00636
00637
00638
00639 s2 = d_max - 2 * s1
00640 t2 = s2 / default_vel
00641 t = 2 * t1 + t2
00642 else:
00643
00644
00645
00646
00647 t = math.sqrt(d_max / default_acc)
00648 point_time = max(t, 0.4)
00649 except ValueError as e:
00650 print "Value Error", e
00651 print "Likely due to mimic joints. Using default point_time: 3.0 [sec]"
00652 point_time = 3.0
00653 return point_time
00654
00655
00656
00657
00658
00659
00660
00661
00662 def move_traj(self,component_name,parameter_name,blocking):
00663 ah = action_handle("move", component_name, parameter_name, blocking, self.parse)
00664 if(self.parse):
00665 return ah
00666 else:
00667 ah.set_active()
00668
00669 rospy.loginfo("Move <<%s>> to <<%s>>",component_name,parameter_name)
00670 (traj_msg, error_code) = self.compose_trajectory(component_name, parameter_name)
00671 if error_code != 0:
00672 message = "Composing the trajectory failed with error: " + str(error_code)
00673 ah.set_failed(error_code, message)
00674 return ah
00675
00676
00677 parameter_name = self.ns_global_prefix + "/" + component_name + "/action_name"
00678 if not rospy.has_param(parameter_name):
00679 message = "Parameter " + parameter_name + " does not exist on ROS Parameter Server, aborting..."
00680 rospy.logerr(message)
00681 ah.set_failed(2, message)
00682 return ah
00683 action_server_name = rospy.get_param(parameter_name)
00684 rospy.logdebug("calling %s action server",action_server_name)
00685 client = actionlib.SimpleActionClient(action_server_name, FollowJointTrajectoryAction)
00686
00687 rospy.logdebug("waiting for %s action server to start",action_server_name)
00688 if not client.wait_for_server(rospy.Duration(1)):
00689
00690 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
00691 rospy.logerr(message)
00692 ah.set_failed(4, message)
00693 return ah
00694 else:
00695 rospy.logdebug("%s action server ready",action_server_name)
00696
00697
00698 client_goal = FollowJointTrajectoryGoal()
00699 client_goal.trajectory = traj_msg
00700
00701 client.send_goal(client_goal)
00702 ah.set_client(client)
00703 ah.wait_inside()
00704 return ah
00705
00706
00707
00708
00709
00710
00711
00712
00713 def move_base_rel(self, component_name, parameter_name=[0,0,0], blocking=True):
00714 ah = action_handle("move_base_rel", component_name, parameter_name, blocking, self.parse)
00715 if(self.parse):
00716 return ah
00717 else:
00718 ah.set_active(mode="topic")
00719
00720 parameter_topic_name = self.ns_global_prefix + "/" + component_name + "/topic_name"
00721 if not rospy.has_param(parameter_topic_name):
00722 message = "Parameter " + parameter_topic_name + " does not exist on ROS Parameter Server, aborting..."
00723 rospy.logerr(message)
00724 ah.set_failed(3, message)
00725 return ah
00726 topic_name = rospy.get_param(parameter_topic_name)
00727 rospy.loginfo("Move base relatively by <<%s>>", parameter_name)
00728
00729
00730 if not len(parameter_name) == 3 or not isinstance(parameter_name[0], (int, float)) or not isinstance(parameter_name[1], (int, float)) or not isinstance(parameter_name[2], (int, float)):
00731 message = "Parameter " + parameter_name + " not formated correctly (non-numeric list), aborting move_base_rel"
00732 rospy.logerr(message)
00733 print("parameter_name must be numeric list of length 3; (relative x and y transl [m], relative rotation [rad])")
00734 ah.set_failed(3, message)
00735 return ah
00736 max_rel_trans_step = 1.0
00737 max_rel_rot_step = math.pi/2
00738 if math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) > max_rel_trans_step:
00739 message = "Parameter " + str(parameter_name) + " exceeds maximal relative translation step (" + str(max_rel_trans_step) + "), aborting move_base_rel"
00740 rospy.logerr(message)
00741 ah.set_failed(3, message)
00742 return(ah)
00743 if abs(parameter_name[2]) > max_rel_rot_step:
00744 message = "Parameter " + str(parameter_name) + " exceeds maximal relative rotation step (" + str(max_rel_rot_step) + "), aborting move_base_rel"
00745 rospy.logerr(message)
00746 ah.set_failed(3, message)
00747 return(ah)
00748
00749
00750 max_trans_vel = 0.05
00751 max_rot_vel = 0.2
00752 duration_trans_sec = math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) / max_trans_vel
00753 duration_rot_sec = abs(parameter_name[2] / max_rot_vel)
00754 duration_sec = max(duration_trans_sec, duration_rot_sec)
00755 duration_ros = rospy.Duration.from_sec(duration_sec)
00756
00757
00758 x_vel = parameter_name[0] / duration_sec
00759 y_vel = parameter_name[1] / duration_sec
00760 rot_vel = parameter_name[2] / duration_sec
00761
00762
00763 pub = rospy.Publisher(topic_name, Twist, queue_size=1)
00764 twist = Twist()
00765 twist.linear.x = x_vel
00766 twist.linear.y = y_vel
00767 twist.angular.z = rot_vel
00768 end_time = rospy.Time.now() + duration_ros
00769
00770 if blocking:
00771 rospy.loginfo("Wait for <<%s>> to finish move_base_rel...", component_name)
00772 self.publish_twist(pub, twist, end_time)
00773 else:
00774 thread.start_new_thread(self.publish_twist,(pub, twist, end_time))
00775
00776 ah.set_succeeded()
00777 return ah
00778
00779 def publish_twist(self, pub, twist, end_time):
00780 r = rospy.Rate(10)
00781 while not rospy.is_shutdown() and rospy.Time.now() < end_time:
00782 pub.publish(twist)
00783 r.sleep()
00784
00785
00786
00787
00788
00789
00790
00791
00792 def compose_color(self,component_name,parameter_name):
00793
00794 if type(parameter_name) is str:
00795 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + parameter_name
00796 if not rospy.has_param(full_parameter_name):
00797 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",full_parameter_name)
00798 return 2, None
00799 param = rospy.get_param(full_parameter_name)
00800 else:
00801 param = parameter_name
00802
00803
00804 if not type(param) is list:
00805 rospy.logerr("no valid parameter for light: not a list, aborting...")
00806 print "parameter is:",param
00807 return 3, None
00808 else:
00809 if not len(param) == 4:
00810 rospy.logerr("no valid parameter for light: dimension should be 4 (r,g,b,a) and is %d, aborting...",len(param))
00811 print "parameter is:",param
00812 return 3, None
00813 else:
00814 for i in param:
00815
00816 if not ((type(i) is float) or (type(i) is int)):
00817
00818 rospy.logerr("no valid parameter for light: not a list of float or int, aborting...")
00819 print "parameter is:",param
00820 return 3, None
00821 else:
00822 rospy.logdebug("accepted parameter %f for light",i)
00823
00824
00825 color = ColorRGBA()
00826 color.r = param[0]
00827 color.g = param[1]
00828 color.b = param[2]
00829 color.a = param[3]
00830 return 0, color
00831
00832 def set_light(self,component_name,parameter_name,blocking=False):
00833 ah = action_handle("set_light", component_name, parameter_name, blocking, self.parse)
00834 if(self.parse):
00835 return ah
00836 else:
00837 ah.set_active()
00838 rospy.loginfo("Set <<%s>> to <<%s>>", component_name, parameter_name)
00839
00840 mode = LightMode()
00841 mode.mode = LightModes.STATIC
00842 color = ColorRGBA()
00843 (error,color) = self.compose_color(component_name, parameter_name)
00844 if error != 0:
00845 message = "Composing the color failed with error: " + str(error)
00846 ah.set_failed(error, message)
00847 return ah
00848 mode.colors = []
00849 mode.colors.append(color)
00850
00851
00852 action_server_name = component_name + "/set_light"
00853 rospy.logdebug("calling %s action server",action_server_name)
00854 client = actionlib.SimpleActionClient(action_server_name, SetLightModeAction)
00855
00856 rospy.logdebug("waiting for %s action server to start",action_server_name)
00857 if not client.wait_for_server(rospy.Duration(1)):
00858
00859 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
00860 rospy.logerr(message)
00861 ah.set_failed(4, message)
00862 return ah
00863 else:
00864 rospy.logdebug("%s action server ready",action_server_name)
00865
00866
00867 goal = SetLightModeGoal()
00868 goal.mode = mode
00869 client.send_goal(goal)
00870 ah.set_client(client)
00871 ah.wait_inside()
00872 return ah
00873
00874
00875
00876
00877
00878
00879
00880
00881 def set_mimic(self,component_name,parameter_name,blocking=False):
00882 ah = action_handle("set_mimic", component_name, parameter_name, blocking, self.parse)
00883 if(self.parse):
00884 return ah
00885 else:
00886 ah.set_active()
00887 rospy.loginfo("Set <<%s>> to <<%s>>", component_name, parameter_name)
00888
00889
00890 mimic = SetMimicGoal()
00891 if not (type(parameter_name) is str or type(parameter_name) is list):
00892 message = "No valid parameter for mimic: not a string or list, aborting..."
00893 rospy.logerr(message)
00894 print "parameter is:",parameter_name
00895 ah.set_failed(3, message)
00896 return ah
00897
00898 if type(parameter_name) is str:
00899 mimic.mimic = parameter_name
00900 elif type(parameter_name) is list:
00901 if len(parameter_name) != 3:
00902 message = "No valid parameter for mimic: not a list with size 3, aborting..."
00903 rospy.logerr(message)
00904 print "parameter is:",parameter_name
00905 ah.set_failed(3, message)
00906 return ah
00907 if ((type(parameter_name[0]) is str) and (type(parameter_name[1]) is float or type(parameter_name[1]) is int) and (type(parameter_name[2]) is float or type(parameter_name[2]) is int)):
00908 mimic.mimic = parameter_name[0]
00909 mimic.speed = parameter_name[1]
00910 mimic.repeat = parameter_name[2]
00911 else:
00912 message = "No valid parameter for mimic: not a list with [mode, speed, repeat], aborting..."
00913 rospy.logerr(message)
00914 print "parameter is:",parameter_name
00915 ah.set_failed(3, message)
00916 return ah
00917 else:
00918 rospy.logerr("you should never be here")
00919 rospy.logdebug("accepted parameter %s for mimic",parameter_name)
00920
00921
00922 action_server_name = component_name + "/set_mimic"
00923 rospy.logdebug("calling %s action server",action_server_name)
00924 client = actionlib.SimpleActionClient(action_server_name, SetMimicAction)
00925
00926 rospy.logdebug("waiting for %s action server to start",action_server_name)
00927 if not client.wait_for_server(rospy.Duration(1)):
00928
00929 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
00930 rospy.logerr(message)
00931 ah.set_failed(4, message)
00932 return ah
00933 else:
00934 rospy.logdebug("%s action server ready",action_server_name)
00935
00936
00937 client.send_goal(mimic)
00938 ah.set_client(client)
00939 ah.wait_inside()
00940 return ah
00941
00942
00943
00944
00945
00946
00947
00948
00949 def say(self,component_name,parameter_name,blocking=True):
00950 ah = action_handle("say", component_name, parameter_name, blocking, self.parse)
00951 if(self.parse):
00952 return ah
00953 else:
00954 ah.set_active()
00955
00956 text = ""
00957
00958 language = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/language","en")
00959 if type(parameter_name) is str:
00960 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + language + "/" + parameter_name
00961 if not rospy.has_param(full_parameter_name):
00962 message = "Parameter " + full_parameter_name + " does not exist on ROS Parameter Server, aborting..."
00963 rospy.logerr(message)
00964 ah.set_failed(2, message)
00965 return ah
00966 param = rospy.get_param(full_parameter_name)
00967 else:
00968 param = parameter_name
00969
00970
00971 if not type(param) is list:
00972 message = "No valid parameter for " + component_name + ": not a list, aborting..."
00973 rospy.logerr(message)
00974 print "parameter is:",param
00975 ah.set_failed(3, message)
00976 return ah
00977 else:
00978 for i in param:
00979
00980 if not type(i) is str:
00981 message = "No valid parameter for " + component_name + ": not a list of strings, aborting..."
00982 rospy.logerr(message)
00983 print "parameter is:",param
00984 ah.set_failed(3, message)
00985 return ah
00986 else:
00987 text = text + i + " "
00988 rospy.logdebug("accepted parameter <<%s>> for <<%s>>",i,component_name)
00989 rospy.loginfo("Saying <<%s>>",text)
00990
00991
00992 action_server_name = component_name + "/say"
00993 rospy.logdebug("calling %s action server",action_server_name)
00994 client = actionlib.SimpleActionClient(action_server_name, SayAction)
00995
00996 rospy.logdebug("waiting for %s action server to start",action_server_name)
00997 if not client.wait_for_server(rospy.Duration(1)):
00998
00999 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
01000 rospy.logerr(message)
01001 ah.set_failed(4, message)
01002 return ah
01003 else:
01004 rospy.logdebug("%s action server ready",action_server_name)
01005
01006
01007 client_goal = SayGoal()
01008 client_goal.text = text
01009
01010 client.send_goal(client_goal)
01011 ah.set_client(client)
01012 ah.wait_inside()
01013 return ah
01014
01015
01016
01017
01018
01019 def play(self,component_name, parameter_name,blocking=True):
01020 ah = action_handle("play", component_name, parameter_name, False, self.parse)
01021 if(self.parse):
01022 return ah
01023 else:
01024 ah.set_active()
01025
01026 if not (type(parameter_name) is str or type(parameter_name) is list):
01027 message = "No valid parameter for play: not a string or list, aborting..."
01028 rospy.logerr(message)
01029 print "parameter is:",parameter_name
01030 ah.set_failed(3, message)
01031 return ah
01032
01033 if type(parameter_name) is str:
01034 full_parameter_name = self.ns_global_prefix + "/" + component_name + "/" + "audio_file_path"
01035 if not rospy.has_param(full_parameter_name):
01036 message = "Parameter " + full_parameter_name + " does not exist on ROS Parameter Server, aborting..."
01037 rospy.logerr(message)
01038 ah.set_failed(2, message)
01039 return ah
01040 filename = rospy.get_param(full_parameter_name) + "/" + parameter_name + ".wav"
01041 elif type(parameter_name) is list:
01042 if len(parameter_name) != 3:
01043 message = "No valid parameter for play: not a list with size 3, aborting..."
01044 rospy.logerr(message)
01045 print "parameter is:",parameter_name
01046 ah.set_failed(3, message)
01047 return ah
01048 if ((type(parameter_name[0]) is str) and (type(parameter_name[1]) is str) and (type(parameter_name[2]) is str)):
01049 filename = parameter_name[1] + "/" + parameter_name[0] + "." + parameter_name[2]
01050 else:
01051 message = "No valid parameter for play: not a list with [filename, file_path, file_suffix], aborting..."
01052 rospy.logerr(message)
01053 print "parameter is:",parameter_name
01054 ah.set_failed(3, message)
01055 return ah
01056 else:
01057 rospy.logerr("you should never be here")
01058 rospy.logdebug("accepted parameter %s for play",parameter_name)
01059
01060 action_server_name = component_name + "/play"
01061 rospy.logdebug("calling %s action server",action_server_name)
01062 client = actionlib.SimpleActionClient(action_server_name, PlayAction)
01063
01064 rospy.logdebug("waiting for %s action server to start",action_server_name)
01065 if not client.wait_for_server(rospy.Duration(1)):
01066
01067 message = "ActionServer " + action_server_name + " not ready within timeout, aborting..."
01068 rospy.logerr(message)
01069 ah.set_failed(4, message)
01070 return ah
01071 else:
01072 rospy.logdebug("%s action server ready",action_server_name)
01073
01074
01075 rospy.loginfo("Playing <<%s>>",filename)
01076 client_goal = PlayGoal()
01077 client_goal.filename = filename
01078
01079 client.send_goal(client_goal)
01080 ah.set_client(client)
01081 ah.wait_inside()
01082 ah.set_succeeded()
01083 return ah
01084
01085 def set_wav_path(self,parameter_name,blocking=True):
01086 if type(parameter_name) is str:
01087 self.wav_path = parameter_name
01088 else:
01089 message = "Invalid wav_path parameter specified, aborting..."
01090 rospy.logerr(message)
01091 print "parameter is:", parameter_name
01092 ah.set_failed(2, message)
01093 return ah
01094
01095
01096
01097
01098
01099
01100 def sleep(self,duration):
01101 ah = action_handle("sleep", "", str(duration), True, self.parse)
01102 if(self.parse):
01103 return ah
01104 else:
01105 ah.set_active()
01106 rospy.loginfo("Wait for %f sec",duration)
01107 rospy.sleep(duration)
01108 ah.set_succeeded()
01109 return ah
01110
01111
01112
01113
01114
01115
01116
01117
01118 def wait_for_input(self,duration=0):
01119 ah = action_handle("wait", "input", str(duration), True, self.parse)
01120 if(self.parse):
01121 return ah
01122 else:
01123 ah.set_active()
01124
01125 if (duration != 0):
01126 rospy.logerr("Wait with duration not implemented yet")
01127
01128 rospy.loginfo("Wait for user input...")
01129 retVal = raw_input()
01130 rospy.loginfo("...got string <<%s>>",retVal)
01131 ah.set_succeeded()
01132 return retVal
01133
01134
01135
01136
01137
01138 class action_handle:
01139
01140 def __init__(self, function_name, component_name, parameter_name, blocking, parse):
01141 global graph
01142 self.parent_node = ""
01143 self.error_code = -1
01144 self.success = False
01145 self.message = ""
01146 self.function_name = function_name
01147 self.component_name = component_name
01148 self.parameter_name = parameter_name
01149 self.state = ScriptState.UNKNOWN
01150 self.blocking = blocking
01151 self.parse = parse
01152 self.level = int(rospy.get_param("/script_server/level",100))
01153 self.state_pub = rospy.Publisher("/script_server/state", ScriptState, queue_size=1)
01154 self.AppendNode(blocking)
01155 self.client = None
01156 self.client_state = 9
01157 self.client_mode = ""
01158
01159
01160 def set_client(self,client):
01161 self.client = client
01162
01163
01164 def set_active(self,mode=""):
01165 if mode != "":
01166 self.client_mode = mode
01167 self.client_state = 1
01168 self.check_pause()
01169 self.state = ScriptState.ACTIVE
01170 self.error_code = -1
01171 self.PublishState()
01172
01173 global ah_counter
01174 ah_counter += 1
01175
01176
01177 def check_pause(self):
01178 param_string = "/script_server/pause"
01179 while bool(rospy.get_param(param_string,False)):
01180 rospy.logwarn("Script is paused...")
01181 self.state = ScriptState.PAUSED
01182 self.PublishState()
01183 rospy.sleep(1)
01184 if self.state == ScriptState.PAUSED:
01185 rospy.loginfo("...continuing script")
01186
01187
01188 def set_succeeded(self,message=""):
01189 if self.client_mode != "":
01190 self.client_state = 3
01191 self.state = ScriptState.SUCCEEDED
01192 self.error_code = 0
01193 self.success = True
01194 self.message = message
01195 self.PublishState()
01196
01197 global ah_counter
01198 ah_counter -= 1
01199
01200
01201 def set_failed(self,error_code,message=""):
01202 if self.client_mode != "":
01203 self.client_state = 4
01204 self.state = ScriptState.FAILED
01205 self.error_code = error_code
01206 self.success = False
01207 self.message = message
01208 self.PublishState()
01209
01210 global ah_counter
01211 ah_counter -= 1
01212
01213
01214 def get_state(self):
01215 if self.client_mode != "":
01216 return self.client_state
01217 elif self.client == None:
01218 return None
01219 else:
01220 return self.client.get_state()
01221
01222
01223 def get_error_code(self):
01224 return self.error_code
01225
01226
01227 def GetGraphstring(self):
01228 if type(self.parameter_name) is types.StringType:
01229 graphstring = str(datetime.datetime.utcnow())+"_"+self.function_name+"_"+self.component_name+"_"+self.parameter_name
01230 else:
01231 graphstring = str(datetime.datetime.utcnow())+"_"+self.function_name+"_"+self.component_name
01232 return graphstring
01233
01234
01235 def GetLevel(self,function_name):
01236 if (function_name == "move"):
01237 level = 0
01238 elif (function_name == "init"):
01239 level = 1
01240 elif (function_name == "stop"):
01241 level = 1
01242 elif (function_name == "sleep"):
01243 level = 2
01244 else:
01245 level = 100
01246 return level
01247
01248
01249 def AppendNode(self, blocking=True):
01250 global graph
01251 global graph_wait_list
01252 global last_node
01253 graphstring = self.GetGraphstring()
01254 if self.parse:
01255 if ( self.level >= self.GetLevel(self.function_name)):
01256
01257 graph.add_edge(last_node, graphstring)
01258 for waiter in graph_wait_list:
01259 graph.add_edge(waiter, graphstring)
01260 graph_wait_list=[]
01261 if blocking:
01262 last_node = graphstring
01263 else:
01264 self.parent_node = graphstring
01265
01266
01267
01268
01269
01270
01271 def PublishState(self):
01272 script_state = ScriptState()
01273 script_state.header.stamp = rospy.Time.now()
01274 script_state.function_name = self.function_name
01275 script_state.component_name = self.component_name
01276 script_state.full_graph_name = self.GetGraphstring()
01277 if ( type(self.parameter_name) is str ):
01278 script_state.parameter_name = self.parameter_name
01279 else:
01280 script_state.parameter_name = ""
01281 script_state.state = self.state
01282 script_state.error_code = self.error_code
01283 self.state_pub.publish(script_state)
01284
01285
01286
01287
01288
01289
01290 def wait(self, duration=None):
01291 global ah_counter
01292 ah_counter += 1
01293 self.blocking = True
01294 self.wait_for_finished(duration,True)
01295
01296
01297
01298
01299
01300
01301 def wait_inside(self, duration=None):
01302 if self.blocking:
01303 self.wait_for_finished(duration,True)
01304 else:
01305 thread.start_new_thread(self.wait_for_finished,(duration,False,))
01306 return self.error_code
01307
01308
01309
01310
01311
01312
01313
01314 def wait_for_finished(self, duration, logging):
01315 global graph_wait_list
01316 if(self.parse):
01317 if(self.parent_node != ""):
01318 graph_wait_list.append(self.parent_node)
01319 return
01320
01321 if self.error_code <= 0:
01322 if duration is None:
01323 if logging:
01324 rospy.loginfo("Wait for <<%s>> reaching <<%s>>...",self.component_name, self.parameter_name)
01325 self.client.wait_for_result()
01326 else:
01327 if logging:
01328 rospy.loginfo("Wait for <<%s>> reached <<%s>> (max %f secs)...",self.component_name, self.parameter_name,duration)
01329 if not self.client.wait_for_result(rospy.Duration(duration)):
01330 message = "Timeout while waiting for <<%s>> to reach <<%s>>. Continuing..."%(self.component_name, self.parameter_name)
01331 if logging:
01332 rospy.logerr(message)
01333 self.set_failed(10, message)
01334 return
01335
01336
01337 if self.client.get_state() != 3:
01338 message = "...<<%s>> could not reach <<%s>>, aborting..."%(self.component_name, self.parameter_name)
01339 if logging:
01340 rospy.logerr(message)
01341 self.set_failed(11, message)
01342 return
01343 if logging:
01344 rospy.loginfo("...<<%s>> reached <<%s>>",self.component_name, self.parameter_name)
01345 else:
01346 message = "Execution of <<%s>> to <<%s>> was aborted, wait not possible. Continuing..."%(self.component_name, self.parameter_name)
01347 rospy.logwarn(message)
01348 self.set_failed(self.error_code, message)
01349 return
01350
01351 self.set_succeeded()
01352
01353
01354
01355
01356 def cancel(self):
01357 self.client.cancel_all_goals()