class Syskit::Models::ComBusModel

Metamodel for all communication busses

Attributes

bus_base_srv[R]
bus_in_srv[R]
bus_out_srv[R]
bus_srv[R]
client_in_srv[R]
client_out_srv[R]
client_srv[R]
message_type[R]

The name of the type used to communicate with the supported components

@return [String]

Public Class Methods

new(*args, &block) click to toggle source
Calls superclass method Syskit::Models::DataServiceModel.new
# File lib/syskit/models/data_service.rb, line 398
def initialize(*args, &block)
    super
    @override_policy = true
end

Public Instance Methods

apply_attached_device_configuration_extensions(device_instance) click to toggle source

Applies the configuration extensions declaredwith extend_device_configuration to the provided class

# File lib/syskit/models/data_service.rb, line 594
def apply_attached_device_configuration_extensions(device_instance)
    device_instance.extend(attached_device_configuration_module)
end
bus_to_client?() click to toggle source

Retursn whether this bus clients send messages to the bus

# File lib/syskit/models/data_service.rb, line 409
def bus_to_client?
    !!client_in_srv
end
clear_model() click to toggle source
# File lib/syskit/models/data_service.rb, line 464
def clear_model
    super
    @message_type = nil
end
client_to_bus?() click to toggle source

Returns whether this bus clients receive messages from the bus

# File lib/syskit/models/data_service.rb, line 404
def client_to_bus?
    !!client_out_srv
end
dynamic_service_name() click to toggle source

The name of the #bus_in_srv dynamic service defined on driver tasks

# File lib/syskit/models/data_service.rb, line 470
def dynamic_service_name
    name = "com_bus"
    if self.name
        name = "#{name}_#{self.name}"
    end
    name
end
extend_attached_device_configuration(&block) click to toggle source

Requires that the given block is used to add methods to the device configuration objects.

I.e. if a combus type is defined with

com_bus_type('canbus').
   extend_attached_device_configuration do
       def can_id(id, mask)
           @id, @mask = id, mask
       end
   end

Then the can_id method will be available on device instances that are attached to a canbus device

device(Type).attach_to(can).can_id(0x10, 0x10)
# File lib/syskit/models/data_service.rb, line 585
def extend_attached_device_configuration(&block)
    if block
        attached_device_configuration_module.class_eval(&block)
    end
    self
end
included(mod) click to toggle source
# File lib/syskit/models/data_service.rb, line 478
def included(mod)
    return if !(mod <= Syskit::Component)

    # declare the relevant dynamic service
    combus_m = self
    dyn_name = dynamic_service_name
    bus_srv  = bus_base_srv
    mod.dynamic_service bus_base_srv, as: dynamic_service_name do
        options = Kernel.validate_options self.options, client_to_bus: nil, bus_to_client: nil
        in_name =
            if in_srv = mod.find_data_service_from_type(combus_m.bus_in_srv)
                in_srv.port_mappings_for_task['to_bus']
            else
                combus_m.input_name_for(name)
            end

        begin
            client_to_bus, bus_to_client =
                options.fetch(:client_to_bus), options.fetch(:bus_to_client)
        rescue KeyError
            raise ArgumentError, "you must provide both the client_to_bus and bus_to_client option when instanciating the a com bus dynamic service"
        end

        if client_to_bus && bus_to_client
            provides combus_m.bus_srv, 'from_bus' => combus_m.output_name_for(name),
                'to_bus' => in_name
            component_model.orogen_model.find_port(in_name).needs_reliable_connection
        elsif client_to_bus
            provides combus_m.bus_in_srv, 'to_bus' => in_name
            component_model.orogen_model.find_port(in_name).needs_reliable_connection
        elsif bus_to_client
            provides combus_m.bus_out_srv, 'from_bus' => combus_m.output_name_for(name)
        else raise ArgumentError, "at least one of bus_to_client or client_to_bus must be true"
        end
    end
end
input_name_for(device_name) click to toggle source

The name of the port that will receive data from the device of the given name to the bus

# File lib/syskit/models/data_service.rb, line 606
def input_name_for(device_name)
    "w#{device_name}"
