Module: Orocos

Defined in:
lib/orocos/base.rb,
lib/orocos.rb,
lib/orocos/ros.rb,
lib/orocos/rake.rb,
lib/orocos/test.rb,
lib/orocos/corba.rb,
lib/orocos/ports.rb,
lib/orocos/mqueue.rb,
lib/orocos/ros/rpc.rb,
lib/orocos/process.rb,
lib/orocos/scripts.rb,
lib/orocos/version.rb,
lib/orocos/logging.rb,
lib/orocos/ros/node.rb,
lib/orocos/typekits.rb,
lib/orocos/ros/base.rb,
lib/orocos/namespace.rb,
lib/orocos/ros/ports.rb,
lib/orocos/ros/topic.rb,
lib/orocos/ros/async.rb,
lib/orocos/ports_base.rb,
lib/orocos/test/mocks.rb,
lib/orocos/ruby_tasks.rb,
lib/orocos/extensions.rb,
lib/orocos/operations.rb,
lib/orocos/log/replay.rb,
lib/orocos/task_context.rb,
lib/orocos/name_service.rb,
lib/orocos/input_writer.rb,
lib/orocos/async/orocos.rb,
lib/orocos/output_reader.rb,
lib/orocos/test/component.rb,
lib/orocos/process_server.rb,
lib/orocos/configurations.rb,
lib/orocos/default_loader.rb,
lib/orocos/log/log_marker.rb,
lib/orocos/test/ruby_tasks.rb,
lib/orocos/ruby_tasks/ports.rb,
lib/orocos/ros/name_service.rb,
lib/orocos/ports_searchable.rb,
lib/orocos/log/task_context.rb,
lib/orocos/remote_processes.rb,
lib/orocos/task_context_base.rb,
lib/orocos/ros/name_mappings.rb,
lib/orocos/ruby_task_context.rb,
lib/orocos/ruby_tasks/process.rb,
lib/orocos/ros/process_manager.rb,
lib/orocos/ruby_process_server.rb,
lib/orocos/ruby_tasks/deprecated.rb,
lib/orocos/remote_processes/client.rb,
lib/orocos/ruby_tasks/task_context.rb,
lib/orocos/remote_processes/loader.rb,
lib/orocos/remote_processes/server.rb,
lib/orocos/remote_processes/process.rb,
lib/orocos/remote_processes/protocol.rb,
lib/orocos/ruby_tasks/process_manager.rb,
lib/orocos/remote_processes/deprecated.rb,
lib/orocos/ruby_tasks/stub_task_context.rb,
ext/rorocos/operations.cc

Overview

The Orocos main class

Defined Under Namespace

Modules: Async, Avahi, CORBA, InputPortBase, Local, Log, MQueue, Namespace, OutputPortBase, PortBase, PortsSearchable, ROS, Rake, RemoteProcesses, RubyTasks, Scripts, SelfTest, TaskContextBaseAbstract, Test Classes: AlreadyInitialized, AmbiguousName, Attribute, AttributeBase, CORBANameService, ComError, ConfigurationManager, DefaultLoader, InputPort, InputWriter, InterfaceObjectNotFound, InternalError, NameService, NameServiceBase, NoModel, NotFound, NotInitialized, NotOrogenComponent, Operation, OutputPort, OutputReader, Port, Process, ProcessBase, Property, PropertyChangeRejected, SendHandle, TaskConfigurations, TaskContext, TaskContextAttribute, TaskContextBase, TypekitNotFound

Constant Summary collapse

OROCOSRB_LIB_DIR =
File.expand_path('orocos', File.dirname(__FILE__))
ConfigError =
Deprecated.

use OroGen::ConfigError instead

OroGen::ConfigError
TypekitTypeNotFound =
OroGen::NotTypekitType
TypekitTypeNotExported =
OroGen::NotExportedType
TRANSPORT_MQ =

This is hardcoded here, as we need it to make sure people don't use MQueues on systems where it is not available

The comparison with the actual value from the RTT is done in MQueue.available?

2
VERSION =
"0.1.0"
AUTOLOADED_TRANSPORTS =

The set of transports that should be automatically loaded. The associated boolean is true if an exception should be raised if the typekit fails to load, and false otherwise

{
    'typelib' => true,
    'corba' => true,
    'mqueue' => false,
    'ros' => false
}
RubyProcessServer =
RubyTasks::ProcessManager
RubyDeployment =
RubyTasks::Process
RubyTaskContext =
RubyTasks::TaskContext
LocalInputPort =
RubyTasks::LocalInputPort
LocalOutputPort =
RubyTasks::LocalOutputPort
ProcessClient =
RemoteProcesses::Client
ProcessServer =
RemoteProcesses::Server
RemoteProcess =
RemoteProcesses::Process

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.confObject (readonly)

The main configuration manager object


42
43
44
# File 'lib/orocos/base.rb', line 42

def conf
  @conf
end

.configuration_log_nameObject

Returns the value of attribute configuration_log_name


34
35
36
# File 'lib/orocos/logging.rb', line 34

def configuration_log_name
  @configuration_log_name
end

.default_log_buffer_sizeObject

Returns the value of attribute default_log_buffer_size


3
4
5
# File 'lib/orocos/extensions.rb', line 3

def default_log_buffer_size
  @default_log_buffer_size
end

.extension_modulesObject (readonly)

Returns the value of attribute extension_modules


843
844
845
# File 'lib/orocos/task_context_base.rb', line 843

def extension_modules
  @extension_modules
end

.known_orogen_extensionsObject (readonly)

The set of extension names seen so far

Whenever a new extension is encountered, Orocos.task_model_from_name tries to require 'extension_name/runtime', which might no exist. Once it has done that, it registers the extension name in this set to avoid trying loading it again


