Class: Syskit::Models::ComBusModel

Inherits:
DeviceModel show all
Defined in:
lib/syskit/models/data_service.rb

Overview

Metamodel for all communication busses

Instance Attribute Summary collapse

Attributes inherited from DataServiceModel

#orogen_model, #rw port_mappings

Instance Method Summary collapse

Methods inherited from DeviceModel

#apply_device_configuration_extensions, #default_driver, #extend_device_configuration, #find_all_drivers

Methods inherited from DataServiceModel

#apply_block, #as_plan, #bind, #connected?, #create_placeholder_task, #create_proxy_task, #each_fullfilled_model, #each_required_model, #if_already_present, #instanciate, new_permanent_root, #placeholder?, #placeholder_model, #port_mappings_for, #pretty_print, #provides?, #proxy_task_model, #resolve, #to_component_model, #to_dot, #try_bind, #try_resolve

Methods included from PortAccess

#each_input_port, #each_output_port, #each_port, #find_input_port, #find_output_port, #find_port, #find_through_method_missing, #has_dynamic_input_port?, #has_dynamic_output_port?, #has_input_port?, #has_output_port?, #has_port?, #has_through_method_missing?, #port_by_name

Methods included from Base

#dependency_injection_names, #pretty_print, #short_name, #to_instance_requirements, #to_s

Constructor Details

#initialize(*args, &block) ⇒ ComBusModel

Returns a new instance of ComBusModel



444
445
446
447
# File 'lib/syskit/models/data_service.rb', line 444

def initialize(*args, &block)
    super
    @override_policy = true
end

Instance Attribute Details

#bus_base_srvObject (readonly)

Returns the value of attribute bus_base_srv



459
460
461
# File 'lib/syskit/models/data_service.rb', line 459

def bus_base_srv
  @bus_base_srv
end

#bus_in_srvObject (readonly)

Returns the value of attribute bus_in_srv



460
461
462
# File 'lib/syskit/models/data_service.rb', line 460

def bus_in_srv
  @bus_in_srv
end

#bus_out_srvObject (readonly)

Returns the value of attribute bus_out_srv



461
462
463
# File 'lib/syskit/models/data_service.rb', line 461

def bus_out_srv
  @bus_out_srv
end

#bus_srvObject (readonly)

Returns the value of attribute bus_srv



462
463
464
# File 'lib/syskit/models/data_service.rb', line 462

def bus_srv
  @bus_srv
end

#client_in_srvObject (readonly)

Returns the value of attribute client_in_srv



464
465
466
# File 'lib/syskit/models/data_service.rb', line 464

def client_in_srv
  @client_in_srv
end

#client_out_srvObject (readonly)

Returns the value of attribute client_out_srv



465
466
467
# File 'lib/syskit/models/data_service.rb', line 465

def client_out_srv
  @client_out_srv
end

#client_srvObject (readonly)

Returns the value of attribute client_srv



466
467
468
# File 'lib/syskit/models/data_service.rb', line 466

def client_srv
  @client_srv
end

#message_typeString

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

Returns:

  • (String)


592
593
594
# File 'lib/syskit/models/data_service.rb', line 592

def message_type
  @message_type
end

Instance Method Details

#apply_attached_device_configuration_extensions(device_instance) ⇒ Object

Applies the configuration extensions declaredwith #extend_device_configuration to the provided class



640
641
642
# File 'lib/syskit/models/data_service.rb', line 640

def apply_attached_device_configuration_extensions(device_instance)
    device_instance.extend(attached_device_configuration_module)
end

#bus_to_client?Boolean

Retursn whether this bus clients send messages to the bus

Returns:

  • (Boolean)


455
456
457
# File 'lib/syskit/models/data_service.rb', line 455

def bus_to_client?
    !!client_in_srv
end

#clear_modelObject



510
511
512
513
# File 'lib/syskit/models/data_service.rb', line 510

def clear_model
    super
    @message_type = nil
end

#client_to_bus?Boolean

Returns whether this bus clients receive messages from the bus

Returns:

  • (Boolean)


450
451
452
# File 'lib/syskit/models/data_service.rb', line 450

def client_to_bus?
    !!client_out_srv
end

#dynamic_service_nameObject

The name of the bus_in_srv dynamic service defined on driver tasks



516
517
518
519
520
521
522
# File 'lib/syskit/models/data_service.rb', line 516

def dynamic_service_name
    name = "com_bus"
    if self.name
        name = "#{name}_#{self.name}"
    end
    name
end

#extend_attached_device_configuration(&block) ⇒ Object

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)


631
632
633
634
635
636
# File 'lib/syskit/models/data_service.rb', line 631

def extend_attached_device_configuration(&block)
    if block
        attached_device_configuration_module.class_eval(&block)
    end
    self
end

#included(mod) ⇒ Object



524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/syskit/models/data_service.rb', line 524

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) ⇒ Object

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



652
653
654
# File 'lib/syskit/models/data_service.rb', line 652

def input_name_for(device_name)
    "w#{device_name}"
end

#lazy_dispatch=(value) ⇒ Boolean

Parameters:

  • (Boolean)

    value

Returns:

  • (Boolean)


468
# File 'lib/syskit/models/data_service.rb', line 468

attr_predicate :lazy_dispatch?, true

#lazy_dispatch?Boolean

Returns:

  • (Boolean)


468
# File 'lib/syskit/models/data_service.rb', line 468

attr_predicate :lazy_dispatch?, true

#new_submodel(lazy_dispatch: false, override_policy: override_policy?, , message_type: self.message_type, **options, &block) ⇒ Object

Creates a new submodel of this communication bus model

Parameters:

  • options (Hash)

    the configuration options. See DataServiceModel#provides for the list of options from data services

  • lazy_dispatch (Boolean)

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

  • override_policy (Boolean)

    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.

  • message_type (String, Model<Type>)

    the type name of the type that is used by this combus to communicate with the components it supports



485
486
487
# File 'lib/syskit/models/data_service.rb', line 485

def new_submodel(lazy_dispatch: false, override_policy: override_policy?, message_type: self.message_type, **options, &block)
    super
end

#output_name_for(device_name) ⇒ Object

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



646
647
648
# File 'lib/syskit/models/data_service.rb', line 646

def output_name_for(device_name)
    device_name
end

#override_policy=(value) ⇒ Object

If true, the com bus autoconnection code will override the input port default policies to needs_reliable_connection

It is true by default



586
# File 'lib/syskit/models/data_service.rb', line 586

attr_predicate :override_policy?, true

#override_policy?Boolean

If true, the com bus autoconnection code will override the input port default policies to needs_reliable_connection

It is true by default

Returns:

  • (Boolean)


586
# File 'lib/syskit/models/data_service.rb', line 586

attr_predicate :override_policy?, true

#provides(service_model, new_port_mappings = Hash.new) ⇒ Object



561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# File 'lib/syskit/models/data_service.rb', line 561

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) ⇒ Object



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/syskit/models/data_service.rb', line 489

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