simple_script_server.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 #################################################################
00003 ##\file
00004 #
00005 # \note
00006 #   Copyright (c) 2010 \n
00007 #   Fraunhofer Institute for Manufacturing Engineering
00008 #   and Automation (IPA) \n\n
00009 #
00010 #################################################################
00011 #
00012 # \note
00013 #   Project name: care-o-bot
00014 # \note
00015 #   ROS stack name: cob_command_tools
00016 # \note
00017 #   ROS package name: cob_script_server
00018 #
00019 # \author
00020 #   Author: Florian Weisshardt, email:florian.weisshardt@ipa.fhg.de
00021 # \author
00022 #   Supervised by: Florian Weisshardt, email:florian.weisshardt@ipa.fhg.de
00023 #
00024 # \date Date of creation: Aug 2010
00025 #
00026 # \brief
00027 #   Implements script server functionalities.
00028 #
00029 #################################################################
00030 #
00031 # Redistribution and use in source and binary forms, with or without
00032 # modification, are permitted provided that the following conditions are met:
00033 #
00034 #     - Redistributions of source code must retain the above copyright
00035 #       notice, this list of conditions and the following disclaimer. \n
00036 #     - Redistributions in binary form must reproduce the above copyright
00037 #       notice, this list of conditions and the following disclaimer in the
00038 #       documentation and/or other materials provided with the distribution. \n
00039 #     - Neither the name of the Fraunhofer Institute for Manufacturing
00040 #       Engineering and Automation (IPA) nor the names of its
00041 #       contributors may be used to endorse or promote products derived from
00042 #       this software without specific prior written permission. \n
00043 #
00044 # This program is free software: you can redistribute it and/or modify
00045 # it under the terms of the GNU Lesser General Public License LGPL as 
00046 # published by the Free Software Foundation, either version 3 of the 
00047 # License, or (at your option) any later version.
00048 # 
00049 # This program is distributed in the hope that it will be useful,
00050 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00051 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00052 # GNU Lesser General Public License LGPL for more details.
00053 # 
00054 # You should have received a copy of the GNU Lesser General Public 
00055 # License LGPL along with this program. 
00056 # If not, see <http://www.gnu.org/licenses/>.
00057 #
00058 #################################################################
00059 
00060 import time
00061 import os
00062 import sys
00063 import types
00064 import thread
00065 import commands
00066 import math
00067 
00068 # ROS imports
00069 import roslib
00070 roslib.load_manifest('cob_script_server')
00071 import rospy
00072 import actionlib
00073 
00074 # msg imports
00075 from trajectory_msgs.msg import *
00076 from geometry_msgs.msg import *
00077 #from pr2_controllers_msgs.msg import * #replaced by control_msgs.msg (FollowJointTrajectoryAction)
00078 from move_base_msgs.msg import *
00079 from arm_navigation_msgs.msg import *
00080 from arm_navigation_msgs.srv import *
00081 from tf.transformations import *
00082 from std_msgs.msg import String,ColorRGBA
00083 from kinematics_msgs.srv import *
00084 from control_msgs.msg import *
00085 
00086 # care-o-bot includes
00087 from cob_sound.msg import *
00088 from cob_script_server.msg import *
00089 from cob_srvs.srv import *
00090 
00091 # graph includes
00092 import pygraphviz as pgv
00093 
00094 graph=""
00095 graph_wait_list=[]
00096 function_counter = 0
00097 ah_counter = 0
00098 graph = pgv.AGraph()
00099 graph.node_attr['shape']='box'
00100 last_node = "Start"
00101 
00102 ## Script class from which all script inherit.
00103 #
00104 # Implements basic functionalities for all scripts.
00105 class script():
00106         def __init__(self):
00107                 # use filename as nodename
00108                 filename = os.path.basename(sys.argv[0])
00109                 self.basename, extension = os.path.splitext(filename)
00110                 rospy.init_node(self.basename)
00111                 self.graph_pub = rospy.Publisher("/script_server/graph", String)
00112 
00113         ## Dummy function for initialization
00114         def Initialize(self):
00115                 pass
00116 
00117         ## Dummy function for main run function
00118         def Run(self):
00119                 pass
00120 
00121         ## Function to start the script
00122         #
00123         # First does a simulated turn and then calls Initialize() and Run().
00124         def Start(self):
00125                 self.Parse()
00126                 global ah_counter
00127                 ah_counter = 0
00128                 self.sss = simple_script_server()
00129                 rospy.loginfo("Starting <<%s>> script...",self.basename)
00130                 self.Initialize()
00131                 self.Run()
00132                 # wait until last threaded action finishes
00133                 rospy.loginfo("Wait for script to finish...")
00134                 while ah_counter != 0:
00135                         rospy.sleep(1)
00136                 rospy.loginfo("...script finished.")
00137         
00138         ## Function to generate graph view of script.
00139         #
00140         # Starts the script in simulation mode and calls Initialize() and Run().
00141         def Parse(self):
00142                 rospy.loginfo("Start parsing...")
00143                 global graph
00144                 global function_counter
00145                 function_counter = 0
00146                 # run script in simulation mode
00147                 self.sss = simple_script_server(parse=True)
00148                 self.Initialize()
00149                 self.Run()
00150                 
00151                 # save graph on parameter server for further processing
00152 #               self.graph = graph
00153                 rospy.set_param("/script_server/graph", graph.string())
00154                 self.graph_pub.publish(graph.string())
00155                 rospy.loginfo("...parsing finished")
00156                 function_counter = 0
00157                 return graph.string()
00158 
00159 ## Simple script server class.
00160 #
00161 # Implements the python interface for the script server.
00162 class simple_script_server:
00163         ## Initializes simple_script_server class.
00164         #
00165         # \param parse Defines wether to run script in simulation for graph generation or not
00166         def __init__(self, parse=False):
00167                 global graph
00168                 self.ns_global_prefix = "/script_server"
00169                 self.wav_path = ""
00170                 self.parse = parse
00171                 
00172                 # init publishers
00173                 self.pub_light = rospy.Publisher('/light_controller/command', ColorRGBA)
00174                 
00175                 rospy.sleep(1) # we have to wait here until publishers are ready, don't ask why
00176 
00177     #------------------- Init section -------------------#
00178         ## Initializes different components.
00179         #
00180         # Based on the component, the corresponding init service will be called.
00181         #
00182         # \param component_name Name of the component.
00183         def init(self,component_name,blocking=True):
00184                 return self.trigger(component_name,"init",blocking=blocking)
00185 
00186         ## Stops different components.
00187         #
00188         # Based on the component, the corresponding stop service will be called.
00189         #
00190         # \param component_name Name of the component.
00191         def stop(self,component_name,mode="omni",blocking=True):
00192                 #return self.trigger(component_name,"stop",blocking=blocking)
00193                 if component_name == "base":
00194                         ah = action_handle("stop", component_name, "", False, self.parse)
00195                         if(self.parse):
00196                                 return ah
00197                         else:
00198                                 ah.set_active(mode="service")
00199         
00200                         rospy.loginfo("<<stop>> <<%s>>", component_name)
00201         
00202                         # call action server
00203                         if(mode == None or mode == ""):
00204                                 action_server_name = "/move_base"
00205                         elif(mode == "omni"):
00206                                 action_server_name = "/move_base"
00207                         elif(mode == "diff"):
00208                                 action_server_name = "/move_base_diff"
00209                         elif(mode == "linear"):
00210                                 action_server_name = "/move_base_linear"
00211                         else:
00212                                 rospy.logerr("no valid navigation mode given for %s, aborting...",component_name)
00213                                 print "navigation mode is:",mode
00214                                 ah.set_failed(33)
00215                                 return ah
00216 
00217                         rospy.logdebug("calling %s action server",action_server_name)
00218                         client = actionlib.SimpleActionClient(action_server_name, MoveBaseAction)
00219                         
00220                         if blocking:
00221                                 # trying to connect to server
00222                                 rospy.logdebug("waiting for %s action server to start",action_server_name)
00223                                 if not client.wait_for_server(rospy.Duration(5)):
00224                                         # error: server did not respond
00225                                         rospy.logerr("%s action server not ready within timeout, aborting...", action_server_name)
00226                                         ah.set_failed(4)
00227                                         return ah
00228                                 else:
00229                                         rospy.logdebug("%s action server ready",action_server_name)
00230 
00231                         # cancel all goals
00232                         client.cancel_all_goals()
00233                         
00234                         ah.set_succeeded() # full success
00235                         return ah       
00236                 else:
00237                         return self.trigger(component_name,"stop",blocking=blocking)
00238 
00239         ## Recovers different components.
00240         #
00241         # Based on the component, the corresponding recover service will be called.
00242         #
00243         # \param component_name Name of the component.
00244         def recover(self,component_name,blocking=True):
00245                 return self.trigger(component_name,"recover",blocking=blocking)
00246 
00247         ## Deals with all kind of trigger services for different components.
00248         #
00249         # Based on the component and service name, the corresponding trigger service will be called.
00250         #
00251         # \param component_name Name of the component.
00252         # \param service_name Name of the trigger service.
00253         # \param blocking Service calls are always blocking. The parameter is only provided for compatibility with other functions.
00254         def trigger(self,component_name,service_name,blocking=True, planning=False):
00255                 ah = action_handle(service_name, component_name, "", blocking, self.parse)
00256                 if(self.parse):
00257                         return ah
00258                 else:
00259                         ah.set_active(mode="service")
00260 
00261                 rospy.loginfo("<<%s>> <<%s>>", service_name, component_name)
00262                 service_full_name = "/" + component_name + "_controller/" + service_name
00263                 
00264                 if blocking:
00265                         # check if service is available
00266                         try:
00267                                 rospy.wait_for_service(service_full_name,rospy.get_param('server_timeout',3))
00268                         except rospy.ROSException, e:
00269                                 error_message = "%s"%e
00270                                 rospy.logerr("...<<%s>> service of <<%s>> not available, error: %s",service_name, component_name, error_message)
00271                                 ah.set_failed(4)
00272                                 return ah
00273 
00274                 # check if service is callable
00275                 try:
00276                         init = rospy.ServiceProxy(service_full_name,Trigger)
00277                         #print init()
00278                         #resp = init()
00279                         if blocking:
00280                                 rospy.loginfo("Wait for <<%s>> to <<%s>>...", component_name, service_name)
00281                                 resp = init()
00282                         else:
00283                                 thread.start_new_thread(init,())
00284                 except rospy.ServiceException, e:
00285                         error_message = "%s"%e
00286                         rospy.logerr("...calling <<%s>> service of <<%s>> not successfull, error: %s",service_name, component_name, error_message)
00287                         ah.set_failed(10)
00288                         return ah
00289 
00290                 if blocking:
00291                         # evaluate sevice response
00292                         if not resp.success.data:
00293                                 rospy.logerr("...<<%s>> <<%s>> not successfull, error: %s",service_name, component_name, resp.error_message.data) 
00294                                 ah.set_failed(10)
00295                                 return ah
00296                 
00297                         # full success
00298                         rospy.loginfo("...<<%s>> is <<%s>>", component_name, service_name)
00299                         ah.set_succeeded() # full success
00300                 return ah
00301 
00302 #------------------- Move section -------------------#
00303         ## Deals with all kind of movements for different components.
00304         #
00305         # Based on the component, the corresponding move functions will be called.
00306         #
00307         # \param component_name Name of the component.
00308         # \param parameter_name Name of the parameter on the ROS parameter server.
00309         # \param blocking Bool value to specify blocking behaviour.
00310         def move(self,component_name,parameter_name,blocking=True, mode=None):
00311                 if component_name == "base":
00312                         return self.move_base(component_name,parameter_name,blocking, mode)
00313                 elif component_name == "arm" and mode=="planned":
00314                         return self.move_planned(component_name,parameter_name,blocking)
00315                 else:
00316                         return self.move_traj(component_name,parameter_name,blocking)
00317 
00318         ## Deals with movements of the base.
00319         #
00320         # A target will be sent to the actionlib interface of the move_base node.
00321         #
00322         # \param component_name Name of the component.
00323         # \param parameter_name Name of the parameter on the ROS parameter server.
00324         # \param blocking Bool value to specify blocking behaviour.
00325         def move_base(self,component_name,parameter_name,blocking, mode):
00326                 ah = action_handle("move", component_name, parameter_name, blocking, self.parse)
00327                 if(self.parse):
00328                         return ah
00329                 else:
00330                         ah.set_active()
00331                 
00332                 if(mode == None or mode == ""):
00333                         rospy.loginfo("Move <<%s>> to <<%s>>",component_name,parameter_name)
00334                 else:
00335                         rospy.loginfo("Move <<%s>> to <<%s>> using <<%s>> mode",component_name,parameter_name,mode)
00336                 
00337                 # get joint values from parameter server
00338                 if type(parameter_name) is str:
00339                         if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name):
00340                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00341                                 ah.set_failed(2)
00342                                 return ah
00343                         param = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00344                 else:
00345                         param = parameter_name
00346                 
00347                 # check trajectory parameters
00348                 if not type(param) is list: # check outer list
00349                                 rospy.logerr("no valid parameter for %s: not a list, aborting...",component_name)
00350                                 print "parameter is:",param
00351                                 ah.set_failed(3)
00352                                 return ah
00353                 else:
00354                         #print i,"type1 = ", type(i)
00355                         DOF = 3
00356                         if not len(param) == DOF: # check dimension
00357                                 rospy.logerr("no valid parameter for %s: dimension should be %d and is %d, aborting...",component_name,DOF,len(param))
00358                                 print "parameter is:",param
00359                                 ah.set_failed(3)
00360                                 return ah
00361                         else:
00362                                 for i in param:
00363                                         #print i,"type2 = ", type(i)
00364                                         if not ((type(i) is float) or (type(i) is int)): # check type
00365                                                 #print type(i)
00366                                                 rospy.logerr("no valid parameter for %s: not a list of float or int, aborting...",component_name)
00367                                                 print "parameter is:",param
00368                                                 ah.set_failed(3)
00369                                                 return ah
00370                                         else:
00371                                                 rospy.logdebug("accepted parameter %f for %s",i,component_name)
00372 
00373                 # convert to pose message
00374                 pose = PoseStamped()
00375                 pose.header.stamp = rospy.Time.now()
00376                 pose.header.frame_id = "/map"
00377                 pose.pose.position.x = param[0]
00378                 pose.pose.position.y = param[1]
00379                 pose.pose.position.z = 0.0
00380                 q = quaternion_from_euler(0, 0, param[2])
00381                 pose.pose.orientation.x = q[0]
00382                 pose.pose.orientation.y = q[1]
00383                 pose.pose.orientation.z = q[2]
00384                 pose.pose.orientation.w = q[3]
00385                 
00386                 # call action server
00387                 if(mode == None or mode == ""):
00388                         action_server_name = "/move_base"
00389                 elif(mode == "omni"):
00390                         action_server_name = "/move_base"
00391                 elif(mode == "diff"):
00392                         action_server_name = "/move_base_diff"
00393                 elif(mode == "linear"):
00394                         action_server_name = "/move_base_linear"
00395                 else:
00396                         rospy.logerr("no valid navigation mode given for %s, aborting...",component_name)
00397                         print "navigation mode is:",mode
00398                         ah.set_failed(33)
00399                         return ah
00400                 
00401                 rospy.logdebug("calling %s action server",action_server_name)
00402                 client = actionlib.SimpleActionClient(action_server_name, MoveBaseAction)
00403                 # trying to connect to server
00404                 rospy.logdebug("waiting for %s action server to start",action_server_name)
00405                 if not client.wait_for_server(rospy.Duration(5)):
00406                         # error: server did not respond
00407                         rospy.logerr("%s action server not ready within timeout, aborting...", action_server_name)
00408                         ah.set_failed(4)
00409                         return ah
00410                 else:
00411                         rospy.logdebug("%s action server ready",action_server_name)
00412 
00413                 # sending goal
00414                 client_goal = MoveBaseGoal()
00415                 client_goal.target_pose = pose
00416                 #print client_goal
00417                 client.send_goal(client_goal)
00418                 ah.set_client(client)
00419 
00420                 ah.wait_inside()
00421 
00422                 return ah
00423 
00424         ## Deals with all kind of trajectory movements for different components.
00425         #
00426         # A trajectory will be sent to the actionlib interface of the corresponding component.
00427         #
00428         # \param component_name Name of the component.
00429         # \param parameter_name Name of the parameter on the ROS parameter server.
00430         # \param blocking Bool value to specify blocking behaviour.
00431         def move_traj(self,component_name,parameter_name,blocking):
00432                 ah = action_handle("move", component_name, parameter_name, blocking, self.parse)
00433                 if(self.parse):
00434                         return ah
00435                 else:
00436                         ah.set_active()
00437                 
00438                 rospy.loginfo("Move <<%s>> to <<%s>>",component_name,parameter_name)
00439                 
00440                 # get joint_names from parameter server
00441                 param_string = self.ns_global_prefix + "/" + component_name + "/joint_names"
00442                 if not rospy.has_param(param_string):
00443                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",param_string)
00444                                 ah.set_failed(2)
00445                                 return ah
00446                 joint_names = rospy.get_param(param_string)
00447                 
00448                 # check joint_names parameter
00449                 if not type(joint_names) is list: # check list
00450                                 rospy.logerr("no valid joint_names for %s: not a list, aborting...",component_name)
00451                                 print "joint_names are:",joint_names
00452                                 ah.set_failed(3)
00453                                 return ah
00454                 else:
00455                         for i in joint_names:
00456                                 #print i,"type1 = ", type(i)
00457                                 if not type(i) is str: # check string
00458                                         rospy.logerr("no valid joint_names for %s: not a list of strings, aborting...",component_name)
00459                                         print "joint_names are:",param
00460                                         ah.set_failed(3)
00461                                         return ah
00462                                 else:
00463                                         rospy.logdebug("accepted joint_names for component %s",component_name)
00464                 
00465                 # get joint values from parameter server
00466                 if type(parameter_name) is str:
00467                         if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name):
00468                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00469                                 ah.set_failed(2)
00470                                 return ah
00471                         param = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00472                 else:
00473                         param = parameter_name
00474 
00475                 # check trajectory parameters
00476                 if not type(param) is list: # check outer list
00477                                 rospy.logerr("no valid parameter for %s: not a list, aborting...",component_name)
00478                                 print "parameter is:",param
00479                                 ah.set_failed(3)
00480                                 return ah
00481 
00482                 traj = []
00483 
00484                 for point in param:
00485                         #print point,"type1 = ", type(point)
00486                         if type(point) is str:
00487                                 if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + point):
00488                                         rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + point)
00489                                         ah.set_failed(2)
00490                                         return ah
00491                                 point = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + point)
00492                                 point = point[0] # \todo TODO: hack because only first point is used, no support for trajectories inside trajectories
00493                                 #print point
00494                         elif type(point) is list:
00495                                 rospy.logdebug("point is a list")
00496                         else:
00497                                 rospy.logerr("no valid parameter for %s: not a list of lists or strings, aborting...",component_name)
00498                                 print "parameter is:",param
00499                                 ah.set_failed(3)
00500                                 return ah
00501 
00502                         # here: point should be list of floats/ints
00503                         #print point
00504                         if not len(point) == len(joint_names): # check dimension
00505                                 rospy.logerr("no valid parameter for %s: dimension should be %d and is %d, aborting...",component_name,len(joint_names),len(point))
00506                                 print "parameter is:",param
00507                                 ah.set_failed(3)
00508                                 return ah
00509 
00510                         for value in point:
00511                                 #print value,"type2 = ", type(value)
00512                                 if not ((type(value) is float) or (type(value) is int)): # check type
00513                                         #print type(value)
00514                                         rospy.logerr("no valid parameter for %s: not a list of float or int, aborting...",component_name)
00515                                         print "parameter is:",param
00516                                         ah.set_failed(3)
00517                                         return ah
00518                         
00519                                 rospy.logdebug("accepted value %f for %s",value,component_name)
00520                         traj.append(point)
00521 
00522                 rospy.logdebug("accepted trajectory for %s",component_name)
00523                 
00524                 # convert to ROS trajectory message
00525                 traj_msg = JointTrajectory()
00526                 traj_msg.header.stamp = rospy.Time.now()+rospy.Duration(0.5)
00527                 traj_msg.joint_names = joint_names
00528                 point_nr = 0
00529                 for point in traj:
00530                         point_nr = point_nr + 1
00531                         point_msg = JointTrajectoryPoint()
00532                         point_msg.positions = point
00533                         point_msg.velocities = [0]*len(joint_names)
00534                         point_msg.time_from_start=rospy.Duration(3*point_nr) # this value is set to 3 sec per point. \todo TODO: read from parameter
00535                         traj_msg.points.append(point_msg)
00536 
00537                 # call action server
00538                 action_server_name = "/" + component_name + '_controller/follow_joint_trajectory'
00539                 rospy.logdebug("calling %s action server",action_server_name)
00540                 client = actionlib.SimpleActionClient(action_server_name, FollowJointTrajectoryAction)
00541                 # trying to connect to server
00542                 rospy.logdebug("waiting for %s action server to start",action_server_name)
00543                 if not client.wait_for_server(rospy.Duration(5)):
00544                         # error: server did not respond
00545                         rospy.logerr("%s action server not ready within timeout, aborting...", action_server_name)
00546                         ah.set_failed(4)
00547                         return ah
00548                 else:
00549                         rospy.logdebug("%s action server ready",action_server_name)
00550                 
00551                 # set operation mode to position
00552                 #if not component_name == "arm":
00553                 #       self.set_operation_mode(component_name,"position")
00554                 #self.set_operation_mode(component_name,"position")             
00555 
00556                 # sending goal
00557                 client_goal = FollowJointTrajectoryGoal()
00558                 client_goal.trajectory = traj_msg
00559                 #print client_goal
00560                 client.send_goal(client_goal)
00561                 ah.set_client(client)
00562 
00563                 ah.wait_inside()
00564                 return ah
00565                 
00566         def move_planned(self, component_name, parameter_name, blocking=True): # for backward compatibility
00567                 return self.move_joint_goal_planned(component_name, parameter_name, blocking)
00568         
00569         def move_joint_goal_planned(self, component_name, parameter_name, blocking=True):
00570                 ah = action_handle("move_joint_goal_planned", component_name, parameter_name, blocking, self.parse)
00571                 if(self.parse):
00572                         return ah
00573                 else:
00574                         ah.set_active()
00575                 
00576                 if component_name != "arm":
00577                         rospy.logerr("Only arm component is supported in move_joint_goal_planned.")
00578                         ah.set_failed(4)
00579                         return ah
00580                         
00581                 rospy.loginfo("Move planned <<%s>> to <<%s>>",component_name,parameter_name)
00582                 
00583                 # get joint_names from parameter server
00584                 param_string = self.ns_global_prefix + "/" + component_name + "/joint_names"
00585                 if not rospy.has_param(param_string):
00586                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",param_string)
00587                                 ah.set_failed(2)
00588                                 return ah
00589                 joint_names = rospy.get_param(param_string)
00590                 
00591                 # check joint_names parameter
00592                 if not type(joint_names) is list: # check list
00593                                 rospy.logerr("no valid joint_names for %s: not a list, aborting...",component_name)
00594                                 print "joint_names are:",joint_names
00595                                 ah.set_failed(3)
00596                                 return ah
00597                 else:
00598                         for i in joint_names:
00599                                 #print i,"type1 = ", type(i)
00600                                 if not type(i) is str: # check string
00601                                         rospy.logerr("no valid joint_names for %s: not a list of strings, aborting...",component_name)
00602                                         print "joint_names are:",param
00603                                         ah.set_failed(3)
00604                                         return ah
00605                                 else:
00606                                         rospy.logdebug("accepted joint_names for component %s",component_name)
00607                 
00608                 # get joint values from parameter server
00609                 if type(parameter_name) is str:
00610                         if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name):
00611                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00612                                 ah.set_failed(2)
00613                                 return ah
00614                         param = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + parameter_name)
00615                 else:
00616                         param = parameter_name
00617 
00618                 # check trajectory parameters
00619                 if not type(param) is list: # check outer list
00620                                 rospy.logerr("no valid parameter for %s: not a list, aborting...",component_name)
00621                                 print "parameter is:",param
00622                                 ah.set_failed(3)
00623                                 return ah
00624 
00625                 traj = []
00626 
00627                 for point in param:
00628                         #print point,"type1 = ", type(point)
00629                         if type(point) is str:
00630                                 if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + point):
00631                                         rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + point)
00632                                         ah.set_failed(2)
00633                                         return ah
00634                                 point = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + point)
00635                                 point = point[0] # \todo TODO: hack because only first point is used, no support for trajectories inside trajectories
00636                                 #print point
00637                         elif type(point) is list:
00638                                 rospy.logdebug("point is a list")
00639                         else:
00640                                 rospy.logerr("no valid parameter for %s: not a list of lists or strings, aborting...",component_name)
00641                                 print "parameter is:",param
00642                                 ah.set_failed(3)
00643                                 return ah
00644 
00645                         # here: point should be list of floats/ints
00646                         #print point
00647                         if not len(point) == len(joint_names): # check dimension
00648                                 rospy.logerr("no valid parameter for %s: dimension should be %d and is %d, aborting...",component_name,len(joint_names),len(point))
00649                                 print "parameter is:",param
00650                                 ah.set_failed(3)
00651                                 return ah
00652 
00653                         for value in point:
00654                                 #print value,"type2 = ", type(value)
00655                                 if not ((type(value) is float) or (type(value) is int)): # check type
00656                                         #print type(value)
00657                                         rospy.logerr("no valid parameter for %s: not a list of float or int, aborting...",component_name)
00658                                         print "parameter is:",param
00659                                         ah.set_failed(3)
00660                                         return ah
00661                         
00662                                 rospy.logdebug("accepted value %f for %s",value,component_name)
00663                         traj.append(point)
00664 
00665                 rospy.logdebug("accepted trajectory for %s",component_name)
00666 
00667                 goal_constraints = Constraints() #arm_navigation_msgs/Constraints
00668                 goal_constraints.joint_constraints=[]
00669                 
00670                 for i in range(len(joint_names)):
00671                         new_constraint = JointConstraint()
00672                         new_constraint.joint_name = joint_names[i]
00673                         new_constraint.position = 0.0
00674                         new_constraint.tolerance_below = 0.4
00675                         new_constraint.tolerance_above = 0.4
00676                         goal_constraints.joint_constraints.append(new_constraint)
00677                 #no need for trajectories anymore, since planning (will) guarantee collision-free motion!
00678                 traj_endpoint = traj[len(traj)-1]
00679                 for k in range(len(traj_endpoint)):
00680                         #print "traj_endpoint[%d]: %f", k, traj_endpoint[k]
00681                         goal_constraints.joint_constraints[k].position = traj_endpoint[k]
00682 
00683                 return self.move_constrained_planned(component_name, goal_constraints, blocking, ah)
00684 
00685 
00686         def move_constrained_planned(self, component_name, parameter_name, blocking=True, ah=None):
00687                 if ah is None:
00688                         ah = action_handle("move_constrained_planned", component_name, "constraint_goal", blocking, self.parse)
00689                         if(self.parse):
00690                                 return ah
00691                         else:
00692                                 ah.set_active()
00693                         
00694                 if component_name != "arm":
00695                         rospy.logerr("Only arm component is supported in move_constrained_planned.")
00696                         ah.set_failed(4)
00697                         return ah
00698                 
00699                 # convert to ROS Move arm message
00700                 motion_plan = MotionPlanRequest()
00701                 motion_plan.group_name = component_name
00702                 motion_plan.num_planning_attempts = 1
00703                 motion_plan.allowed_planning_time = rospy.Duration(50.0)
00704 
00705                 motion_plan.planner_id= ""
00706                 motion_plan.goal_constraints = parameter_name
00707 
00708                 # call action server
00709                 action_server_name = "/move_"+component_name
00710                 rospy.logdebug("calling %s action server",action_server_name)
00711                 client = actionlib.SimpleActionClient(action_server_name, MoveArmAction)
00712                 # trying to connect to server
00713                 rospy.logdebug("waiting for %s action server to start",action_server_name)
00714                 if not client.wait_for_server(rospy.Duration(5)):
00715                         # error: server did not respond
00716                         rospy.logerr("%s action server not ready within timeout, aborting...", action_server_name)
00717                         ah.set_failed(4)
00718                         return ah
00719                 else:
00720                         rospy.logdebug("%s action server ready",action_server_name)
00721                 
00722                 # set operation mode to position
00723                 #self.set_operation_mode(component_name,"position")
00724                 
00725                 # sending goal
00726                 client_goal = MoveArmGoal()
00727                 client_goal.planner_service_name = "ompl_planning/plan_kinematic_path"          #choose planner
00728                 #client_goal.planner_service_name = "cob_prmce_planner/plan_kinematic_path"
00729                 client_goal.motion_plan_request = motion_plan
00730                 #print client_goal
00731                 client.send_goal(client_goal)
00732                 ah.set_client(client)
00733 
00734                 ah.wait_inside()
00735                 return ah
00736         ## Relative movement of the base
00737         #
00738         # \param component_name Name of component; here always "base".
00739         # \param parameter_name List of length 3: (item 1 & 2) relative x and y translation [m]; (item 3) relative rotation about z axis [rad].
00740         # \param blocking Bool value to specify blocking behaviour.
00741         # 
00742         # # throws error code 3 in case of invalid parameter_name vector 
00743         def move_base_rel(self, component_name, parameter_name=[0,0,0], blocking=True): 
00744                 ah = action_handle("move_base_rel", component_name, parameter_name, blocking, self.parse)
00745                 if(self.parse):
00746                         return ah
00747                 else:
00748                         ah.set_active(mode="topic")
00749 
00750                 rospy.loginfo("Move base relatively by <<%s>>", parameter_name)
00751 
00752                 # step 0: check validity of parameters:
00753                 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)):
00754                         rospy.logerr("Non-numeric parameter_name list, aborting move_base_rel")
00755                         print("parameter_name must be numeric list of length 3; (relative x and y transl [m], relative rotation [rad])")
00756                         ah.set_failed(3)
00757                         return ah
00758                 if math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) >= 0.15:
00759                         rospy.logerr("Maximal relative translation step exceeded, aborting move_base_rel")
00760                         print("Maximal relative translation step is 0.1 m")
00761                         ah.set_failed(3)
00762                         return(ah)
00763                 if abs(parameter_name[2]) >= math.pi/2:
00764                         rospy.logerr("Maximal relative rotation step exceeded, aborting move_base_rel")
00765                         print("Maximal relative rotation step is pi/2")
00766                         ah.set_failed(3)
00767                         return(ah)
00768 
00769                 # step 1: determine duration of motion so that upper thresholds for both translational as well as rotational velocity are not exceeded
00770                 max_trans_vel = 0.05 # [m/s]
00771                 max_rot_vel = 0.2 # [rad/s]
00772                 duration_trans_sec = math.sqrt(parameter_name[0]**2 + parameter_name[1]**2) / max_trans_vel
00773                 duration_rot_sec = abs(parameter_name[2] / max_rot_vel)
00774                 duration_sec = max(duration_trans_sec, duration_rot_sec)
00775                 duration_ros = rospy.Duration.from_sec(duration_sec) # duration of motion in ROS time
00776 
00777                 # step 2: determine actual velocities based on calculated duration
00778                 x_vel = parameter_name[0] / duration_sec
00779                 y_vel = parameter_name[1] / duration_sec
00780                 rot_vel = parameter_name[2] / duration_sec
00781 
00782                 # step 3: send constant velocity command to base_controller for the calculated duration of motion
00783                 pub = rospy.Publisher('/base_controller/command_safe', Twist)  # todo: use Matthias G.'s safe_command
00784                 twist = Twist()
00785                 twist.linear.x = x_vel
00786                 twist.linear.y = y_vel
00787                 twist.angular.z = rot_vel
00788                 r = rospy.Rate(10) # send velocity commands at 10 Hz
00789                 end_time = rospy.Time.now() + duration_ros
00790                 while not rospy.is_shutdown() and rospy.Time.now() < end_time:
00791                         pub.publish(twist)
00792                         r.sleep()
00793 
00794                 ah.set_succeeded()
00795                 return ah
00796 
00797         
00798         ## Set the operation mode for different components.
00799         #
00800         # Based on the component, the corresponding set_operation_mode service will be called.
00801         #
00802         # \param component_name Name of the component.
00803         # \param mode Name of the operation mode to set.
00804         # \param blocking Service calls are always blocking. The parameter is only provided for compatibility with other functions.
00805         def set_operation_mode(self,component_name,mode,blocking=True, planning=False):
00806                 #rospy.loginfo("setting <<%s>> to operation mode <<%s>>",component_name, mode)
00807                 rospy.set_param("/" + component_name + "_controller/OperationMode",mode) # \todo TODO: remove and only use service call
00808                 #rospy.wait_for_service("/" + component_name + "_controller/set_operation_mode")
00809                 try:
00810                         set_operation_mode = rospy.ServiceProxy("/" + component_name + "_controller/set_operation_mode", SetOperationMode)
00811                         req = SetOperationModeRequest()
00812                         req.operation_mode.data = mode
00813                         #print req
00814                         resp = set_operation_mode(req)
00815                         #print resp
00816                 except rospy.ServiceException, e:
00817                         print "Service call failed: %s"%e
00818                 
00819 #------------------- LED section -------------------#
00820         ## Set the color of the cob_light component.
00821         #
00822         # The color is given by a parameter on the parameter server.
00823         #
00824         # \param parameter_name Name of the parameter on the parameter server which holds the rgb values.
00825         def set_light(self,parameter_name,blocking=False):
00826                 ah = action_handle("set", "light", parameter_name, blocking, self.parse)
00827                 if(self.parse):
00828                         return ah
00829                 else:
00830                         ah.set_active(mode="topic")
00831 
00832                 rospy.loginfo("Set light to <<%s>>",parameter_name)
00833                 
00834                 # get joint values from parameter server
00835                 if type(parameter_name) is str:
00836                         if not rospy.has_param(self.ns_global_prefix + "/light/" + parameter_name):
00837                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/light/" + parameter_name)
00838                                 return 2
00839                         param = rospy.get_param(self.ns_global_prefix + "/light/" + parameter_name)
00840                 else:
00841                         param = parameter_name
00842                         
00843                 # check color parameters
00844                 if not type(param) is list: # check outer list
00845                         rospy.logerr("no valid parameter for light: not a list, aborting...")
00846                         print "parameter is:",param
00847                         ah.error_code = 3
00848                         return ah
00849                 else:
00850                         if not len(param) == 3: # check dimension
00851                                 rospy.logerr("no valid parameter for light: dimension should be 3 (r,g,b) and is %d, aborting...",len(param))
00852                                 print "parameter is:",param
00853                                 ah.error_code = 3
00854                                 return ah
00855                         else:
00856                                 for i in param:
00857                                         #print i,"type1 = ", type(i)
00858                                         if not ((type(i) is float) or (type(i) is int)): # check type
00859                                                 #print type(i)
00860                                                 rospy.logerr("no valid parameter for light: not a list of float or int, aborting...")
00861                                                 print "parameter is:",param
00862                                                 ah.error_code = 3
00863                                                 return ah
00864                                         else:
00865                                                 rospy.logdebug("accepted parameter %f for light",i)
00866                 
00867                 # convert to ColorRGBA message
00868                 color = ColorRGBA()
00869                 color.r = param[0]
00870                 color.g = param[1]
00871                 color.b = param[2]
00872                 color.a = 1 # Transparency
00873 
00874                 # publish color         
00875                 self.pub_light.publish(color)
00876                 
00877                 ah.set_succeeded()
00878                 ah.error_code = 0
00879                 return ah
00880 
00881 #-------------------- Sound section --------------------#
00882         ## Say some text.
00883         #
00884         # The text to say may be given by a list of strings or a single string which points to a parameter on the ROS parameter server.
00885         #
00886         # \param parameter_name Name of the parameter
00887         # \param language Language to use for the TTS system
00888         def say(self,parameter_name,blocking=True):
00889                 component_name = "sound"
00890                 ah = action_handle("say", component_name, parameter_name, blocking, self.parse)
00891                 if(self.parse):
00892                         return ah
00893                 else:
00894                         ah.set_active()
00895                         
00896                 text = ""
00897                 
00898                 # get values from parameter server
00899                 language = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/language","en")
00900                 if type(parameter_name) is str:
00901                         if not rospy.has_param(self.ns_global_prefix + "/" + component_name + "/" + language + "/" + parameter_name):
00902                                 rospy.logerr("parameter %s does not exist on ROS Parameter Server, aborting...",self.ns_global_prefix + "/" + component_name + "/" + language + "/" + parameter_name)
00903                                 ah.set_failed(2)
00904                                 return ah
00905                         param = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/" + language + "/" + parameter_name)
00906                 else:
00907                         param = parameter_name
00908                 
00909                 # check parameters
00910                 if not type(param) is list: # check list
00911                                 rospy.logerr("no valid parameter for %s: not a list, aborting...",component_name)
00912                                 print "parameter is:",param
00913                                 ah.set_failed(3)
00914                                 return ah
00915                 else:
00916                         for i in param:
00917                                 #print i,"type1 = ", type(i)
00918                                 if not type(i) is str:
00919                                         rospy.logerr("no valid parameter for %s: not a list of strings, aborting...",component_name)
00920                                         print "parameter is:",param
00921                                         ah.set_failed(3)
00922                                         return ah
00923                                 else:
00924                                         text = text + i + " "
00925                                         rospy.logdebug("accepted parameter <<%s>> for <<%s>>",i,component_name)
00926 
00927                 rospy.loginfo("Saying <<%s>>",text)
00928                 
00929                 # call action server
00930                 action_server_name = "/sound_controller/say"
00931                 rospy.logdebug("calling %s action server",action_server_name)
00932                 client = actionlib.SimpleActionClient(action_server_name, SayAction)
00933                 # trying to connect to server
00934                 rospy.logdebug("waiting for %s action server to start",action_server_name)
00935                 if not client.wait_for_server(rospy.Duration(5)):
00936                         # error: server did not respond
00937                         rospy.logerr("%s action server not ready within timeout, aborting...", action_server_name)
00938                         ah.set_failed(4)
00939                         return ah
00940                 else:
00941                         rospy.logdebug("%s action server ready",action_server_name)
00942 
00943                 # sending goal
00944                 client_goal = SayGoal()
00945                 client_goal.text.data = text
00946                 #print client_goal
00947                 client.send_goal(client_goal)
00948                 ah.set_client(client)
00949 
00950                 ah.wait_inside()
00951                 return ah
00952 
00953         ## Play a sound file.
00954         #
00955         # \param parameter_name Name of the parameter
00956         # \param language Language to use
00957         def play(self,parameter_name,blocking=True):
00958                 component_name = "sound"
00959                 ah = action_handle("play", component_name, parameter_name, False, self.parse)
00960                 if(self.parse):
00961                         return ah
00962                 else:
00963                         ah.set_active(mode="system")
00964                 
00965                 language = rospy.get_param(self.ns_global_prefix + "/" + component_name + "/language","en")
00966                 if self.wav_path == "":
00967                         wav_path = commands.getoutput("rospack find cob_script_server")
00968                 else:
00969                         wav_path = self.wav_path
00970                 filename = wav_path + "/common/files/" + language + "/" + parameter_name + ".wav"
00971                 
00972                 rospy.loginfo("Playing <<%s>>",filename)
00973                 #self.soundhandle.playWave(filename)
00974                 
00975                 #\todo TODO: check if file exists
00976                 # if filename exists:
00977                 #       do ...
00978                 # else 
00979                 #       ah.set_fail(3)
00980                 #       return ah
00981                 
00982                 if blocking:
00983                         ret = os.system("aplay -q " + filename)
00984                         if ret != 0:
00985                                 ah.set_failed(99)
00986                                 return ah
00987                 else:
00988                         os.system("aplay -q " + filename + "&") # TODO how to check if execution failed (e.g. file could be found)?
00989                 ah.set_succeeded()
00990                 return ah
00991                 
00992         def set_wav_path(self,parameter_name,blocking=True):
00993                 if type(parameter_name) is str:
00994                         self.wav_path = parameter_name
00995                 else:
00996                         rospy.logerr("invalid wav_path parameter specified, aborting...")
00997                         print "parameter is:", parameter_name
00998                         ah.set_failed(2)
00999                         return ah               
01000 
01001 #------------------- General section -------------------#
01002         ## Sleep for a certain time.
01003         #
01004         # \param duration Duration in seconds to sleep.
01005         #
01006         def sleep(self,duration):
01007                 ah = action_handle("sleep", "", str(duration), True, self.parse)
01008                 if(self.parse):
01009                         return ah
01010                 else:
01011                         ah.set_active()
01012                 rospy.loginfo("Wait for %f sec",duration)
01013                 rospy.sleep(duration)
01014                 
01015                 ah.set_succeeded()
01016                 return ah
01017 
01018         ## Waits for user input.
01019         #
01020         # Waits either for a user input or until timeout is reached.
01021         #
01022         # \param duration Duration in seconds for timeout.
01023         # 
01024         # \todo TODO: implement waiting for timeout
01025         def wait_for_input(self,duration=0):
01026                 ah = action_handle("wait", "input", str(duration), True, self.parse)
01027                 if(self.parse):
01028                         return ah
01029                 else:
01030                         ah.set_active()
01031                 
01032                 if (duration != 0):
01033                         rospy.logerr("Wait with duration not implemented yet") # \todo TODO: implement waiting with duration
01034                 
01035                 rospy.loginfo("Wait for user input...")
01036                 retVal = raw_input()
01037                 rospy.loginfo("...got string <<%s>>",retVal)
01038                 ah.set_succeeded()
01039                 return retVal
01040 
01041 #------------------- action_handle section -------------------# 
01042 ## Action handle class.
01043 #
01044 # The action handle is used to implement asynchronous behaviour within the script.
01045 class action_handle:
01046         ## Initializes the action handle.
01047         def __init__(self, function_name, component_name, parameter_name, blocking, parse):
01048                 global graph
01049                 global function_counter
01050                 self.parent_node = ""
01051                 self.error_code = -1
01052                 self.wait_log = False
01053                 self.function_counter = function_counter
01054                 self.function_name = function_name
01055                 self.component_name = component_name
01056                 self.parameter_name = parameter_name
01057                 self.state = ScriptState.UNKNOWN
01058                 self.blocking = blocking
01059                 self.parse = parse
01060                 self.level = int(rospy.get_param("/script_server/level",100))
01061                 self.state_pub = rospy.Publisher("/script_server/state", ScriptState)
01062                 self.AppendNode(blocking)
01063                 self.client = actionlib.SimpleActionClient("dummy",ScriptAction)
01064                 self.client_state = 9
01065                 self.client_mode = ""
01066 
01067         ## Sets the actionlib client.
01068         def set_client(self,client):
01069                 self.client = client
01070 
01071         ## Sets the execution state to active, if not paused
01072         def set_active(self,mode=""):
01073                 if mode != "": # not processing an actionlib client
01074                         self.client_mode = mode
01075                         self.client_state = 1
01076                 self.check_pause()
01077                 self.state = ScriptState.ACTIVE
01078                 self.error_code = -1
01079                 self.PublishState()
01080                 
01081                 global ah_counter
01082                 ah_counter += 1
01083                 
01084         ## Checks for pause
01085         def check_pause(self):
01086                 param_string = "/script_server/pause"
01087                 while bool(rospy.get_param(param_string,False)):
01088                         rospy.logwarn("Script is paused...")
01089                         self.state = ScriptState.PAUSED
01090                         self.PublishState()
01091                         rospy.sleep(1)
01092                 if self.state == ScriptState.PAUSED:
01093                         rospy.loginfo("...continuing script")
01094                 
01095         ## Sets the execution state to succeeded.
01096         def set_succeeded(self):
01097                 if self.client_mode != "": # not processing an actionlib client
01098                         self.client_state = 3
01099                 self.state = ScriptState.SUCCEEDED
01100                 self.error_code = 0
01101                 self.PublishState()
01102                 
01103                 global ah_counter
01104                 ah_counter -= 1
01105                 
01106         ## Sets the execution state to failed.
01107         def set_failed(self,error_code):
01108                 if self.client_mode != "": # not processing an actionlib client
01109                         self.client_state = 4
01110                 self.state = ScriptState.FAILED
01111                 self.error_code = error_code
01112                 self.PublishState()
01113 
01114                 global ah_counter
01115                 ah_counter -= 1
01116                 
01117         ## Gets the state of an action handle.
01118         def get_state(self):
01119                 if self.client_mode != "": # not processing an actionlib client
01120                         return self.client_state
01121                 else:
01122                         return self.client.get_state()
01123 
01124         ## Gets the error code of an action handle.
01125         def get_error_code(self):
01126                 return self.error_code
01127         
01128         ## Returns the graphstring.
01129         def GetGraphstring(self):
01130                 if type(self.parameter_name) is types.StringType:
01131                         graphstring = str(self.function_counter)+"_"+self.function_name+"_"+self.component_name+"_"+self.parameter_name
01132                 else:
01133                         graphstring = str(self.function_counter)+"_"+self.function_name+"_"+self.component_name
01134                 return graphstring
01135 
01136         ## Gets level of function name.
01137         def GetLevel(self,function_name):
01138                 if (function_name == "move"):
01139                         level = 0
01140                 elif (function_name == "init"):
01141                         level = 1
01142                 elif (function_name == "stop"):
01143                         level = 1
01144                 elif (function_name == "sleep"):
01145                         level = 2
01146                 else:
01147                         level = 100
01148                 return level
01149                 
01150         ## Appends a registered function to the graph.
01151         def AppendNode(self, blocking=True):
01152                 global graph
01153                 global graph_wait_list
01154                 global function_counter
01155                 global last_node
01156                 graphstring = self.GetGraphstring()
01157                 if self.parse:
01158                         if ( self.level >= self.GetLevel(self.function_name)):
01159                                 #print "adding " + graphstring + " to graph"
01160                                 graph.add_edge(last_node, graphstring)
01161                                 for waiter in graph_wait_list:
01162                                         graph.add_edge(waiter, graphstring)
01163                                 graph_wait_list=[]
01164                                 if blocking:
01165                                         last_node = graphstring
01166                                 else:
01167                                         self.parent_node = graphstring
01168                         #else:
01169                                 #print "not adding " + graphstring + " to graph"
01170                 #else:
01171                         #self.PublishState()
01172                 function_counter += 1
01173                 
01174         ## Publishs the state of the action handle
01175         def PublishState(self):
01176                 script_state = ScriptState()
01177                 script_state.header.stamp = rospy.Time.now()
01178                 script_state.number = self.function_counter
01179                 script_state.function_name = self.function_name
01180                 script_state.component_name = self.component_name
01181                 script_state.full_graph_name = self.GetGraphstring()
01182                 if ( type(self.parameter_name) is str ):
01183                         script_state.parameter_name = self.parameter_name
01184                 else:
01185                         script_state.parameter_name = ""
01186                 script_state.state = self.state
01187                 script_state.error_code = self.error_code
01188                 self.state_pub.publish(script_state)
01189                 
01190         ## Handles wait.
01191         #
01192         # This function is meant to be uses directly in the script.
01193         #
01194         # \param duration Duration for timeout.
01195         def wait(self, duration=None):
01196                 global ah_counter
01197                 ah_counter += 1
01198                 self.blocking = True
01199                 self.wait_for_finished(duration,True)
01200 
01201         ## Handles inside wait.
01202         #
01203         # This function is meant to be uses inside the simple_script_server.
01204         #
01205         # \param duration Duration for timeout.
01206         def wait_inside(self, duration=None):
01207                 if self.blocking:
01208                         self.wait_for_finished(duration,True)
01209                 else:
01210                         thread.start_new_thread(self.wait_for_finished,(duration,False,))
01211                 return self.error_code
01212         
01213         ## Waits for the action to be finished.
01214         #
01215         # If duration is specified, waits until action is finished or timeout is reached.
01216         #
01217         # \param duration Duration for timeout.
01218         # \param logging Enables or disables logging for this wait.
01219         def wait_for_finished(self, duration, logging):
01220                 global graph_wait_list
01221                 if(self.parse):
01222                         if(self.parent_node != ""):
01223                                 graph_wait_list.append(self.parent_node)
01224                         return
01225 
01226                 if self.error_code <= 0:                        
01227                         if duration is None:
01228                                 if logging:
01229                                         rospy.loginfo("Wait for <<%s>> reaching <<%s>>...",self.component_name, self.parameter_name)
01230                                 self.client.wait_for_result()
01231                         else:
01232                                 if logging:
01233                                         rospy.loginfo("Wait for <<%s>> reached <<%s>> (max %f secs)...",self.component_name, self.parameter_name,duration)
01234                                 if not self.client.wait_for_result(rospy.Duration(duration)):
01235                                         if logging:
01236                                                 rospy.logerr("Timeout while waiting for <<%s>> to reach <<%s>>. Continuing...",self.component_name, self.parameter_name)
01237                                         self.set_failed(10)
01238                                         return
01239                         # check state of action server
01240                         #print self.client.get_state()
01241                         if self.client.get_state() != 3:
01242                                 if logging:
01243                                         rospy.logerr("...<<%s>> could not reach <<%s>>, aborting...",self.component_name, self.parameter_name)
01244                                 self.set_failed(11)
01245                                 return
01246 
01247                         if logging:
01248                                 rospy.loginfo("...<<%s>> reached <<%s>>",self.component_name, self.parameter_name)
01249                 else:
01250                         rospy.logwarn("Execution of <<%s>> to <<%s>> was aborted, wait not possible. Continuing...",self.component_name, self.parameter_name)
01251                         self.set_failed(self.error_code)
01252                         return
01253                         
01254                 self.set_succeeded() # full success
01255         
01256         ## Cancel action
01257         #
01258         # Cancels action goal(s).
01259         def cancel(self):
01260                 self.client.cancel_all_goals()


cob_script_server
Author(s): Florian Weisshardt
autogenerated on Sun Oct 5 2014 22:59:42