141
142
143
# File 'lib/orocos/base.rb', line 141

def known_orogen_extensions
  @known_orogen_extensions
end

.loaded_pluginsObject (readonly)

List of already loaded plugins, as a set of full paths to the shared library


11
12
13
# File 'lib/orocos/typekits.rb', line 11

def loaded_plugins
  @loaded_plugins
end

.loaded_typekit_pluginsObject (readonly)

The set of typekits whose shared libraries have been loaded in this process


7
8
9
# File 'lib/orocos/typekits.rb', line 7

def loaded_typekit_plugins
  @loaded_typekit_plugins
end

.orocos_logfileObject (readonly)

The name of the orocos logfile for this Ruby process


63
64
65
# File 'lib/orocos/base.rb', line 63

def orocos_logfile
  @orocos_logfile
end

.ruby_taskObject (readonly)

RubyTasks::TaskContext

the ruby task context that is used to provide a RTT

interface to this Ruby process. Among other things, it manages the data readers and writers


68
69
70
# File 'lib/orocos/base.rb', line 68

def ruby_task
  @ruby_task
end

Instance Attribute Details

#configuration_log=(value) ⇒ Object (writeonly)

The Pocolog::Logfiles object used by default by Orocos.log_all_configuration. It will automatically be created by Oroocs.configuration_log if Orocos.log_all_configuration is called without an argument


42
43
44
# File 'lib/orocos/logging.rb', line 42

def configuration_log=(value)
  @configuration_log = value
end

Class Method Details

.apply_conf(task, path, names = ['default'], overrides = true) ⇒ Object

Applies the configuration stored in path on task. The selected sections can be listed in names (by default, uses the default configuration).

overrides controls whether the sections listed in names can override each other, if a value set in one of them can be overriden by another one.

path can either be a file or a directory. In the latter case, the configuration stored in path/model_name.yml will be used


960
961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/orocos/configurations.rb', line 960

def self.apply_conf(task, path, names = ['default'], overrides = true)
    if File.directory?(path)
        path = File.join(path, "#{task.model.name}.yml")
        if !File.file?(path)
            return
        end
    end

    conf = TaskConfigurations.new(task.model)
    conf.load_from_yaml(path)
    conf.apply(task, names, overrides)
    task
end

.apply_conf_file(task, path, names = ['default'], overrides = true) ⇒ Object

Deprecated.

use Orocos.apply_conf instead


944
945
946
947
948
949
# File 'lib/orocos/configurations.rb', line 944

def self.apply_conf_file(task, path, names = ['default'], overrides = true)
    conf = TaskConfigurations.new(task.model)
    conf.load_from_yaml(path)
    conf.apply(task, names, overrides)
    task
end

.cleanupObject

Removes dangling references from all name services added to the global name service name_service


60
61
62
# File 'lib/orocos/name_service.rb', line 60

def self.cleanup
    name_service.cleanup
end

.clearObject


197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/orocos/base.rb', line 197

def self.clear
    if !keep_orocos_logfile? && orocos_logfile
        FileUtils.rm_f orocos_logfile
    end

    @ruby_task.dispose if @ruby_task
    default_loader.clear
    known_orogen_extensions.clear

    @max_sizes.clear

    Orocos::CORBA.clear
    @name_service = nil
    if defined? Orocos::Async
        Orocos::Async.clear
    end
    if Orocos::ROS.enabled?
        Orocos::ROS.clear
    end
    @loaded = false
    @initialized = false
end

.configuration_logObject

If Orocos.configuration_log is not set, it creates a new configuration log file that will be used by default by Orocos.log_all_configuration. The log file is named as Orocos.configuration_log_name ('task_configuration' by default). This log file becomes the new default log file for all following calls to Orocos.log_all_configuration


49
50
51
52
53
54
# File 'lib/orocos/logging.rb', line 49

def self.configuration_log
    if !HAS_POCOLOG
        raise ArgumentError, "the pocolog Ruby library is not available, configuration logging cannot be used"
    end
    @configuration_log ||= Pocolog::Logfiles.create(File.expand_path(Orocos.configuration_log_name, Orocos.default_working_directory))
end

.create_or_get_null_type(type_name) ⇒ Object


224
225
226
227
228
229
230
231
232
233
234
# File 'lib/orocos/typekits.rb', line 224

def self.create_or_get_null_type(type_name)
    if registry.include?(type_name)
        type = registry.get type_name
        if !type.null?
            return create_or_get_null_type("/orocos#{type_name}")
        end
        type
    else
        registry.create_null(type_name)
    end
end

.create_orogen_deployment_model(name = nil) ⇒ Object


291
292
293
# File 'lib/orocos/base.rb', line 291

def self.create_orogen_deployment_model(name = nil)
    OroGen::Spec::Deployment.new(default_project, name)
end

.create_orogen_task_context_model(name = nil) ⇒ Object


288
289
290
# File 'lib/orocos/base.rb', line 288

def self.create_orogen_task_context_model(name = nil)
    OroGen::Spec::TaskContext.new(default_project, name)
end

.default_cmdline_argumentsObject

The default commandline arguments that will be passed by default in Orocos.run


33
34
35
# File 'lib/orocos/process.rb', line 33

def self.default_cmdline_arguments
	@default_cmdline_arguments || {}
end

.default_cmdline_arguments=(value) ⇒ Object

Sets the default commandline arguments that will be passed by default in Orocos.run

Use #reset_default_arguments to use the default of the underlying oroGen components


46
47
48
49
50
51
# File 'lib/orocos/process.rb', line 46

