Go to the documentation of this file.00001
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
00060 self.door_state = None
00061 self.chuck_state = None
00062 self.close_door = None
00063
00064
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
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
00084 start = time.time()
00085
00086
00087 rospy.loginfo('In MaterialLoad Server while loop')
00088 previous = time.time()
00089 dwell = True
00090 while dwell == True:
00091 try:
00092
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
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
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
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
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
00144 rospy.init_node('MaterialLoadServer')
00145 rospy.loginfo('Started ROS MaterialLoad Server')
00146
00147
00148 server = MaterialLoadServer()
00149 rospy.spin()