$search
00001 #!/usr/bin/env python 00002 # Software License Agreement (BSD License) 00003 # 00004 # Based on actionlib axserver.py 00005 # Modified by Christian Dornhege to sxserver.py 00006 # 00007 # Copyright (c) 2009, Willow Garage, Inc. 00008 # All rights reserved. 00009 # 00010 # Redistribution and use in source and binary forms, with or without 00011 # modification, are permitted provided that the following conditions 00012 # are met: 00013 # 00014 # * Redistributions of source code must retain the above copyright 00015 # notice, this list of conditions and the following disclaimer. 00016 # * Redistributions in binary form must reproduce the above 00017 # copyright notice, this list of conditions and the following 00018 # disclaimer in the documentation and/or other materials provided 00019 # with the distribution. 00020 # * Neither the name of Willow Garage, Inc. nor the names of its 00021 # contributors may be used to endorse or promote products derived 00022 # from this software without specific prior written permission. 00023 # 00024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00026 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00027 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00028 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00029 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00030 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00031 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00033 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00034 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00035 # POSSIBILITY OF SUCH DAMAGE. 00036 00037 """ 00038 usage: %prog /service_name service_type 00039 """ 00040 00041 PKG='fr_tools' 00042 00043 import roslib; roslib.load_manifest(PKG) 00044 00045 from optparse import OptionParser 00046 import wx 00047 import sys 00048 import rospy 00049 import time 00050 import threading 00051 from cStringIO import StringIO 00052 from library import * 00053 from dynamic_service import DynamicService 00054 00055 SUCCEED = 0 00056 FAIL = 1 00057 00058 class SXServerApp(wx.App): 00059 def __init__(self, service_type, service_name): 00060 self.service_type = service_type 00061 wx.App.__init__(self) 00062 00063 self.server = rospy.Service(service_name, self.service_type.service, self.execute) 00064 self.condition = threading.Condition() 00065 self.response_msg = None 00066 self.execute_type = None 00067 00068 def set_request(self, request): 00069 if request is None: 00070 self.status_bg.SetBackgroundColour(wx.Colour(200,0,0)) 00071 self.status.SetLabel("Waiting For Request...") 00072 self.succeed.Disable() 00073 self.fail.Disable() 00074 00075 self.request.SetValue("") 00076 00077 else: 00078 self.status_bg.SetBackgroundColour(wx.Colour(0,200,0)) 00079 self.status.SetLabel("Received Request. Send succeed, or fail.") 00080 self.succeed.Enable() 00081 self.fail.Enable() 00082 00083 try: 00084 self.request.SetValue(to_yaml(request)) 00085 except UnicodeDecodeError: 00086 self.request.SetValue("Cannot display request due to unprintable characters") 00087 00088 def execute(self, request): 00089 00090 wx.CallAfter(self.set_request, request) 00091 00092 self.condition.acquire() 00093 00094 self.response_msg = None 00095 self.execute_type = None 00096 00097 while self.execute_type is None: 00098 00099 self.response_msg = None 00100 self.execute_type = None 00101 00102 while self.execute_type is None: 00103 self.condition.wait() 00104 00105 retVal = False 00106 if self.execute_type == SUCCEED: 00107 retVal = True 00108 00109 if self.execute_type == FAIL: 00110 retVal = False 00111 00112 wx.CallAfter(self.set_request, None) 00113 00114 self.condition.release() 00115 if retVal: 00116 return self.response_msg 00117 else: 00118 return None 00119 00120 def on_succeed(self, event): 00121 self.condition.acquire() 00122 00123 try: 00124 self.response_msg = yaml_msg_str(self.service_type.response, self.response.GetValue()) 00125 buff = StringIO() 00126 self.response_msg.serialize(buff) 00127 00128 self.execute_type = SUCCEED 00129 self.condition.notify() 00130 except roslib.message.SerializationError, e: 00131 self.response_msg = None 00132 wx.MessageBox(str(e), "Error serializing response", wx.OK) 00133 00134 self.condition.release() 00135 00136 def on_fail(self, event): 00137 self.condition.acquire() 00138 00139 self.execute_type = FAIL 00140 self.condition.notify() 00141 00142 self.condition.release() 00143 00144 def OnInit(self): 00145 self.frame = wx.Frame(None, -1, self.service_type.name + ' Standin') 00146 00147 self.sz = wx.BoxSizer(wx.VERTICAL) 00148 00149 tmp_response = self.service_type.response() 00150 00151 self.request = wx.TextCtrl(self.frame, -1, style=(wx.TE_MULTILINE | wx.TE_READONLY)) 00152 self.request_st_bx = wx.StaticBox(self.frame, -1, "Request") 00153 self.request_st = wx.StaticBoxSizer(self.request_st_bx, wx.VERTICAL) 00154 self.request_st.Add(self.request, 1, wx.EXPAND) 00155 00156 self.response = wx.TextCtrl(self.frame, -1, style=wx.TE_MULTILINE) 00157 self.response.SetValue(to_yaml(tmp_response)) 00158 self.response_st_bx = wx.StaticBox(self.frame, -1, "Response") 00159 self.response_st = wx.StaticBoxSizer(self.response_st_bx, wx.VERTICAL) 00160 self.response_st.Add(self.response, 1, wx.EXPAND) 00161 00162 self.succeed = wx.Button(self.frame, -1, label="SUCCEED") 00163 self.succeed.Bind(wx.EVT_BUTTON, self.on_succeed) 00164 00165 self.fail = wx.Button(self.frame, -1, label="FAIL") 00166 self.fail.Bind(wx.EVT_BUTTON, self.on_fail) 00167 00168 self.status_bg = wx.Panel(self.frame, -1) 00169 self.status_bg.SetBackgroundColour(wx.Colour(200,0,0)) 00170 self.status = wx.StaticText(self.status_bg, -1, label="Waiting For Request...") 00171 00172 self.sz.Add(self.request_st, 1, wx.EXPAND) 00173 self.sz.Add(self.response_st, 1, wx.EXPAND) 00174 self.sz.Add(self.succeed, 0, wx.EXPAND) 00175 self.sz.Add(self.fail, 0, wx.EXPAND) 00176 self.sz.Add(self.status_bg, 0, wx.EXPAND) 00177 00178 self.frame.SetSizer(self.sz) 00179 00180 self.set_request(None) 00181 00182 self.sz.Layout() 00183 self.frame.Show() 00184 00185 return True 00186 00187 if __name__ == '__main__': 00188 rospy.init_node('sxserver', anonymous=True) 00189 00190 parser = OptionParser(__doc__.strip()) 00191 00192 (options, args) = parser.parse_args(rospy.myargv()) 00193 00194 if (len(args) != 3): 00195 parser.error("You must specify the service name and type. Eg: ./sxserver.py my_service my_msgs/Test") 00196 00197 service = DynamicService(args[2]) 00198 00199 app = SXServerApp(service, args[1]) 00200 app.MainLoop() 00201 rospy.signal_shutdown('GUI shutdown')