def self.default_cmdline_arguments=(value)
	if not default_cmdline_arguments.kind_of?(Hash)
 raise ArgumentError, "Orocos::default_cmdline_arguments expects to be set as hash"
	end
	@default_cmdline_arguments = value
end

.default_file_loaderOroGen::Loaders::Files

The loader object that should be used to register additional oroGen models


94
95
96
97
# File 'lib/orocos/base.rb', line 94

def self.default_file_loader
    Orocos.default_loader
    @default_file_loader ||= OroGen::Loaders::Files.new(default_loader)
end

.default_loaderOroGen::Loaders::Aggregate

The loader object that should be used to load typekits and projects

See Also:


80
81
82
83
84
85
86
87
88
89
# File 'lib/orocos/base.rb', line 80

def self.default_loader
    if !@default_loader
        @default_loader = DefaultLoader.new
        # Instanciate all the sub-loaders 
        default_pkgconfig_loader
        default_file_loader
        ROS.default_loader
    end
    @default_loader
end

.default_pkgconfig_loaderOroGen::Loaders::PkgConfig

The loader object that should be used to load installed oroGen typekits and projects

See Also:


104
105
106
107
# File 'lib/orocos/base.rb', line 104

def self.default_pkgconfig_loader
    Orocos.default_loader
    @default_pkgconfig_loader ||= OroGen::Loaders::PkgConfig.new(orocos_target, default_loader)
end

.default_projectObject

A project that can be used to create models on-the-fly using default_loader


53
54
55
# File 'lib/orocos/base.rb', line 53

def default_project
    @default_project ||= OroGen::Spec::Project.new(Orocos.default_loader)
end

.default_working_directoryObject

The working directory that should be used by default in Orocos.run


7
8
9
# File 'lib/orocos/process.rb', line 7

def self.default_working_directory
    @default_working_directory || Dir.pwd
end

.default_working_directory=(value) ⇒ Object

Sets the working directory that should be used by default in Orocos.run. By default, the current directory at the time where Orocos.run is called is used.

Use #reset_working_directory to use the default of using the current directory.


24
25
26
27
28
29
30
# File 'lib/orocos/process.rb', line 24

def self.default_working_directory=(value)
    value = File.expand_path(value)
    if !File.directory?(value)
        raise ArgumentError, "#{value} is not an existing directory"
    end
    @default_working_directory = value
end

.each_process(&block) ⇒ Object

Enumerates the Orocos::Process objects that are currently available in this Ruby instance


1237
1238
1239
# File 'lib/orocos/process.rb', line 1237

def self.each_process(&block)
    Process.each(&block)
end

.each_task {|TaskContext| ... } ⇒ Object

Enumerates the tasks that are currently available on this sytem (i.e. registered on the global name service name_service).

Yields:

  • (TaskContext)

    code block which is called for each TaskContext


54
55
56
# File 'lib/orocos/name_service.rb', line 54

def self.each_task(&block)
    Orocos.name_service.each_task(&block)
end

.export_types=(value) ⇒ Object

Deprecated.

use default_loader.export_types= instead


24
# File 'lib/orocos/typekits.rb', line 24

def self.export_types=(value); default_loader.export_types = value end

.export_types?Boolean

Deprecated.

use default_loader.export_types? instead


22
# File 'lib/orocos/typekits.rb', line 22

def self.export_types?; default_loader.export_types? end

.extend_task(model_name, &block) ⇒ Object

Requires orocos.rb to extend tasks of the given model with the given block.

For instance, the #log method that is defined on every logger task is implemented with

Orocos.extend_task 'logger::Logger' do
  def log(port, buffer_size = 25)
    # setup the logging component to log the given port
  end
end

859
860
861
# File 'lib/orocos/task_context_base.rb', line 859

def self.extend_task(model_name, &block)
    extension_modules[model_name] << Module.new(&block)
end

.find_orocos_type_name_by_type(type) ⇒ Object


272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/orocos/typekits.rb', line 272

def self.find_orocos_type_name_by_type(type)
    if type.respond_to?(:name)
        type = type.name
    end
    type = default_loader.resolve_type(type)
    type = default_loader.opaque_type_for(type)
    type = default_loader.resolve_interface_type(type)
    if !registered_type?(type.name)
        load_typekit_for(type.name)
    end
    type.name
end

.find_plugin_library(pkg, libname) ⇒ Object

Given a pkg-config file and a base name for a shared library, finds the full path to the library


28
29
30
31
32
33
# File 'lib/orocos/typekits.rb', line 28

def self.find_plugin_library(pkg, libname)
    pkg.library_dirs.find do |dir|
        full_path = File.join(dir, "lib#{libname}.#{Orocos.shared_library_suffix}")
        break(full_path) if File.file?(full_path)
    end
end

.find_type_by_orocos_type_name(orocos_type_name, options = Hash.new) ⇒ Model<Typelib::Type>

Finds the typelib type that maps to the given orocos type name

Options Hash (options):

  • :fallback_to_null_type (Boolean) — default: false

    if true, a new null type with the given orocos type name will be added to the registry and returned if the type cannot be found

Raises:


254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/orocos/typekits.rb', line 254

def self.find_type_by_orocos_type_name(orocos_type_name, options = Hash.new)
    options = Kernel.validate_options options,
        :fallback_to_null_type => false

    if !registered_type?(orocos_type_name)
        load_typekit_for(orocos_type_name)
    end
    typelib_type_for(orocos_type_name)
rescue Orocos::TypekitTypeNotFound, Typelib::NotFound
    # Create an opaque type as a placeholder for the unknown
    # type name
    if options[:fallback_to_null_type]
        type_name = '/' + orocos_type_name.gsub(/[^\w]/, '_')
        create_or_get_null_type(type_name)
    else raise
    end
