module Roby::EventStructure::TemporalConstraints::Extension

Public Instance Methods

add_occurence_constraint(other_event, min, max = Infinity, recurrent = false) click to toggle source

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
add_temporal_constraint(other_event, min, max) click to toggle source

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
find_failed_occurence_constraint(next_event) { |parent| ... } click to toggle source
# 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
find_failed_temporal_constraint(time) { |parent| ... } click to toggle source

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
has_temporal_constraints?() click to toggle source

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
meets_temporal_constraints?(time, &block) click to toggle source

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
should_emit_after(other_event, options = nil) click to toggle source

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
should_emit_after?(generator) click to toggle source

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