def _add_msgs_depends(spec, deps, package_context, includepath): """ Add the list of message types that spec depends on to depends. @param spec: message to compute dependencies for @type spec: rosidl.msgs.MsgSpec/rosidl.srvs.SrvSpec @param deps [str]: list of dependencies. This list will be updated with the dependencies of spec when the method completes @type deps: [str] """ log("_add_msgs_depends <spec>", deps, package_context) for t in spec.types: t = rosidl.msgs.base_msg_type(t) if not rosidl.msgs.is_builtin(t): # special mapping for header if t == rosidl.msgs.HEADER: # have to re-names Header deps.append(_header_type_name) if rosidl.msgs.is_registered(t): depspec = rosidl.msgs.get_registered(t) if t != rosidl.msgs.HEADER: if '/' in t: deps.append(t) else: deps.append(package_context+'/'+t) else: #lazy-load key, depspec = rosidl.msgs.load_by_type(t, includepath, package_context) if t != rosidl.msgs.HEADER: deps.append(key) rosidl.msgs.register(key, depspec) _add_msgs_depends(depspec, deps, package_context, includepath)
def load_package_dependencies(package, load_recursive=False): """ Register all messages that the specified package depends on. @param load_recursive: (optional) if True, load all dependencies, not just direct dependencies. By default, this is false to prevent packages from incorrectly inheriting dependencies. @type load_recursive: bool """ global _loaded_packages _init() log("Load dependencies for package", package) if not load_recursive: manifest_file = rosidl.manifest.manifest_file(package, True) m = rosidl.manifest.parse_file(manifest_file) depends = [d.package for d in m.depends] # #391 else: depends = rosidl.rospack.rospack_depends(package) msgs = [] failures = [] for d in depends: log("Load dependency", d) #check if already loaded # - we are dependent on manifest.getAll returning first-order dependencies first if d in _loaded_packages or d == package: continue _loaded_packages.append(d) specs, failed = get_pkg_msg_specs(d) msgs.extend(specs) failures.extend(failed) for key, spec in msgs: register(key, spec)
def register(msg_type_name, msg_spec): """ Load MsgSpec into the type dictionary @param msg_type_name: name of message type @type msg_type_name: str @param msg_spec: spec to load @type msg_spec: L{MsgSpec} """ log("Register msg %s"%msg_type_name) REGISTERED_TYPES[msg_type_name] = msg_spec
def load_package(package): """ Load package into the local registered namespace. All messages found in the package will be registered if they are successfully loaded. This should only be done with one package (i.e. the 'main' package) per Python instance. @param package: package name @type package: str """ global _loaded_packages _init() log("Load package", package) #check if already loaded # - we are dependent on manifest.getAll returning first-order dependencies first if package in _loaded_packages: log("Package %s is already loaded" % package) return _loaded_packages.append(package) specs, failed = get_pkg_msg_specs(package) log("Package contains the following messages: %s" % specs) for key, spec in specs: #register spec under both local and fully-qualified key register(key, spec) register(package + rosidl.names.PRN_SEPARATOR + key, spec)
def load_from_file(file_path, package_context=''): """ Convert the .msg representation in the file to a MsgSpec instance. This does *not* register the object. @param file_path: path of file to load from @type file_path: str: @param package_context: package name to prepend to type name or '' to use local (relative) naming convention. @type package_context: str @return: Message type name and message specification @rtype: (str, L{MsgSpec}) @raise MsgSpecException: if syntax errors or other problems are detected in file """ if package_context: log("Load spec from", file_path, "into package [%s]"%package_context) else: log("Load spec from", file_path) file_name = os.path.basename(file_path) type_ = file_name[:-len(EXT)] base_type_ = type_ # determine the type name if package_context: while package_context.endswith(SEP): package_context = package_context[:-1] #strip message separators type_ = "%s%s%s"%(package_context, SEP, type_) if not rosidl.names.is_legal_resource_name(type_): raise MsgSpecException("%s: [%s] is not a legal type name"%(file_path, type_)) f = open(file_path, 'r') try: try: text = f.read() return (type_, load_from_string(text, package_context, type_, base_type_)) except MsgSpecException, e: raise MsgSpecException('%s: %s'%(file_name, e)) finally: f.close()
def msg_file(package, type_, searchpath): """ Determine the file system path for the specified .msg on path .msg resource does not have to exist. @param package: name of package .msg file is in @type package: str @param type_: type name of message, e.g. 'Point2DFloat32' @type type_: str @return: file path of .msg file in specified package @rtype: str """ log("msg_file(%s, %s, %s)" % (package, type_, str(searchpath))) assert isinstance(searchpath, list) for p in searchpath: j = os.path.join(p, "msg", type_ + ".msg") log(j, "???") if os.path.isfile(j): return j # FIXME: 'hardcoded' path return os.path.dirname(os.path.dirname(rosidl.__path__[0])) + "/msg/" + type_ + ".msg"
def load_by_type(msgtype, includepath, package_context=''): """ Load message specification for specified type @param package_context: package name to use for the type name or '' to use the local (relative) naming convention. @type package_context: str @return: Message type name and message specification @rtype: (str, L{MsgSpec}) """ assert isinstance(includepath, list) log("load_by_type(%s, %s, %s)" % (msgtype, str(includepath), package_context)) pkg, basetype = rosidl.names.package_resource_name(msgtype) pkg = pkg or package_context # convert '' -> local package log("pkg", pkg) log("here") m_f = msg_file(pkg, basetype, includepath) log("m_f", m_f) return load_from_file(m_f, pkg)
def generate(args): """ Generate a message @param msg_path: The path to the .msg file @type msg_path: str """ log("generate(%s)" % args) from optparse import OptionParser parser = OptionParser("generates c++ message serialization code") parser.add_option('-p', dest='package', help="package name") parser.add_option('-o', dest='outdir', help="absolute path to output directory") parser.add_option('-I', dest='includepath', help="include path to search for messages", action='append') (options, args) = parser.parse_args(args) if not isinstance(options.includepath, list): options.includepath = [] # print "input==", options.input, "outdir==", options.outdir # package = os.path.basename # (package_dir, package) = rosidl.packages.get_dir_pkg(args[1]) rosidl.msgs._init() (_, spec) = rosidl.msgs.load_from_file(args[1], options.package) plog("spec", spec) s = StringIO() write_begin(s, spec, args[1]) write_generic_includes(s) write_includes(s, spec) cpp_prefix = '%s::'%(options.package) s.write('namespace %s\n{\n'%(options.package)) write_struct(s, spec, cpp_prefix, options.includepath) write_constant_definitions(s, spec) write_ostream_operator(s, spec, cpp_prefix) s.write('} // namespace %s\n\n'%(options.package)) write_traits(s, spec, cpp_prefix, options.includepath) write_serialization(s, spec, cpp_prefix) write_operations(s, spec, cpp_prefix) if options.package == "std_msgs" and spec.short_name == "Header": s.write("#define STD_MSGS_INCLUDING_HEADER_DEPRECATED_DEF 1\n") s.write("#include <std_msgs/header_deprecated_def.h>\n") s.write("#undef STD_MSGS_INCLUDING_HEADER_DEPRECATED_DEF\n\n") write_end(s, spec) if 'ROS_BUILD' in os.environ: package_dir = os.environ['ROS_BUILD'] odir = os.path.join(options.outdir, options.package) if (not os.path.exists(odir)): # if we're being run concurrently, the above test can report false but os.makedirs can still fail if # another copy just created the directory try: os.makedirs(odir) except OSError, e: pass
def generate(args): """ Generate a message @param msg_path: The path to the .msg file @type msg_path: str """ log("generate(%s)" % args) from optparse import OptionParser parser = OptionParser("generates c++ message serialization code") parser.add_option('-p', dest='package', help="package name") parser.add_option('-o', dest='outdir', help="absolute path to output directory") parser.add_option('-I', dest='includepath', help="include path to search for messages", action='append') (options, args) = parser.parse_args(args) if not isinstance(options.includepath, list): options.includepath = [] # print "input==", options.input, "outdir==", options.outdir # package = os.path.basename # (package_dir, package) = rosidl.packages.get_dir_pkg(args[1]) rosidl.msgs._init() (_, spec) = rosidl.msgs.load_from_file(args[1], options.package) plog("spec", spec) s = StringIO() write_begin(s, spec, args[1]) write_generic_includes(s) write_includes(s, spec) cpp_prefix = '%s::' % (options.package) s.write('namespace %s\n{\n' % (options.package)) write_struct(s, spec, cpp_prefix, options.includepath) write_constant_definitions(s, spec) write_ostream_operator(s, spec, cpp_prefix) s.write('} // namespace %s\n\n' % (options.package)) write_traits(s, spec, cpp_prefix, options.includepath) write_serialization(s, spec, cpp_prefix) write_operations(s, spec, cpp_prefix) if options.package == "std_msgs" and spec.short_name == "Header": s.write("#define STD_MSGS_INCLUDING_HEADER_DEPRECATED_DEF 1\n") s.write("#include <std_msgs/header_deprecated_def.h>\n") s.write("#undef STD_MSGS_INCLUDING_HEADER_DEPRECATED_DEF\n\n") write_end(s, spec) if 'ROS_BUILD' in os.environ: package_dir = os.environ['ROS_BUILD'] odir = os.path.join(options.outdir, options.package) if (not os.path.exists(odir)): # if we're being run concurrently, the above test can report false but os.makedirs can still fail if # another copy just created the directory try: os.makedirs(odir) except OSError, e: pass
def generate(srv_path, options): """ Generate a service @param srv_path: the path to the .srv file @type srv_path: str """ # (package_dir, package) = roslib.packages.get_dir_pkg(srv_path) (_, spec) = rosidl.srvs.load_from_file(srv_path, options.package) s = StringIO() cpp_prefix = '%s::' % (options.package) write_begin(s, spec, srv_path) genmsg_cpp.write_generic_includes(s) write_generic_includes(s) genmsg_cpp.write_includes(s, spec.request) s.write('\n') genmsg_cpp.write_includes(s, spec.response) gendeps_dict = rosidl.gentools.get_dependencies(spec, spec.package, options.includepath, compute_files=False) md5sum = rosidl.gentools.compute_md5(gendeps_dict, options.includepath) s.write('namespace %s\n{\n' % (options.package)) genmsg_cpp.write_struct(s, spec.request, cpp_prefix, {'ServerMD5Sum': md5sum}) s.write('\n') genmsg_cpp.write_struct(s, spec.response, cpp_prefix, {'ServerMD5Sum': md5sum}) s.write('struct %s\n{\n' % (spec.short_name)) s.write('\n') s.write('typedef %s Request;\n' % (spec.request.short_name)) s.write('typedef %s Response;\n' % (spec.response.short_name)) s.write('Request request;\n') s.write('Response response;\n\n') s.write('typedef Request RequestType;\n') s.write('typedef Response ResponseType;\n') s.write('}; // struct %s\n' % (spec.short_name)) s.write('} // namespace %s\n\n' % (options.package)) request_cpp_name = "Request" response_cpp_name = "Response" log("options.includepath", str(options.includepath)) genmsg_cpp.write_traits(s, spec.request, cpp_prefix, options.includepath) s.write('\n') genmsg_cpp.write_traits(s, spec.response, cpp_prefix, options.includepath) genmsg_cpp.write_serialization(s, spec.request, cpp_prefix) s.write('\n') genmsg_cpp.write_serialization(s, spec.response, cpp_prefix) write_traits(s, spec, cpp_prefix, options.includepath) write_end(s, spec) if 'ROS_BUILD' in os.environ: package_dir = os.environ['ROS_BUILD'] output_dir = os.path.join(options.outdir, options.package) if (not os.path.exists(output_dir)): # if we're being run concurrently, the above test can report false but os.makedirs can still fail if # another copy just created the directory try: os.makedirs(output_dir) except OSError, e: pass
def generate(srv_path, options): """ Generate a service @param srv_path: the path to the .srv file @type srv_path: str """ # (package_dir, package) = roslib.packages.get_dir_pkg(srv_path) (_, spec) = rosidl.srvs.load_from_file(srv_path, options.package) s = StringIO() cpp_prefix = '%s::'%(options.package) write_begin(s, spec, srv_path) genmsg_cpp.write_generic_includes(s) write_generic_includes(s) genmsg_cpp.write_includes(s, spec.request) s.write('\n') genmsg_cpp.write_includes(s, spec.response) gendeps_dict = rosidl.gentools.get_dependencies(spec, spec.package, options.includepath, compute_files=False) md5sum = rosidl.gentools.compute_md5(gendeps_dict, options.includepath) s.write('namespace %s\n{\n'%(options.package)) genmsg_cpp.write_struct(s, spec.request, cpp_prefix, {'ServerMD5Sum': md5sum}) s.write('\n') genmsg_cpp.write_struct(s, spec.response, cpp_prefix, {'ServerMD5Sum': md5sum}) s.write('struct %s\n{\n'%(spec.short_name)) s.write('\n') s.write('typedef %s Request;\n'%(spec.request.short_name)) s.write('typedef %s Response;\n'%(spec.response.short_name)) s.write('Request request;\n') s.write('Response response;\n\n') s.write('typedef Request RequestType;\n') s.write('typedef Response ResponseType;\n') s.write('}; // struct %s\n'%(spec.short_name)) s.write('} // namespace %s\n\n'%(options.package)) request_cpp_name = "Request" response_cpp_name = "Response" log("options.includepath", str(options.includepath)) genmsg_cpp.write_traits(s, spec.request, cpp_prefix, options.includepath) s.write('\n') genmsg_cpp.write_traits(s, spec.response, cpp_prefix, options.includepath) genmsg_cpp.write_serialization(s, spec.request, cpp_prefix) s.write('\n') genmsg_cpp.write_serialization(s, spec.response, cpp_prefix) write_traits(s, spec, cpp_prefix, options.includepath) write_end(s, spec) if 'ROS_BUILD' in os.environ: package_dir = os.environ['ROS_BUILD'] output_dir = os.path.join(options.outdir, options.package) if (not os.path.exists(output_dir)): # if we're being run concurrently, the above test can report false but os.makedirs can still fail if # another copy just created the directory try: os.makedirs(output_dir) except OSError, e: pass