end

.find_typekit_pkg(name) ⇒ Object


80
81
82
83
84
# File 'lib/orocos/typekits.rb', line 80

def self.find_typekit_pkg(name)
    Utilrb::PkgConfig.new("#{name}-typekit-#{Orocos.orocos_target}")
rescue Utilrb::PkgConfig::NotFound
    raise TypekitNotFound, "the '#{name}' typekit is not available to pkgconfig"
end

.find_typekit_plugin_paths(name, typekit_pkg = nil) ⇒ Array<(String,Boolean)>

Returns the full path of all the plugin libraries that should be loaded for the given typekit

If given, typekit_pkg is the PkgConfig file for the requested typekit


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/orocos/typekits.rb', line 135

def self.find_typekit_plugin_paths(name, typekit_pkg = nil)
    plugins = Hash.new
    libs = Array.new

    plugin_name = typekit_library_name(name, Orocos.orocos_target)
    plugins[plugin_name] = [typekit_pkg || find_typekit_pkg(name), true]
    if OroGen::VERSION >= "0.8"
        AUTOLOADED_TRANSPORTS.each do |transport_name, required|
            plugin_name = transport_library_name(name, transport_name, Orocos.orocos_target)
            begin
                pkg = Utilrb::PkgConfig.new(plugin_name)
                if pkg.disabled != "true"
                    plugins[plugin_name] = [pkg, required]
                elsif required
                    raise NotFound, "the '#{name}' typekit has a #{transport_name} transport installed, but it is disabled"
                end
            rescue Utilrb::PkgConfig::NotFound => e
                if required
                    raise NotFound, "the '#{name}' typekit has no #{transport_name} transport: could not find pkg-config package #{e.name} in #{ENV['PKG_CONFIG_PATH']}"
                end
            end
        end
    end

    plugins.each_pair do |file, (pkg, required)| 
        lib = find_plugin_library(pkg, file)
        if !lib
            if required
                raise NotFound, "cannot find shared library #{file} for #{name} (searched in #{pkg.library_dirs.join(", ")})"
            else
                Orocos.warn "plugin #{file} is registered through pkg-config, but the library cannot be found in #{pkg.library_dirs.join(", ")}"
            end
        else
            libs << [lib, required]
        end
    end
    libs
end

.get(name, options = Hash.new) ⇒ Orocos::TaskContext, Orocos::Log::TaskContext

Gets an handle to a local/remote Orocos Task having the given name.

Options Hash (options):

  • :name (String)

    Overwrites The real name of the task

  • :process (Orocos::Process)

    The process supporting the task

Raises:

See Also:


65
66
67
# File 'lib/orocos/name_service.rb', line 65

def self.get(name, options = Hash.new)
    Orocos.name_service.get(name, options)
end

.guard(*processes_or_tasks) ⇒ Object

Evaluates a block, ensuring that a set of processes or tasks are killed when the control flow leaves it


1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
# File 'lib/orocos/process.rb', line 1243

def self.guard(*processes_or_tasks)
    yield

rescue Interrupt
rescue Exception => e
	Orocos.warn "killing running task contexts and deployments because of unhandled exception"
	Orocos.warn "  #{e.backtrace[0]}: #{e.message}"
	e.backtrace[1..-1].each do |line|
 Orocos.warn "    #{line}"
	end
    raise

ensure
    processes, tasks = processes_or_tasks.partition do |obj|
        obj.kind_of?(Orocos::Process)
    end

    if processes.empty?
        processes = each_process.to_a
    end
    if !tasks.empty?
        processes.each do |p|
            tasks -= p.each_task.to_a
        end
    end

    # NOTE: Process#kill stops all the tasks from the process first, so
    # that's fine.
    tasks.each do |t|
        Orocos.info "guard: stopping task #{t.name}"
        Orocos::Process.try_task_cleanup(t)
    end
    processes.each do |p|
        if p.running?
            Orocos.info "guard: stopping process #{p.name}"
            p.kill(false) 
        end
    end
    processes.each do |p|
        if p.running?
            Orocos.info "guard: joining process #{p.name}"
            p.join
        end
    end
end

.initialize(name = "orocosrb_#{::Process.pid}") ⇒ Object

Initialize the Orocos communication layer and load all the oroGen models that are available.

This method will verify that the pkg-config environment is sane, as it is demanded by the oroGen deployments. If it is not the case, it will raise a RuntimeError exception whose message will describe the particular problem. See the “Error messages” package in the user's guide for more information on how to fix those.


243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/orocos/base.rb', line 243

def self.initialize(name = "orocosrb_#{::Process.pid}")
    if !loaded?
        self.load(name)
    end

    # Install the SIGCHLD handler if it has not been disabled
    if !disable_sigchld_handler?
        trap('SIGCHLD') do
            begin
                while dead = ::Process.wait(-1, ::Process::WNOHANG)
                    if mod = Orocos::Process.from_pid(dead)
                        mod.dead!($?)
                    end
                end
            rescue Errno::ECHILD
            end
        end
    end

    if !Orocos::CORBA.initialized?
        Orocos::CORBA.initialize
    end
    @initialized = true

    if Orocos::ROS.enabled?
        # ROS does not support being teared down and reinitialized.
        if !Orocos::ROS.initialized?
            Orocos::ROS.initialize(name)
        end
    end

    # add default name services
    self.name_service << Orocos::CORBA.name_service
    if defined?(Orocos::ROS) && Orocos::ROS.enabled?
        self.name_service << Orocos::ROS.name_service
    end
    if defined?(Orocos::Async)
        Orocos.name_service.name_services.each do |ns|
            Orocos::Async.name_service.add(ns)
        end
    end
    load_typekit 'std'
    @ruby_task = RubyTasks::TaskContext.new(name)
