Class: Roby::StateSpace
- Inherits:
-
StateField
- Object
- OpenStruct
- StateField
- Roby::StateSpace
- Defined in:
- lib/roby/state/state_model.rb,
lib/roby/state/events.rb
Overview
Implementation of the state representation at runtime.
It gives access to three views to the state:
* the current values are directly accessible from this state object
* the last known value is stored in last_known.path.to.value
* the state model is stored in model.path.to.value
* the current data source for a state variable is stored in
data_sources.path.to.value
Constant Summary
Constants inherited from OpenStruct
OpenStruct::FORBIDDEN_NAMES, OpenStruct::FORBIDDEN_NAMES_RX, OpenStruct::NOT_OVERRIDABLE, OpenStruct::NOT_OVERRIDABLE_RX
Instance Attribute Summary
Attributes inherited from StateField
#data_sources, #last_known, #model
Attributes inherited from OpenStruct
#__parent_name, #__parent_struct, #model
Instance Method Summary collapse
-
#_dump(lvl = -1)) ⇒ Object
Implementation of marshalling with Ruby’s Marshal.
-
#at(options) ⇒ Object
Returns an event which emits when the given state is reached.
- #create_subfield(name) ⇒ Object
- #deep_copy ⇒ Object
-
#export(*names) ⇒ Object
Declares that only the given names should be marshalled, instead of marshalling every field.
-
#export_all ⇒ Object
Declares that all the state fields should be marshalled.
-
#export_none ⇒ Object
Declares that no state fields should be marshalled.
-
#initialize(model = nil) ⇒ StateSpace
constructor
A new instance of StateSpace.
-
#on_delta(spec) ⇒ Object
Create an event which will be emitted everytime some state parameters vary more than the given deltas.
-
#reset_when(event, state_name = nil, &block) ⇒ Object
Installs a condition at which the event should be reset.
- #simulation? ⇒ Boolean
- #testing? ⇒ Boolean
-
#trigger_when(*state_path, &block) ⇒ Object
Returns a state event that emits the first time the block returns true.
Methods inherited from StateField
#__get, #attach, #create_model, #install_type_checking_filter, #link_to, #method_missing, #read, #to_s
Methods inherited from OpenStruct
#__get, #__merge, #__parent, #__root, #__root?, _load, #alias, #alias?, #attach, #attach_child, #attach_model, #attach_to, #attached?, #clear, #clear_model, #create_model, #delete, #detached!, #each_member, #empty?, #filter, #freeze, #get, #global_filter, #has_method?, #link_to, #member?, #method_missing, #new_model, #on_change, #path, #pretty_print, #respond_to_missing?, #set, #stable!, #stable?, #to_hash, #update, #updated
Constructor Details
#initialize(model = nil) ⇒ StateSpace
Returns a new instance of StateSpace.
237 238 239 240 |
# File 'lib/roby/state/state_model.rb', line 237 def initialize(model = nil) @exported_fields = nil super(model) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Roby::StateField
Instance Method Details
#_dump(lvl = -1)) ⇒ Object
Implementation of marshalling with Ruby’s Marshal
Only the fields that can be marshalled will be saved. Any other field will silently be ignored.
Which fields get marshalled can be controlled with #export_all, #export_none and #export. The default is to marshal all fields.
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/roby/state/state_model.rb', line 287 def _dump(lvl = -1) if !@exported_fields super else marshalled_members = @exported_fields.map do |name| value = @members[name] [name, Marshal.dump(value)] rescue nil end marshalled_members.compact! Marshal.dump([marshalled_members, @aliases]) end end |
#at(options) ⇒ Object
Returns an event which emits when the given state is reached. For now, the following state variables are available:
t
-
time as a Time object
See TimePointEvent
95 96 97 98 99 100 |
# File 'lib/roby/state/events.rb', line 95 def at() = , t: nil if time = [:t] trigger_when { Time.now >= time } end end |
#create_subfield(name) ⇒ Object
275 276 277 278 |
# File 'lib/roby/state/state_model.rb', line 275 def create_subfield(name) model = self.model&.get(name) StateField.new(model, self, name) end |
#deep_copy ⇒ Object
300 301 302 303 304 305 |
# File 'lib/roby/state/state_model.rb', line 300 def deep_copy exported_fields, @exported_fields = @exported_fields, Set.new Marshal.load(Marshal.dump(self)) ensure @exported_fields = exported_fields end |
#export(*names) ⇒ Object
Declares that only the given names should be marshalled, instead of marshalling every field. It is cumulative, i.e. if multiple calls to #export follow each other then the fields get added to the list of exported fields instead of replacing it.
If #export_all has been called, a call to #export cancels it.
See also #export_none and #export_all
270 271 272 273 |
# File 'lib/roby/state/state_model.rb', line 270 def export(*names) @exported_fields ||= Set.new @exported_fields.merge names.map(&:to_s).to_set end |
#export_all ⇒ Object
Declares that all the state fields should be marshalled. This is the default
It cancels any list of fields exported with #export
See also #export_none and #export
258 259 260 |
# File 'lib/roby/state/state_model.rb', line 258 def export_all @exported_fields = nil end |
#export_none ⇒ Object
Declares that no state fields should be marshalled. The default is to export everything
It cancels any list of fields exported with #export
See also #export_all and #export
248 249 250 |
# File 'lib/roby/state/state_model.rb', line 248 def export_none @exported_fields = Set.new end |
#on_delta(spec) ⇒ Object
Create an event which will be emitted everytime some state parameters vary more than the given deltas. The following state parameters are available:
t
-
time in seconds
d
-
distance in meters
yaw
-
heading in radians
For instance:
Roby.state.on_delta d: 10, t: 20
will emit everytime the robot moves more than 10 meters AND more than 20 seconds have elapsed.
If more than once specification is given, the resulting event is combined with the & operator. This can be changed by setting the :or option to ‘true’.
Roby.state.on_delta d: 10, t: 20, or: true
See DeltaEvent and its subclasses.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/roby/state/events.rb', line 25 def on_delta(spec) or_aggregate = spec.delete(:or) events = spec.map do |name, value| unless klass = DeltaEvent.event_types[name] raise "unknown delta type #{name}. Known types are #{DeltaEvent.event_types.keys}" end ev = klass.new ev.threshold = value ev end if events.size > 1 result = if or_aggregate then OrGenerator.new else AndGenerator.new end result.on { |ev| result.reset } def result.or(spec) DeltaEvent.or(spec, self) end events.each { |ev| result << ev } result else events.first end end |
#reset_when(event, state_name = nil, &block) ⇒ Object
Installs a condition at which the event should be reset
81 82 83 84 85 86 87 88 |
# File 'lib/roby/state/events.rb', line 81 def reset_when(event, state_name = nil, &block) reset_event = trigger_when(state_name, &block) reset_event.add_causal_link event reset_event.armed = !event.armed? event.on { |ev| reset_event.reset } reset_event.on { |ev| event.reset } reset_event end |
#simulation? ⇒ Boolean
311 312 313 |
# File 'lib/roby/state/state_model.rb', line 311 def simulation? Roby.app.simulation? end |
#testing? ⇒ Boolean
307 308 309 |
# File 'lib/roby/state/state_model.rb', line 307 def testing? Roby.app.testing? end |
#trigger_when(*state_path, &block) ⇒ Object
Returns a state event that emits the first time the block returns true
The block is given the value of the specified state value state_name
. For instance, with
event = State.position.trigger_when(:x) do |value|
value > 23
end
event
will be emitted once if the X value of the position gets greater than 23. One can also specify a reset condition with
State.position.reset_when(event, :x) do |value|
value < 20
end
71 72 73 74 75 76 77 78 |
# File 'lib/roby/state/events.rb', line 71 def trigger_when(*state_path, &block) unless block_given? raise ArgumentError, "#trigger_when expects a block" end state_path.map!(&:to_s) StateConditionEvent.new(self, state_path, block) end |