end
message_type=(message_type) click to toggle source
# File lib/syskit/models/data_service.rb, line 548
def message_type=(message_type)
    @message_type = message_type
    @bus_base_srv = data_service_type 'BusBaseSrv'
    @bus_in_srv  = data_service_type('BusInSrv') { input_port 'to_bus', message_type }
    @bus_out_srv = data_service_type('BusOutSrv') { output_port 'from_bus', message_type }
    @bus_srv     = data_service_type 'BusSrv'

    bus_in_srv.provides bus_base_srv
    bus_out_srv.provides bus_base_srv
    bus_srv.provides bus_in_srv
    bus_srv.provides bus_out_srv

    @client_in_srv  = data_service_type('ClientInSrv') { input_port 'from_bus', message_type }
    @client_out_srv = data_service_type('ClientOutSrv') { output_port 'to_bus', message_type }
    @client_srv     = data_service_type 'ClientSrv'
    client_srv.provides client_in_srv
    client_srv.provides client_out_srv
end
new_submodel(lazy_dispatch: false, override_policy: override_policy?, message_type: self.message_type, **options, &block) click to toggle source

Creates a new submodel of this communication bus model

@param [Hash] options the configuration options. See

DataServiceModel#provides for the list of options from data
services

@param [Boolean] lazy_dispatch whether the dynamic services used

to attach the devices should be all instanciated at the beginning
(the default) or only on-demand

@param [Boolean] override_policy if true (the default),

the communication bus handling will mark the associated component's
input ports as needs_reliable_connection so that relevant
policies are chosen.

@param [String,Model<Type>] #message_type the type name of the

type that is used by this combus to communicate with the
components it supports
Calls superclass method
# File lib/syskit/models/data_service.rb, line 439
def new_submodel(lazy_dispatch: false, override_policy: override_policy?, message_type: self.message_type, **options, &block)
    super
end
output_name_for(device_name) click to toggle source

The name of the port that will send data from the bus to the device of the given name

# File lib/syskit/models/data_service.rb, line 600
def output_name_for(device_name)
    device_name
end
provides(service_model, new_port_mappings = Hash.new) click to toggle source
Calls superclass method Syskit::Models::DeviceModel#provides
# File lib/syskit/models/data_service.rb, line 515
def provides(service_model, new_port_mappings = Hash.new)
    if service_model.respond_to?(:message_type)
        if message_type && service_model.message_type && message_type != service_model.message_type
            raise ArgumentError, "#{self.name} cannot provide #{service_model.name} as their message type differs (resp. #{message_type} and #{service_model.message_type}"
        end
    end

    super

    if service_model.respond_to?(:message_type) && !message_type
        @message_type = service_model.message_type
        @bus_base_srv   = service_model.bus_base_srv
        @bus_in_srv     = service_model.bus_in_srv
        @bus_out_srv    = service_model.bus_out_srv
        @bus_srv        = service_model.bus_srv
        @client_in_srv  = service_model.client_in_srv
        @client_out_srv = service_model.client_out_srv
        @client_srv     = service_model.client_srv
    end
end
setup_submodel(model, lazy_dispatch: false, override_policy: override_policy?, message_type: self.message_type, **options, &block) click to toggle source
# File lib/syskit/models/data_service.rb, line 443
def setup_submodel(model, lazy_dispatch: false, override_policy: override_policy?, message_type: self.message_type, **options, &block)
    if message_type.respond_to?(:to_str)
        message_type = Roby.app.default_loader.resolve_type(message_type)
    end
    super(model, **options, &block)

    model.lazy_dispatch   = lazy_dispatch
    model.override_policy = override_policy
    if !message_type && !model.message_type
        raise ArgumentError, "com bus types must either have a message_type or provide another com bus type that does"
    elsif message_type && model.message_type
        if message_type != model.message_type
            raise ArgumentError, "cannot override message types. The current message type of #{model.name} is #{model.message_type}, which might come from another provided com bus"
        end
    elsif !model.message_type
        model.message_type = message_type
    end

    model.attached_device_configuration_module.include(attached_device_configuration_module)
end