end

.initialized?Boolean

Returns true if Orocos.initialize has been called and completed successfully


231
232
233
# File 'lib/orocos/base.rb', line 231

def self.initialized?
    @initialized
end

.load(name = nil) ⇒ Object


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/orocos/base.rb', line 168

def self.load(name = nil)
    if @loaded
        raise AlreadyInitialized, "Orocos is already loaded. Try to call 'clear' before callign load a second time."
    end

    if ENV['ORO_LOGFILE'] && orocos_logfile && (ENV['ORO_LOGFILE'] != orocos_logfile)
        raise "trying to change the path to ORO_LOGFILE from #{orocos_logfile} to #{ENV['ORO_LOGFILE']}. This is not supported"
    end
    ENV['ORO_LOGFILE'] ||= File.expand_path("orocos.#{name || 'orocosrb'}-#{::Process.pid}.txt")
    @orocos_logfile = ENV['ORO_LOGFILE']

    @conf = ConfigurationManager.new
    @loaded_typekit_plugins.clear
    @max_sizes = Hash.new { |h, k| h[k] = Hash.new }

    load_standard_typekits

    if Orocos::ROS.enabled?
        if !Orocos::ROS.loaded?
            # Loads all ROS projects that can be found in
            # Orocos::ROS#spec_search_directories
            Orocos::ROS.load
        end
    end
    @loaded = true

    nil
end

.load_all_typekitsObject

Loads all typekits that are available on this system


107
108
109
110
111
# File 'lib/orocos/typekits.rb', line 107

def self.load_all_typekits
    default_pkgconfig_loader.available_typekits.each_key do |typekit_name|
        load_typekit(typekit_name)
    end
end

.load_config_dir(dir) ⇒ Object

Loads a directory containing configuration files

See the documentation of ConfigurationManager#load_dir for more information


149
150
151
# File 'lib/orocos/base.rb', line 149

def self.load_config_dir(dir)
    conf.load_dir(dir)
end

.load_extension_runtime_library(extension_name) ⇒ Object


153
154
155
156
157
158
159
160
161
# File 'lib/orocos/base.rb', line 153

def self.load_extension_runtime_library(extension_name)
    if !known_orogen_extensions.include?(extension_name)
        begin
            require "runtime/#{extension_name}"
        rescue LoadError
        end
        known_orogen_extensions << extension_name
    end
end

.load_plugin_library(libpath) ⇒ Object

Generic loading of a RTT plugin


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/orocos/typekits.rb', line 36

def self.load_plugin_library(libpath) # :nodoc:
    return if @loaded_plugins.include?(libpath)
    if @failed_plugins.include?(libpath)
        @failed_plugins << libpath
        raise "the RTT plugin system already refused to load #{libpath}, I'm not trying again"
    end
    begin
        Orocos.info "loading plugin library #{libpath}"
        if !Orocos.load_rtt_plugin(libpath)
            raise "the RTT plugin system refused to load #{libpath}"
        end
        @loaded_plugins << libpath
    rescue Exception
        @failed_plugins << libpath
        raise
    end
    true
end

.load_typekit(name) ⇒ Object

Load the typekit whose name is given

Typekits are shared libraries that include marshalling/demarshalling code. It gets automatically loaded in orocos.rb whenever you start processes.


72
73
74
75
76
77
78
# File 'lib/orocos/typekits.rb', line 72

def self.load_typekit(name)
    @lock.synchronize do
        typekit = default_pkgconfig_loader.typekit_model_from_name(name)
        typekit_pkg = find_typekit_pkg(name)
        load_typekit_plugins(name, typekit_pkg)
    end
end

.load_typekit_for(typename, exported = true) ⇒ Object

Looks for and loads the typekit that handles the specified type

If exported is true (the default), the type needs to be both defined and exported by the typekit.

Raises ArgumentError if this type is registered nowhere, or if exported is true and the type is not exported.


181
182
183
184
185
186
187
# File 'lib/orocos/typekits.rb', line 181

def self.load_typekit_for(typename, exported = true)
    typekit = default_loader.typekit_for(typename, exported)
    if !typekit.virtual?
        load_typekit typekit.name
    end
    typekit
end

.load_typekit_plugins(name, typekit_pkg = nil) ⇒ Object


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/orocos/typekits.rb', line 86

def self.load_typekit_plugins(name, typekit_pkg = nil)
    if @loaded_typekit_plugins.include?(name)
        return
    end

    find_typekit_plugin_paths(name, typekit_pkg).each do |path, required|
        begin
            load_plugin_library(path)
        rescue Exception => e
            if required
                raise
            else
                Orocos.warn "plugin #{p}, which is registered as an optional transport for the #{name} typekit, cannot be loaded"
                Orocos.log_pp(:warn, e)
            end
        end
    end
    @loaded_typekit_plugins << name
end

.loaded?Boolean

Returns true if Orocos.load has been called


164
165
166
# File 'lib/orocos/base.rb', line 164

def self.loaded?
    @loaded
end

.log_allObject


4
5
6
7
# File 'lib/orocos/logging.rb', line 4

def self.log_all
    log_all_ports
    log_all_configuration
end

.log_all_configuration(logfile = nil) ⇒ Object


56
57
58
59
60
61
62
63
# File 'lib/orocos/logging.rb', line 56

def self.log_all_configuration(logfile = nil)
    logfile ||= configuration_log
    each_process do |process|
        process.each_task do |t|
            t.log_all_configuration(logfile)
        end
    end
end

.log_all_ports(exclude_ports: nil, exclude_types: nil, tasks: nil) ⇒ Object

