module Roby

The main namespace for the Roby library. The namespace is divided as follows:

Roby

core namespace for the Roby kernel

Roby::Actions

basic tools for plan generation

Roby::Transactions

implementation of transactions. Transactions represent a

change in the main plan, and can be distributed among different plan managers.

Roby::EventStructure

main namespace for event relations. The methods listed

in the documentation of EventStructure are actually methods of Roby::EventGenerator

Roby::TaskStructure

main namespace for task relations. The methods listed in

the documentation of TaskStructure are actually methods of Roby::Task

Constants

BIN_DIR
Conf

The main configuration object

EventStructure
LOG_SYMBOLIC_TO_NUMERIC
NullTask

For backward-compatibility only

ROBY_LIB_DIR
ROBY_ROOT_DIR
RX_IN_FRAMEWORK

Regular expression that matches backtrace paths that are within the Roby framework

RX_IN_METARUBY
RX_IN_UTILRB
RX_REQUIRE

Regular expression that matches backtrace paths that are require lines

SelfTest
State

The main state object

TaskService
TaskStructure
VERSION
VirtualTask

For backward-compatibility

Attributes

colorizer[R]
conf[R]

The one and only ConfModel object

deprecation_warnings_are_errors[RW]
enable_deprecation_warnings[RW]
state[R]

The one and only StateSpace object

Public Class Methods

RelationSpace(klass) click to toggle source

Creates a new relation space which applies on klass. If a block is given, it is eval'd in the context of the new relation space instance

# File lib/roby/relations.rb, line 57
def self.RelationSpace(klass)
    klass.include Relations::DirectedRelationSupport
    klass.extend  Relations::Models::DirectedRelationSupport
    relation_space = Relations::Space.new
    relation_space.apply_on klass
    relation_space
end
app() click to toggle source

The one and only Application object

# File lib/roby/singletons.rb, line 7
def app
    @app ||= Application.new
end
color(string, *colors) click to toggle source
# File lib/roby/exceptions.rb, line 14
def self.color(string, *colors)
    colorizer.decorate(string, *colors)
end
control() click to toggle source

The control / policy object

This is the object that defines the core execution policies (e.g. what to do if the dependency of a non-running task stops). See {DecisionControl}

# File lib/roby/singletons.rb, line 54
def control
    app.plan.execution_engine.control
end
disable_colors() click to toggle source
# File lib/roby/exceptions.rb, line 18
def self.disable_colors
    @colorizer = Pastel.new(enabled: false)
end
display_exception(io = STDOUT, e = nil, filter_backtraces = nil) { || ... } click to toggle source
# File lib/roby/exceptions.rb, line 493
def self.display_exception(io = STDOUT, e = nil, filter_backtraces = nil)
    if !filter_backtraces.nil?
        old_filter_backtraces = Roby.app.filter_backtraces?
        Roby.app.filter_backtraces = filter_backtraces
    end

    if !block_given?
        if !e
            raise ArgumentError, "expected an exception object as no block was given"
        end
        do_display_exception(io, e)
        e
    else
        yield
        false
    end

rescue Interrupt, SystemExit
    raise
rescue Exception => e
    if e.user_error?
        io.print color(e.message, :bold, :red)
    else
        do_display_exception(io, e)
    end
    e

ensure
    if !filter_backtraces.nil?
        Roby.app.filter_backtraces = old_filter_backtraces
    end
end
do_display_exception(io, e) click to toggle source
# File lib/roby/exceptions.rb, line 439
def self.do_display_exception(io, e)
    if colorizer.enabled?
        do_display_exception_formatted(io, e)
    else
        do_display_exception_raw(io, e)
    end

    if e.respond_to?(:original_exceptions)
        e.original_exceptions.each do |original_e|
            do_display_exception(io, original_e)
        end
    end
end
do_display_exception_formatted(io, e) click to toggle source
# File lib/roby/exceptions.rb, line 470
def self.do_display_exception_formatted(io, e)
    first_line = true
    io.puts ""
    format_exception(e).each do |line|
        if first_line
            io.print color("= ", :bold, :red)
            io.puts color(line, :bold, :red)
            first_line = false
        else
            io.print color("| ", :bold, :red)
            io.puts line
        end
    end
    io.puts color("= Backtrace", :bold, :red)
    format_exception(BacktraceFormatter.new(e)).each do |line|
        io.print color("| ", :bold, :red)
        io.puts line
    end
    io.puts color("= ", :bold, :red)
    true
end
do_display_exception_raw(io, e) click to toggle source
# File lib/roby/exceptions.rb, line 453
def self.do_display_exception_raw(io, e)
    first_line = true
    io.puts
    format_exception(e).each do |line|
        if first_line
            io.puts line
            first_line = false
        else
            io.puts "  #{line}"
        end
    end
    format_exception(BacktraceFormatter.new(e)).each do |line|
        io.puts line
    end
    true
