roby 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -5
- data/Manifest.txt +91 -16
- data/README.txt +24 -24
- data/Rakefile +92 -64
- data/app/config/app.yml +42 -43
- data/app/config/init.rb +26 -0
- data/benchmark/alloc_misc.rb +123 -0
- data/benchmark/discovery_latency.rb +67 -0
- data/benchmark/garbage_collection.rb +48 -0
- data/benchmark/genom.rb +31 -0
- data/benchmark/transactions.rb +62 -0
- data/bin/roby +1 -1
- data/bin/roby-log +16 -6
- data/doc/guide/.gitignore +2 -0
- data/doc/guide/config.yaml +34 -0
- data/doc/guide/ext/init.rb +14 -0
- data/doc/guide/ext/previous_next.rb +40 -0
- data/doc/guide/ext/rdoc_links.rb +33 -0
- data/doc/guide/index.rdoc +16 -0
- data/doc/guide/overview.rdoc +62 -0
- data/doc/guide/plan_modifications.rdoc +67 -0
- data/doc/guide/src/abstraction/achieve_with.page +8 -0
- data/doc/guide/src/abstraction/forwarding.page +8 -0
- data/doc/guide/src/abstraction/hierarchy.page +19 -0
- data/doc/guide/src/abstraction/index.page +28 -0
- data/doc/guide/src/abstraction/task_models.page +13 -0
- data/doc/guide/src/basics.template +6 -0
- data/doc/guide/src/basics/app.page +139 -0
- data/doc/guide/src/basics/code_examples.page +33 -0
- data/doc/guide/src/basics/dry.page +69 -0
- data/doc/guide/src/basics/errors.page +443 -0
- data/doc/guide/src/basics/events.page +179 -0
- data/doc/guide/src/basics/hierarchy.page +275 -0
- data/doc/guide/src/basics/index.page +11 -0
- data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_4.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/basics/plan_objects.page +71 -0
- data/doc/guide/src/basics/relations_display.page +203 -0
- data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
- data/doc/guide/src/basics/shell.page +102 -0
- data/doc/guide/src/basics/summary.page +32 -0
- data/doc/guide/src/basics/tasks.page +357 -0
- data/doc/guide/src/basics_shell_header.txt +16 -0
- data/doc/guide/src/cycle/cycle-overview.png +0 -0
- data/doc/guide/src/cycle/cycle-overview.svg +208 -0
- data/doc/guide/src/cycle/error_handling.page +168 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
- data/doc/guide/src/cycle/garbage_collection.page +10 -0
- data/doc/guide/src/cycle/index.page +23 -0
- data/doc/guide/src/cycle/propagation.page +154 -0
- data/doc/guide/src/cycle/propagation_diamond.png +0 -0
- data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
- data/doc/guide/src/default.css +319 -0
- data/doc/guide/src/default.template +74 -0
- data/doc/guide/src/htmldoc.metainfo +20 -0
- data/doc/guide/src/htmldoc.virtual +18 -0
- data/doc/guide/src/images/bodybg.png +0 -0
- data/doc/guide/src/images/contbg.png +0 -0
- data/doc/guide/src/images/footerbg.png +0 -0
- data/doc/guide/src/images/gradient1.png +0 -0
- data/doc/guide/src/images/gradient2.png +0 -0
- data/doc/guide/src/index.page +7 -0
- data/doc/guide/src/introduction/index.page +29 -0
- data/doc/guide/src/introduction/install.page +133 -0
- data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
- data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
- data/doc/guide/src/plugins/fault_tolerance.page +44 -0
- data/doc/guide/src/plugins/index.page +11 -0
- data/doc/guide/src/plugins/subsystems.page +45 -0
- data/doc/guide/src/relations/dependency.page +89 -0
- data/doc/guide/src/relations/index.page +12 -0
- data/doc/misc/update_github +24 -0
- data/doc/tutorials/02-GoForward.rdoc +3 -3
- data/ext/graph/graph.cc +46 -0
- data/lib/roby.rb +57 -22
- data/lib/roby/app.rb +132 -112
- data/lib/roby/app/plugins/rake.rb +21 -0
- data/lib/roby/app/rake.rb +0 -7
- data/lib/roby/app/run.rb +1 -1
- data/lib/roby/app/scripts/distributed.rb +1 -2
- data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
- data/lib/roby/app/scripts/results.rb +2 -1
- data/lib/roby/app/scripts/run.rb +6 -2
- data/lib/roby/app/scripts/shell.rb +11 -11
- data/lib/roby/config.rb +1 -1
- data/lib/roby/decision_control.rb +62 -3
- data/lib/roby/distributed.rb +4 -0
- data/lib/roby/distributed/base.rb +8 -0
- data/lib/roby/distributed/communication.rb +12 -8
- data/lib/roby/distributed/connection_space.rb +61 -44
- data/lib/roby/distributed/distributed_object.rb +1 -1
- data/lib/roby/distributed/notifications.rb +22 -30
- data/lib/roby/distributed/peer.rb +13 -8
- data/lib/roby/distributed/proxy.rb +5 -5
- data/lib/roby/distributed/subscription.rb +4 -4
- data/lib/roby/distributed/transaction.rb +3 -3
- data/lib/roby/event.rb +176 -110
- data/lib/roby/exceptions.rb +12 -4
- data/lib/roby/execution_engine.rb +1604 -0
- data/lib/roby/external_process_task.rb +225 -0
- data/lib/roby/graph.rb +0 -6
- data/lib/roby/interface.rb +221 -137
- data/lib/roby/log/console.rb +5 -3
- data/lib/roby/log/data_stream.rb +94 -16
- data/lib/roby/log/dot.rb +8 -8
- data/lib/roby/log/event_stream.rb +13 -3
- data/lib/roby/log/file.rb +43 -18
- data/lib/roby/log/gui/basic_display_ui.rb +89 -0
- data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
- data/lib/roby/log/gui/data_displays.rb +4 -5
- data/lib/roby/log/gui/data_displays_ui.rb +146 -0
- data/lib/roby/log/gui/relations.rb +18 -18
- data/lib/roby/log/gui/relations_ui.rb +120 -0
- data/lib/roby/log/gui/relations_view_ui.rb +144 -0
- data/lib/roby/log/gui/replay.rb +41 -13
- data/lib/roby/log/gui/replay_controls.rb +3 -0
- data/lib/roby/log/gui/replay_controls.ui +133 -110
- data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
- data/lib/roby/log/hooks.rb +19 -18
- data/lib/roby/log/logger.rb +7 -6
- data/lib/roby/log/notifications.rb +4 -4
- data/lib/roby/log/plan_rebuilder.rb +20 -22
- data/lib/roby/log/relations.rb +44 -16
- data/lib/roby/log/server.rb +1 -4
- data/lib/roby/log/timings.rb +88 -19
- data/lib/roby/plan-object.rb +135 -11
- data/lib/roby/plan.rb +408 -224
- data/lib/roby/planning/loops.rb +32 -25
- data/lib/roby/planning/model.rb +157 -51
- data/lib/roby/planning/task.rb +47 -20
- data/lib/roby/query.rb +128 -92
- data/lib/roby/relations.rb +254 -136
- data/lib/roby/relations/conflicts.rb +6 -9
- data/lib/roby/relations/dependency.rb +358 -0
- data/lib/roby/relations/ensured.rb +0 -1
- data/lib/roby/relations/error_handling.rb +0 -1
- data/lib/roby/relations/events.rb +0 -2
- data/lib/roby/relations/executed_by.rb +26 -11
- data/lib/roby/relations/planned_by.rb +14 -14
- data/lib/roby/robot.rb +46 -0
- data/lib/roby/schedulers/basic.rb +34 -0
- data/lib/roby/standalone.rb +4 -0
- data/lib/roby/standard_errors.rb +21 -15
- data/lib/roby/state/events.rb +5 -4
- data/lib/roby/support.rb +107 -6
- data/lib/roby/task-operations.rb +23 -19
- data/lib/roby/task.rb +522 -148
- data/lib/roby/task_index.rb +80 -0
- data/lib/roby/test/common.rb +283 -44
- data/lib/roby/test/distributed.rb +53 -37
- data/lib/roby/test/testcase.rb +9 -204
- data/lib/roby/test/tools.rb +3 -3
- data/lib/roby/transactions.rb +154 -111
- data/lib/roby/transactions/proxy.rb +40 -7
- data/manifest.xml +20 -0
- data/plugins/fault_injection/README.txt +0 -3
- data/plugins/fault_injection/Rakefile +2 -8
- data/plugins/fault_injection/app.rb +1 -1
- data/plugins/fault_injection/fault_injection.rb +3 -3
- data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
- data/plugins/subsystems/README.txt +0 -3
- data/plugins/subsystems/Rakefile +2 -7
- data/plugins/subsystems/app.rb +27 -16
- data/plugins/subsystems/test/app/config/init.rb +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +1 -1
- data/plugins/subsystems/test/app/tasks/services.rb +1 -1
- data/plugins/subsystems/test/test_subsystems.rb +23 -16
- data/test/distributed/test_communication.rb +32 -15
- data/test/distributed/test_connection.rb +28 -26
- data/test/distributed/test_execution.rb +59 -54
- data/test/distributed/test_mixed_plan.rb +34 -34
- data/test/distributed/test_plan_notifications.rb +26 -26
- data/test/distributed/test_protocol.rb +57 -48
- data/test/distributed/test_query.rb +11 -7
- data/test/distributed/test_remote_plan.rb +71 -71
- data/test/distributed/test_transaction.rb +50 -47
- data/test/mockups/external_process +28 -0
- data/test/planning/test_loops.rb +163 -119
- data/test/planning/test_model.rb +3 -3
- data/test/planning/test_task.rb +27 -7
- data/test/relations/test_conflicts.rb +3 -3
- data/test/relations/test_dependency.rb +324 -0
- data/test/relations/test_ensured.rb +2 -2
- data/test/relations/test_executed_by.rb +94 -19
- data/test/relations/test_planned_by.rb +11 -9
- data/test/suite_core.rb +6 -3
- data/test/suite_distributed.rb +1 -0
- data/test/suite_planning.rb +1 -0
- data/test/suite_relations.rb +2 -2
- data/test/tasks/test_external_process.rb +126 -0
- data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
- data/test/test_bgl.rb +21 -1
- data/test/test_event.rb +229 -155
- data/test/test_exceptions.rb +79 -80
- data/test/test_execution_engine.rb +987 -0
- data/test/test_gui.rb +1 -1
- data/test/test_interface.rb +11 -5
- data/test/test_log.rb +18 -7
- data/test/test_log_server.rb +1 -0
- data/test/test_plan.rb +229 -395
- data/test/test_query.rb +193 -35
- data/test/test_relations.rb +88 -8
- data/test/test_state.rb +55 -37
- data/test/test_support.rb +1 -1
- data/test/test_task.rb +371 -218
- data/test/test_testcase.rb +32 -16
- data/test/test_transactions.rb +211 -170
- data/test/test_transactions_proxy.rb +37 -19
- metadata +169 -71
- data/.gitignore +0 -29
- data/doc/styles/allison.css +0 -314
- data/doc/styles/allison.js +0 -316
- data/doc/styles/allison.rb +0 -276
- data/doc/styles/jamis.rb +0 -593
- data/lib/roby/control.rb +0 -746
- data/lib/roby/executives/simple.rb +0 -30
- data/lib/roby/propagation.rb +0 -562
- data/lib/roby/relations/hierarchy.rb +0 -239
- data/lib/roby/transactions/updates.rb +0 -139
- data/test/relations/test_hierarchy.rb +0 -158
- data/test/test_control.rb +0 -399
- data/test/test_propagation.rb +0 -210
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
require 'roby/task'
|
|
2
|
-
require 'roby/control'
|
|
3
|
-
require 'set'
|
|
4
|
-
|
|
5
|
-
module Roby::TaskStructure
|
|
6
|
-
# Document-module: Hierarchy
|
|
7
|
-
relation :Hierarchy, :child_name => :child, :parent_name => :parent_task do
|
|
8
|
-
# True if +obj+ is a parent of this object in the hierarchy relation
|
|
9
|
-
# (+obj+ is realized by +self+)
|
|
10
|
-
def realizes?(obj); parent_object?(obj, Hierarchy) end
|
|
11
|
-
# True if +obj+ is a child of this object in the hierarchy relation
|
|
12
|
-
def realized_by?(obj); child_object?(obj, Hierarchy) end
|
|
13
|
-
# True if +obj+ can be reached through the Hierarchy relation by
|
|
14
|
-
# starting from this object
|
|
15
|
-
def depends_on?(obj)
|
|
16
|
-
generated_subgraph(Hierarchy).include?(obj)
|
|
17
|
-
end
|
|
18
|
-
# The set of parent objects in the Hierarchy relation
|
|
19
|
-
def parents; parent_objects(Hierarchy) end
|
|
20
|
-
# The set of child objects in the Hierarchy relation
|
|
21
|
-
def children; child_objects(Hierarchy) end
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# Adds +task+ as a child of +self+ in the Hierarchy relation. The
|
|
25
|
-
# following options are allowed:
|
|
26
|
-
#
|
|
27
|
-
# success:: the list of success events. The default is [:success]
|
|
28
|
-
# failure:: the list of failing events. The default is [:failed]
|
|
29
|
-
# model:: a <tt>[task_model, arguments]</tt> pair which defines the task model the parent is expecting.
|
|
30
|
-
# The default value is to get these parameters from +task+
|
|
31
|
-
#
|
|
32
|
-
# The +success+ set describes the events of the child task that are
|
|
33
|
-
# _required_ by the parent task. More specifically, the child task
|
|
34
|
-
# remains useful for the parent task as long as none of these events are
|
|
35
|
-
# emitted. By default, it is the +success+ event. Of course, an error
|
|
36
|
-
# condition is encountered when all events of +success+ become
|
|
37
|
-
# unreachable. In addition, the relation is removed if the
|
|
38
|
-
# +remove_when_done+ flag is set to true (false by default).
|
|
39
|
-
#
|
|
40
|
-
# The +failure+ set describes the events of the child task which are an
|
|
41
|
-
# error condition from the parent task point of view.
|
|
42
|
-
#
|
|
43
|
-
# In both error cases, a +ChildFailedError+ exception is raised.
|
|
44
|
-
def realized_by(task, options = {})
|
|
45
|
-
options = validate_options options,
|
|
46
|
-
:model => [task.model, task.meaningful_arguments],
|
|
47
|
-
:success => [:success],
|
|
48
|
-
:failure => [:failed],
|
|
49
|
-
:remove_when_done => false
|
|
50
|
-
|
|
51
|
-
options[:success] = Array[*options[:success]]
|
|
52
|
-
options[:failure] = Array[*options[:failure]]
|
|
53
|
-
|
|
54
|
-
# Validate failure and success event names
|
|
55
|
-
options[:success].each { |ev| task.event(ev) }
|
|
56
|
-
options[:failure].each { |ev| task.event(ev) }
|
|
57
|
-
|
|
58
|
-
options[:model] = [options[:model], {}] unless Array === options[:model]
|
|
59
|
-
required_model, required_args = *options[:model]
|
|
60
|
-
if !task.fullfills?(required_model, required_args)
|
|
61
|
-
raise ArgumentError, "task #{task} does not fullfills the provided model #{options[:model]}"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
add_child(task, options)
|
|
65
|
-
self
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Set up the event gathering needed by Hierarchy.check_structure
|
|
69
|
-
def added_child_object(child, relations, info) # :nodoc:
|
|
70
|
-
super if defined? super
|
|
71
|
-
if relations.include?(Hierarchy) && !respond_to?(:__getobj__) && !child.respond_to?(:__getobj__)
|
|
72
|
-
events = info[:success].map { |ev| child.event(ev) }
|
|
73
|
-
events.concat info[:failure].map { |ev| child.event(ev) }
|
|
74
|
-
Roby::EventGenerator.gather_events(Hierarchy.interesting_events, events)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Return the set of this task children for which the :start event has
|
|
79
|
-
# no parent in CausalLinks
|
|
80
|
-
def first_children
|
|
81
|
-
result = ValueSet.new
|
|
82
|
-
|
|
83
|
-
generated_subgraph(Hierarchy).each do |task|
|
|
84
|
-
next if task == self
|
|
85
|
-
if task.event(:start).root?(Roby::EventStructure::CausalLink)
|
|
86
|
-
result << task
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
result
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# The set of events that are needed by the parent tasks
|
|
93
|
-
def fullfilled_events
|
|
94
|
-
needed = ValueSet.new
|
|
95
|
-
each_parent_task do |parent|
|
|
96
|
-
needed.merge(parent[self, Hierarchy][:success])
|
|
97
|
-
end
|
|
98
|
-
needed
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Return [tags, arguments] where +tags+ is a list of task models which
|
|
102
|
-
# are required by the parent tasks of this task, and arguments the
|
|
103
|
-
# required arguments
|
|
104
|
-
#
|
|
105
|
-
# If there is a task class in the required models, it is always the
|
|
106
|
-
# first element of +tags+
|
|
107
|
-
def fullfilled_model
|
|
108
|
-
model, tags, arguments = Roby::Task, [], {}
|
|
109
|
-
|
|
110
|
-
each_parent_task do |parent|
|
|
111
|
-
m, a = parent[self, Hierarchy][:model]
|
|
112
|
-
if m.instance_of?(Roby::TaskModelTag)
|
|
113
|
-
tags << m
|
|
114
|
-
elsif m.has_ancestor?(model)
|
|
115
|
-
model = m
|
|
116
|
-
elsif !model.has_ancestor?(m)
|
|
117
|
-
raise "inconsistency in fullfilled models: #{model} and #{m} are incompatible"
|
|
118
|
-
end
|
|
119
|
-
a.merge!(arguments) do |old, new|
|
|
120
|
-
if old != new
|
|
121
|
-
raise "inconsistency in fullfilled models: #{old} and #{new}"
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
tags.unshift(model)
|
|
127
|
-
[tags, arguments]
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Remove all children that have successfully finished
|
|
131
|
-
def remove_finished_children
|
|
132
|
-
# We call #to_a to get a copy of children, since we will remove
|
|
133
|
-
# children in the block. Note that we can't use #delete_if here
|
|
134
|
-
# since #children is a relation enumerator (not the relation list
|
|
135
|
-
# itself)
|
|
136
|
-
children.to_a.each do |child|
|
|
137
|
-
success_events = self[child, Hierarchy][:success]
|
|
138
|
-
if success_events.any? { |ev| child.event(ev).happened? }
|
|
139
|
-
remove_child(child)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Checks the structure of +plan+ w.r.t. the constraints of the hierarchy
|
|
146
|
-
# relations. It returns an array of ChildFailedError for all failed
|
|
147
|
-
# hierarchy relations
|
|
148
|
-
def Hierarchy.check_structure(plan)
|
|
149
|
-
result = []
|
|
150
|
-
|
|
151
|
-
events = Hierarchy.interesting_events
|
|
152
|
-
return result if events.empty? && failing_tasks.empty?
|
|
153
|
-
|
|
154
|
-
# Get the set of tasks for which a possible failure has been
|
|
155
|
-
# registered The tasks that are failing the hierarchy requirements
|
|
156
|
-
# are registered in Hierarchy.failing_tasks. The interesting_events
|
|
157
|
-
# set is cleared at cycle end (see below)
|
|
158
|
-
tasks = events.inject(failing_tasks) { |set, event| set << event.generator.task }
|
|
159
|
-
@failing_tasks = ValueSet.new
|
|
160
|
-
tasks.each do |child|
|
|
161
|
-
# Check if the task has been removed from the plan
|
|
162
|
-
next unless child.plan
|
|
163
|
-
|
|
164
|
-
has_error = false
|
|
165
|
-
child.each_parent_task do |parent|
|
|
166
|
-
next unless parent.self_owned?
|
|
167
|
-
next if parent.finished? || parent.finishing?
|
|
168
|
-
|
|
169
|
-
options = parent[child, Hierarchy]
|
|
170
|
-
success = options[:success]
|
|
171
|
-
failure = options[:failure]
|
|
172
|
-
|
|
173
|
-
if success.any? { |e| child.event(e).happened? }
|
|
174
|
-
if options[:remove_when_done]
|
|
175
|
-
parent.remove_child child
|
|
176
|
-
end
|
|
177
|
-
elsif failing_event = failure.find { |e| child.event(e).happened? }
|
|
178
|
-
result << Roby::ChildFailedError.new(parent, child.event(failing_event).last)
|
|
179
|
-
failing_tasks << child
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
events.clear
|
|
185
|
-
result
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
class << Hierarchy
|
|
189
|
-
# The set of events that have been fired in this cycle and are involved in a Hierarchy relation
|
|
190
|
-
attribute(:interesting_events) { Array.new }
|
|
191
|
-
|
|
192
|
-
# The set of tasks that are currently failing
|
|
193
|
-
attribute(:failing_tasks) { ValueSet.new }
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
module Roby
|
|
198
|
-
# This exception is raised when a {hierarchy relation}[classes/Roby/TaskStructure/Hierarchy.html] fails
|
|
199
|
-
class ChildFailedError < LocalizedError
|
|
200
|
-
# The parent in the relation
|
|
201
|
-
attr_reader :parent
|
|
202
|
-
# The child in the relation
|
|
203
|
-
def child; failed_task end
|
|
204
|
-
# The relation parameters (i.e. the hash given to #realized_by)
|
|
205
|
-
attr_reader :relation
|
|
206
|
-
|
|
207
|
-
# The event which is the cause of this error. This is either the task
|
|
208
|
-
# source of a failure event, or the reason why a positive event has
|
|
209
|
-
# become unreachable (if there is one)
|
|
210
|
-
def initialize(parent, event)
|
|
211
|
-
super(event.task_sources.find { true })
|
|
212
|
-
@parent = parent
|
|
213
|
-
@relation = parent[child, TaskStructure::Hierarchy]
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def pretty_print(pp) # :nodoc:
|
|
217
|
-
super
|
|
218
|
-
pp.breakable
|
|
219
|
-
pp.breakable
|
|
220
|
-
pp.text "The failed relation is"
|
|
221
|
-
pp.breakable
|
|
222
|
-
pp.nest(2) do
|
|
223
|
-
pp.text " "
|
|
224
|
-
parent.pretty_print pp
|
|
225
|
-
pp.breakable
|
|
226
|
-
pp.text "realized_by "
|
|
227
|
-
child.pretty_print pp
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
def backtrace; [] end
|
|
231
|
-
|
|
232
|
-
# True if +obj+ is involved in this exception
|
|
233
|
-
def involved_plan_object?(obj)
|
|
234
|
-
super || obj == parent
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
Control.structure_checks << TaskStructure::Hierarchy.method(:check_structure)
|
|
238
|
-
end
|
|
239
|
-
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
module Roby
|
|
2
|
-
class SolverInvalidateTransaction
|
|
3
|
-
def self.finalized_plan_task(trsc, task); end
|
|
4
|
-
def self.finalized_plan_event(trsc, task); end
|
|
5
|
-
|
|
6
|
-
def self.adding_plan_relation(trsc, parent, child, relations, info)
|
|
7
|
-
end
|
|
8
|
-
def self.removing_plan_relation(trsc, parent, child, relations)
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class SolverUpdateRelations
|
|
13
|
-
def self.finalized_plan_task(trsc, task)
|
|
14
|
-
end
|
|
15
|
-
def self.finalized_plan_event(trsc, task)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.adding_plan_relation(trsc, parent, child, relations, info)
|
|
19
|
-
parent_proxy = trsc.wrap(parent)
|
|
20
|
-
child_proxy = trsc.wrap(child)
|
|
21
|
-
for rel in relations
|
|
22
|
-
rel.link(parent_proxy, child_proxy, info)
|
|
23
|
-
end
|
|
24
|
-
trsc.invalid = false
|
|
25
|
-
end
|
|
26
|
-
def self.removing_plan_relation(trsc, parent, child, relations)
|
|
27
|
-
parent_proxy = trsc.wrap(parent)
|
|
28
|
-
child_proxy = trsc.wrap(child)
|
|
29
|
-
for rel in relations
|
|
30
|
-
rel.unlink(parent_proxy, child_proxy)
|
|
31
|
-
end
|
|
32
|
-
trsc.invalid = false
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class SolverIgnoreUpdate
|
|
37
|
-
def finalized_plan_task(trsc, task)
|
|
38
|
-
Roby.debug "#{trsc} is valid again"
|
|
39
|
-
trsc.invalid = false
|
|
40
|
-
end
|
|
41
|
-
def finalized_plan_event(trsc, task)
|
|
42
|
-
Roby.debug "#{trsc} is valid again"
|
|
43
|
-
trsc.invalid = false
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def adding_plan_relation(trsc, parent, child, relations, info)
|
|
47
|
-
Roby.debug "#{trsc} is valid again"
|
|
48
|
-
trsc.invalid = false
|
|
49
|
-
end
|
|
50
|
-
def removing_plan_relation(trsc, parent, child, relations)
|
|
51
|
-
Roby.debug "#{trsc} is valid again"
|
|
52
|
-
trsc.invalid = false
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
class Transaction
|
|
56
|
-
def finalized_plan_task(task)
|
|
57
|
-
invalidate("task #{task} has been removed from the plan")
|
|
58
|
-
discard_modifications(task)
|
|
59
|
-
conflict_solver.finalized_plan_task(self, task)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def finalized_plan_event(event)
|
|
63
|
-
invalidate("event #{event} has been removed from the plan")
|
|
64
|
-
discard_modifications(event)
|
|
65
|
-
conflict_solver.finalized_plan_event(self, event)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def adding_plan_relation(parent, child, relations, info)
|
|
69
|
-
missing_relations = relations.find_all do |rel|
|
|
70
|
-
!parent.child_object?(child, rel)
|
|
71
|
-
end
|
|
72
|
-
unless missing_relations.empty?
|
|
73
|
-
invalidate("plan added a relation #{parent} -> #{child} in #{relations} with info #{info}")
|
|
74
|
-
conflict_solver.adding_plan_relation(self, parent, child, relations, info)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def removing_plan_relation(parent, child, relations)
|
|
79
|
-
present_relations = relations.find_all do |rel|
|
|
80
|
-
parent.child_object?(child, rel)
|
|
81
|
-
end
|
|
82
|
-
unless present_relations.empty?
|
|
83
|
-
invalidate("plan removed the #{parent} -> #{child} relation in #{relations}")
|
|
84
|
-
conflict_solver.removing_plan_relation(self, parent, child, relations)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
module Transactions
|
|
90
|
-
module PlanUpdates
|
|
91
|
-
def self.finalized_object(plan, object)
|
|
92
|
-
return unless object.root_object?
|
|
93
|
-
plan.transactions.each do |trsc|
|
|
94
|
-
next unless trsc.proxying?
|
|
95
|
-
|
|
96
|
-
if proxy = trsc.wrap(object, false)
|
|
97
|
-
yield(trsc, proxy)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
def finalized_event(event)
|
|
102
|
-
super if defined? super
|
|
103
|
-
PlanUpdates.finalized_object(self, event) { |trsc, proxy| trsc.finalized_plan_event(proxy) }
|
|
104
|
-
end
|
|
105
|
-
def finalized_task(task)
|
|
106
|
-
super if defined? super
|
|
107
|
-
PlanUpdates.finalized_object(self, task) { |trsc, proxy| trsc.finalized_plan_task(proxy) }
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
Roby::Plan.include PlanUpdates
|
|
111
|
-
|
|
112
|
-
module PlanObjectUpdates
|
|
113
|
-
def adding_child_object(child, relations, info)
|
|
114
|
-
super if defined? super
|
|
115
|
-
return if !plan
|
|
116
|
-
|
|
117
|
-
for trsc in plan.transactions
|
|
118
|
-
next unless trsc.proxying?
|
|
119
|
-
if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
|
|
120
|
-
trsc.adding_plan_relation(parent_proxy, child_proxy, relations, info)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
def removing_child_object(child, relations)
|
|
125
|
-
super if defined? super
|
|
126
|
-
return if !plan
|
|
127
|
-
|
|
128
|
-
plan.transactions.each do |trsc|
|
|
129
|
-
next unless trsc.proxying?
|
|
130
|
-
if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
|
|
131
|
-
trsc.removing_plan_relation(parent_proxy, child_proxy, relations)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
Roby::PlanObject.include PlanObjectUpdates
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
2
|
-
require 'roby/test/common'
|
|
3
|
-
require 'roby/test/tasks/simple_task'
|
|
4
|
-
|
|
5
|
-
class TC_RealizedBy < Test::Unit::TestCase
|
|
6
|
-
include Roby::Test
|
|
7
|
-
|
|
8
|
-
def test_definition
|
|
9
|
-
tag = TaskModelTag.new
|
|
10
|
-
klass = Class.new(SimpleTask) do
|
|
11
|
-
argument :id
|
|
12
|
-
include tag
|
|
13
|
-
end
|
|
14
|
-
plan.discover(t1 = SimpleTask.new)
|
|
15
|
-
|
|
16
|
-
# Check validation of the model
|
|
17
|
-
child = nil
|
|
18
|
-
assert_nothing_raised { t1.realized_by((child = klass.new), :model => SimpleTask) }
|
|
19
|
-
|
|
20
|
-
assert_same(Hierarchy.interesting_events, EventGenerator.event_gathering[child.event(:success)].find { true })
|
|
21
|
-
assert_same(Hierarchy.interesting_events, EventGenerator.event_gathering[child.event(:failed)].find { true })
|
|
22
|
-
assert_equal([SimpleTask, {}], t1[child, Hierarchy][:model])
|
|
23
|
-
|
|
24
|
-
assert_nothing_raised { t1.realized_by klass.new, :model => [Roby::Task, {}] }
|
|
25
|
-
assert_nothing_raised { t1.realized_by klass.new, :model => tag }
|
|
26
|
-
|
|
27
|
-
plan.discover(simple_task = SimpleTask.new)
|
|
28
|
-
assert_raises(ArgumentError) { t1.realized_by simple_task, :model => [Class.new(Roby::Task), {}] }
|
|
29
|
-
assert_raises(ArgumentError) { t1.realized_by simple_task, :model => TaskModelTag.new }
|
|
30
|
-
|
|
31
|
-
# Check validation of the arguments
|
|
32
|
-
plan.discover(model_task = klass.new)
|
|
33
|
-
assert_raises(ArgumentError) { t1.realized_by model_task, :model => [SimpleTask, {:id => 'bad'}] }
|
|
34
|
-
|
|
35
|
-
plan.discover(child = klass.new(:id => 'good'))
|
|
36
|
-
assert_raises(ArgumentError) { t1.realized_by child, :model => [klass, {:id => 'bad'}] }
|
|
37
|
-
assert_nothing_raised { t1.realized_by child, :model => [klass, {:id => 'good'}] }
|
|
38
|
-
assert_equal([klass, { :id => 'good' }], t1[child, TaskStructure::Hierarchy][:model])
|
|
39
|
-
|
|
40
|
-
# Check edge annotation
|
|
41
|
-
t2 = SimpleTask.new
|
|
42
|
-
t1.realized_by t2, :model => SimpleTask
|
|
43
|
-
assert_equal([SimpleTask, {}], t1[t2, TaskStructure::Hierarchy][:model])
|
|
44
|
-
t2 = klass.new(:id => 10)
|
|
45
|
-
t1.realized_by t2, :model => [klass, { :id => 10 }]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
Hierarchy = TaskStructure::Hierarchy
|
|
49
|
-
|
|
50
|
-
def assert_children_failed(children, plan)
|
|
51
|
-
result = Hierarchy.check_structure(plan)
|
|
52
|
-
assert_equal(children.to_set, result.map { |e| e.failed_task }.to_set)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def test_failure_point
|
|
56
|
-
model = Class.new(SimpleTask) do
|
|
57
|
-
event :specialized_failure, :command => true
|
|
58
|
-
forward :specialized_failure => :failed
|
|
59
|
-
end
|
|
60
|
-
parent, child = prepare_plan :discover => 1, :tasks => 1, :model => model
|
|
61
|
-
parent.realized_by child
|
|
62
|
-
|
|
63
|
-
parent.start!
|
|
64
|
-
child.start!
|
|
65
|
-
child.specialized_failure!
|
|
66
|
-
|
|
67
|
-
error = Hierarchy.check_structure(plan).first.exception
|
|
68
|
-
assert_kind_of(ChildFailedError, error)
|
|
69
|
-
assert_equal(child.event(:specialized_failure).last, error.failure_point)
|
|
70
|
-
assert_equal(child.event(:specialized_failure).last, error.failed_event)
|
|
71
|
-
|
|
72
|
-
parent.stop!
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def test_exception_printing
|
|
76
|
-
parent, child = prepare_plan :discover => 2, :model => SimpleTask
|
|
77
|
-
parent.realized_by child
|
|
78
|
-
parent.start!
|
|
79
|
-
child.start!
|
|
80
|
-
child.failed!
|
|
81
|
-
|
|
82
|
-
error = Hierarchy.check_structure(plan).first.exception
|
|
83
|
-
assert_kind_of(ChildFailedError, error)
|
|
84
|
-
assert_nothing_raised do
|
|
85
|
-
Roby.format_exception(error)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
parent.stop!
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def test_structure_checking
|
|
92
|
-
child_model = Class.new(SimpleTask) do
|
|
93
|
-
event :first, :command => true
|
|
94
|
-
event :second, :command => true
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
p1 = SimpleTask.new
|
|
98
|
-
child = child_model.new
|
|
99
|
-
plan.discover([p1, child])
|
|
100
|
-
p1.realized_by child
|
|
101
|
-
plan.insert(p1)
|
|
102
|
-
|
|
103
|
-
child.start!; p1.start!
|
|
104
|
-
assert_equal([], Hierarchy.check_structure(plan))
|
|
105
|
-
child.stop!
|
|
106
|
-
assert_equal([child.event(:failed).last], Hierarchy.interesting_events)
|
|
107
|
-
assert_children_failed([child], plan)
|
|
108
|
-
|
|
109
|
-
plan.clear
|
|
110
|
-
p1 = SimpleTask.new
|
|
111
|
-
child = child_model.new
|
|
112
|
-
plan.discover([p1, child])
|
|
113
|
-
p1.realized_by child, :success => [:second], :failure => [:first]
|
|
114
|
-
plan.insert(p1)
|
|
115
|
-
child.start! ; p1.start!
|
|
116
|
-
child.event(:first).emit(nil)
|
|
117
|
-
assert_children_failed([child], plan)
|
|
118
|
-
|
|
119
|
-
plan.clear
|
|
120
|
-
p1 = SimpleTask.new
|
|
121
|
-
child = child_model.new
|
|
122
|
-
plan.discover([p1, child])
|
|
123
|
-
p1.realized_by child, :success => [:first], :failure => [:second]
|
|
124
|
-
plan.insert(p1)
|
|
125
|
-
child.start! ; p1.start!
|
|
126
|
-
child.event(:first).emit(nil)
|
|
127
|
-
assert_children_failed([], plan)
|
|
128
|
-
child.event(:second).emit(nil)
|
|
129
|
-
assert_children_failed([], plan)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def test_fullfilled_model
|
|
133
|
-
tag = TaskModelTag.new
|
|
134
|
-
klass = Class.new(SimpleTask) do
|
|
135
|
-
include tag
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
p1, p2, child = prepare_plan :discover => 3, :model => klass
|
|
139
|
-
|
|
140
|
-
p1.realized_by child, :model => SimpleTask
|
|
141
|
-
p2.realized_by child, :model => Roby::Task
|
|
142
|
-
assert_equal([[SimpleTask], {}], child.fullfilled_model)
|
|
143
|
-
p1.remove_child(child)
|
|
144
|
-
assert_equal([[Roby::Task], {}], child.fullfilled_model)
|
|
145
|
-
p1.realized_by child, :model => tag
|
|
146
|
-
assert_equal([[Roby::Task, tag], {}], child.fullfilled_model)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def test_first_children
|
|
150
|
-
p, c1, c2 = prepare_plan :discover => 3, :model => SimpleTask
|
|
151
|
-
p.realized_by c1
|
|
152
|
-
p.realized_by c2
|
|
153
|
-
assert_equal([c1, c2].to_value_set, p.first_children)
|
|
154
|
-
|
|
155
|
-
c1.on(:start, c2, :start)
|
|
156
|
-
assert_equal([c1].to_value_set, p.first_children)
|
|
157
|
-
end
|
|
158
|
-
end
|