def action_client(self, cb_data): # Execute ROS Action rospy.init_node('ActionClient') # Unpack action client data name, goals, handle = cb_data rospy.loginfo('Launched %s Action CLient' % name) # Creates the SimpleActionClient, passing the type of the action (MaterialLoadAction) to the constructor. # i.e. name = 'MaterialLoad', action_type = mtconnect_msgs.msg.MaterialLoadAction action_type = getattr(handle, name + 'Action') client = actionlib.SimpleActionClient(name + 'Client', action_type) # Waits until the action server has started up and started listening for goals. rospy.loginfo('Waiting for %s Dedicated Action Server' % name) client.wait_for_server() rospy.loginfo('%s Dedicated Action Server Activated' % name) # Creates a MaterialLoad goal to send to the action server. # i.e. goal = mtconnect_msgs.msg.MaterialLoad() goal_handle = getattr(handle, name + 'Goal') goal = goal_handle() # Check to make sure the action goal has been set if self.action_goals[name] == None: # Ping the current url for the goal Event goal_tag = self.action_list[name].keys()[0] response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/current?path=//DataItem[@type='" + goal_tag.upper() +"']")) body = response.read() root = ElementTree.fromstring(body) # Set the action goals self.action_goals = bridge_library.set_goal(name, self.action_list[name], root, self.ns, self.action_goals) # Check goal source for required attributes for attrib, attrib_type, action_goal in zip(goal_handle.__slots__, goal_handle._slot_types, self.action_goals[name]): if bridge_library.type_check(attrib_type, action_goal) == False: rospy.logerr('INCOMPATIBLE GOAL TYPES ROS MSG: %s --> XML: %s' % (attrib_type, type(action_goal))) sys.exit() # Set the goal attributes from XML data try: for attrib, xml_goal in zip(goal_handle.__slots__, self.action_goals[name]): setattr(goal, attrib, xml_goal) except Exception as e: rospy.logerr("ROS Action %s Client failed: %s" % (name, e)) # Sends the goal to the action server. rospy.loginfo('Sending the goal') name_conv = bridge_library.split_event(name) client.send_goal(goal, done_cb = None, active_cb = bridge_library.action_cb((self.adapter, self.di_dict, name_conv, 'ACTIVE'))) # Waits for the server to finish performing the action. rospy.loginfo('Waiting for result') client.wait_for_result() # Obtain result state result = client.get_state() # Prints out the result of the executing action rospy.loginfo('Returning the result --> %s' % result) # Set the Robot XML data item data_item = bridge_library.split_event(name) # Submit converted result to host via MTConnect adapter if result == 3: # SUCCEEDED from actionlib_msgs.msg.GoalStatus rospy.loginfo('Sending COMPLETE flag') bridge_library.action_cb((self.adapter, self.di_dict, data_item, 'COMPLETE')) return name elif result == 4: # ABORTED from actionlib_msgs.msg.GoalStatus rospy.loginfo('%s ABORTED, terminating action request' % data_item) bridge_library.action_cb((self.adapter, self.di_dict, data_item, 'FAIL')) return None
def __init__(self): # Initialize ROS generic client node rospy.init_node('ActionClient') # Setup MTConnect to ROS Conversion self.config = bridge_library.obtain_dataMap() self.msg_parameters = ['url', 'url_port', 'machine_tool', 'xml_namespace', 'adapter_port', 'service'] self.url = self.config[self.msg_parameters[0]] self.url_port = self.config[self.msg_parameters[1]] self.mtool = self.config[self.msg_parameters[2]] self.ns = dict(m = self.config[self.msg_parameters[3]]) self.port = self.config[self.msg_parameters[4]] self.service = self.config[self.msg_parameters[5]] # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1,self.url,self.url_port)) # Setup MTConnect Adapter for robot status data items self.adapter = Adapter((self.url, self.port)) # Create empty lists for actions, message type handles, etc. self.lib_manifests = [] self.type_handle = None self.action_list = {} self.action_goals = {} self.package = None self.xml_goal = None self.di_dict = {} # XML data item dictionary to store MTConnect Adapter Events self.handshake = None # Setup action client data per the config file self.setup_topic_data() # Add data items to the MTConnect Adapter - must be unique data items bridge_library.add_event((self.adapter, self.action_list, self.di_dict, False)) # Start the adapter rospy.loginfo('Start the Robot Link adapter') self.adapter.start() # Create robot Service Server thread for each machine tool action self.action_service = [] for mt_action in self.action_goals.keys(): self.action_service.append(ActionService(mt_action, self.adapter, self.di_dict, self.service_handle, self.service)) # Establish XML connection, read in current XML while True: try: self.conn = HTTPConnection(self.url, self.url_port) response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/current")) body = response.read() break except socket.error as e: rospy.loginfo('HTTP connection error %s' % e) time.sleep(10) # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(body, self.ns, self.action_list) # Start a streaming XML connection response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/sample?interval=1000&count=1000&from=" + seq)) # Create class lock self.lock = thread.allocate_lock() # Create XML polling thread lp = LongPull(response) lp.long_pull(self.xml_callback) # Runs until user interrupts
def __init__(self): # Initialize ROS generic client node rospy.init_node('ActionClient') # Setup MTConnect to ROS Conversion self.config = bridge_library.obtain_dataMap() self.msg_parameters = [ 'url', 'url_port', 'machine_tool', 'xml_namespace', 'adapter_port', 'service' ] self.url = self.config[self.msg_parameters[0]] self.url_port = self.config[self.msg_parameters[1]] self.mtool = self.config[self.msg_parameters[2]] self.ns = dict(m=self.config[self.msg_parameters[3]]) self.port = self.config[self.msg_parameters[4]] self.service = self.config[self.msg_parameters[5]] # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1, self.url, self.url_port)) # Setup MTConnect Adapter for robot status data items self.adapter = Adapter((self.url, self.port)) # Create empty lists for actions, message type handles, etc. self.lib_manifests = [] self.type_handle = None self.action_list = {} self.action_goals = {} self.package = None self.xml_goal = None self.di_dict = { } # XML data item dictionary to store MTConnect Adapter Events self.handshake = None # Setup action client data per the config file self.setup_topic_data() # Add data items to the MTConnect Adapter - must be unique data items bridge_library.add_event( (self.adapter, self.action_list, self.di_dict, False)) # Start the adapter rospy.loginfo('Start the Robot Link adapter') self.adapter.start() # Create robot Service Server thread for each machine tool action self.action_service = [] for mt_action in self.action_goals.keys(): self.action_service.append( ActionService(mt_action, self.adapter, self.di_dict, self.service_handle, self.service)) # Establish XML connection, read in current XML while True: try: self.conn = HTTPConnection(self.url, self.url_port) response = bridge_library.xml_get_response( (self.url, self.url_port, self.port, self.conn, self.mtool + "/current")) body = response.read() break except socket.error as e: rospy.loginfo('HTTP connection error %s' % e) time.sleep(10) # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(body, self.ns, self.action_list) # Start a streaming XML connection response = bridge_library.xml_get_response( (self.url, self.url_port, self.port, self.conn, self.mtool + "/sample?interval=1000&count=1000&from=" + seq)) # Create class lock self.lock = thread.allocate_lock() # Create XML polling thread lp = LongPull(response) lp.long_pull(self.xml_callback) # Runs until user interrupts
def __init__(self): # Initialize the ROS publisher node rospy.init_node('bridge_publisher') # Setup MTConnect to ROS Conversion self.config = bridge_library.obtain_dataMap() self.msg_parameters = ['url', 'url_port', 'machine_tool', 'xml_namespace'] self.url = self.config[self.msg_parameters[0]] self.url_port = self.config[self.msg_parameters[1]] self.mtool = self.config[self.msg_parameters[2]] self.ns = dict(m = self.config[self.msg_parameters[3]]) # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1,self.url,self.url_port)) # Create the data lists for the topic names, types, manifests, data items, ROS publishers, and ROS messages self.topic_name_list = [] self.topic_type_list = [] self.lib_manifests = [] self.data_items = [] self.pub = [] self.msg = [] self.data_hold = None # Setup topic, data items, pub, etc. via configuration file self.setup_topic_data() # Hash table of persistent CNC event states, only updates when state changes self.di_current = self.init_di_dict() # Hash table to store changed CNC event states self.di_changed = None # Establish XML connection, read in current XML while True: try: self.conn = HTTPConnection(self.url, self.url_port) response = bridge_library.xml_get_response((self.url, self.url_port, None, self.conn, self.mtool + "/current")) body = response.read() break except socket.error as e: rospy.loginfo('HTTP connection error %s' % e) time.sleep(10) # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(body, self.ns, self.di_current) # Use XML to establish current data item state dictionary for di in self.di_current.keys(): name = bridge_library.split_event(di) for e in elements: rospy.loginfo('Element %s --> %s' % (e.tag, e.text)) if name == e.attrib['name']: self.di_current[di] = e.text # Confirm that data items in config file are present in XML for di_set in self.data_items: if not set(di_set).issubset(set(self.di_current.keys())): rospy.logerr('ERROR: INCORRECT EVENTS IN TOPIC CONFIG OR XML AGENT FILE') sys.exit() # Start a streaming XML connection response = bridge_library.xml_get_response((self.url, self.url_port, None, self.conn, self.mtool + "/sample?interval=1000&count=1000&from=" + seq)) # Create queue for streaming XML self.XML_queue = Queue() # Create a ROS publishing thread self.ros_publisher() # Streams data from the agent... lp = LongPull(response) lp.long_pull(self.xml_callback) # Runs until user interrupts
def action_client(self, cb_data): # Execute ROS Action rospy.init_node('ActionClient') # Unpack action client data name, goals, handle = cb_data rospy.loginfo('Launched %s Action CLient' % name) # Creates the SimpleActionClient, passing the type of the action (MaterialLoadAction) to the constructor. # i.e. name = 'MaterialLoad', action_type = mtconnect_msgs.msg.MaterialLoadAction action_type = getattr(handle, name + 'Action') client = actionlib.SimpleActionClient(name + 'Client', action_type) # Waits until the action server has started up and started listening for goals. rospy.loginfo('Waiting for %s Dedicated Action Server' % name) client.wait_for_server() rospy.loginfo('%s Dedicated Action Server Activated' % name) # Creates a MaterialLoad goal to send to the action server. # i.e. goal = mtconnect_msgs.msg.MaterialLoad() goal_handle = getattr(handle, name + 'Goal') goal = goal_handle() # Check to make sure the action goal has been set if self.action_goals[name] == None: # Ping the current url for the goal Event goal_tag = self.action_list[name].keys()[0] response = bridge_library.xml_get_response( (self.url, self.url_port, self.port, self.conn, self.mtool + "/current?path=//DataItem[@type='" + goal_tag.upper() + "']")) body = response.read() root = ElementTree.fromstring(body) # Set the action goals self.action_goals = bridge_library.set_goal( name, self.action_list[name], root, self.ns, self.action_goals) # Check goal source for required attributes for attrib, attrib_type, action_goal in zip(goal_handle.__slots__, goal_handle._slot_types, self.action_goals[name]): if bridge_library.type_check(attrib_type, action_goal) == False: rospy.logerr( 'INCOMPATIBLE GOAL TYPES ROS MSG: %s --> XML: %s' % (attrib_type, type(action_goal))) sys.exit() # Set the goal attributes from XML data try: for attrib, xml_goal in zip(goal_handle.__slots__, self.action_goals[name]): setattr(goal, attrib, xml_goal) except Exception as e: rospy.logerr("ROS Action %s Client failed: %s" % (name, e)) # Sends the goal to the action server. rospy.loginfo('Sending the goal') name_conv = bridge_library.split_event(name) client.send_goal(goal, done_cb=None, active_cb=bridge_library.action_cb( (self.adapter, self.di_dict, name_conv, 'ACTIVE'))) # Waits for the server to finish performing the action. rospy.loginfo('Waiting for result') client.wait_for_result() # Obtain result state result = client.get_state() # Prints out the result of the executing action rospy.loginfo('Returning the result --> %s' % result) # Set the Robot XML data item data_item = bridge_library.split_event(name) # Submit converted result to host via MTConnect adapter if result == 3: # SUCCEEDED from actionlib_msgs.msg.GoalStatus rospy.loginfo('Sending COMPLETE flag') bridge_library.action_cb( (self.adapter, self.di_dict, data_item, 'COMPLETE')) return name elif result == 4: # ABORTED from actionlib_msgs.msg.GoalStatus rospy.loginfo('%s ABORTED, terminating action request' % data_item) bridge_library.action_cb( (self.adapter, self.di_dict, data_item, 'FAIL')) return None
def __init__(self): # Initialize ROS generic client node rospy.init_node('robot_link') # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1, 'localhost', 5000)) bridge_library.check_connectivity((1, 'localhost', 5001)) # Global variables self.XML_CNC_queue = Queue() self.XML_RBT_queue = Queue() self.cnc_capture_xml = True self.rbt_capture_xml = True self.cnc_conn = httplib.HTTPConnection('localhost', 5000) self.rbt_conn = httplib.HTTPConnection('localhost', 5001) self.ns = dict(m = 'urn:mtconnect.org:MTConnectStreams:1.2') self.data_items = {'MaterialLoad' : 'MaterialLoad', 'MaterialUnload' : 'MaterialUnload'} # Establish CNC XML connection, read in current XML cnc_response = bridge_library.xml_get_response(('localhost', 5000, None, self.cnc_conn, "/cnc/current")) cnc_body = cnc_response.read() # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(cnc_body, self.ns, self.data_items) # Start a streaming XML connection cnc_response = bridge_library.xml_get_response(('localhost', 5000, None, self.cnc_conn, "/cnc/sample?interval=1000&count=1000&from=" + seq)) # Create CNC XML polling thread cnc_lp = LongPull(cnc_response) self.cnc_thread = threading.Thread(target = cnc_lp.long_pull, args = (self.cnc_xml_callback,)) self.cnc_thread.daemon = True self.cnc_thread.start() rospy.loginfo('STARTED STREAMING CNC XML THREAD') # Establish Robot XML connection, read in current XML rbt_response = bridge_library.xml_get_response(('localhost', 5001, None, self.rbt_conn, "/Robot/current")) rbt_body = rbt_response.read() # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(rbt_body, self.ns, self.data_items) # Start a streaming XML connection rbt_response = bridge_library.xml_get_response(('localhost', 5001, None, self.rbt_conn, "/Robot/sample?interval=1000&count=1000&from=" + seq)) # Create Robot XML polling thread rbt_lp = LongPull(rbt_response) self.rbt_thread = threading.Thread(target = rbt_lp.long_pull, args = (self.rbt_xml_callback,)) self.rbt_thread.daemon = True self.rbt_thread.start() rospy.loginfo('STARTED STREAMING ROBOT XML THREAD') # Create robot initialization publisher thread self.t1 = threading.Thread(target = self.talker) self.t1.daemon = True self.t1.start() rospy.loginfo('STARTED ROBOT INITIALIZATION THREAD') # Create state sequence thread self.t2 = threading.Thread(target = self.run_actions) self.t2.daemon = True self.t2.start() rospy.loginfo('STARTED STATE MACHINE THREAD')
def __init__(self): # Initialize ROS generic client node rospy.init_node('robot_link') # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1, 'localhost', 5000)) bridge_library.check_connectivity((1, 'localhost', 5001)) # Global variables self.XML_CNC_queue = Queue() self.XML_RBT_queue = Queue() self.cnc_capture_xml = True self.rbt_capture_xml = True self.cnc_conn = httplib.HTTPConnection('localhost', 5000) self.rbt_conn = httplib.HTTPConnection('localhost', 5001) self.ns = dict(m='urn:mtconnect.org:MTConnectStreams:1.2') self.data_items = { 'MaterialLoad': 'MaterialLoad', 'MaterialUnload': 'MaterialUnload' } # Establish CNC XML connection, read in current XML cnc_response = bridge_library.xml_get_response( ('localhost', 5000, None, self.cnc_conn, "/cnc/current")) cnc_body = cnc_response.read() # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(cnc_body, self.ns, self.data_items) # Start a streaming XML connection cnc_response = bridge_library.xml_get_response( ('localhost', 5000, None, self.cnc_conn, "/cnc/sample?interval=1000&count=1000&from=" + seq)) # Create CNC XML polling thread cnc_lp = LongPull(cnc_response) self.cnc_thread = threading.Thread(target=cnc_lp.long_pull, args=(self.cnc_xml_callback, )) self.cnc_thread.daemon = True self.cnc_thread.start() rospy.loginfo('STARTED STREAMING CNC XML THREAD') # Establish Robot XML connection, read in current XML rbt_response = bridge_library.xml_get_response( ('localhost', 5001, None, self.rbt_conn, "/Robot/current")) rbt_body = rbt_response.read() # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(rbt_body, self.ns, self.data_items) # Start a streaming XML connection rbt_response = bridge_library.xml_get_response( ('localhost', 5001, None, self.rbt_conn, "/Robot/sample?interval=1000&count=1000&from=" + seq)) # Create Robot XML polling thread rbt_lp = LongPull(rbt_response) self.rbt_thread = threading.Thread(target=rbt_lp.long_pull, args=(self.rbt_xml_callback, )) self.rbt_thread.daemon = True self.rbt_thread.start() rospy.loginfo('STARTED STREAMING ROBOT XML THREAD') # Create robot initialization publisher thread self.t1 = threading.Thread(target=self.talker) self.t1.daemon = True self.t1.start() rospy.loginfo('STARTED ROBOT INITIALIZATION THREAD') # Create state sequence thread self.t2 = threading.Thread(target=self.run_actions) self.t2.daemon = True self.t2.start() rospy.loginfo('STARTED STATE MACHINE THREAD')
def __init__(self): # Initialize ROS generic client node rospy.init_node('ActionServer') # Setup MTConnect to ROS Conversion self.config = bridge_library.obtain_dataMap() self.msg_parameters = ['url', 'url_port', 'machine_tool', 'xml_namespace', 'adapter_port'] self.url = self.config[self.msg_parameters[0]] self.url_port = self.config[self.msg_parameters[1]] self.mtool = self.config[self.msg_parameters[2]] self.ns = dict(m = self.config[self.msg_parameters[3]]) self.port = self.config[self.msg_parameters[4]] # Check for url connectivity, dwell until system timeout bridge_library.check_connectivity((1,self.url,self.url_port)) # Setup MTConnect Adapter for robot status data items self.adapter = Adapter((self.url, self.port)) # Create empty lists for actions, message type handles, etc. self.lib_manifests = [] self.type_handle = None self.action_list = {} self.capture_xml = False self.di_dict = {} # XML data item dictionary to store MTConnect Adapter Events # Create a dictionary of _results to return upon action success self._resultDict = {} # Create a dictionary of action servers self._as = {} # Create a dictionary of server names self.server_name = {} # Setup action client data per the config file self.setup_topic_data() # Add data items to the MTConnect Adapter - must be unique data items bridge_library.add_event((self.adapter, self.action_list, self.di_dict, True)) # Start the adapter rospy.loginfo('Start the Robot Link adapter') self.adapter.start() # Establish XML connection, read in current XML while True: try: self.conn = HTTPConnection(self.url, self.url_port) response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/current")) body = response.read() break except socket.error as e: rospy.loginfo('HTTP connection error %s' % e) time.sleep(10) # Parse the XML and determine the current sequence and XML Event elements seq, elements = bridge_library.xml_components(body, self.ns, self.action_list) # Start a streaming XML connection response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/sample?interval=1000&count=1000&from=" + seq)) # Create queue for streaming XML self.XML_queue = Queue() # Create XML polling thread lp = LongPull(response) xml_thread = Thread(target = lp.long_pull, args = (self.xml_callback,)) xml_thread.daemon = True xml_thread.start()
def execute_cb(self, goal): # If goal is OpenDoor, use the goal defined in the message as your key, access it as goal.__slots__[0] action = goal.__slots__[0] # Empty function -- assumes action was successful rospy.loginfo('In %s Callback -- determining action request result.' % self.server_name[action]) # Check to make sure machine tool is READY, if not, ABORT the robot action request # Change to XML Tag format tokens = re.findall(r'([A-Z][a-z]*)', self.server_name[action]) tokenlist = [val.upper() for val in tokens] di_tag = tokenlist[0] + '_' + tokenlist[1] # Check current status of XML Tag check_response = bridge_library.xml_get_response((self.url, self.url_port, self.port, self.conn, self.mtool + "/current?path=//DataItem[@type='" + di_tag + "']")) body = check_response.read() _, element = bridge_library.xml_components(body, self.ns, {self.server_name[action]:self.server_name[action]}) # Complete the action request if element[0].text == 'READY': # Execute the action request # Submit goal value to MTConnect via agent (i.e. goal.open_door = 'ACTIVE') bridge_library.action_cb((self.adapter, self.di_dict, action, 'ACTIVE')) robot_hold = 0 # Used to make sure you only change robot state once after 'COMPLETE' received from CNC # Start capturing XML self.capture_xml = True # While loop to poll CNC XML until READY is received for Robot action request dwell = True while dwell == True: try: # Obtain XML chunk if not self.XML_queue.empty(): chunk = self.XML_queue.get() # Parse the XML and determine the current sequence and XML Event elements root = ElementTree.fromstring(chunk) element_list = root.findall('.//m:' + self.server_name[action], namespaces = self.ns) if len(element_list) > 1: rospy.logdebug('XML --> %s' % chunk) if element_list: # Must iterate -- multiple elements possible for a single tag for element in element_list: if element.text == 'ACTIVE': # Set accepted back to action client pass # While polling monitor CNC response for COMPLETE, submit READY handshake elif element.text == 'COMPLETE' and robot_hold == 0: bridge_library.action_cb((self.adapter, self.di_dict, action, 'READY')) robot_hold = 1 elif element.text == 'READY' and robot_hold == 1: dwell = False self.capture_xml = False # When response is READY, set server result and communicate as below: # Extract action attribute result_attribute = self._resultDict[self.server_name[action]].__slots__[0] # Set the attribute per the ROS to MTConnect conversion setattr(self._resultDict[self.server_name[action]], result_attribute, 'READY') # Indicate a successful action self._as[self.server_name[action]].set_succeeded(self._resultDict[self.server_name[action]]) rospy.loginfo('In %s Callback -- action succeeded.' % self.server_name[action]) elif element.text == 'FAIL': bridge_library.action_cb((self.adapter, self.di_dict, action, 'FAIL')) dwell = False self.capture_xml = False # When response is FAIL, set server result and communicate as below: # Extract action attribute. For CNC Actions, only one result --> i.e. OpenDoorResult.__slots__[0] = 'door_ready' result_attribute = self._resultDict[self.server_name[action]].__slots__[0] # Set the attribute per the ROS to MTConnect conversion setattr(self._resultDict[self.server_name[action]], result_attribute, 'FAIL') # Indicate an aborted action self._as[self.server_name[action]].set_aborted(self._resultDict[self.server_name[action]]) rospy.loginfo('In %s Callback -- action aborted by CNC.' % self.server_name[action]) # Release the queue self.XML_queue.task_done() except rospy.ROSInterruptException: rospy.loginfo('program interrupted before completion') else: # Abort the action request, machine tool not ready or faulted # Extract action attribute. For CNC Actions, only one result --> i.e. OpenDoorResult.__slots__[0] = 'door_ready' result_attribute = self._resultDict[self.server_name[action]].__slots__[0] # Set the attribute per the ROS to MTConnect conversion setattr(self._resultDict[self.server_name[action]], result_attribute, 'NOT_READY') # Indicate an aborted action self._as[self.server_name[action]].set_aborted(self._resultDict[self.server_name[action]]) rospy.loginfo('In %s Callback -- action aborted, machine tool NOT_READY, FAULTED, or UNAVAILABLE.' % self.server_name[action]) return