end
each_cycle(&block) click to toggle source

Make the main engine call block during each propagation step. See ExecutionEngine#each_cycle

# File lib/roby/execution_engine.rb, line 2617
def self.each_cycle(&block); execution_engine.each_cycle(&block) end
enable_colors() click to toggle source
# File lib/roby/exceptions.rb, line 26
def self.enable_colors
    @colorizer = Pastel.new(enabled: true)
end
enable_colors_if_available() click to toggle source
# File lib/roby/exceptions.rb, line 22
def self.enable_colors_if_available
    @colorizer = Pastel.new
end
engine() click to toggle source

@deprecated use {Roby.execution_engine} instead

# File lib/roby/singletons.rb, line 68
def engine
    Roby.warn_deprecated "Roby.engine is deprecated, use Roby.execution_engine instead"
    app.execution_engine
end
error_deprecated(msg, caller_depth = 1) click to toggle source
# File lib/roby/support.rb, line 128
def self.error_deprecated(msg, caller_depth = 1)
    Roby.fatal "Deprecation Error: #{msg} at #{caller[1, caller_depth].join("\n")}"
    raise NotImplementedError
end
every(duration, options = Hash.new, &block) click to toggle source

Install a periodic handler on the main engine

# File lib/roby/execution_engine.rb, line 2620
def self.every(duration, options = Hash.new, &block); execution_engine.every(duration, options, &block) end
execute() { || ... } click to toggle source

Execute the given block during the event propagation step of the main engine. See ExecutionEngine#execute

# File lib/roby/execution_engine.rb, line 2634
def self.execute
    execution_engine.execute do
        yield
    end
end
execution_engine() click to toggle source

The main execution engine

It is always the same as Roby.plan.execution_engine

Note that it is nil until the Roby application is configured

@return [ExecutionEngine]

# File lib/roby/singletons.rb, line 31
def execution_engine
    app.execution_engine
end
filter_backtrace(original_backtrace = nil, force: false, display_full_framework_backtraces: false) { || ... } click to toggle source
# File lib/roby/exceptions.rb, line 208
def self.filter_backtrace(original_backtrace = nil, force: false, display_full_framework_backtraces: false)
    filter_out = Roby.app.filter_out_patterns

    if !original_backtrace && block_given?
        begin
            return yield
        rescue Exception => e
            filtered = filter_backtrace(
                e.backtrace, force: force,
                display_full_framework_backtraces: display_full_framework_backtraces)
            raise e, e.message, filtered
        end
    end

    if (Roby.app.filter_backtraces? || force) && original_backtrace
        app_dir = Roby.app.app_dir

        original_backtrace = original_backtrace.dup

        # First, read out the "bottom" of the backtrace: search for the
        # first backtrace line that is within the framework
        backtrace_bottom   = []
        while !original_backtrace.empty? && !filter_out.any? { |rx| rx =~ original_backtrace.last }
            backtrace_bottom.unshift original_backtrace.pop
        end

        got_user_line = false
        backtrace = original_backtrace.enum_for(:each_with_index).map do |line, idx|
            case line
            when /in `poll_handler'$/
                got_user_line = true
                line.gsub(/:in.*/, ':in the polling handler')
            when /in `event_command_(\w+)'$/
                got_user_line = true
                line.gsub(/:in.*/, ":in command for '#{$1}'")
            when /in `event_handler_(\w+)_(?:[a-f0-9]+)'$/
                got_user_line = true
                line.gsub(/:in.*/, ":in event handler for '#{$1}'")
            else
                if original_backtrace.size > idx + 4 &&
                    original_backtrace[idx + 1] =~ /in `call'$/ &&
                    original_backtrace[idx + 2] =~ /in `call_handlers'$/ &&
                    original_backtrace[idx + 3] =~ /`each'$/ &&
                    original_backtrace[idx + 4] =~ /`each_handler'$/

                    got_user_line = true
                    line.gsub(/:in /, ":in event handler, ")
                else
                    is_user = !filter_out.any? { |rx| rx =~ line }
                    got_user_line ||= is_user
                    if !got_user_line || is_user
                        case line
                        when /^\(eval\):\d+:in `each(?:_handler)?'/
                        else
                            line
                        end
                    end
                end
            end
        end

        backtrace.compact!

        if app_dir
            backtrace = backtrace.map do |line|
                line.gsub(/^#{app_dir}\/?/, './')
            end
        end
        backtrace.concat backtrace_bottom
        if original_backtrace.size == backtrace.size && !display_full_framework_backtraces
            # The backtrace is only within the framework, make it empty
            backtrace = []
        end
    end
    backtrace || original_backtrace || []
end
flatten_exception(e) click to toggle source
# File lib/roby/exceptions.rb, line 526
def self.flatten_exception(e)
    result = [e].to_set
    if e.respond_to?(:original_exceptions)
        e.original_exceptions.each do |orig_e|
            result.merge(flatten_exception(orig_e))
        end
    end
    result
end
format_backtrace(e, filter: Roby.app.filter_backtraces?) click to toggle source
# File lib/roby/exceptions.rb, line 379
def self.format_backtrace(e, filter: Roby.app.filter_backtraces?)
    backtrace = e.backtrace
    if filter
        backtrace = filter_backtrace(backtrace)
    end

    format_exception(BacktraceFormatter.new(e, backtrace))
end
format_exception(exception, with_original_exceptions: true) click to toggle source
# File lib/roby/exceptions.rb, line 314
def self.format_exception(exception, with_original_exceptions: true)
    message = format_one_exception(exception)
    if with_original_exceptions && exception.respond_to?(:original_exceptions)
        exception.original_exceptions.each do |original_e|
            message.concat(format_exception(original_e, with_original_exceptions: true))
        end
    end
    message
end
format_one_exception(exception) click to toggle source
# File lib/roby/exceptions.rb, line 296
def self.format_one_exception(exception)
    message = begin
                  PP.pp(exception, "")
              rescue Exception => formatting_error
                  begin
                      "error formatting exception\n" +
                          exception.full_message +
                      "\nplease report the formatting error: \n" + 
                          formatting_error.full_message
                  rescue Exception => formatting_error
                      "\nerror formatting exception\n" +
                          formatting_error.full_message
                  end
              end

    message.split("\n")
end
format_time(time, format = 'hms') click to toggle source
# File lib/roby/support.rb, line 101
def self.format_time(time, format = 'hms')
    if format == 'sec'
        time.to_f.to_s
    elsif format == 'hms'
        "#{time.strftime('%H:%M:%S.%3N')}"
    else
        "#{time.strftime(format)}"
    end
end
from(object) click to toggle source

Use to specify that a task argument should be initialized from an object's attribute.

For instance,

task.new(goal: Roby.from(State).pose.position))

