module Syskit

Constants

ActualDataFlow

(see ConnectionGraph)

BasicObject
COLOR_PALETTE

A set of colors to be used in graphiz graphs

ComBus
DataFlow
DataService
Device
Flows
RequiredDataFlow

(see ConnectionGraph)

SYSKIT_LIB_DIR
SYSKIT_ROOT_DIR
VERSION

Attributes

current_color[R]

Used by the to_dot* methods for color allocation

Public Class Methods

allocate_color() click to toggle source

Returns a color from COLOR_PALETTE, rotating each time the method is called. It is used by the to_dot* methods.

# File lib/syskit/graphviz.rb, line 10
def self.allocate_color
    @current_color = (@current_color + 1) % COLOR_PALETTE.size
    COLOR_PALETTE[@current_color]
end
conf() click to toggle source

The main configuration object

For consistency reasons, it is also available as Roby.conf.syskit when running in a Roby application

# File lib/syskit/roby_app.rb, line 29
def conf
    @conf ||= RobyApp::Configuration.new(Roby.app)
end
connect(source, sink, policy) click to toggle source

Generic implementation of connection handling

This is used to connect everything that can be connected: component and service instances, composition child models. The method resolves both source and sinks as a set of ports using each_output_port and each_input_port if they are not plain ports, finds which connections need to be created using {Syskit.resolve_connections} and then calls output_port.connect_to input_port for each of these connections.