Setup logging on all output ports of the processes started with Orocos.run

This method is designed to be called within an Orocos.run block

Examples:

log all ports whose name does not start with 'io_'

Orocos.log_all_ports(exclude_ports: /^io_/)

log all ports whose type name does not contain 'debug'

Orocos.log_all_ports(exclude_types: /debug/)

27
28
29
30
31
# File 'lib/orocos/logging.rb', line 27

def self.log_all_ports(exclude_ports: nil, exclude_types: nil, tasks: nil)
    each_process do |process|
        process.log_all_ports(exclude_ports: exclude_ports, exclude_types: exclude_types, tasks: tasks)
    end
end

.log_all_process_ports(process, options = Hash.new) ⇒ Object

Common implementation of log_all_ports for a single process

This is shared by local and remote processes alike


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/orocos/logging.rb', line 68

def self.log_all_process_ports(process, options = Hash.new)
    options, logger_options = Kernel.filter_options options,
        :tasks => nil, :exclude_ports => nil, :exclude_types => nil

    tasks = options[:tasks]
    exclude_ports = options[:exclude_ports]
    exclude_types = options[:exclude_types]

    if !(logger = process.setup_default_logger(logger_options))
        return Set.new
    end

    logged_ports = Set.new
    process.task_names.each do |task_name|
        task = TaskContext.get(task_name)
        next if task == logger
        next if tasks && !(tasks === task_name)

        task.each_output_port do |port|
            next if exclude_ports && exclude_ports === port.name
            next if exclude_types && exclude_types === port.type.name
            next if block_given? && !yield(port)

            Orocos.info "logging % 50s of type %s" % ["#{task.name}:#{port.name}", port.type.name]
            logged_ports << [task.name, port.name]
            logger.log(port)
        end
    end
    if !logger.running?
        logger.start
    end

    logged_ports
end

.macos?Boolean


110
111
112
# File 'lib/orocos/base.rb', line 110

def self.macos?
    @macos
end

.max_sizes( = >Hash) ⇒ Hash<String,Hash> .max_sizes('/namespace/Compound', 'to[].field' = >10, 'other' = >20) ⇒ Object

Gets or update known maximum size for variable-sized containers in types

This method can only be called after Orocos.load

Size specification is path.to.field => size, where [] is used to get elements of an array or variable-size container.

If type is a container itself, the second form is used, where the first argument is the container size and the rest specifies its element sizes (and must start with [])

For instance, with the types

struct A
{
    std::vector<int> values;
};
struct B
{
    std::vector<A> field;
};

Then sizes of type B would be given with

max_sizes('/B', 'field' => 10, 'field[].values' => 20)

while the sizes of /std/vector</A> would be given with

max_sizes('/std/vector</A>', 10, '[].values' => 20)

Finally, for /std/vector</std/vector</A>>, one would use

