Class: OroGen::ROS::Loader

Inherits:
Loaders::Base show all
Defined in:
lib/orogen/ros/loader.rb

Direct Known Subclasses

DefaultLoader

Instance Attribute Summary collapse

Attributes inherited from Loaders::Base

#interface_typelist, #loaded_deployment_models, #loaded_projects, #loaded_task_models, #loaded_typekits, #project_load_callbacks, #registry, #root_loader, #typekit_load_callbacks, #typekits_by_type_name

Instance Method Summary collapse

Methods inherited from Loaders::Base

#added_child, #define_dummy_types=, #define_dummy_types?, #deployed_task_model_from_name, #deployment_model_from_name, #each_available_project_name, #find_deployments_from_deployed_task_name, #find_project_from_deployment_name, #find_task_library_from_task_model_name, #has_loaded_project?, #has_loaded_typekit?, #imported_typekits_for, #inspect, #interface_type?, #intermediate_type?, #intermediate_type_for, #m_type?, #on_project_load, #on_typekit_load, #opaque_type_for, #project_model_from_text, #register_deployment_model, #register_project_model, #register_task_context_model, #register_type_model, #register_typekit_model, #remove_project_load_callback, #resolve_interface_type, #resolve_type, #task_library_model_from_name, #task_model_from_name, #typekit_model_from_name, #typelib_type_for

Constructor Details

#initialize(root_loader = self) ⇒ Loader

Returns a new instance of Loader



22
23
24
25
26
27
28
29
30
# File 'lib/orogen/ros/loader.rb', line 22

def initialize(root_loader = self)
    @spec_file_suffix = ".orogen"

    super(root_loader)

    root_loader.on_typekit_load do |tk|
        load_rosmap_by_package_name(tk.name)
    end
end

Instance Attribute Details

#orogen_to_ros_mappingsHash<String,String> (readonly)

Returns mapping from typelib type names to the corresponding ROS message name

Returns:

  • (Hash<String,String>)

    mapping from typelib type names to the corresponding ROS message name



17
18
19
# File 'lib/orogen/ros/loader.rb', line 17

def orogen_to_ros_mappings
  @orogen_to_ros_mappings
end

#package_pathsHash<String,String> (readonly)

Returns mapping from a package name to its full path. This is used as both a cache for ROS.rospack_find, and as a way to register paths for launchfiles on systems that do not have ROS installed

Returns:

  • (Hash<String,String>)

    mapping from a package name to its full path. This is used as both a cache for ROS.rospack_find, and as a way to register paths for launchfiles on systems that do not have ROS installed



14
15
16
# File 'lib/orogen/ros/loader.rb', line 14

def package_paths
  @package_paths
end

#packsObject (readonly)

Returns the value of attribute packs



5
6
7
# File 'lib/orogen/ros/loader.rb', line 5

def packs
  @packs
end

#ros_to_orogen_mappingsHash<String,String> (readonly)

Returns mapping from ROS message names to typelib type names

Returns:

  • (Hash<String,String>)

    mapping from ROS message names to typelib type names



20
21
22
# File 'lib/orogen/ros/loader.rb', line 20

def ros_to_orogen_mappings
  @ros_to_orogen_mappings
end

#search_pathObject (readonly)

Returns the value of attribute search_path



4
5
6
# File 'lib/orogen/ros/loader.rb', line 4

def search_path
  @search_path
end

#spec_file_suffixString

Returns the suffix of files that contain ROS package models

Returns:

  • (String)

    the suffix of files that contain ROS package models



9
10
11
# File 'lib/orogen/ros/loader.rb', line 9

def spec_file_suffix
  @spec_file_suffix
end

Instance Method Details

#clearObject



32
33
34
35
36
37
38
39
# File 'lib/orogen/ros/loader.rb', line 32

def clear
    super
    @search_path = Array.new
    @packs = Array.new
    @package_paths = Hash.new
    @orogen_to_ros_mappings = Hash.new
    @ros_to_orogen_mappings = Hash.new
end

#compatible_message_type?(message_type) ⇒ Boolean

Check if a given ROS message type can be accessed on this side

At first call, it calls load_all_rosmaps to load all the known mappings

Returns:

  • (Boolean)


214
215
216
# File 'lib/orogen/ros/loader.rb', line 214

def compatible_message_type?(message_type)
    ros_to_orogen_mappings.has_key?(message_type)
end

#find_all_types_for(message_name) ⇒ Object

Get the list of oroGen types that can be used to communicate with a given ROS message name

At first call, it calls load_all_rosmaps to load all the known mappings



206
207
208
# File 'lib/orogen/ros/loader.rb', line 206

def find_all_types_for(message_name)
    ros_to_orogen_mappings[message_name] || Set.new
end

#find_project_file_from_name(name) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/orogen/ros/loader.rb', line 71

def find_project_file_from_name(name)
    search_path.each do |dir|
        file = File.join(dir, "#{name}#{spec_file_suffix}")
        if File.file?(file)
            return file
        end
    end
    nil
end

#find_rosmap_by_package_name(name) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/orogen/ros/loader.rb', line 43

def find_rosmap_by_package_name(name)
    OroGen::TypekitMarshallers::ROS.load_rosmap_by_package_name(name)
