make_library.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 #####################################################################
00004 # Software License Agreement (BSD License)
00005 #
00006 # Copyright (c) 2011, Willow Garage, Inc.
00007 # All rights reserved.
00008 #
00009 # Redistribution and use in source and binary forms, with or without
00010 # modification, are permitted provided that the following conditions
00011 # are met:
00012 #
00013 #  * Redistributions of source code must retain the above copyright
00014 #    notice, this list of conditions and the following disclaimer.
00015 #  * Redistributions in binary form must reproduce the above
00016 #    copyright notice, this list of conditions and the following
00017 #    disclaimer in the documentation and/or other materials provided
00018 #    with the distribution.
00019 #  * Neither the name of Willow Garage, Inc. nor the names of its
00020 #    contributors may be used to endorse or promote products derived
00021 #    from this software without specific prior written permission.
00022 #
00023 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034 # POSSIBILITY OF SUCH DAMAGE.
00035 
00036 __author__ = "mferguson@willowgarage.com (Michael Ferguson)"
00037 
00038 __usage__ = """
00039 make_library.py generates the Arduino rosserial library files.  It 
00040 requires the location of your arduino libraries folder and the name of 
00041 one or more packages for which you want to make libraries.  
00042 
00043 rosrun rosserial_client make_library.py <output_path> pkg_name [pkg2 pkg3 ...]
00044 """
00045 
00046 import roslib; roslib.load_manifest("rosserial_client")
00047 import roslib.gentools, roslib.srvs
00048 import roslib.rospack
00049 import rospy
00050 
00051 import os, sys, subprocess, re
00052 
00053 def type_to_var(ty):
00054     lookup = {
00055         1 : 'uint8_t',
00056         2 : 'uint16_t',
00057         4 : 'uint32_t',
00058         8 : 'uint64_t',
00059     }
00060     return lookup[ty]
00061 
00062 #####################################################################
00063 # Data Types
00064 
00065 class EnumerationType:
00066     """ For data values. """
00067     
00068     def __init__(self, name, ty, value):
00069         self.name = name
00070         self.type = ty
00071         self.value = value
00072     
00073     def make_declaration(self, f):
00074         f.write('      enum { %s = %s };\n' % (self.name, self.value))    
00075 
00076 class PrimitiveDataType:
00077     """ Our datatype is a C/C++ primitive. """    
00078 
00079     def __init__(self, name, ty, bytes):
00080         self.name = name
00081         self.type = ty
00082         self.bytes = bytes
00083 
00084     def make_declaration(self, f):
00085         f.write('      %s %s;\n' % (self.type, self.name) )
00086 
00087     def serialize(self, f):
00088         cn = self.name.replace("[","").replace("]","").split(".")[-1]
00089         if self.type != type_to_var(self.bytes):
00090             f.write('      union {\n')
00091             f.write('        %s real;\n' % self.type)
00092             f.write('        %s base;\n' % type_to_var(self.bytes))
00093             f.write('      } u_%s;\n' % cn)
00094             f.write('      u_%s.real = this->%s;\n' % (cn,self.name))
00095             for i in range(self.bytes):
00096                 f.write('      *(outbuffer + offset + %d) = (u_%s.base >> (8 * %d)) & 0xFF;\n' % (i, cn, i) )
00097         else:
00098             for i in range(self.bytes):
00099                 f.write('      *(outbuffer + offset + %d) = (this->%s >> (8 * %d)) & 0xFF;\n' % (i, self.name, i) )
00100         f.write('      offset += sizeof(this->%s);\n' % self.name)
00101 
00102     def deserialize(self, f):
00103         cn = self.name.replace("[","").replace("]","").split(".")[-1]
00104         if self.type != type_to_var(self.bytes):
00105             f.write('      union {\n')
00106             f.write('        %s real;\n' % self.type)
00107             f.write('        %s base;\n' % type_to_var(self.bytes))
00108             f.write('      } u_%s;\n' % cn)
00109             f.write('      u_%s.base = 0;\n' % cn)
00110             for i in range(self.bytes):
00111                 f.write('      u_%s.base |= ((%s) (*(inbuffer + offset + %d))) << (8 * %d);\n' % (cn,type_to_var(self.bytes),i,i) )
00112             f.write('      this->%s = u_%s.real;\n' % (self.name, cn) )
00113         else:
00114             f.write('      this->%s =  ((%s) (*(inbuffer + offset)));\n' % (self.name,self.type) )
00115             for i in range(self.bytes-1):
00116                 f.write('      this->%s |= ((%s) (*(inbuffer + offset + %d))) << (8 * %d);\n' % (self.name,self.type,i+1,i+1) )
00117         f.write('      offset += sizeof(this->%s);\n' % self.name)
00118 
00119 
00120 class MessageDataType(PrimitiveDataType):
00121     """ For when our data type is another message. """
00122     def serialize(self, f):
00123         f.write('      offset += this->%s.serialize(outbuffer + offset);\n' % self.name)
00124 
00125     def deserialize(self, f):
00126         f.write('      offset += this->%s.deserialize(inbuffer + offset);\n' % self.name)
00127 
00128 
00129 class Float64DataType(PrimitiveDataType):
00130     """ AVR C/C++ has no native 64-bit support, we automatically convert to 32-bit float. """
00131         
00132     def make_declaration(self, f):
00133         f.write('      float %s;\n' % self.name )
00134     
00135     def serialize(self, f):
00136         cn = self.name.replace("[","").replace("]","")
00137         f.write('      int32_t * val_%s = (long *) &(this->%s);\n' % (cn,self.name))
00138         f.write('      int32_t exp_%s = (((*val_%s)>>23)&255);\n' % (cn,cn))
00139         f.write('      if(exp_%s != 0)\n' % cn)
00140         f.write('        exp_%s += 1023-127;\n' % cn)
00141         f.write('      int32_t sig_%s = *val_%s;\n' % (cn,cn))
00142         f.write('      *(outbuffer + offset++) = 0;\n') # 29 blank bits
00143         f.write('      *(outbuffer + offset++) = 0;\n')
00144         f.write('      *(outbuffer + offset++) = 0;\n')
00145         f.write('      *(outbuffer + offset++) = (sig_%s<<5) & 0xff;\n' % cn)
00146         f.write('      *(outbuffer + offset++) = (sig_%s>>3) & 0xff;\n' % cn)
00147         f.write('      *(outbuffer + offset++) = (sig_%s>>11) & 0xff;\n' % cn)
00148         f.write('      *(outbuffer + offset++) = ((exp_%s<<4) & 0xF0) | ((sig_%s>>19)&0x0F);\n' % (cn,cn))
00149         f.write('      *(outbuffer + offset++) = (exp_%s>>4) & 0x7F;\n' % cn)
00150         f.write('      if(this->%s < 0) *(outbuffer + offset -1) |= 0x80;\n' % self.name)
00151 
00152     def deserialize(self, f):
00153         cn = self.name.replace("[","").replace("]","")
00154         f.write('      uint32_t * val_%s = (uint32_t*) &(this->%s);\n' % (cn,self.name))
00155         f.write('      offset += 3;\n') # 29 blank bits
00156         f.write('      *val_%s = ((uint32_t)(*(inbuffer + offset++))>>5 & 0x07);\n' % cn)
00157         f.write('      *val_%s |= ((uint32_t)(*(inbuffer + offset++)) & 0xff)<<3;\n' % cn)
00158         f.write('      *val_%s |= ((uint32_t)(*(inbuffer + offset++)) & 0xff)<<11;\n' % cn)
00159         f.write('      *val_%s |= ((uint32_t)(*(inbuffer + offset)) & 0x0f)<<19;\n' % cn)
00160         f.write('      uint32_t exp_%s = ((uint32_t)(*(inbuffer + offset++))&0xf0)>>4;\n' % cn)
00161         f.write('      exp_%s |= ((uint32_t)(*(inbuffer + offset)) & 0x7f)<<4;\n' % cn)
00162         f.write('      if(exp_%s !=0)\n' % cn)
00163         f.write('        *val_%s |= ((exp_%s)-1023+127)<<23;\n' % (cn,cn))
00164         f.write('      if( ((*(inbuffer+offset++)) & 0x80) > 0) this->%s = -this->%s;\n' % (self.name,self.name))
00165 
00166     
00167 class StringDataType(PrimitiveDataType):
00168     """ Need to convert to signed char *. """
00169 
00170     def make_declaration(self, f):
00171         f.write('      char * %s;\n' % self.name)
00172 
00173     def serialize(self, f):
00174         cn = self.name.replace("[","").replace("]","")
00175         f.write('      uint32_t * length_%s = (uint32_t *)(outbuffer + offset);\n' % cn)
00176         f.write('      *length_%s = strlen( (const char*) this->%s);\n' % (cn,self.name))
00177         f.write('      offset += 4;\n')
00178         f.write('      memcpy(outbuffer + offset, this->%s, *length_%s);\n' % (self.name,cn))
00179         f.write('      offset += *length_%s;\n' % cn)
00180 
00181     def deserialize(self, f):
00182         cn = self.name.replace("[","").replace("]","")
00183         f.write('      uint32_t length_%s = *(uint32_t *)(inbuffer + offset);\n' % cn)
00184         f.write('      offset += 4;\n')
00185         f.write('      for(unsigned int k= offset; k< offset+length_%s; ++k){\n'%cn) #shift for null character
00186         f.write('          inbuffer[k-1]=inbuffer[k];\n')
00187         f.write('      }\n')
00188         f.write('      inbuffer[offset+length_%s-1]=0;\n'%cn)
00189         f.write('      this->%s = (char *)(inbuffer + offset-1);\n' % self.name)
00190         f.write('      offset += length_%s;\n' % cn)
00191 
00192 
00193 class TimeDataType(PrimitiveDataType):
00194 
00195     def __init__(self, name, ty, bytes):
00196         self.name = name
00197         self.type = ty
00198         self.sec = PrimitiveDataType(name+'.sec','uint32_t',4)
00199         self.nsec = PrimitiveDataType(name+'.nsec','uint32_t',4)
00200 
00201     def make_declaration(self, f):
00202         f.write('      %s %s;\n' % (self.type, self.name))
00203 
00204     def serialize(self, f):
00205         self.sec.serialize(f)
00206         self.nsec.serialize(f)
00207 
00208     def deserialize(self, f):
00209         self.sec.deserialize(f)
00210         self.nsec.deserialize(f)
00211 
00212 
00213 class ArrayDataType(PrimitiveDataType):
00214 
00215     def __init__(self, name, ty, bytes, cls, array_size=None):
00216         self.name = name
00217         self.type = ty  
00218         self.bytes = bytes
00219         self.size = array_size
00220         self.cls = cls 
00221 
00222     def make_declaration(self, f):
00223         c = self.cls("*"+self.name, self.type, self.bytes)
00224         if self.size == None:
00225             f.write('      uint8_t %s_length;\n' % self.name)
00226             f.write('      %s st_%s;\n' % (self.type, self.name)) # static instance for copy
00227             f.write('      %s * %s;\n' % (self.type, self.name))
00228         else:
00229             f.write('      %s %s[%d];\n' % (self.type, self.name, self.size))
00230     
00231     def serialize(self, f):
00232         c = self.cls(self.name+"[i]", self.type, self.bytes)
00233         if self.size == None:
00234             # serialize length
00235             f.write('      *(outbuffer + offset++) = %s_length;\n' % self.name)
00236             f.write('      *(outbuffer + offset++) = 0;\n')
00237             f.write('      *(outbuffer + offset++) = 0;\n')
00238             f.write('      *(outbuffer + offset++) = 0;\n')
00239             f.write('      for( uint8_t i = 0; i < %s_length; i++){\n' % self.name)
00240             c.serialize(f)
00241             f.write('      }\n')
00242         else:
00243             f.write('      unsigned char * %s_val = (unsigned char *) this->%s;\n' % (self.name, self.name))    
00244             f.write('      for( uint8_t i = 0; i < %d; i++){\n' % (self.size) )
00245             c.serialize(f)            
00246             f.write('      }\n')
00247         
00248     def deserialize(self, f):
00249         if self.size == None:
00250             c = self.cls("st_"+self.name, self.type, self.bytes)
00251             # deserialize length
00252             f.write('      uint8_t %s_lengthT = *(inbuffer + offset++);\n' % self.name)
00253             f.write('      if(%s_lengthT > %s_length)\n' % (self.name, self.name))
00254             f.write('        this->%s = (%s*)realloc(this->%s, %s_lengthT * sizeof(%s));\n' % (self.name, self.type, self.name, self.name, self.type))
00255             f.write('      offset += 3;\n')
00256             f.write('      %s_length = %s_lengthT;\n' % (self.name, self.name))
00257             # copy to array
00258             f.write('      for( uint8_t i = 0; i < %s_length; i++){\n' % (self.name) )
00259             c.deserialize(f)
00260             f.write('        memcpy( &(this->%s[i]), &(this->st_%s), sizeof(%s));\n' % (self.name, self.name, self.type))                     
00261             f.write('      }\n')
00262         else:
00263             c = self.cls(self.name+"[i]", self.type, self.bytes)
00264             f.write('      uint8_t * %s_val = (uint8_t*) this->%s;\n' % (self.name, self.name))    
00265             f.write('      for( uint8_t i = 0; i < %d; i++){\n' % (self.size) )
00266             c.deserialize(f)            
00267             f.write('      }\n')
00268 
00269 
00270 ros_to_arduino_types = {
00271     'bool'    :   ('bool',              1, PrimitiveDataType, []),
00272     'int8'    :   ('int8_t',            1, PrimitiveDataType, []),
00273     'uint8'   :   ('uint8_t',           1, PrimitiveDataType, []),
00274     'int16'   :   ('int16_t',           2, PrimitiveDataType, []),
00275     'uint16'  :   ('uint16_t',          2, PrimitiveDataType, []),
00276     'int32'   :   ('int32_t',           4, PrimitiveDataType, []),
00277     'uint32'  :   ('uint32_t',          4, PrimitiveDataType, []),
00278     'int64'   :   ('int64_t',           4, PrimitiveDataType, []),
00279     'uint64'  :   ('uint64_t',          4, PrimitiveDataType, []),
00280     'float32' :   ('float',             4, PrimitiveDataType, []),
00281     'float64' :   ('float',             4, Float64DataType, []),
00282     'time'    :   ('ros::Time',         8, TimeDataType, ['ros/time']),
00283     'duration':   ('ros::Duration',     8, TimeDataType, ['ros/duration']),
00284     'string'  :   ('char*',             0, StringDataType, []),
00285     'Header'  :   ('std_msgs::Header',  0, MessageDataType, ['std_msgs/Header'])
00286 }
00287 
00288 
00289 #####################################################################
00290 # Messages
00291 
00292 class Message:    
00293     """ Parses message definitions into something we can export. """
00294 
00295     def __init__(self, name, package, definition, md5):
00296 
00297         self.name = name            # name of message/class
00298         self.package = package      # package we reside in
00299         self.md5 = md5              # checksum
00300         self.includes = list()      # other files we must include
00301 
00302         self.data = list()          # data types for code generation
00303         self.enums = list()
00304 
00305         # parse definition
00306         for line in definition:
00307             # prep work
00308             line = line.strip().rstrip()    
00309             value = None
00310             if line.find("#") > -1:
00311                 line = line[0:line.find("#")]
00312             if line.find("=") > -1:
00313                 try:
00314                     value = line[line.find("=")+1:]
00315                 except:
00316                     value = '"' + line[line.find("=")+1:] + '"';
00317                 line = line[0:line.find("=")]
00318             
00319             # find package/class name   
00320             line = line.replace("\t", " ")
00321             l = line.split(" ")
00322             while "" in l:
00323                 l.remove("")
00324             if len(l) < 2:
00325                 continue
00326             ty, name = l[0:2]
00327             if value != None:
00328                 self.enums.append( EnumerationType(name, ty, value))            
00329                 continue
00330 
00331             try:
00332                 type_package, type_name = ty.split("/")
00333             except:
00334                 type_package = None
00335                 type_name = ty
00336             type_array = False
00337             if type_name.find('[') > 0:
00338                 type_array = True   
00339                 try:
00340                     type_array_size = int(type_name[type_name.find('[')+1:type_name.find(']')])
00341                 except:
00342                     type_array_size = None
00343                 type_name = type_name[0:type_name.find('[')]
00344 
00345             # convert to C type if primitive, expand name otherwise
00346             try:
00347                 code_type = ros_to_arduino_types[type_name][0]
00348                 size = ros_to_arduino_types[type_name][1]
00349                 cls = ros_to_arduino_types[type_name][2]
00350                 for include in ros_to_arduino_types[type_name][3]:
00351                     if include not in self.includes:
00352                         self.includes.append(include)
00353             except:
00354                 if type_package == None:
00355                     type_package = self.package
00356                 if type_package+"/"+type_name not in self.includes:
00357                     self.includes.append(type_package+"/"+type_name)
00358                 cls = MessageDataType
00359                 code_type = type_package + "::" + type_name
00360                 size = 0
00361             if type_array:
00362                 self.data.append( ArrayDataType(name, code_type, size, cls, type_array_size ) )
00363             else:
00364                 self.data.append( cls(name, code_type, size) )
00365 
00366     def _write_serializer(self, f):
00367                 # serializer   
00368         f.write('\n')
00369         f.write('    virtual int serialize(unsigned char *outbuffer) const\n')
00370         f.write('    {\n')
00371         f.write('      int offset = 0;\n')
00372         for d in self.data:
00373             d.serialize(f)
00374         f.write('      return offset;\n');
00375         f.write('    }\n')
00376         f.write('\n')
00377         
00378     def _write_deserializer(self, f):
00379         # deserializer
00380         f.write('    virtual int deserialize(unsigned char *inbuffer)\n')
00381         f.write('    {\n')
00382         f.write('      int offset = 0;\n')
00383         for d in self.data:
00384             d.deserialize(f)
00385         f.write('     return offset;\n');
00386         f.write('    }\n')         
00387         f.write('\n')
00388 
00389     def _write_std_includes(self, f):
00390         f.write('#include <stdint.h>\n')
00391         f.write('#include <string.h>\n')
00392         f.write('#include <stdlib.h>\n')
00393         f.write('#include "ros/msg.h"\n')
00394 
00395     def _write_msg_includes(self,f):
00396         for i in self.includes:
00397             f.write('#include "%s.h"\n' % i)
00398             
00399     def _write_data(self, f):
00400         for d in self.data:
00401             d.make_declaration(f)
00402         for e in self.enums:
00403             e.make_declaration(f)
00404             
00405     def _write_getType(self, f):
00406         f.write('    const char * getType(){ return "%s/%s"; };\n'%(self.package, self.name))
00407 
00408     def _write_getMD5(self, f):
00409         f.write('    const char * getMD5(){ return "%s"; };\n'%self.md5)
00410 
00411     def _write_impl(self, f):
00412         f.write('  class %s : public ros::Msg\n' % self.name)
00413         f.write('  {\n')
00414         f.write('    public:\n')
00415         self._write_data(f)
00416         self._write_serializer(f)
00417         self._write_deserializer(f)
00418         self._write_getType(f)
00419         self._write_getMD5(f)
00420         f.write('\n')
00421         f.write('  };\n')
00422         
00423     def make_header(self, f):
00424         f.write('#ifndef _ROS_%s_%s_h\n'%(self.package, self.name))
00425         f.write('#define _ROS_%s_%s_h\n'%(self.package, self.name))
00426         f.write('\n')
00427         self._write_std_includes(f)
00428         self._write_msg_includes(f)
00429        
00430         f.write('\n')
00431         f.write('namespace %s\n' % self.package)
00432         f.write('{\n')
00433         f.write('\n')
00434         self._write_impl(f)
00435         f.write('\n')
00436         f.write('}\n')
00437 
00438         f.write('#endif')
00439 
00440 class Service:
00441     def __init__(self, name, package, definition, md5req, md5res):
00442         """ 
00443         @param name -  name of service
00444         @param package - name of service package
00445         @param definition - list of lines of  definition
00446         """
00447         
00448         self.name = name
00449         self.package = package
00450         
00451         sep_line = None
00452         sep = re.compile('---*')
00453         for i in range(0, len(definition)):
00454             if (None!= re.match(sep, definition[i]) ):
00455                 sep_line = i
00456                 break
00457         self.req_def = definition[0:sep_line]
00458         self.resp_def = definition[sep_line+1:]
00459         
00460         self.req = Message(name+"Request", package, self.req_def, md5req)
00461         self.resp = Message(name+"Response", package, self.resp_def, md5res)
00462         
00463     def make_header(self, f):
00464         f.write('#ifndef _ROS_SERVICE_%s_h\n' % self.name)
00465         f.write('#define _ROS_SERVICE_%s_h\n' % self.name)
00466         
00467         self.req._write_std_includes(f)
00468         includes = self.req.includes
00469         includes.extend(self.resp.includes)
00470         includes = list(set(includes))
00471         for inc in includes:
00472             f.write('#include "%s.h"\n' % inc)
00473             
00474         f.write('\n')
00475         f.write('namespace %s\n' % self.package)
00476         f.write('{\n')
00477         f.write('\n')       
00478         f.write('static const char %s[] = "%s/%s";\n'%(self.name.upper(), self.package, self.name))
00479         
00480         def write_type(out, name):
00481             out.write('    const char * getType(){ return %s; };\n'%(name))
00482         _write_getType = lambda out: write_type(out, self.name.upper())
00483         self.req._write_getType = _write_getType
00484         self.resp._write_getType = _write_getType
00485         
00486         f.write('\n')
00487         self.req._write_impl(f)
00488         f.write('\n')
00489         self.resp._write_impl(f)
00490         f.write('\n')
00491         f.write('  class %s {\n' % self.name )
00492         f.write('    public:\n')
00493         f.write('    typedef %s Request;\n' % self.req.name )
00494         f.write('    typedef %s Response;\n' % self.resp.name )
00495         f.write('  };\n')
00496         f.write('\n')
00497 
00498         f.write('}\n')
00499 
00500         f.write('#endif')
00501         
00502    
00503         
00504 #####################################################################
00505 # Make a Library
00506 
00507 def MakeLibrary(package, output_path):
00508     print "Exporting " + package + "\n", 
00509 
00510     pkg_dir = roslib.packages.get_pkg_dir(package)
00511         
00512     sys.stdout.write('  Messages:')
00513     # find the messages in this package
00514     messages = list()
00515     if os.path.exists(pkg_dir+"/msg"):
00516         sys.stdout.write('\n    ')
00517         for f in os.listdir(pkg_dir+"/msg"):
00518             if f.endswith(".msg"):
00519                 file = pkg_dir + "/msg/" + f
00520                 # add to list of messages
00521                 print "%s," % f[0:-4],
00522                 definition = open(file).readlines()
00523                 md5sum = roslib.gentools.compute_md5(roslib.gentools.get_file_dependencies(file)) 
00524                 messages.append( Message(f[0:-4], package, definition, md5sum) )
00525     print "\n"
00526      
00527     sys.stdout.write('  Services:')
00528     # find the services in this package
00529     services = list()
00530     if (os.path.exists(pkg_dir+"/srv/")):
00531         sys.stdout.write('\n    ')
00532         for f in os.listdir(pkg_dir+"/srv"):
00533             if f.endswith(".srv"):
00534                 file = pkg_dir + "/srv/" + f
00535                 # add to list of messages
00536                 print "%s," % f[0:-4],
00537                 definition, service = roslib.srvs.load_from_file(file)
00538                 definition = open(file).readlines()
00539                 md5req = roslib.gentools.compute_md5(roslib.gentools.get_dependencies(service.request, package))
00540                 md5res = roslib.gentools.compute_md5(roslib.gentools.get_dependencies(service.response, package))
00541                 messages.append( Service(f[0:-4], package, definition, md5req, md5res ) )
00542     print "\n"
00543     
00544     # generate for each message
00545     output_path = output_path + "/" + package
00546     for msg in messages:
00547         if not os.path.exists(output_path):
00548             os.makedirs(output_path)
00549         header = open(output_path + "/" + msg.name + ".h", "w")
00550         msg.make_header(header)
00551         header.close()
00552 
00553 
00554 def add_depends(packages, package):
00555     depend = [package] + roslib.rospack.rospack_depends(package)
00556     for p in depend:
00557         if not p in packages:
00558             packages.append(p)
00559             packages = add_depends(packages, p)
00560     return packages
00561     
00562 if __name__=="__main__":
00563     
00564     # need correct inputs
00565     if (len(sys.argv) <3):
00566         print __usage__
00567         exit()
00568     
00569     # get output path
00570     path = sys.argv[1]
00571     if path[-1] == "/":
00572         path = path[0:-1]
00573     path += "/ros_lib"
00574     print "\nExporting to %s" % path
00575 
00576     packages = list()
00577     # make libraries
00578     for package in sys.argv[2:]:
00579         packages = add_depends(packages, package)
00580 
00581     print packages
00582     for package in packages:
00583         MakeLibrary(package, path)
00584 


rosserial_client
Author(s): Michael Ferguson, Adam Stambler
autogenerated on Fri Dec 6 2013 20:35:51