@param [Port,Models::Port,#each_output_port] source the source part of

the connection

@param [Port,Models::Port,#each_input_port] sink the sink part of the

connection

@param [Hash] policy the connection policy @return [Array<(Port,Port)>] the set of connections actually created @raise (see ::resolve_connections)

# File lib/syskit/connection_graphs.rb, line 151
def self.connect(source, sink, policy)
    output_ports =
        if source.respond_to?(:each_output_port)
            source.each_output_port.to_a
        else [source]
        end
    input_ports =
        if sink.respond_to?(:each_input_port)
            sink.each_input_port.to_a
        else [sink]
        end

    connections = resolve_connections(output_ports, input_ports)
    if connections.empty?
        raise InvalidAutoConnection.new(source, sink) 
    end

    connections.each do |out_port, in_port|
        out_port.connect_to in_port, policy
    end

    connections
end
create_proxy_task_model_for(models, options = Hash.new) click to toggle source

This method creates a task model that is an aggregate of all the provided models (components and services)

@option options (see Component#create_proxy_task_model)

# File lib/syskit/models/component.rb, line 1311
def self.create_proxy_task_model_for(models, options = Hash.new)
    task_model, service_models, _ = resolve_proxy_task_model_requirements(models)
    task_model.create_proxy_task_model(service_models, options)
end
extend_model(model, &block) click to toggle source

Extend an auto-generated with custom code

This is used mainly for Syskit models generated from oroGen models, in extension files within models/orogen/:

Syskit.extend_model OroGen.test.Task do
  def configure
    super
    ...
  end
end
# File lib/syskit/models/task_context.rb, line 21
def self.extend_model(model, &block)
    model.class_eval(&block)
end
proxy_task_model_for(models) click to toggle source

This method creates a task model that can be used to represent the models listed in models in a plan. The returned task model is obviously abstract

@option options [Boolean] :force (false) if false, the returned model will

be a plain component model if the models argument contains only a
component model. Otherwise, a proxy task model will always be returned

@option options [String] name if given, it is used to name the returned

model. See {Component#create_proxy_task_model) for more details
# File lib/syskit/models/component.rb, line 1325
def self.proxy_task_model_for(models)
    task_model, service_models, service = resolve_proxy_task_model_requirements(models)

    # If all that is required is a proper task model, just return it
    task_model =
        if service_models.empty?
            task_model
        else
            task_model.proxy_task_model(service_models)
        end

    if service
        service.attach(task_model)
    else task_model
    end
end
register_process_server(name, client, log_dir = nil) click to toggle source

(see Syskit::RobyApp::Configuration#register_process_server)

# File lib/syskit/deployment.rb, line 8
def register_process_server(name, client, log_dir = nil)
    Syskit.conf.register_process_server(name, client, log_dir = nil)
end
resolve_connections(output_ports, input_ports) click to toggle source

Resolves possible connections between a set of output ports and a set of input ports

@param [Array<Port>] output_ports the set of output ports @param [Array<Port>] input_ports the set of output ports @return [Array<(Port,Port)>] the set of connections @raise [AmbiguousAutoConnection] if more than one input port is found

for a given output port
# File lib/syskit/connection_graphs.rb, line 65
def self.resolve_connections(output_ports, input_ports)
    Models.debug do
        Models.debug "resolving connections from #{output_ports.map(&:name).sort.join(",")} to #{input_ports.map(&:name).sort.join(",")}"
        break
    end

    result = Array.new
    matched_input_ports = Set.new

    # First resolve the exact matches
    remaining_outputs = output_ports.dup
    remaining_outputs.delete_if do |out_port|
        in_port = input_ports.
            find do |in_port|
                in_port.name == out_port.name &&
                    in_port.type == out_port.type
            end
        if in_port
            result << [out_port, in_port]
            matched_input_ports << in_port
            true
        end
    end

    # In the second stage, we match by type. If there are ambiguities,
    # we try to resolve them by excluding the ports that had an exact
    # match. This is, by experience, expected behaviour in practice
    remaining_outputs.each do |out_port|
        candidates = input_ports.
            find_all { |in_port| in_port.type == out_port.type }
        if candidates.size > 1
            filtered_candidates = candidates.
                find_all { |p| !matched_input_ports.include?(p) }
            if filtered_candidates.size == 1
                candidates = filtered_candidates
            end
        end
        if candidates.size > 1
            raise AmbiguousAutoConnection.new(out_port, candidates)
        elsif candidates.size == 1
            result << [out_port, candidates.first]
        end
    end

    # Finally, verify that we autoconnect multiple outputs to a single
    # input only if it is a multiplexing port
    outputs_per_input = Hash.new
    result.each do |out_port, in_port|
        if outputs_per_input[in_port]
            if !in_port.multiplexes?
                candidates = result.map { |o, i| o if i == in_port }.
                    compact
                raise AmbiguousAutoConnection.new(in_port, candidates)
            end
        end
        outputs_per_input[in_port] = out_port
    end

    Models.debug do
        result.each do |out_port, in_port|
            Models.debug "  #{out_port.name} => #{in_port.name}"
        end
        if !remaining_outputs.empty?
            Models.debug "  no matches found for outputs #{remaining_outputs.map(&:name).sort.join(",")}"
        end
        break
    end
    result
end
resolve_proxy_task_model_requirements(models) click to toggle source

Resolves the base task model and set of service models that should be used to create a proxy task model for the given component and/or service models

@param [Array<Model<Component>,Model<DataService>>] set of component and

services that will be proxied

@return [Model<Component>,Array<Model<DataService>>,(BoundDataService,nil)

This is a helper method for {create_proxy_task_model_for} and {proxy_task_model_for}

# File lib/syskit/models/component.rb, line 1286
def self.resolve_proxy_task_model_requirements(models)
    service = nil
    models = models.map do |m|
        if m.respond_to?(:component_model)
            service = m
            m.component_model
        else m
        end
    end
    task_models, service_models = models.partition { |t| t <= Component }
    if task_models.empty?
        return Component, service_models, service
    elsif task_models.size == 1
        task_model = task_models.first
        service_models.delete_if { |srv| task_model.fullfills?(srv) }
        return task_model, service_models, service
    else
        raise ArgumentError, "cannot create a proxy for multiple component models at the same time"
    end
end
update_connection_policy(old, new) click to toggle source
# File lib/syskit/connection_graphs.rb, line 12
def self.update_connection_policy(old, new)
    old = old.dup
    new = new.dup
    if old.empty?
        return new
    elsif new.empty?
        return old
    end

    old_fallback = old.delete(:fallback_policy)
    new_fallback = new.delete(:fallback_policy)
    if old_fallback && new_fallback
        fallback = update_connection_policy(old_fallback, new_fallback)
    else
        fallback = old_fallback || new_fallback
    end

    old = Orocos::Port.validate_policy(old)
    new = Orocos::Port.validate_policy(new)

    type = old[:type] || new[:type]
    merged = old.merge(new) do |key, old_value, new_value|
        if old_value == new_value
            old_value
        elsif key == :type
            raise ArgumentError, "connection types mismatch: #{old_value} != #{new_value}"
        elsif key == :transport
            if old_value == 0 then new_value
            elsif new_value == 0 then old_value
            else
                raise ArgumentError, "policy mismatch for transport: #{old_value} != #{new_value}"
            end
        elsif key == :size
            [old_value, new_value].max
        else
            raise ArgumentError, "policy mismatch for #{key}: #{old_value} != #{new_value}"
        end
    end

    if fallback
        merged[:fallback_policy] = fallback
    end
    merged
end
warn_about_new_naming_convention() click to toggle source
# File lib/syskit/roby_app/plugin.rb, line 16
def self.warn_about_new_naming_convention
    Syskit.warn 'We have finally adopted a systematic naming convention in Syskit, this led to files and classes to be renamed'
end