Class: Syskit::Robot::MasterDeviceInstance
- Inherits:
-
DeviceInstance
- Object
- DeviceInstance
- Syskit::Robot::MasterDeviceInstance
- Includes:
- MetaRuby::DSLs::FindThroughMethodMissing
- Defined in:
- lib/syskit/robot/master_device_instance.rb
Overview
Subclass of DeviceInstance used to represent root devices
Direct Known Subclasses
Defined Under Namespace
Classes: DRoby
Constant Summary collapse
- KNOWN_PARAMETERS =
{ :period => nil, :sample_size => nil, :device_id => nil }
Instance Attribute Summary collapse
-
#com_busses ⇒ Object
readonly
The communication busses this device is attached to.
-
#combus_client_in_srv ⇒ BoundDataService?
readonly
The data service of #task_model that is used to receive data from the attached com bus for this device.
-
#combus_client_out_srv ⇒ BoundDataService?
readonly
The data service of #task_model that is used to send data to the attached com bus for this device.
-
#configuration ⇒ Object
readonly
Configuration data structure.
-
#configuration_block ⇒ Object
readonly
Block given to #configure to configure the device.
-
#device_model ⇒ Object
readonly
The device model, as a subclass of Device.
-
#driver_model ⇒ BoundDataService
readonly
The driver for this device.
-
#name ⇒ Object
readonly
The device name.
-
#requirements ⇒ Syskit::InstanceRequirements
readonly
Additional specifications for deployment of the driver.
-
#robot ⇒ Object
readonly
The RobotDefinition instance we are built upon.
-
#slaves ⇒ Object
readonly
The device slaves, as a mapping from the slave's name to the SlaveDeviceInstance object.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#advanced ⇒ Object
Sets #advanced?.
-
#advanced=(value) ⇒ Object
Whether this device should be hidden from the user interfaces.
-
#advanced? ⇒ Boolean
Whether this device should be hidden from the user interfaces.
-
#arguments ⇒ Object
The arguments passed to the underlying device driver.
- #as_plan ⇒ Object
- #attach_to(com_bus, bus_to_client: true, client_to_bus: true, **options) ⇒ Object
-
#attached_to?(com_bus) ⇒ Boolean
True if this device is attached to the given combus.
-
#bus_to_client? ⇒ Boolean
Whether this device sends messages to the bus it is attached to.
-
#client_to_bus? ⇒ Boolean
Whether this device sends messages to the bus it is attached to.
-
#device_id ⇒ Object
:method:device_id.
- #droby_dump(peer) ⇒ Object
- #each_fullfilled_model(&block) ⇒ Object
-
#each_slave(&block) ⇒ Object
Enumerates the slaves that are known for this device, as [slave_name, SlaveDeviceInstance object] pairs.
-
#find_combus_client_srv(srv_m, srv_name) ⇒ Object
Finds in #driver_model.component_model the data service that should be used to interface with a combus.
- #find_through_method_missing(m, args) ⇒ Object
- #full_name ⇒ Object
- #has_slave?(slave_service) ⇒ Boolean
- #has_through_method_missing?(m) ⇒ Boolean
-
#initialize(robot, name, device_model, options, driver_model, task_arguments) ⇒ MasterDeviceInstance
constructor
A new instance of MasterDeviceInstance.
- #model ⇒ Object
-
#prefer_deployed_tasks(hints) ⇒ Object
Specify deployment selection hints for the device's driver.
- #pretty_print(pp) ⇒ Object
-
#short_name ⇒ Object
Defined to be consistent with task and data service models.
-
#slave(slave_service, options = Hash.new) ⇒ Object
Gets the required slave device, or creates a dynamic one.
-
#to_action_model ⇒ Actions::Model::Action
Create an action model that represent an instanciation of this device.
-
#to_instance_requirements ⇒ Object
Returns the InstanceRequirements object that can be used to represent this device.
- #to_s ⇒ Object
-
#use(dependency_injection) ⇒ Object
If this device's driver is a composition, allows to specify dependency injections for it.
- #use_conf(*conf) ⇒ Object deprecated Deprecated.
- #use_deployments(hints) ⇒ Object
-
#with_arguments(arguments = Hash.new) ⇒ Object
Add arguments to the underlying device driver.
-
#with_conf(*conf) ⇒ Object
Declares that the following configuration chain should be used for this device.
Methods inherited from DeviceInstance
#doc, #instanciate, #period, #to_action
Constructor Details
#initialize(robot, name, device_model, options, driver_model, task_arguments) ⇒ MasterDeviceInstance
Returns a new instance of MasterDeviceInstance
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/syskit/robot/master_device_instance.rb', line 46 def initialize(robot, name, device_model, , 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.name = "#{name}_dev" requirements.with_arguments(:"#{driver_model.service.name}_dev" => self) requirements.with_arguments(**task_arguments) sample_size 1 burst 0 end |
Instance Attribute Details
#com_busses ⇒ Object (readonly)
The communication busses this device is attached to
15 16 17 |
# File 'lib/syskit/robot/master_device_instance.rb', line 15 def com_busses @com_busses end |
#combus_client_in_srv ⇒ BoundDataService? (readonly)
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)
106 107 108 |
# File 'lib/syskit/robot/master_device_instance.rb', line 106 def combus_client_in_srv @combus_client_in_srv end |
#combus_client_out_srv ⇒ BoundDataService? (readonly)
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)
114 115 116 |
# File 'lib/syskit/robot/master_device_instance.rb', line 114 def combus_client_out_srv @combus_client_out_srv end |
#configuration ⇒ Object (readonly)
Configuration data structure
36 37 38 |
# File 'lib/syskit/robot/master_device_instance.rb', line 36 def configuration @configuration end |
#configuration_block ⇒ Object (readonly)
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
44 45 46 |
# File 'lib/syskit/robot/master_device_instance.rb', line 44 def configuration_block @configuration_block end |
#device_model ⇒ Object (readonly)
The device model, as a subclass of Device
10 11 12 |
# File 'lib/syskit/robot/master_device_instance.rb', line 10 def device_model @device_model end |
#driver_model ⇒ BoundDataService (readonly)
The driver for this device
34 35 36 |
# File 'lib/syskit/robot/master_device_instance.rb', line 34 def driver_model @driver_model end |
#name ⇒ Object (readonly)
The device name
8 9 10 |
# File 'lib/syskit/robot/master_device_instance.rb', line 8 def name @name end |
#requirements ⇒ Syskit::InstanceRequirements (readonly)
Additional specifications for deployment of the driver
18 19 20 |
# File 'lib/syskit/robot/master_device_instance.rb', line 18 def requirements @requirements end |
#robot ⇒ Object (readonly)
The RobotDefinition instance we are built upon
6 7 8 |
# File 'lib/syskit/robot/master_device_instance.rb', line 6 def robot @robot end |
#slaves ⇒ Object (readonly)
The device slaves, as a mapping from the slave's name to the SlaveDeviceInstance object
13 14 15 |
# File 'lib/syskit/robot/master_device_instance.rb', line 13 def slaves @slaves end |
Instance Method Details
#==(other) ⇒ Object
387 388 389 390 391 392 |
# File 'lib/syskit/robot/master_device_instance.rb', line 387 def ==(other) if other.kind_of?(MasterDeviceInstance) other.robot == robot && other.name == name end end |
#advanced ⇒ Object
Sets #advanced?
77 78 79 80 |
# File 'lib/syskit/robot/master_device_instance.rb', line 77 def advanced @advanced = true self end |
#advanced=(value) ⇒ Object
Whether this device should be hidden from the user interfaces
74 |
# File 'lib/syskit/robot/master_device_instance.rb', line 74 attr_predicate :advanced?, true |
#advanced? ⇒ Boolean
Whether this device should be hidden from the user interfaces
74 |
# File 'lib/syskit/robot/master_device_instance.rb', line 74 attr_predicate :advanced?, true |
#arguments ⇒ Object
The arguments passed to the underlying device driver
327 328 329 |
# File 'lib/syskit/robot/master_device_instance.rb', line 327 def arguments requirements.arguments end |
#as_plan ⇒ Object
372 |
# File 'lib/syskit/robot/master_device_instance.rb', line 372 def as_plan; to_instance_requirements.as_plan end |
#attach_to(com_bus, bus_to_client: true, client_to_bus: true, **options) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/syskit/robot/master_device_instance.rb', line 140 def attach_to(com_bus, bus_to_client: true, client_to_bus: true, **) 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 = .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 = .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 !.empty? raise ArgumentError, "unexpected 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 |
#attached_to?(com_bus) ⇒ Boolean
True if this device is attached to the given combus
96 97 98 |
# File 'lib/syskit/robot/master_device_instance.rb', line 96 def attached_to?(com_bus) com_busses.include?(com_bus) end |
#bus_to_client? ⇒ Boolean
Whether this device sends messages to the bus it is attached to
It will return false if not attached to a bus
126 127 128 |
# File 'lib/syskit/robot/master_device_instance.rb', line 126 def bus_to_client? !!combus_client_in_srv end |
#client_to_bus? ⇒ Boolean
Whether this device sends messages to the bus it is attached to
It will return false if not attached to a bus
119 120 121 |
# File 'lib/syskit/robot/master_device_instance.rb', line 119 def client_to_bus? !!combus_client_out_srv end |
#device_id ⇒ Object
:method:device_id
call-seq:
device_id(device_id, definition)
device_id => current_id or nil
The device ID. It is dependent on the method of communication to the device. For a serial line, it would be the device file (/dev/ttyS0):
device(XsensImu).
device_id('/dev/ttyS0')
For CAN, it would be the device ID and mask:
device(Motors).
device_id(0x0, 0x700)
241 242 243 244 245 246 247 |
# File 'lib/syskit/robot/master_device_instance.rb', line 241 dsl_attribute(:device_id) do |*values| if values.size > 1 values else values.first end end |
#droby_dump(peer) ⇒ Object
383 384 385 |
# File 'lib/syskit/robot/master_device_instance.rb', line 383 def droby_dump(peer) DRoby.new(name, peer.dump(device_model), peer.dump(driver_model)) end |
#each_fullfilled_model(&block) ⇒ Object
374 375 376 |
# File 'lib/syskit/robot/master_device_instance.rb', line 374 def each_fullfilled_model(&block) device_model.each_fullfilled_model(&block) end |
#each_slave(&block) ⇒ Object
Enumerates the slaves that are known for this device, as
- slave_name, SlaveDeviceInstance object
-
pairs
251 252 253 |
# File 'lib/syskit/robot/master_device_instance.rb', line 251 def each_slave(&block) slaves.each_value(&block) end |
#find_combus_client_srv(srv_m, srv_name) ⇒ Object
Finds in #driver_model.component_model the data service that should be used to interface with a combus
205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/syskit/robot/master_device_instance.rb', line 205 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 |
#find_through_method_missing(m, args) ⇒ Object
312 313 314 315 |
# File 'lib/syskit/robot/master_device_instance.rb', line 312 def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( self, m, args, '_dev'.freeze => :slave) || super end |
#full_name ⇒ Object
69 70 71 |
# File 'lib/syskit/robot/master_device_instance.rb', line 69 def full_name name end |
#has_slave?(slave_service) ⇒ Boolean
255 256 257 258 259 260 |
# File 'lib/syskit/robot/master_device_instance.rb', line 255 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 |
#has_through_method_missing?(m) ⇒ Boolean
307 308 309 310 |
# File 'lib/syskit/robot/master_device_instance.rb', line 307 def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( self, m, '_dev'.freeze => :has_slave?) || super end |
#model ⇒ Object
20 |
# File 'lib/syskit/robot/master_device_instance.rb', line 20 def model; device_model end |
#prefer_deployed_tasks(hints) ⇒ Object
Specify deployment selection hints for the device's driver
338 339 340 341 |
# File 'lib/syskit/robot/master_device_instance.rb', line 338 def prefer_deployed_tasks(hints) requirements.prefer_deployed_tasks(hints) self end |
#pretty_print(pp) ⇒ Object
27 28 29 |
# File 'lib/syskit/robot/master_device_instance.rb', line 27 def pretty_print(pp) pp.text "MasterDeviceInstance(#{short_name}_dev)" end |
#short_name ⇒ Object
Defined to be consistent with task and data service models
23 24 25 |
# File 'lib/syskit/robot/master_device_instance.rb', line 23 def short_name "#{name}[#{model.short_name}]" end |
#slave(slave_name) ⇒ Syskit::Robot::SlaveDeviceInstance #slave(dynamic_service_name, : as=>slave_name) ⇒ Syskit::Robot::SlaveDeviceInstance
Gets the required slave device, or creates a dynamic one
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/syskit/robot/master_device_instance.rb', line 276 def slave(slave_service, = Hash.new) = Kernel. , :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 [:as] new_task_model = task_model.ensure_model_is_specialized srv = new_task_model.require_dynamic_service(slave_service, :as => [: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 |
#to_action_model ⇒ Actions::Model::Action
Create an action model that represent an instanciation of this device
362 363 364 365 366 367 368 369 370 |
# File 'lib/syskit/robot/master_device_instance.rb', line 362 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 |
#to_instance_requirements ⇒ Object
Returns the InstanceRequirements object that can be used to represent this device
351 352 353 354 355 356 |
# File 'lib/syskit/robot/master_device_instance.rb', line 351 def to_instance_requirements result = requirements.dup robot.inject_di_context(result) result.select_service(driver_model) result end |
#to_s ⇒ Object
65 66 67 |
# File 'lib/syskit/robot/master_device_instance.rb', line 65 def to_s "device(#{device_model}, as: #{full_name})" end |
#use(dependency_injection) ⇒ Object
If this device's driver is a composition, allows to specify dependency injections for it
321 322 323 324 |
# File 'lib/syskit/robot/master_device_instance.rb', line 321 def use(dependency_injection) requirements.use(dependency_injection) self end |
#use_conf(*conf) ⇒ Object
83 84 85 86 |
# File 'lib/syskit/robot/master_device_instance.rb', line 83 def use_conf(*conf) Roby.warn_deprecated "MasterDeviceInstance#use_conf is deprecated. Use #with_conf instead" with_conf(*conf) end |
#use_deployments(hints) ⇒ Object
343 344 345 346 347 |
# File 'lib/syskit/robot/master_device_instance.rb', line 343 def use_deployments(hints) Roby.warn_deprecated "MasterDeviceInstance#use_deployments is deprecated. Use #prefer_deployed_tasks instead" prefer_deployed_tasks(hints) self end |
#with_arguments(arguments = Hash.new) ⇒ Object
Add arguments to the underlying device driver
332 333 334 335 |
# File 'lib/syskit/robot/master_device_instance.rb', line 332 def with_arguments(arguments = Hash.new) requirements.with_arguments(arguments) self end |
#with_conf(*conf) ⇒ Object
Declares that the following configuration chain should be used for this device
90 91 92 93 |
# File 'lib/syskit/robot/master_device_instance.rb', line 90 def with_conf(*conf) requirements.with_conf(*conf) self end |