class Syskit::Robot::MasterDeviceInstance
Subclass of DeviceInstance used to represent root devices
Constants
- DRoby
- KNOWN_PARAMETERS
Attributes
The communication busses this device is attached to
The data service of {#task_model} that is used to receive data from the attached com bus for this device. If nil, the task is not expecting to receive any data from the communication bus (only send)
@return [BoundDataService,nil]
The data service of {#task_model} that is used to send data to the attached com bus for this device. If nil, the task is not expecting to send any data from the communication bus (only receives)
@return [BoundDataService,nil]
Configuration data structure
Block given to configure to configure the device. It will be yield a data structure that represents the set of properties of the underlying task
Note that it is executed twice. Once at loading time to verify that the block is compatible with the data structure, and once at runtime to actually configure the task
The device model, as a subclass of Device
The driver for this device @return [BoundDataService]
The device name
Additional specifications for deployment of the driver @return [Syskit::InstanceRequirements]
The RobotDefinition instance we are built upon
The device slaves, as a mapping from the slave's name to the SlaveDeviceInstance object
Public Class Methods
# File lib/syskit/robot/master_device_instance.rb, line 46 def initialize(robot, name, device_model, options, driver_model, task_arguments) @robot, @name, @device_model, @task_arguments = robot, name, device_model, task_arguments @slaves = Hash.new @conf = Array.new @com_busses = Array.new driver_model = driver_model.to_instance_requirements @driver_model = driver_model.service @requirements = driver_model.to_component_model requirements.with_arguments(:"#{driver_model.service.name}_dev" => self) requirements.with_arguments(**task_arguments) sample_size 1 burst 0 end
Public Instance Methods
# File lib/syskit/robot/master_device_instance.rb, line 386 def ==(other) if other.kind_of?(MasterDeviceInstance) other.robot == robot && other.name == name end end
Sets {#advanced?}
# File lib/syskit/robot/master_device_instance.rb, line 76 def advanced @advanced = true self end
The arguments passed to the underlying device driver
# File lib/syskit/robot/master_device_instance.rb, line 326 def arguments requirements.arguments end
# File lib/syskit/robot/master_device_instance.rb, line 371 def as_plan; to_instance_requirements.as_plan end
Attaches this device on the given communication bus
@param [Boolean,String] bus_to_client whether the device expects a
connection from the bus. It can be set to a string, in which case the string is used as the name of the service on the client's device driver that should be used for connection
@param [Boolean,String] client_to_bus whether the device expects a
connection to the bus. It can be set to a string, in which case the string is used as the name of the service on the client device driver that should be used for connection
# File lib/syskit/robot/master_device_instance.rb, line 139 def attach_to(com_bus, bus_to_client: true, client_to_bus: true, **options) if com_bus.respond_to?(:to_str) com_bus, com_bus_name = robot.find_device(com_bus), com_bus if !com_bus raise ArgumentError, "no device declared with the name '#{com_bus_name}'" end end if srv_name = options.delete(:in) Roby.warn_deprecated "the in: option of MasterDeviceInstance#attach_to has been renamed to bus_to_client" bus_to_client = srv_name end if srv_name = options.delete(:out) Roby.warn_deprecated "the out: option of MasterDeviceInstance#attach_to has been renamed to client_to_bus" client_to_bus = srv_name end if !options.empty? raise ArgumentError, "unexpected options #{options}" end if bus_to_client && com_bus.model.bus_to_client? client_in_srv = if bus_to_client.respond_to?(:to_str) bus_to_client end client_in_srv_m = com_bus.model.client_in_srv @combus_client_in_srv = begin find_combus_client_srv(client_in_srv_m, client_in_srv) rescue AmbiguousServiceSelection raise ArgumentError, "#{driver_model.to_component_model} provides more than one input service to connect to the com bus, select one explicitely with the bus_to_client option" end if !combus_client_in_srv raise ArgumentError, "#{driver_model.to_component_model} does not provide an input service to connect to the com bus, and was expected to" end end if client_to_bus && com_bus.model.client_to_bus? client_out_srv = if client_to_bus.respond_to?(:to_str) client_to_bus end client_out_srv_m = com_bus.model.client_out_srv @combus_client_out_srv = begin find_combus_client_srv(client_out_srv_m, client_out_srv) rescue AmbiguousServiceSelection raise ArgumentError, "#{driver_model.to_component_model} provides more than one output service to connect to the com bus, select one explicitely with the client_to_bus option" end if !combus_client_out_srv raise ArgumentError, "#{driver_model.to_component_model} does not provide an output service to connect to the com bus, and was expected to" end end com_busses << com_bus com_bus.attached_devices << self com_bus.model.apply_attached_device_configuration_extensions(self) self end
True if this device is attached to the given combus
# File lib/syskit/robot/master_device_instance.rb, line 95 def attached_to?(com_bus) com_busses.include?(com_bus) end
Whether this device sends messages to the bus it is attached to
It will return false if not attached to a bus
# File lib/syskit/robot/master_device_instance.rb, line 125 def bus_to_client? !!combus_client_in_srv end
Whether this device sends messages to the bus it is attached to
It will return false if not attached to a bus
# File lib/syskit/robot/master_device_instance.rb, line 118 def client_to_bus? !!combus_client_out_srv end
# File lib/syskit/robot/master_device_instance.rb, line 382 def droby_dump(peer) DRoby.new(name, peer.dump(device_model), peer.dump(driver_model)) end
# File lib/syskit/robot/master_device_instance.rb, line 373 def each_fullfilled_model(&block) device_model.each_fullfilled_model(&block) end
Enumerates the slaves that are known for this device, as
- slave_name, SlaveDeviceInstance object
-
pairs
# File lib/syskit/robot/master_device_instance.rb, line 250 def each_slave(&block) slaves.each_value(&block) end
Finds in {#driver_model}.component_model the data service that should be used to interface with a combus
@param [Model<DataService>] the data service model for the client
interface to the combus
@param [String,nil] the expected data service name, or nil if none
is given. In this case, one is searched by type
# File lib/syskit/robot/master_device_instance.rb, line 204 def find_combus_client_srv(srv_m, srv_name) driver_task_model = driver_model.to_component_model if srv_name result = driver_task_model.find_data_service(srv_name) if !result raise ArgumentError, "#{srv_name} is specified as a client service on device #{name} for combus #{com_bus.name}, but it is not a data service on #{driver_task_model}" elsif !result.fullfills?(srv_m) raise ArgumentError, "#{srv_name} is specified as a client service on device #{name} for combus #{com_bus.name}, but it does not provide the required service from #{com_bus.model}" end result else driver_task_model.find_data_service_from_type(srv_m) end end
# File lib/syskit/robot/master_device_instance.rb, line 311 def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( self, m, args, '_dev'.freeze => :slave) || super end
# File lib/syskit/robot/master_device_instance.rb, line 68 def full_name name end
# File lib/syskit/robot/master_device_instance.rb, line 254 def has_slave?(slave_service) return true if slaves[slave_service] slave_name = "#{driver_model.full_name}.#{slave_service}" !!task_model.find_data_service(slave_name) end
# File lib/syskit/robot/master_device_instance.rb, line 306 def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( self, m, '_dev'.freeze => :has_slave?) || super end
# File lib/syskit/robot/master_device_instance.rb, line 20 def model; device_model end
Specify deployment selection hints for the device's driver
# File lib/syskit/robot/master_device_instance.rb, line 337 def prefer_deployed_tasks(hints) requirements.prefer_deployed_tasks(hints) self end
# File lib/syskit/robot/master_device_instance.rb, line 27 def pretty_print(pp) pp.text "MasterDeviceInstance(#{short_name}_dev)" end
Defined to be consistent with task and data service models
# File lib/syskit/robot/master_device_instance.rb, line 23 def short_name "#{name}[#{model.short_name}]" end
Gets the required slave device, or creates a dynamic one
@overload slave(slave_name)
@arg [String] slave_name the name of a slave service on the device's driver @return [Syskit::Robot::SlaveDeviceInstance]
@overload slave(dynamic_service_name, :as => slave_name)
@arg [String] dynamic_service_name the name of a dynamic service declared on the device's driver with #dynamic_service @arg [String] slave_name the name of the slave as it should be created @return [Syskit::Robot::SlaveDeviceInstance]
# File lib/syskit/robot/master_device_instance.rb, line 275 def slave(slave_service, options = Hash.new) options = Kernel.validate_options options, :as => nil if existing_slave = slaves[slave_service] return existing_slave end # If slave_service is a string, it should refer to an actual # service on +task_model+ task_model = driver_model.to_component_model slave_name = "#{driver_model.full_name}.#{slave_service}" srv = task_model.find_data_service(slave_name) if !srv if options[:as] new_task_model = task_model.ensure_model_is_specialized srv = new_task_model.require_dynamic_service(slave_service, :as => options[:as]) end if !srv raise ArgumentError, "there is no service #{slave_name} and no dynamic service in #{task_model.short_name}" end @driver_model = driver_model.attach(new_task_model) end device_instance = SlaveDeviceInstance.new(self, srv) slaves[srv.name] = device_instance if srv.model.respond_to?(:apply_device_configuration_extensions) srv.model.apply_device_configuration_extensions(device_instance) end robot.devices["#{name}.#{srv.name}"] = device_instance end
Create an action model that represent an instanciation of this device
@return [Actions::Model::Action]
# File lib/syskit/robot/master_device_instance.rb, line 361 def to_action_model profile = robot.profile req = to_instance_requirements profile.inject_di_context(req) action_model = Actions::Models::Action. new(req, doc || "device from profile #{profile.name}") action_model.name = "#{name}_dev" action_model end
Returns the InstanceRequirements object that can be used to represent this device
# File lib/syskit/robot/master_device_instance.rb, line 350 def to_instance_requirements result = requirements.dup robot.inject_di_context(result) result.select_service(driver_model) result end
# File lib/syskit/robot/master_device_instance.rb, line 64 def to_s "device(#{device_model}, as: #{full_name})" end
If this device's driver is a composition, allows to specify dependency injections for it
# File lib/syskit/robot/master_device_instance.rb, line 320 def use(dependency_injection) requirements.use(dependency_injection) self end
@deprecated
# File lib/syskit/robot/master_device_instance.rb, line 82 def use_conf(*conf) Roby.warn_deprecated "MasterDeviceInstance#use_conf is deprecated. Use #with_conf instead" with_conf(*conf) end
# File lib/syskit/robot/master_device_instance.rb, line 342 def use_deployments(hints) Roby.warn_deprecated "MasterDeviceInstance#use_deployments is deprecated. Use #prefer_deployed_tasks instead" prefer_deployed_tasks(hints) self end
Add arguments to the underlying device driver
# File lib/syskit/robot/master_device_instance.rb, line 331 def with_arguments(arguments = Hash.new) requirements.with_arguments(arguments) self end
Declares that the following configuration chain should be used for this device
# File lib/syskit/robot/master_device_instance.rb, line 89 def with_conf(*conf) requirements.with_conf(*conf) self end