module Roby::EventStructure::TemporalConstraints::Extension
Public Instance Methods
Adds a constraint on the allowed emission of other_event
based on the existing emissions of self
min
and max
specify the minimum (resp. maximum) of times self
should be emitted before other_event
has the right to be emitted.
If recurrent
is true, then the min/max values are computed using the emissions of self
since the last emission of other_event
. Otherwise, all emissions since the creation of self
are taken into account.
# File lib/roby/event_structure/temporal_constraints.rb, line 523 def add_occurence_constraint(other_event, min, max = Infinity, recurrent = false) set = TemporalConstraintSet.new set.add_occurence_constraint(min, max, recurrent) add_forward_temporal_constraint(other_event, set) end
Creates a temporal constraint between self
and other_event
. min
is the minimum time
# File lib/roby/event_structure/temporal_constraints.rb, line 493 def add_temporal_constraint(other_event, min, max) if min > max raise ArgumentError, "min should be lower than max (min == #{min} and max == #{max})" end if max < 0 return other_event.add_temporal_constraint(self, -max, -min) elsif min < 0 set = TemporalConstraintSet.new set.add(-max, -min) other_event.add_forward_temporal_constraint(self, set) end set = TemporalConstraintSet.new set.add(min, max) add_forward_temporal_constraint(other_event, set) set end
# File lib/roby/event_structure/temporal_constraints.rb, line 529 def find_failed_occurence_constraint(next_event) base_event = if next_event then last else history[-2] end if base_event base_time = base_event.time end each_backward_temporal_constraint do |parent| if block_given? next if !yield(parent) end constraints = parent[self, TemporalConstraints] counts = { false => parent.history.size } if base_time negative_count = parent.history.inject(0) do |count, ev| break(count) if ev.time > base_time count + 1 end else negative_count = 0 end counts[true] = counts[false] - negative_count counts.each do |recurrent, count| min_count, max_count = constraints.occurence_constraints[recurrent] if count < min_count || count > max_count if recurrent && base_time return [parent, parent.history.size, [min_count, max_count], base_time] else return [parent, parent.history.size, [min_count, max_count]] end end end end nil end
Returns a [parent, intervals] pair that represents a temporal constraint the given time fails to meet
# File lib/roby/event_structure/temporal_constraints.rb, line 459 def find_failed_temporal_constraint(time) each_backward_temporal_constraint do |parent| if block_given? next if !yield(parent) end disjoint_set = parent[self, TemporalConstraints] next if disjoint_set.intervals.empty? if disjoint_set.boundaries[0] < 0 # It might be fullfilled in the future next end max_diff = disjoint_set.boundaries[1] parent.history.each do |parent_event| diff = time - parent_event.time if diff > max_diff || !disjoint_set.include?(diff) return parent, disjoint_set end disjoint_set.include?(diff) end end nil end
True if this event is constrained by the TemporalConstraints
relation in any way
# File lib/roby/event_structure/temporal_constraints.rb, line 450 def has_temporal_constraints? each_backward_temporal_constraint do |parent| return true end false end
Returns true if this event meets its temporal constraints
# File lib/roby/event_structure/temporal_constraints.rb, line 486 def meets_temporal_constraints?(time, &block) !find_failed_temporal_constraint(time, &block) && !find_failed_occurence_constraint(true, &block) end
Shortcut to specify that self
should be emitted after other_event
# File lib/roby/event_structure/temporal_constraints.rb, line 428 def should_emit_after(other_event, options = nil) if options options = Kernel.validate_options options, min_t: nil, max_t: nil, recurrent: false recurrent = options[:recurrent] end other_event.add_occurence_constraint(self, 1, Infinity, recurrent) if options && (options[:min_t] || options[:max_t]) other_event.add_temporal_constraint(self, options[:min_t] || 0, options[:max_t] || Infinity) end end
Returns true if there is a constraint that specifies that self and generator are ordered in time
# File lib/roby/event_structure/temporal_constraints.rb, line 443 def should_emit_after?(generator) graph = plan.event_relation_graph_for(TemporalConstraints) graph.has_edge?(generator, self) end