max_sizes('/std/vector</std/vector</A>>, 10, '[]' => 20, '[][].values' => 30)

Overloads:

  • .max_sizes( = >Hash) ⇒ Hash<String,Hash>

    Gets all known maximum sizes

  • .max_sizes('/namespace/Compound', 'to[].field' = >10, 'other' = >20) ⇒ Object

    Updates the known maximum sizes for the given type. When updating, any new field value will erase old ones, unless a block is given in which case the block is given the old and new values and should return the value that should be stored


332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/orocos/typekits.rb', line 332

def self.max_sizes(typename = nil, *sizes, &block)
    if !@max_sizes
        raise ArgumentError, "cannot call Orocos.max_sizes before Orocos.load"
    end

    if !typename && sizes.empty?
        return @max_sizes
    end

    type = default_loader.resolve_type(typename)
    type = default_loader.intermediate_type_for(type)
    sizes = OroGen::Spec::Port.validate_max_sizes_spec(type, sizes)
    @max_sizes[type.name].merge!(sizes, &block)
end

.max_sizes_for(type) ⇒ Hash

Returns the max size specification for the given type


352
353
354
355
356
357
# File 'lib/orocos/typekits.rb', line 352

def self.max_sizes_for(type)
    if type.respond_to?(:name)
        type = type.name
    end
    @max_sizes.fetch(type, Hash.new)
end

.name_serviceOrocos::NameService

Returns the global name service abstracting all underlying name services. This should be the default way to acquire an handle to an Orocos Task by its name. If the IOR of the task is already known TaskContext should directly be used.

Examples:

getting a remote/local task context.

require 'orocos'
Orocos.initialize 
task = Orocos.name_service.get "task_name"

changing the default underlying CORBA name service

Orocos::CORBA.name_service.ip = "host_name"
Orocos.initialize
task = Orocos.name_service.get 'task_name'

adding a second CORBA name service

Orocos.name_service << Orocos::CORBA::NameService.new("192.168.101.12")
Orocos.initialize
task = Orocos.name_service.get 'task_name'

adding a second CORBA name service having a namespace

Orocos.name_service << Orocos::CORBA::NameService.new("192.168.101.12",:namespace => "robot")
Orocos.initialize
task = Orocos.name_service.get 'robot/task_name'

adding an Avahi name service

Orocos.name_service << Orocos::Avahi::NameService.new("_robot._tcp")
Orocos.initialize
task = Orocos.name_service.get 'task_name'

33
34
35
# File 'lib/orocos/name_service.rb', line 33

def self.name_service
    @name_service ||= NameService.new()
end

.name_service=(name_service) ⇒ Object


37
38
39
# File 'lib/orocos/name_service.rb', line 37

def self.name_service=(name_service)
    @name_service = name_service
end

.normalize_typename(typename) ⇒ Object


359
360
361
362
# File 'lib/orocos/typekits.rb', line 359

def self.normalize_typename(typename)
    load_typekit_for(typename)
    registry.get(typename).name
end

.orocos_targetObject


126
127
128
129
130
131
132
# File 'lib/orocos/base.rb', line 126

def self.orocos_target
    if ENV['OROCOS_TARGET']
        ENV['OROCOS_TARGET']
    else
        'gnulinux'
    end
end

.orocos_type_for(typelib_type) ⇒ Object

Finds the C++ type that maps to the given typelib type name


239
240
241
# File 'lib/orocos/typekits.rb', line 239

def self.orocos_type_for(typelib_type)
    default_loader.opaque_type_for(typelib_type)
end

.plugin_libs_for_name(name) ⇒ Object

For backward compatibility only. Use #find_typekit_plugin_paths instead


122
123
124
# File 'lib/orocos/typekits.rb', line 122

def self.plugin_libs_for_name(name)
    find_typekit_plugin_paths(name).map(&:first)
end

.register_pkgconfig_path(path) ⇒ Object


27
28
29
30
# File 'lib/orocos/base.rb', line 27

def self.register_pkgconfig_path(path)
	base_path = caller(1).first.gsub(/:\d+:.*/, '')
	ENV['PKG_CONFIG_PATH'] = "#{File.expand_path(path, File.dirname(base_path))}:#{ENV['PKG_CONFIG_PATH']}"
end

.registryTypelib::Registry

The registry that is the union of all loaded typekits


47
48
49
# File 'lib/orocos/base.rb', line 47

def registry
    default_loader.registry
end

.resetObject


220
221
222
223
# File 'lib/orocos/base.rb', line 220

def self.reset
    clear
    load
end

.reset_default_cmdline_argumentsObject

Resets the default arguments that should be used by default in Orocos.run which is the default setting of the underlying oroGen components


39
40
41
# File 'lib/orocos/process.rb', line 39

def self.reset_default_cmdline_arguments
	@default_cmdline_arguments = {}
end

.reset_working_directoryObject

Resets the working directory that should be used by default in Orocos.run to its default, that is the current directory at the time where Orocos.run is called is used.


14
15
16
# File 'lib/orocos/process.rb', line 14

def self.reset_working_directory
    @default_working_directory = nil
end

.Orocos.run('mod1', 'mod2') { ... } ⇒ Object .Orocos.run('mod1', 'mod2' = >'prefix') { ... } ⇒ Object .Orocos.run('mod1', 'mod2' = >'prefix', 'project::Task' = >'task_name') { ... } ⇒ Object

call-seq:

Orocos.run('mod1', 'mod2')
Orocos.run('mod1', 'mod2', wait: false, output: '%m-%p.log')
Orocos.run('mod1', 'mod2', wait: false, output: '%m-%p.log') do |mod1, mod2|
end

Valid options are:

wait

wait that number of seconds (can be floating-point) for the processes to be ready. If it did not start into the provided timeout, an Orocos::NotFound exception raised.

output

redirect the process output to the given file. The %m and %p patterns will be replaced by respectively the name and the PID of each process.

valgrind

start some or all the processes under valgrind. It can either be an array of process names (e.g. valgrind: ['p1', 'p2']) or 'true'. In the first case, the listed processes will be added to the list of processes to start (if they are not already in it) and will be started under valgrind. In the second case, all processes are started under valgrind.

valgrind_options

an array of options that should be passed to valgrind, e.g.

valgrind_options: ["--track-origins=yes"]
cmdline_args

When command line arguments are available to deployments, they can be set using the following option:

cmdline_args: { "sd-domain" => '_robot._tcp', "prefix" => "test" }

This will be mapped to '–sd-domain=_robot._tcp –prefix=test'

Existing commandline arguments: –sd-domain

the service discovery domain in which this process should be published This is only supported by deployments and orogen if the service_discovery package has been installed along with orogen The sd domain is of the format: <name>.<suffix> where the suffix has to be one of _tcp or _udp

Overloads:

  • .Orocos.run('mod1', 'mod2') { ... } ⇒ Object

    Starts a list of deployments. The deployment names are as given to the 'deployment' statement in oroGen

    Yields:

    • a block that is evaluated, ensuring that all tasks and processes are killed when the execution flow leaves the block. The block is given to guard

  • .Orocos.run('mod1', 'mod2' = >'prefix') { ... } ⇒ Object

    Starts a list of deployments. The prefix is prepended to all tasks in the 'mod2' deployment. The deployment names are as given to the 'deployment' statement in oroGen

    Yields:

    • a block that is evaluated, ensuring that all tasks and processes are killed when the execution flow leaves the block. The block is given to guard

  • .Orocos.run('mod1', 'mod2' = >'prefix', 'project::Task' = >'task_name') { ... } ⇒ Object

    Starts a list of deployments. The prefix is prepended to all tasks in the 'mod2' deployment, and a process is spawned to deploy a single task of model 'project::Task' (as defined in oroGen). task_name in this case becomes the task's name, as can be resolved by Orocos.get.

    Yields:

    • a block that is evaluated, ensuring that all tasks and processes are killed when the execution flow leaves the block. The block is given to guard


135
136
137
# File 'lib/orocos/process.rb', line 135

def self.run(*args, **options, &block)
    Process.run(*args, **options, &block)
end

.shared_library_suffixObject


119
120
121
122
123
124
# File 'lib/orocos/base.rb', line 119

def self.shared_library_suffix
    if macos? then 'dylib'
    elsif windows? then 'dll'
    else 'so'
    end
end

.spawn(*args, &block) ⇒ Object

Deprecated. Use Orocos.run instead.


140
141
142
143
# File 'lib/orocos/process.rb', line 140

def self.spawn(*args, &block)
    STDERR.puts "#{caller(1)}: Orocos.spawn is deprecated, use Orocos.run instead"
    run(*args, &block)
end

.task_model_from_name(*args, &block) ⇒ Object

Deprecated.

access default_loader.task_model_from_name directly instead


296
297
298
# File 'lib/orocos/base.rb', line 296

def self.task_model_from_name(*args, &block)
    default_loader.task_model_from_name(*args, &block)
end

.task_namesObject

Deprecated.

Returns the task names that are registered on CORBA

You should use Orocos.name_service.names


46
47
48
# File 'lib/orocos/name_service.rb', line 46

def self.task_names
    name_service.names
end

.tracing=(flag) ⇒ Object


57
58
59
# File 'lib/orocos/process.rb', line 57

def self.tracing=(flag)
    @tracing_enabled = flag
end

.tracing?Boolean


53
54
55
# File 'lib/orocos/process.rb', line 53

def self.tracing?
    !!@tracing_enabled
end

.tracing_library_pathObject


61
62
63
# File 'lib/orocos/process.rb', line 61

def self.tracing_library_path
    File.join(Utilrb::PkgConfig.new("orocos-rtt-#{Orocos.orocos_target}").libdir, "liborocos-rtt-traces-#{Orocos.orocos_target}.so")
end

.transport_library_name(typekit_name, transport_name, target) ⇒ Object


117
118
119
# File 'lib/orocos/typekits.rb', line 117

def self.transport_library_name(typekit_name, transport_name, target)
    "#{typekit_name}-transport-#{transport_name}-#{target}"
end

.type_export_namespaceObject

Deprecated.

use default_loader.type_export_namespace instead


18
# File 'lib/orocos/typekits.rb', line 18

def self.type_export_namespace; default_loader.type_export_namespace end

.type_export_namespace=(namespace) ⇒ Object

Deprecated.

use default_loader.type_export_namespace= instead


20
# File 'lib/orocos/typekits.rb', line 20

def self.type_export_namespace=(namespace); default_loader.type_export_namespace = namespace end

.typekit_library_name(typekit_name, target) ⇒ Object


113
114
115
# File 'lib/orocos/typekits.rb', line 113

def self.typekit_library_name(typekit_name, target)
    "#{typekit_name}-typekit-#{target}"
end

.typelib_type_for(t) ⇒ Object

Returns the type that is used to manipulate t in Typelib

For simple types, it is t itself. For opaque types, it will be the corresponding marshalling type. The returned value is a subclass of Typelib::Type

Raises Typelib::NotFound if this type is not registered anywhere.


196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/orocos/typekits.rb', line 196

def self.typelib_type_for(t)
    if t.respond_to?(:name)
        return t if !t.contains_opaques?
        t = t.name
    end

    begin
        if typelib_type = do_typelib_type_for(t)
            return registry.get(typelib_type)
        end
    rescue ArgumentError
    end

    if registry.include?(t)
        type = registry.get(t)
        if type.contains_opaques?
            default_loader.intermediate_type_for(type)
        elsif type.null?
            # 't' is an opaque type and there are no typelib marshallers
            # to convert it to something we can manipulate, raise
            raise Typelib::NotFound, "#{t} is a null type and there are no typelib marshallers registered in RTT to convert it to a typelib-compatible type"
        else type
        end
    else
        raise Typelib::NotFound, "#{t} cannot be found in the currently loaded registries"
    end
end

.watch(*objects, &block) ⇒ Object

Deprecated.

renamed to Orocos::Scripts.watch

– TODO move the code and test


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/orocos/scripts.rb', line 5

def self.watch(*objects, &block)
    options = Hash.new
    if objects.last.kind_of?(Hash)
        options = objects.pop
    end
    options = Kernel.validate_options options, :sleep => 0.1, :display => true, :main => nil

    tasks, ports = objects.partition do |obj|
        obj.kind_of?(TaskContext)
    end
    ports, readers = ports.partition do |obj|
        obj.kind_of?(OutputPort)
    end

    tasks = tasks.sort_by { |t| t.name }
    readers.concat(ports.map { |p| p.reader })
    readers = readers.sort_by { |r| r.port.full_name }
    readers = readers.map do |r|
        [r, r.new_sample]
    end

    dead_processes = Set.new
    
    should_quit = false
    while true
        updated_tasks = Set.new
        updated_ports = Set.new

        needs_display = true
        while needs_display
            needs_display = false
            info = tasks.map do |t|
                if t.process && !t.process.running?
                    if !dead_processes.include?(t)
                        needs_display = true
                        updated_tasks << t
                        dead_processes << t
                        "#{t.name}=DEAD"
                    end
                elsif t.state_changed?
                    needs_display = true
                    updated_tasks << t
                    "#{t.name}=#{t.state(false)}"
                else
                    "#{t.name}=#{t.current_state}"
                end
            end

            if needs_display
                puts info.join(" | ")
            end
        end

        readers.each do |r, sample|
            while r.read_new(sample)
                puts "new data on #{r.port.full_name}"
                updated_ports << r.port
                if options[:display]
                    pp = PP.new(STDOUT)
                    pp.nest(2) do
                        pp.breakable
                        sample.pretty_print(pp)
                    end
                end
            end
        end

        if should_quit
            break
        end

        if block_given?
            should_quit = yield(updated_tasks, updated_ports) 
        end
        if options[:main]
            should_quit = !options[:main].runtime_state?(options[:main].peek_current_state)
        end
        sleep options[:sleep]
    end
end

.windows?Boolean


115
116
117
# File 'lib/orocos/base.rb', line 115

def self.windows?
    @windows
end