will set the task's 'goal' argument from State.pose.position *at the time the task is started*

It can also be used as default argument values (in which case Task.from can be used instead of Roby.from):

class MyTask < Roby::Task
  argument :goal, default: from(State).pose.position
end

If the provided object is nil, the receiver will be the task itself.

@example initialize an argument from the task's parent

MyTaskModel.new(arg: Task.from(:parent_task).parent_arg)
# File lib/roby/task_arguments.rb, line 402
def self.from(object)
    DelayedArgumentFromObject.new(object)
end
from_conf() click to toggle source

Use to specify that a task argument should be initialized from a value in the Conf object. The value will be taken at the point in time where the task is executed.

For instance:

task.new(goal: Roby.from_state.pose.position))
# File lib/roby/task_arguments.rb, line 425
def self.from_conf
    from_state(Conf)
end
from_state(state_object = State) click to toggle source

Use to specify that a task argument should be initialized from a value in the State

For instance:

task.new(goal: Roby.from_state.pose.position))
# File lib/roby/task_arguments.rb, line 413
def self.from_state(state_object = State)
    DelayedArgumentFromState.new(state_object)
end
inside_control?() click to toggle source

True if the current thread is the execution thread of the main engine

See ExecutionEngine#inside_control?

# File lib/roby/execution_engine.rb, line 2625
def self.inside_control?; execution_engine.inside_control? end
log_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?) click to toggle source
# File lib/roby/exceptions.rb, line 388
def self.log_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?)
    format_backtrace(e, filter: filter).each do |line|
        logger.send(level, line)
    end
end
log_error(e, logger, level, with_backtrace: true) click to toggle source
# File lib/roby/exceptions.rb, line 417
def self.log_error(e, logger, level, with_backtrace: true)
    if e.respond_to?(:backtrace) && with_backtrace
        log_exception_with_backtrace(e, logger, level)
    else
        log_exception(e, logger, level)
    end
end
log_exception(e, logger, level, with_original_exceptions: true) click to toggle source
# File lib/roby/exceptions.rb, line 366
def self.log_exception(e, logger, level, with_original_exceptions: true)
    return if !log_level_enabled?(logger, level)

    first_line = true
    format_exception(e, with_original_exceptions: with_original_exceptions).each do |line|
        if first_line
            line = color(line, :bold, :red)
            first_line = false
        end
        logger.send(level, line)
    end