rescue ArgumentError
rescue Utilrb::PkgConfig::NotFound
    # Nothing installed, look into the pack_paths
    packs.each do |dir|
        rosmap_path = File.join(dir, "#{name}.rosmap")
        if File.file?(rosmap_path)
            return OroGen::TypekitMarshallers::ROS.load_rosmap(rosmap_path)
        end
    end
    nil
end

#has_project?(name) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/orogen/ros/loader.rb', line 81

def has_project?(name)
    !!find_project_file_from_name(name)
end

#has_typekit?(name) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/orogen/ros/loader.rb', line 85

def has_typekit?(name)
    false
end

#load_all_rosmaps(typekits) ⇒ Object

Loads all known mappings from the oroGen types to the ROS messages. Builds a reverse mapping as well



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/orogen/ros/loader.rb', line 183

def load_all_rosmaps(typekits)
    orogen_to_ros_mappings.clear
    ros_to_orogen_mappings.clear

    typekits.each do |name|
        find_rosmap_by_package_name(name)
    end

    rosmaps.each do |rosmap|
        orogen_to_ros_mappings.merge! rosmap
        rosmap.each do |type_name, ros_name, _|
            set = (ros_to_orogen_mappings[ros_name] ||= Set.new)
            set << type_name
        end
    end
    nil
end

#load_rosmap_by_package_name(name) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/orogen/ros/loader.rb', line 57

def load_rosmap_by_package_name(name)
    rosmaps = find_rosmap_by_package_name(name)
    return if !rosmaps

    rosmaps = [rosmaps, OroGen::TypekitMarshallers::ROS::DEFAULT_TYPE_TO_MSG]
    rosmaps.each do |rosmap|
        orogen_to_ros_mappings.merge! rosmap
        rosmap.each do |type_name, ros_name, _|
            set = (ros_to_orogen_mappings[ros_name] ||= Set.new)
            set << type_name
        end
    end
end

#map_message_type_to_orogen(message_type) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/orogen/ros/loader.rb', line 173

def map_message_type_to_orogen(message_type)
    orogen_types = find_all_types_for(message_type)
    if orogen_types.empty?
        raise ArgumentError, "there are not oroGen equivalent for #{message_type}"
    end
    orogen_types.first
end

#project_model_from_name(name) ⇒ OroGen::Spec::Project

Returns the project model corresponding to the given name

Parameters:

  • the (String)

    project name

Returns:

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/orogen/ros/loader.rb', line 95

def project_model_from_name(name)
    if project = loaded_projects[name]
        return project
    end

    name = name.to_str

    text, path = project_model_text_from_name(name)

    ROS.info "loading model for ROS package #{name}"
    project = Spec::Package.new(root_loader, self)
    project.typekit = OroGen::Spec::Typekit.new(root_loader, name)

    # ROS packages don't have the same issue than oroGen, namely
    # there is no code generation so we don't need an intermediate
    # as oroGen needs
    project.__eval__(path, text)
    register_project_model(project)
    project
end

#project_model_text_from_name(name) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/orogen/ros/loader.rb', line 116

def project_model_text_from_name(name)
    path = find_project_file_from_name(name)
    if !path
        raise OroGen::ProjectNotFound, "could not find an oroGen model for the ROS package #{name} in #{search_path.inspect}"
    end
    return File.read(path), path
end

#register_package_path(package_name, path) ⇒ void

This method returns an undefined value.

Manually registers the path to a package



131
132
133
# File 'lib/orogen/ros/loader.rb', line 131

def register_package_path(package_name, path)
    package_paths[package_name] = path
end

#roslaunch_find(package_name, name) ⇒ String

Finds the path to a given ROS launch file

Returns:

  • (String)


160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/orogen/ros/loader.rb', line 160

def roslaunch_find(package_name, name)
    package_path = rospack_find(package_name)
    launchfile_name = "#{name}.launch"
    path = File.join(package_path, "launch", launchfile_name)
    alternative_path = File.join(package_path, launchfile_name)
    if File.file?(path)
        return path
    elsif File.file?(alternative_path)
        return alternative_path
    else raise ArgumentError, "package #{package_name} has no launch file #{launchfile_name} (looked for #{path} and #{alternative_path})"
    end
end

#rospack_find(package_name) ⇒ String

Find the path of a ros package

Returns:

  • (String)

    Path to the rospackage



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/orogen/ros/loader.rb', line 137

def rospack_find(package_name)
    if path = package_paths[package_name]
        return path
    end

    # Look for it in the packs
    packs.each do |pack_dir|
        pkg_dir = File.join(pack_dir, package_name)
        if File.directory?(pkg_dir)
            package_paths[package_name] = pkg_dir
            return pkg_dir
        end
    end

    package_path = (`rospack find #{package_name}` || '').strip
    if package_path.empty?
        raise ArgumentError, "rospack cannot find package #{package_name}"
    end
    package_paths[package_name] = package_path
end

#to_sObject



41
# File 'lib/orogen/ros/loader.rb', line 41

def to_s; "#<#{self.class.name} packs=#{packs.inspect} search_path=#{search_path.inspect}>" end

#typekit_model_text_from_name(name) ⇒ Object



124
125
126
# File 'lib/orogen/ros/loader.rb', line 124

def typekit_model_text_from_name(name)
    raise OroGen::TypekitNotFound, "ROS packages define no typekits (was looking for #{name})"
end