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 from __future__ import print_function
00037 
00038 __author__ = "mferguson@willowgarage.com (Michael Ferguson)"
00039 
00040 import roslib
00041 import roslib.srvs
00042 import roslib.message
00043 import traceback
00044 
00045 import os, sys, re
00046 
00047 # for copying files
00048 import shutil
00049 
00050 def type_to_var(ty):
00051     lookup = {
00052         1 : 'uint8_t',
00053         2 : 'uint16_t',
00054         4 : 'uint32_t',
00055         8 : 'uint64_t',
00056     }
00057     return lookup[ty]
00058 
00059 #####################################################################
00060 # Data Types
00061 
00062 class EnumerationType:
00063     """ For data values. """
00064 
00065     def __init__(self, name, ty, value):
00066         self.name = name
00067         self.type = ty
00068         self.value = value
00069 
00070     def make_declaration(self, f):
00071         f.write('      enum { %s = %s };\n' % (self.name, self.value))
00072 
00073 class PrimitiveDataType:
00074     """ Our datatype is a C/C++ primitive. """
00075 
00076     def __init__(self, name, ty, bytes):
00077         self.name = name
00078         self.type = ty
00079         self.bytes = bytes
00080 
00081     def make_initializer(self, f, trailer):
00082         f.write('      %s(0)%s\n' % (self.name, trailer))
00083 
00084     def make_declaration(self, f):
00085         f.write('      typedef %s _%s_type;\n      _%s_type %s;\n' % (self.type, self.name, self.name, 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 
00123     def make_initializer(self, f, trailer):
00124         f.write('      %s()%s\n' % (self.name, trailer))
00125 
00126     def serialize(self, f):
00127         f.write('      offset += this->%s.serialize(outbuffer + offset);\n' % self.name)
00128 
00129     def deserialize(self, f):
00130         f.write('      offset += this->%s.deserialize(inbuffer + offset);\n' % self.name)
00131 
00132 
00133 class AVR_Float64DataType(PrimitiveDataType):
00134     """ AVR C/C++ has no native 64-bit support, we automatically convert to 32-bit float. """
00135 
00136     def make_initializer(self, f, trailer):
00137         f.write('      %s(0)%s\n' % (self.name, trailer))
00138 
00139     def make_declaration(self, f):
00140         f.write('      typedef float _%s_type;\n      _%s_type %s;\n' % (self.name, self.name, self.name) )
00141 
00142     def serialize(self, f):
00143         f.write('      offset += serializeAvrFloat64(outbuffer + offset, this->%s);\n' % self.name)
00144 
00145     def deserialize(self, f):
00146         f.write('      offset += deserializeAvrFloat64(inbuffer + offset, &(this->%s));\n' % self.name)
00147 
00148 
00149 class StringDataType(PrimitiveDataType):
00150     """ Need to convert to signed char *. """
00151 
00152     def make_initializer(self, f, trailer):
00153         f.write('      %s("")%s\n' % (self.name, trailer))
00154 
00155     def make_declaration(self, f):
00156         f.write('      typedef const char* _%s_type;\n      _%s_type %s;\n' % (self.name, self.name, self.name) )
00157 
00158     def serialize(self, f):
00159         cn = self.name.replace("[","").replace("]","")
00160         f.write('      uint32_t length_%s = strlen(this->%s);\n' % (cn,self.name))
00161         f.write('      varToArr(outbuffer + offset, length_%s);\n' % cn)
00162         f.write('      offset += 4;\n')
00163         f.write('      memcpy(outbuffer + offset, this->%s, length_%s);\n' % (self.name,cn))
00164         f.write('      offset += length_%s;\n' % cn)
00165 
00166     def deserialize(self, f):
00167         cn = self.name.replace("[","").replace("]","")
00168         f.write('      uint32_t length_%s;\n' % cn)
00169         f.write('      arrToVar(length_%s, (inbuffer + offset));\n' % cn)
00170         f.write('      offset += 4;\n')
00171         f.write('      for(unsigned int k= offset; k< offset+length_%s; ++k){\n'%cn) #shift for null character
00172         f.write('          inbuffer[k-1]=inbuffer[k];\n')
00173         f.write('      }\n')
00174         f.write('      inbuffer[offset+length_%s-1]=0;\n'%cn)
00175         f.write('      this->%s = (char *)(inbuffer + offset-1);\n' % self.name)
00176         f.write('      offset += length_%s;\n' % cn)
00177 
00178 
00179 class TimeDataType(PrimitiveDataType):
00180 
00181     def __init__(self, name, ty, bytes):
00182         self.name = name
00183         self.type = ty
00184         self.sec = PrimitiveDataType(name+'.sec','uint32_t',4)
00185         self.nsec = PrimitiveDataType(name+'.nsec','uint32_t',4)
00186 
00187     def make_initializer(self, f, trailer):
00188         f.write('      %s()%s\n' % (self.name, trailer))
00189 
00190     def make_declaration(self, f):
00191         f.write('      typedef %s _%s_type;\n      _%s_type %s;\n' % (self.type, self.name, self.name, self.name) )
00192 
00193     def serialize(self, f):
00194         self.sec.serialize(f)
00195         self.nsec.serialize(f)
00196 
00197     def deserialize(self, f):
00198         self.sec.deserialize(f)
00199         self.nsec.deserialize(f)
00200 
00201 
00202 class ArrayDataType(PrimitiveDataType):
00203 
00204     def __init__(self, name, ty, bytes, cls, array_size=None):
00205         self.name = name
00206         self.type = ty
00207         self.bytes = bytes
00208         self.size = array_size
00209         self.cls = cls
00210 
00211     def make_initializer(self, f, trailer):
00212         if self.size == None:
00213             f.write('      %s_length(0), %s(NULL)%s\n' % (self.name, self.name, trailer))
00214         else:
00215             f.write('      %s()%s\n' % (self.name, trailer))
00216 
00217     def make_declaration(self, f):
00218         if self.size == None:
00219             f.write('      uint32_t %s_length;\n' % self.name)
00220             f.write('      typedef %s _%s_type;\n' % (self.type, self.name))
00221             f.write('      _%s_type st_%s;\n' % (self.name, self.name)) # static instance for copy
00222             f.write('      _%s_type * %s;\n' % (self.name, self.name))
00223         else:
00224             f.write('      %s %s[%d];\n' % (self.type, self.name, self.size))
00225 
00226     def serialize(self, f):
00227         c = self.cls(self.name+"[i]", self.type, self.bytes)
00228         if self.size == None:
00229             # serialize length
00230             f.write('      *(outbuffer + offset + 0) = (this->%s_length >> (8 * 0)) & 0xFF;\n' % self.name)
00231             f.write('      *(outbuffer + offset + 1) = (this->%s_length >> (8 * 1)) & 0xFF;\n' % self.name)
00232             f.write('      *(outbuffer + offset + 2) = (this->%s_length >> (8 * 2)) & 0xFF;\n' % self.name)
00233             f.write('      *(outbuffer + offset + 3) = (this->%s_length >> (8 * 3)) & 0xFF;\n' % self.name)
00234             f.write('      offset += sizeof(this->%s_length);\n' % self.name)
00235             f.write('      for( uint32_t i = 0; i < %s_length; i++){\n' % self.name)
00236             c.serialize(f)
00237             f.write('      }\n')
00238         else:
00239             f.write('      for( uint32_t i = 0; i < %d; i++){\n' % (self.size) )
00240             c.serialize(f)
00241             f.write('      }\n')
00242 
00243     def deserialize(self, f):
00244         if self.size == None:
00245             c = self.cls("st_"+self.name, self.type, self.bytes)
00246             # deserialize length
00247             f.write('      uint32_t %s_lengthT = ((uint32_t) (*(inbuffer + offset))); \n' % self.name)
00248             f.write('      %s_lengthT |= ((uint32_t) (*(inbuffer + offset + 1))) << (8 * 1); \n' % self.name)
00249             f.write('      %s_lengthT |= ((uint32_t) (*(inbuffer + offset + 2))) << (8 * 2); \n' % self.name)
00250             f.write('      %s_lengthT |= ((uint32_t) (*(inbuffer + offset + 3))) << (8 * 3); \n' % self.name)
00251             f.write('      offset += sizeof(this->%s_length);\n' % self.name)
00252             f.write('      if(%s_lengthT > %s_length)\n' % (self.name, self.name))
00253             f.write('        this->%s = (%s*)realloc(this->%s, %s_lengthT * sizeof(%s));\n' % (self.name, self.type, self.name, self.name, self.type))
00254             f.write('      %s_length = %s_lengthT;\n' % (self.name, self.name))
00255             # copy to array
00256             f.write('      for( uint32_t i = 0; i < %s_length; i++){\n' % (self.name) )
00257             c.deserialize(f)
00258             f.write('        memcpy( &(this->%s[i]), &(this->st_%s), sizeof(%s));\n' % (self.name, self.name, self.type))
00259             f.write('      }\n')
00260         else:
00261             c = self.cls(self.name+"[i]", self.type, self.bytes)
00262             f.write('      for( uint32_t i = 0; i < %d; i++){\n' % (self.size) )
00263             c.deserialize(f)
00264             f.write('      }\n')
00265 
00266 #####################################################################
00267 # Messages
00268 
00269 class Message:
00270     """ Parses message definitions into something we can export. """
00271     global ROS_TO_EMBEDDED_TYPES
00272 
00273     def __init__(self, name, package, definition, md5):
00274 
00275         self.name = name            # name of message/class
00276         self.package = package      # package we reside in
00277         self.md5 = md5              # checksum
00278         self.includes = list()      # other files we must include
00279 
00280         self.data = list()          # data types for code generation
00281         self.enums = list()
00282 
00283         # parse definition
00284         for line in definition:
00285             # prep work
00286             line = line.strip().rstrip()
00287             value = None
00288             if line.find("#") > -1:
00289                 line = line[0:line.find("#")]
00290             if line.find("=") > -1:
00291                 try:
00292                     value = line[line.find("=")+1:]
00293                 except:
00294                     value = '"' + line[line.find("=")+1:] + '"';
00295                 line = line[0:line.find("=")]
00296 
00297             # find package/class name
00298             line = line.replace("\t", " ")
00299             l = line.split(" ")
00300             while "" in l:
00301                 l.remove("")
00302             if len(l) < 2:
00303                 continue
00304             ty, name = l[0:2]
00305             if value != None:
00306                 self.enums.append( EnumerationType(name, ty, value))
00307                 continue
00308 
00309             try:
00310                 type_package, type_name = ty.split("/")
00311             except:
00312                 type_package = None
00313                 type_name = ty
00314             type_array = False
00315             if type_name.find('[') > 0:
00316                 type_array = True
00317                 try:
00318                     type_array_size = int(type_name[type_name.find('[')+1:type_name.find(']')])
00319                 except:
00320                     type_array_size = None
00321                 type_name = type_name[0:type_name.find('[')]
00322 
00323             # convert to C type if primitive, expand name otherwise
00324             try:
00325                 code_type = ROS_TO_EMBEDDED_TYPES[type_name][0]
00326                 size = ROS_TO_EMBEDDED_TYPES[type_name][1]
00327                 cls = ROS_TO_EMBEDDED_TYPES[type_name][2]
00328                 for include in ROS_TO_EMBEDDED_TYPES[type_name][3]:
00329                     if include not in self.includes:
00330                         self.includes.append(include)
00331             except:
00332                 if type_package == None:
00333                     type_package = self.package
00334                 if type_package+"/"+type_name not in self.includes:
00335                     self.includes.append(type_package+"/"+type_name)
00336                 cls = MessageDataType
00337                 code_type = type_package + "::" + type_name
00338                 size = 0
00339             if type_array:
00340                 self.data.append( ArrayDataType(name, code_type, size, cls, type_array_size ) )
00341             else:
00342                 self.data.append( cls(name, code_type, size) )
00343 
00344     def _write_serializer(self, f):
00345                 # serializer
00346         f.write('    virtual int serialize(unsigned char *outbuffer) const\n')
00347         f.write('    {\n')
00348         f.write('      int offset = 0;\n')
00349         for d in self.data:
00350             d.serialize(f)
00351         f.write('      return offset;\n');
00352         f.write('    }\n')
00353         f.write('\n')
00354 
00355     def _write_deserializer(self, f):
00356         # deserializer
00357         f.write('    virtual int deserialize(unsigned char *inbuffer)\n')
00358         f.write('    {\n')
00359         f.write('      int offset = 0;\n')
00360         for d in self.data:
00361             d.deserialize(f)
00362         f.write('     return offset;\n');
00363         f.write('    }\n')
00364         f.write('\n')
00365 
00366     def _write_std_includes(self, f):
00367         f.write('#include <stdint.h>\n')
00368         f.write('#include <string.h>\n')
00369         f.write('#include <stdlib.h>\n')
00370         f.write('#include "ros/msg.h"\n')
00371 
00372     def _write_msg_includes(self,f):
00373         for i in self.includes:
00374             f.write('#include "%s.h"\n' % i)
00375 
00376     def _write_constructor(self, f):
00377         f.write('    %s()%s\n' % (self.name, ':' if self.data else ''))
00378         if self.data:
00379             for d in self.data[:-1]:
00380                 d.make_initializer(f, ',')
00381             self.data[-1].make_initializer(f, '')
00382         f.write('    {\n    }\n\n')
00383 
00384     def _write_data(self, f):
00385         for d in self.data:
00386             d.make_declaration(f)
00387         for e in self.enums:
00388             e.make_declaration(f)
00389         f.write('\n')
00390 
00391     def _write_getType(self, f):
00392         f.write('    const char * getType(){ return "%s/%s"; };\n'%(self.package, self.name))
00393 
00394     def _write_getMD5(self, f):
00395         f.write('    const char * getMD5(){ return "%s"; };\n'%self.md5)
00396 
00397     def _write_impl(self, f):
00398         f.write('  class %s : public ros::Msg\n' % self.name)
00399         f.write('  {\n')
00400         f.write('    public:\n')
00401         self._write_data(f)
00402         self._write_constructor(f)
00403         self._write_serializer(f)
00404         self._write_deserializer(f)
00405         self._write_getType(f)
00406         self._write_getMD5(f)
00407         f.write('\n')
00408         f.write('  };\n')
00409 
00410     def make_header(self, f):
00411         f.write('#ifndef _ROS_%s_%s_h\n'%(self.package, self.name))
00412         f.write('#define _ROS_%s_%s_h\n'%(self.package, self.name))
00413         f.write('\n')
00414         self._write_std_includes(f)
00415         self._write_msg_includes(f)
00416 
00417         f.write('\n')
00418         f.write('namespace %s\n' % self.package)
00419         f.write('{\n')
00420         f.write('\n')
00421         self._write_impl(f)
00422         f.write('\n')
00423         f.write('}\n')
00424 
00425         f.write('#endif')
00426 
00427 class Service:
00428     def __init__(self, name, package, definition, md5req, md5res):
00429         """
00430         @param name -  name of service
00431         @param package - name of service package
00432         @param definition - list of lines of  definition
00433         """
00434 
00435         self.name = name
00436         self.package = package
00437 
00438         sep_line = len(definition)
00439         sep = re.compile('---*')
00440         for i in range(0, len(definition)):
00441             if (None!= re.match(sep, definition[i]) ):
00442                 sep_line = i
00443                 break
00444         self.req_def = definition[0:sep_line]
00445         self.resp_def = definition[sep_line+1:]
00446 
00447         self.req = Message(name+"Request", package, self.req_def, md5req)
00448         self.resp = Message(name+"Response", package, self.resp_def, md5res)
00449 
00450     def make_header(self, f):
00451         f.write('#ifndef _ROS_SERVICE_%s_h\n' % self.name)
00452         f.write('#define _ROS_SERVICE_%s_h\n' % self.name)
00453 
00454         self.req._write_std_includes(f)
00455         includes = self.req.includes
00456         includes.extend(self.resp.includes)
00457         includes = list(set(includes))
00458         for inc in includes:
00459             f.write('#include "%s.h"\n' % inc)
00460 
00461         f.write('\n')
00462         f.write('namespace %s\n' % self.package)
00463         f.write('{\n')
00464         f.write('\n')
00465         f.write('static const char %s[] = "%s/%s";\n'%(self.name.upper(), self.package, self.name))
00466 
00467         def write_type(out, name):
00468             out.write('    const char * getType(){ return %s; };\n'%(name))
00469         _write_getType = lambda out: write_type(out, self.name.upper())
00470         self.req._write_getType = _write_getType
00471         self.resp._write_getType = _write_getType
00472 
00473         f.write('\n')
00474         self.req._write_impl(f)
00475         f.write('\n')
00476         self.resp._write_impl(f)
00477         f.write('\n')
00478         f.write('  class %s {\n' % self.name )
00479         f.write('    public:\n')
00480         f.write('    typedef %s Request;\n' % self.req.name )
00481         f.write('    typedef %s Response;\n' % self.resp.name )
00482         f.write('  };\n')
00483         f.write('\n')
00484 
00485         f.write('}\n')
00486 
00487         f.write('#endif\n')
00488 
00489 
00490 #####################################################################
00491 # Make a Library
00492 
00493 def MakeLibrary(package, output_path, rospack):
00494     pkg_dir = rospack.get_path(package)
00495 
00496     # find the messages in this package
00497     messages = list()
00498     if os.path.exists(pkg_dir+"/msg"):
00499         print('Exporting %s\n'%package)
00500         sys.stdout.write('  Messages:')
00501         sys.stdout.write('\n    ')
00502         for f in os.listdir(pkg_dir+"/msg"):
00503             if f.endswith(".msg"):
00504                 msg_file = pkg_dir + "/msg/" + f
00505                 # add to list of messages
00506                 print('%s,'%f[0:-4], end='')
00507                 definition = open(msg_file).readlines()
00508                 msg_class = roslib.message.get_message_class(package+'/'+f[0:-4])
00509                 if msg_class:
00510                     md5sum = msg_class._md5sum
00511                     messages.append( Message(f[0:-4], package, definition, md5sum) )
00512                 else:
00513                     err_msg = "Unable to build message: %s/%s\n" % (package, f[0:-4])
00514                     sys.stderr.write(err_msg)
00515 
00516     # find the services in this package
00517     if (os.path.exists(pkg_dir+"/srv/")):
00518         if messages == list():
00519             print('Exporting %s\n'%package)
00520         else:
00521             print('\n')
00522         sys.stdout.write('  Services:')
00523         sys.stdout.write('\n    ')
00524         for f in os.listdir(pkg_dir+"/srv"):
00525             if f.endswith(".srv"):
00526                 srv_file = pkg_dir + "/srv/" + f
00527                 # add to list of messages
00528                 print('%s,'%f[0:-4], end='')
00529                 definition, service = roslib.srvs.load_from_file(srv_file)
00530                 definition = open(srv_file).readlines()
00531                 srv_class = roslib.message.get_service_class(package+'/'+f[0:-4])
00532                 if srv_class:
00533                     md5req = srv_class._request_class._md5sum
00534                     md5res = srv_class._response_class._md5sum
00535                     messages.append( Service(f[0:-4], package, definition, md5req, md5res ) )
00536                 else:
00537                     err_msg = "Unable to build service: %s/%s\n" % (package, f[0:-4])
00538                     sys.stderr.write(err_msg)
00539         print('\n')
00540     elif messages != list():
00541         print('\n')
00542 
00543     # generate for each message
00544     output_path = output_path + "/" + package
00545     for msg in messages:
00546         if not os.path.exists(output_path):
00547             os.makedirs(output_path)
00548         header = open(output_path + "/" + msg.name + ".h", "w")
00549         msg.make_header(header)
00550         header.close()
00551 
00552 def rosserial_generate(rospack, path, mapping):
00553     # horrible hack -- make this die
00554     global ROS_TO_EMBEDDED_TYPES
00555     ROS_TO_EMBEDDED_TYPES = mapping
00556 
00557     # gimme messages
00558     failed = []
00559     for p in sorted(rospack.list()):
00560         try:
00561             MakeLibrary(p, path, rospack)
00562         except Exception as e:
00563             failed.append(p + " ("+str(e)+")")
00564             print('[%s]: Unable to build messages: %s\n' % (p, str(e)))
00565             print(traceback.format_exc())
00566     print('\n')
00567     if len(failed) > 0:
00568         print('*** Warning, failed to generate libraries for the following packages: ***')
00569         for f in failed:
00570             print('    %s'%f)
00571         raise Exception("Failed to generate libraries for: " + str(failed))
00572     print('\n')
00573 
00574 def rosserial_client_copy_files(rospack, path):
00575     os.makedirs(path+"/ros")
00576     os.makedirs(path+"/tf")
00577     files = ['duration.cpp',
00578              'time.cpp',
00579              'ros/duration.h',
00580              'ros/msg.h',
00581              'ros/node_handle.h',
00582              'ros/publisher.h',
00583              'ros/service_client.h',
00584              'ros/service_server.h',
00585              'ros/subscriber.h',
00586              'ros/time.h',
00587              'tf/tf.h',
00588              'tf/transform_broadcaster.h']
00589     mydir = rospack.get_path("rosserial_client")
00590     for f in files:
00591         shutil.copy(mydir+"/src/ros_lib/"+f, path+f)
00592 


rosserial_client
Author(s): Michael Ferguson, Adam Stambler
autogenerated on Sat Oct 7 2017 03:08:37