end
log_exception_with_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?, with_original_exceptions: true) click to toggle source
# File lib/roby/exceptions.rb, line 394
def self.log_exception_with_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?, with_original_exceptions: true)
    log_exception(e, logger, level, with_original_exceptions: false)
    logger.send level, color("= Backtrace", :bold, :red)

    backtrace = e.backtrace
    if filter
        backtrace = filter_backtrace(backtrace)
    end
    if !backtrace || backtrace.empty?
        logger.send level, color("= No backtrace", :bold, :red)
    else
        logger.send level, color("= ", :bold, :red)
        log_backtrace(e, logger, level)
        logger.send level, color("= ", :bold, :red)
    end

    if with_original_exceptions && e.respond_to?(:original_exceptions)
        e.original_exceptions.each do |orig_e|
            log_exception_with_backtrace(orig_e, logger, level, with_original_exceptions: true)
        end
    end
end
log_level_enabled?(logger, level) click to toggle source
# File lib/roby/exceptions.rb, line 332
def self.log_level_enabled?(logger, level)
    logger_level = if logger.respond_to?(:log_level)
                       logger.log_level
                   else logger.level
                   end

    if numeric_level = LOG_SYMBOLIC_TO_NUMERIC.index(level.to_sym)
        logger_level <= numeric_level
    else
        raise ArgumentError, "#{level} is not a valid log level, log levels are #{LOG_SYMBOLIC_TO_NUMERIC.map(&:inspect).join(", ")}"
    end
end
log_pp(obj, logger, level) click to toggle source
# File lib/roby/exceptions.rb, line 345
def self.log_pp(obj, logger, level)
    return if !log_level_enabled?(logger, level)

    message = begin
                  PP.pp(obj, "")
              rescue Exception => formatting_error
                  begin
                      "error formatting object\n" +
                          obj + "\nplease report the formatting error: \n" + 
                          formatting_error.full_message
                  rescue Exception => formatting_error
                      "\nerror formatting object\n" +
                          formatting_error.full_message
                  end
              end

    message.split("\n").each do |line|
        logger.send(level, line)
    end
end
on_exception(matcher, &handler) click to toggle source

Defines a global exception handler on the main plan. See also Plan#on_exception

# File lib/roby/singletons.rb, line 76
def self.on_exception(matcher, &handler); Roby.app.plan.on_exception(matcher, &handler) end
once() { || ... } click to toggle source

Execute the given block in the main plan's propagation context, but don't wait for its completion like Roby.execute does

See ExecutionEngine#once

# File lib/roby/execution_engine.rb, line 2613
def self.once; execution_engine.once { yield } end
outside_control?() click to toggle source

True if the current thread is not the execution thread of the main engine

See ExecutionEngine#outside_control?

# File lib/roby/execution_engine.rb, line 2630
def self.outside_control?; execution_engine.outside_control? end
plan() click to toggle source

The main plan

It is always the same as Roby.app.plan

@return [Plan]

# File lib/roby/singletons.rb, line 22
def plan; app.plan end
pretty_print_backtrace(pp, backtrace, **options) click to toggle source
# File lib/roby/exceptions.rb, line 285
def self.pretty_print_backtrace(pp, backtrace, **options)
    if backtrace && !backtrace.empty?
        pp.nest(2) do
            filter_backtrace(backtrace, **options).each do |line|
                pp.breakable
                pp.text line
            end
        end
    end
end
scheduler() click to toggle source

The main scheduler

It is always the same as Roby.plan.execution_engine.scheduler

# File lib/roby/singletons.rb, line 38
def scheduler
    app.plan.execution_engine.scheduler
end
scheduler=(scheduler) click to toggle source

Sets the main scheduler

It is always the same as Roby.plan.execution_engine.scheduler

# File lib/roby/singletons.rb, line 45
def scheduler=(scheduler)
    app.plan.execution_engine.scheduler = scheduler
end
wait_one_cycle() click to toggle source

Blocks until the main engine has executed at least one cycle. See ExecutionEngine#wait_one_cycle

# File lib/roby/execution_engine.rb, line 2642
def self.wait_one_cycle; execution_engine.wait_one_cycle end
wait_until(ev, &block) click to toggle source

Stops the current thread until the given even is emitted. If the event becomes unreachable, an UnreachableEvent exception is raised.

See ExecutionEngine#wait_until

# File lib/roby/execution_engine.rb, line 2648
def self.wait_until(ev, &block); execution_engine.wait_until(ev, &block) end
warn_deprecated(msg, caller_depth = 1) click to toggle source
# File lib/roby/support.rb, line 120
def self.warn_deprecated(msg, caller_depth = 1)
    if deprecation_warnings_are_errors
        error_deprecated(msg, caller_depth)
    elsif enable_deprecation_warnings
        Roby.warn "Deprecation Warning: #{msg} at #{caller[1, caller_depth].join("\n")}"
    end
end