material_load_server.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 """
00004    Copyright 2013 Southwest Research Institute
00005  
00006    Licensed under the Apache License, Version 2.0 (the "License");
00007    you may not use this file except in compliance with the License.
00008    You may obtain a copy of the License at
00009  
00010      http://www.apache.org/licenses/LICENSE-2.0
00011  
00012    Unless required by applicable law or agreed to in writing, software
00013    distributed under the License is distributed on an "AS IS" BASIS,
00014    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015    See the License for the specific language governing permissions and
00016    limitations under the License.
00017    """
00018 
00019 import sys
00020 import logging
00021 import threading
00022 import time
00023 import collections
00024 from httplib import HTTPConnection
00025 from xml.etree import ElementTree
00026 
00027 import roslib; roslib.load_manifest('mtconnect_msgs')
00028 import rospy
00029 import actionlib
00030 import mtconnect_msgs.msg
00031 
00032 
00033 class MaterialLoadServer():
00034     """Dedicated Material Load Server -- without robot interface
00035     Class establishes a simple action server for the MaterialLoadAction, and
00036     starts a thread to subscribe to the ROS topic CncStatus.
00037     
00038     The Material Load sequence is completed once the door state and the chuck
00039     state are closed.
00040     
00041     @param server_name: string, 'MaterialLoad'
00042     @param _result: instance of the mtconnect_msgs.msg.MaterialLoadResult class
00043     @param _as: ROS actionlib SimpleActionServer
00044     @param door_state: int, published value for the CNC door state [0:Open, 1:Closed, -1:Unlatched]
00045     @param chuck_state: int, published value for the CNC chuck state [0:Open, 1:Closed, -1:Unlatched]
00046     @param sub_thread: thread that launches a ROS subscriber to the CncResponseTopic via bridge_publisher node
00047 
00048     """
00049 
00050     def __init__(self):
00051         self.server_name = 'MaterialLoad'
00052         
00053         self._result = mtconnect_msgs.msg.MaterialLoadResult()
00054         self._as = actionlib.SimpleActionServer('MaterialLoadClient', mtconnect_msgs.msg.MaterialLoadAction, self.execute_cb, False)
00055         self._as.start()
00056         self._as.accept_new_goal()
00057         self.counter = 1
00058         
00059         # Subscribe to CNC state topic
00060         self.door_state = None
00061         self.chuck_state = None
00062         self.close_door = None
00063         
00064         # Check for CncResponseTopic
00065         dwell = 2
00066         while True:
00067             published_topics = dict(rospy.get_published_topics())
00068             if '/CncResponseTopic' in published_topics.keys():
00069                 rospy.loginfo('ROS CncResponseTopic available, starting subscriber')
00070                 break
00071             else:
00072                 rospy.loginfo('ROS CncResponseTopic not available, will try to subscribe in %d seconds' % dwell)
00073                 time.sleep(dwell)
00074         
00075         # Create ROS Subscriber thread
00076         sub_thread = threading.Thread(target = self.subscriber_thread)
00077         sub_thread.daemon = True
00078         sub_thread.start()
00079         
00080     def execute_cb(self, goal):
00081         rospy.loginfo('In %s Bridge Server Callback -- determining action request result.' % self.server_name)
00082         
00083         # Initialize timeout parameter
00084         start = time.time()
00085         
00086         # Start while loop and check for cnc action changes
00087         rospy.loginfo('In MaterialLoad Server while loop')
00088         previous = time.time()
00089         dwell = True
00090         while dwell == True:
00091             try:
00092                 # Current CNC state
00093                 if time.time() - previous > 1.0:
00094                     rospy.loginfo('CNC States [door_state, chuck_state, close_door]: %s' % [self.door_state, self.chuck_state, self.close_door])
00095                     previous = time.time()
00096     
00097                 if self.door_state == 1 and self.chuck_state == 1 and self.close_door == 1 and self.counter < 25:
00098                     # Chuck and Door are closed, complete the material load cycle
00099                     self._result.load_state = 'COMPLETE'
00100                     dwell = False
00101                     rospy.loginfo('CNC States [door_state, chuck_state, close_door]: %s' % [self.door_state, self.chuck_state, self.close_door])
00102                     rospy.loginfo('CYCLE NUMBER --> %d' % self.counter)
00103                     self.counter += 1
00104                     
00105                     # Indicate a successful action
00106                     self._as.set_succeeded(self._result)
00107                     rospy.loginfo('In %s Callback -- action succeeded. Result --> %s' % (self.server_name, self._result.load_state))
00108                     return self._result
00109                 
00110                 elif self.door_state == 1 and self.chuck_state == 1 and self.close_door == 1 and self.counter == 25:
00111                     self._result.load_state = 'FAIL'
00112                     dwell = False
00113                     rospy.loginfo('CNC States [door_state, chuck_state, close_door]: %s' % [self.door_state, self.chuck_state, self.close_door])
00114                     rospy.loginfo('CYCLE NUMBER --> %d' % self.counter)
00115                     self.counter += 1
00116                     
00117                     # Indicate an aborted action
00118                     self._as.set_aborted(self._result)
00119                     rospy.loginfo('In %s Callback -- action aborted. Result --> %s' % (self.server_name, self._result.load_state))
00120                     return self._result
00121                 
00122                 # Check for timeout
00123                 if time.time() - start > 120.0:
00124                     rospy.loginfo('Material Load Server Timed Out')
00125                     sys.exit()
00126             except rospy.ROSInterruptException:
00127                 rospy.loginfo('program interrupted before completion')
00128                 return
00129         
00130 
00131     def topic_callback(self, msg):
00132         self.door_state = msg.door_state.val
00133         self.chuck_state = msg.chuck_state.val
00134         self.close_door = msg.close_door.val
00135         return
00136     
00137     def subscriber_thread(self):
00138         rospy.Subscriber('CncResponseTopic', mtconnect_msgs.msg.CncStatus, self.topic_callback)
00139         rospy.spin()
00140         return
00141 
00142 if __name__ == '__main__':
00143     # Initialize the ROS node
00144     rospy.init_node('MaterialLoadServer')
00145     rospy.loginfo('Started ROS MaterialLoad Server')
00146     
00147     # Launch the action server
00148     server = MaterialLoadServer()
00149     rospy.spin()


mtconnect_ros_bridge
Author(s): Stephen L. Wiedmann
autogenerated on Mon Jan 6 2014 11:30:45