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
Used by the to_dot* methods for color allocation
Public Class Methods
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
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
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
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 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
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
(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
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
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
# 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
# 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