roby 0.7
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/.gitignore +29 -0
- data/History.txt +4 -0
- data/License-fr.txt +519 -0
- data/License.txt +515 -0
- data/Manifest.txt +245 -0
- data/NOTES +4 -0
- data/README.txt +163 -0
- data/Rakefile +161 -0
- data/TODO.txt +146 -0
- data/app/README.txt +24 -0
- data/app/Rakefile +8 -0
- data/app/config/ROBOT.rb +5 -0
- data/app/config/app.yml +91 -0
- data/app/config/init.rb +7 -0
- data/app/config/roby.yml +3 -0
- data/app/controllers/.gitattributes +0 -0
- data/app/controllers/ROBOT.rb +2 -0
- data/app/data/.gitattributes +0 -0
- data/app/planners/ROBOT/main.rb +6 -0
- data/app/planners/main.rb +5 -0
- data/app/scripts/distributed +3 -0
- data/app/scripts/generate/bookmarks +3 -0
- data/app/scripts/replay +3 -0
- data/app/scripts/results +3 -0
- data/app/scripts/run +3 -0
- data/app/scripts/server +3 -0
- data/app/scripts/shell +3 -0
- data/app/scripts/test +3 -0
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby +210 -0
- data/bin/roby-log +168 -0
- data/bin/roby-shell +25 -0
- data/doc/images/event_generalization.png +0 -0
- data/doc/images/exception_propagation_1.png +0 -0
- data/doc/images/exception_propagation_2.png +0 -0
- data/doc/images/exception_propagation_3.png +0 -0
- data/doc/images/exception_propagation_4.png +0 -0
- data/doc/images/exception_propagation_5.png +0 -0
- data/doc/images/replay_handler_error.png +0 -0
- data/doc/images/replay_handler_error_0.png +0 -0
- data/doc/images/replay_handler_error_1.png +0 -0
- data/doc/images/roby_cycle_overview.png +0 -0
- data/doc/images/roby_replay_02.png +0 -0
- data/doc/images/roby_replay_03.png +0 -0
- data/doc/images/roby_replay_04.png +0 -0
- data/doc/images/roby_replay_event_representation.png +0 -0
- data/doc/images/roby_replay_first_state.png +0 -0
- data/doc/images/roby_replay_relations.png +0 -0
- data/doc/images/roby_replay_startup.png +0 -0
- data/doc/images/task_event_generalization.png +0 -0
- data/doc/papers.rdoc +11 -0
- data/doc/styles/allison.css +314 -0
- data/doc/styles/allison.js +316 -0
- data/doc/styles/allison.rb +276 -0
- data/doc/styles/jamis.rb +593 -0
- data/doc/tutorials/01-GettingStarted.rdoc +86 -0
- data/doc/tutorials/02-GoForward.rdoc +220 -0
- data/doc/tutorials/03-PlannedPath.rdoc +268 -0
- data/doc/tutorials/04-EventPropagation.rdoc +236 -0
- data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
- data/doc/tutorials/06-Overview.rdoc +40 -0
- data/doc/videos.rdoc +69 -0
- data/ext/droby/dump.cc +175 -0
- data/ext/droby/extconf.rb +3 -0
- data/ext/graph/algorithm.cc +746 -0
- data/ext/graph/extconf.rb +7 -0
- data/ext/graph/graph.cc +529 -0
- data/ext/graph/graph.hh +183 -0
- data/ext/graph/iterator_sequence.hh +102 -0
- data/ext/graph/undirected_dfs.hh +226 -0
- data/ext/graph/undirected_graph.hh +421 -0
- data/lib/roby.rb +41 -0
- data/lib/roby/app.rb +870 -0
- data/lib/roby/app/rake.rb +56 -0
- data/lib/roby/app/run.rb +14 -0
- data/lib/roby/app/scripts/distributed.rb +13 -0
- data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
- data/lib/roby/app/scripts/replay.rb +31 -0
- data/lib/roby/app/scripts/results.rb +15 -0
- data/lib/roby/app/scripts/run.rb +26 -0
- data/lib/roby/app/scripts/server.rb +18 -0
- data/lib/roby/app/scripts/shell.rb +88 -0
- data/lib/roby/app/scripts/test.rb +40 -0
- data/lib/roby/basic_object.rb +151 -0
- data/lib/roby/config.rb +5 -0
- data/lib/roby/control.rb +747 -0
- data/lib/roby/decision_control.rb +17 -0
- data/lib/roby/distributed.rb +32 -0
- data/lib/roby/distributed/base.rb +440 -0
- data/lib/roby/distributed/communication.rb +871 -0
- data/lib/roby/distributed/connection_space.rb +592 -0
- data/lib/roby/distributed/distributed_object.rb +206 -0
- data/lib/roby/distributed/drb.rb +62 -0
- data/lib/roby/distributed/notifications.rb +539 -0
- data/lib/roby/distributed/peer.rb +550 -0
- data/lib/roby/distributed/protocol.rb +529 -0
- data/lib/roby/distributed/proxy.rb +343 -0
- data/lib/roby/distributed/subscription.rb +311 -0
- data/lib/roby/distributed/transaction.rb +498 -0
- data/lib/roby/event.rb +897 -0
- data/lib/roby/exceptions.rb +234 -0
- data/lib/roby/executives/simple.rb +30 -0
- data/lib/roby/graph.rb +166 -0
- data/lib/roby/interface.rb +390 -0
- data/lib/roby/log.rb +3 -0
- data/lib/roby/log/chronicle.rb +303 -0
- data/lib/roby/log/console.rb +72 -0
- data/lib/roby/log/data_stream.rb +197 -0
- data/lib/roby/log/dot.rb +279 -0
- data/lib/roby/log/event_stream.rb +151 -0
- data/lib/roby/log/file.rb +340 -0
- data/lib/roby/log/gui/basic_display.ui +83 -0
- data/lib/roby/log/gui/chronicle.rb +26 -0
- data/lib/roby/log/gui/chronicle_view.rb +40 -0
- data/lib/roby/log/gui/chronicle_view.ui +70 -0
- data/lib/roby/log/gui/data_displays.rb +172 -0
- data/lib/roby/log/gui/data_displays.ui +155 -0
- data/lib/roby/log/gui/notifications.rb +26 -0
- data/lib/roby/log/gui/relations.rb +248 -0
- data/lib/roby/log/gui/relations.ui +123 -0
- data/lib/roby/log/gui/relations_view.rb +185 -0
- data/lib/roby/log/gui/relations_view.ui +149 -0
- data/lib/roby/log/gui/replay.rb +327 -0
- data/lib/roby/log/gui/replay_controls.rb +200 -0
- data/lib/roby/log/gui/replay_controls.ui +259 -0
- data/lib/roby/log/gui/runtime.rb +130 -0
- data/lib/roby/log/hooks.rb +185 -0
- data/lib/roby/log/logger.rb +202 -0
- data/lib/roby/log/notifications.rb +244 -0
- data/lib/roby/log/plan_rebuilder.rb +470 -0
- data/lib/roby/log/relations.rb +1056 -0
- data/lib/roby/log/server.rb +550 -0
- data/lib/roby/log/sqlite.rb +47 -0
- data/lib/roby/log/timings.rb +164 -0
- data/lib/roby/plan-object.rb +247 -0
- data/lib/roby/plan.rb +762 -0
- data/lib/roby/planning.rb +13 -0
- data/lib/roby/planning/loops.rb +302 -0
- data/lib/roby/planning/model.rb +906 -0
- data/lib/roby/planning/task.rb +151 -0
- data/lib/roby/propagation.rb +562 -0
- data/lib/roby/query.rb +619 -0
- data/lib/roby/relations.rb +583 -0
- data/lib/roby/relations/conflicts.rb +70 -0
- data/lib/roby/relations/ensured.rb +20 -0
- data/lib/roby/relations/error_handling.rb +23 -0
- data/lib/roby/relations/events.rb +9 -0
- data/lib/roby/relations/executed_by.rb +193 -0
- data/lib/roby/relations/hierarchy.rb +239 -0
- data/lib/roby/relations/influence.rb +10 -0
- data/lib/roby/relations/planned_by.rb +63 -0
- data/lib/roby/robot.rb +7 -0
- data/lib/roby/standard_errors.rb +218 -0
- data/lib/roby/state.rb +5 -0
- data/lib/roby/state/events.rb +221 -0
- data/lib/roby/state/information.rb +55 -0
- data/lib/roby/state/pos.rb +110 -0
- data/lib/roby/state/shapes.rb +32 -0
- data/lib/roby/state/state.rb +353 -0
- data/lib/roby/support.rb +92 -0
- data/lib/roby/task-operations.rb +182 -0
- data/lib/roby/task.rb +1618 -0
- data/lib/roby/test/common.rb +399 -0
- data/lib/roby/test/distributed.rb +214 -0
- data/lib/roby/test/tasks/empty_task.rb +9 -0
- data/lib/roby/test/tasks/goto.rb +36 -0
- data/lib/roby/test/tasks/simple_task.rb +23 -0
- data/lib/roby/test/testcase.rb +519 -0
- data/lib/roby/test/tools.rb +160 -0
- data/lib/roby/thread_task.rb +87 -0
- data/lib/roby/transactions.rb +462 -0
- data/lib/roby/transactions/proxy.rb +292 -0
- data/lib/roby/transactions/updates.rb +139 -0
- data/plugins/fault_injection/History.txt +4 -0
- data/plugins/fault_injection/README.txt +37 -0
- data/plugins/fault_injection/Rakefile +18 -0
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +52 -0
- data/plugins/fault_injection/fault_injection.rb +89 -0
- data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
- data/plugins/subsystems/README.txt +40 -0
- data/plugins/subsystems/Rakefile +18 -0
- data/plugins/subsystems/app.rb +171 -0
- data/plugins/subsystems/test/app/README +24 -0
- data/plugins/subsystems/test/app/Rakefile +8 -0
- data/plugins/subsystems/test/app/config/app.yml +71 -0
- data/plugins/subsystems/test/app/config/init.rb +9 -0
- data/plugins/subsystems/test/app/config/roby.yml +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +20 -0
- data/plugins/subsystems/test/app/scripts/distributed +3 -0
- data/plugins/subsystems/test/app/scripts/replay +3 -0
- data/plugins/subsystems/test/app/scripts/results +3 -0
- data/plugins/subsystems/test/app/scripts/run +3 -0
- data/plugins/subsystems/test/app/scripts/server +3 -0
- data/plugins/subsystems/test/app/scripts/shell +3 -0
- data/plugins/subsystems/test/app/scripts/test +3 -0
- data/plugins/subsystems/test/app/tasks/services.rb +15 -0
- data/plugins/subsystems/test/test_subsystems.rb +71 -0
- data/test/distributed/test_communication.rb +178 -0
- data/test/distributed/test_connection.rb +282 -0
- data/test/distributed/test_execution.rb +373 -0
- data/test/distributed/test_mixed_plan.rb +341 -0
- data/test/distributed/test_plan_notifications.rb +238 -0
- data/test/distributed/test_protocol.rb +516 -0
- data/test/distributed/test_query.rb +102 -0
- data/test/distributed/test_remote_plan.rb +491 -0
- data/test/distributed/test_transaction.rb +463 -0
- data/test/mockups/tasks.rb +27 -0
- data/test/planning/test_loops.rb +380 -0
- data/test/planning/test_model.rb +427 -0
- data/test/planning/test_task.rb +106 -0
- data/test/relations/test_conflicts.rb +42 -0
- data/test/relations/test_ensured.rb +38 -0
- data/test/relations/test_executed_by.rb +149 -0
- data/test/relations/test_hierarchy.rb +158 -0
- data/test/relations/test_planned_by.rb +54 -0
- data/test/suite_core.rb +24 -0
- data/test/suite_distributed.rb +9 -0
- data/test/suite_planning.rb +3 -0
- data/test/suite_relations.rb +8 -0
- data/test/test_bgl.rb +508 -0
- data/test/test_control.rb +399 -0
- data/test/test_event.rb +894 -0
- data/test/test_exceptions.rb +592 -0
- data/test/test_interface.rb +37 -0
- data/test/test_log.rb +114 -0
- data/test/test_log_server.rb +132 -0
- data/test/test_plan.rb +584 -0
- data/test/test_propagation.rb +210 -0
- data/test/test_query.rb +266 -0
- data/test/test_relations.rb +180 -0
- data/test/test_state.rb +414 -0
- data/test/test_support.rb +16 -0
- data/test/test_task.rb +938 -0
- data/test/test_testcase.rb +122 -0
- data/test/test_thread_task.rb +73 -0
- data/test/test_transactions.rb +569 -0
- data/test/test_transactions_proxy.rb +198 -0
- metadata +570 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
require 'roby/task'
|
|
2
|
+
require 'roby/event'
|
|
3
|
+
require 'delegate'
|
|
4
|
+
require 'forwardable'
|
|
5
|
+
require 'utilrb/module/ancestor_p'
|
|
6
|
+
|
|
7
|
+
# The Transactions module define all tools needed to implement
|
|
8
|
+
# the Transaction class
|
|
9
|
+
module Roby::Transactions
|
|
10
|
+
# In transactions, we do not manipulate plan objects like Task and EventGenerator directly,
|
|
11
|
+
# but through proxies which make sure that nothing forbidden is done
|
|
12
|
+
#
|
|
13
|
+
# The Proxy module define base functionalities for these proxy objects
|
|
14
|
+
module Proxy
|
|
15
|
+
@@proxy_klass = []
|
|
16
|
+
@@forwarders = Hash.new
|
|
17
|
+
|
|
18
|
+
def to_s; "tProxy(#{__getobj__.to_s})" end
|
|
19
|
+
|
|
20
|
+
# Returns the proxy for +object+. Raises ArgumentError if +object+ is
|
|
21
|
+
# not an object which should be wrapped
|
|
22
|
+
def self.proxy_class(object)
|
|
23
|
+
proxy_class = @@proxy_klass.find { |_, real_klass| object.kind_of?(real_klass) }
|
|
24
|
+
unless proxy_class
|
|
25
|
+
raise ArgumentError, "no proxy for #{object.class}"
|
|
26
|
+
end
|
|
27
|
+
proxy_class[0]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Declare that +proxy_klass+ should be used to wrap objects of +real_klass+.
|
|
31
|
+
# Order matters: if more than one wrapping matches, we will use the one
|
|
32
|
+
# defined last.
|
|
33
|
+
def self.proxy_for(proxy_klass, real_klass)
|
|
34
|
+
@@proxy_klass.unshift [proxy_klass, real_klass]
|
|
35
|
+
proxy_klass.extend Forwardable
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Returns a class that forwards every calls to +proxy.__getobj__+
|
|
39
|
+
def self.forwarder(object)
|
|
40
|
+
klass = object.class
|
|
41
|
+
@@forwarders[klass] ||= DelegateClass(klass)
|
|
42
|
+
@@forwarders[klass].new(object)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def initialize(object, transaction)
|
|
46
|
+
@distribute = nil
|
|
47
|
+
@transaction = transaction
|
|
48
|
+
@__getobj__ = object
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module ClassExtension
|
|
52
|
+
def proxy_for(klass); Proxy.proxy_for(self, klass) end
|
|
53
|
+
|
|
54
|
+
def proxy_code(m)
|
|
55
|
+
"return unless proxying?
|
|
56
|
+
args = args.map(&plan.method(:may_unwrap))
|
|
57
|
+
result = if block_given?
|
|
58
|
+
__getobj__.#{m}(*args) do |*objects|
|
|
59
|
+
objects.map! { |o| transaction.may_wrap(o) }
|
|
60
|
+
yield(*objects)
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
__getobj__.#{m}(*args)
|
|
64
|
+
end
|
|
65
|
+
transaction.may_wrap(result)"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def proxy(*methods)
|
|
69
|
+
methods.each do |m|
|
|
70
|
+
class_eval "def #{m}(*args); #{proxy_code(m)} end"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
attr_reader :transaction
|
|
76
|
+
attr_reader :__getobj__
|
|
77
|
+
|
|
78
|
+
alias :== :eql?
|
|
79
|
+
|
|
80
|
+
def pretty_print(pp)
|
|
81
|
+
plan.disable_proxying { super }
|
|
82
|
+
end
|
|
83
|
+
def proxying?; plan && plan.proxying? end
|
|
84
|
+
|
|
85
|
+
# Uses the +enum+ method on this proxy and on the proxied object to get
|
|
86
|
+
# a set of objects related to this one in both the plan and the
|
|
87
|
+
# transaction.
|
|
88
|
+
#
|
|
89
|
+
# The block is then given a plan_object => transaction_object hash, the
|
|
90
|
+
# relation which is being considered, the set of new relations (the
|
|
91
|
+
# relations that are in the transaction but not in the plan) and the
|
|
92
|
+
# set of deleted relation (relations that are in the plan but not in
|
|
93
|
+
# the transaction)
|
|
94
|
+
def partition_new_old_relations(enum) # :yield:
|
|
95
|
+
trsc_objects = Hash.new
|
|
96
|
+
each_relation do |rel|
|
|
97
|
+
trsc_others = send(enum, rel).
|
|
98
|
+
map do |obj|
|
|
99
|
+
plan_object = plan.may_unwrap(obj)
|
|
100
|
+
trsc_objects[plan_object] = obj
|
|
101
|
+
plan_object
|
|
102
|
+
end.to_value_set
|
|
103
|
+
|
|
104
|
+
plan_others = __getobj__.send(enum, rel).
|
|
105
|
+
find_all { |obj| plan[obj, false] }.
|
|
106
|
+
to_value_set
|
|
107
|
+
|
|
108
|
+
new = (trsc_others - plan_others)
|
|
109
|
+
del = (plan_others - trsc_others)
|
|
110
|
+
|
|
111
|
+
yield(trsc_objects, rel, new, del)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Commits the modifications of this proxy. It copies the relations of
|
|
116
|
+
# the proxy on the proxied object
|
|
117
|
+
def commit_transaction
|
|
118
|
+
real_object = __getobj__
|
|
119
|
+
partition_new_old_relations(:parent_objects) do |trsc_objects, rel, new, del|
|
|
120
|
+
for other in new
|
|
121
|
+
other.add_child_object(real_object, rel, trsc_objects[other][self, rel])
|
|
122
|
+
end
|
|
123
|
+
for other in del
|
|
124
|
+
other.remove_child_object(real_object, rel)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
partition_new_old_relations(:child_objects) do |trsc_objects, rel, new, del|
|
|
129
|
+
for other in new
|
|
130
|
+
real_object.add_child_object(other, rel, self[trsc_objects[other], rel])
|
|
131
|
+
end
|
|
132
|
+
for other in del
|
|
133
|
+
real_object.remove_child_object(other, rel)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
super if defined? super
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Discards the transaction by clearing this proxy
|
|
141
|
+
def discard_transaction
|
|
142
|
+
clear_vertex
|
|
143
|
+
super if defined? super
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Proxy for Roby::EventGenerator
|
|
148
|
+
class EventGenerator < Roby::EventGenerator
|
|
149
|
+
include Proxy
|
|
150
|
+
proxy_for Roby::EventGenerator
|
|
151
|
+
|
|
152
|
+
def_delegator :@__getobj__, :symbol
|
|
153
|
+
def_delegator :@__getobj__, :model
|
|
154
|
+
proxy :can_signal?
|
|
155
|
+
|
|
156
|
+
def initialize(object, transaction)
|
|
157
|
+
super(object, transaction)
|
|
158
|
+
@unreachable_handlers = []
|
|
159
|
+
if object.controlable?
|
|
160
|
+
self.command = method(:emit)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def commit_transaction
|
|
165
|
+
super
|
|
166
|
+
handlers.each { |h| __getobj__.on(&h) }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def_delegator :@__getobj__, :owners
|
|
170
|
+
def_delegator :@__getobj__, :distribute?
|
|
171
|
+
def has_sibling?(peer); plan.has_sibling?(peer) end
|
|
172
|
+
|
|
173
|
+
def executable?; false end
|
|
174
|
+
def unreachable!; end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Transaction proxy for Roby::TaskEventGenerator
|
|
178
|
+
class TaskEventGenerator < Roby::Transactions::EventGenerator
|
|
179
|
+
proxy_for Roby::TaskEventGenerator
|
|
180
|
+
|
|
181
|
+
# The transaction proxy which represents the event generator's real
|
|
182
|
+
# task
|
|
183
|
+
attr_reader :task
|
|
184
|
+
child_plan_object :task
|
|
185
|
+
|
|
186
|
+
# Create a new proxy representing +object+ in +transaction+
|
|
187
|
+
def initialize(object, transaction)
|
|
188
|
+
super(object, transaction)
|
|
189
|
+
@task = transaction.wrap(object.task)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Task event generators do not have siblings on remote plan managers.
|
|
193
|
+
# They are always referenced by their name and task.
|
|
194
|
+
def has_sibling?(peer); false end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Transaction proxy for Roby::Task
|
|
198
|
+
class Task < Roby::Task
|
|
199
|
+
include Proxy
|
|
200
|
+
proxy_for Roby::Task
|
|
201
|
+
|
|
202
|
+
def_delegator :@__getobj__, :running?
|
|
203
|
+
def_delegator :@__getobj__, :finished?
|
|
204
|
+
def_delegator :@__getobj__, :pending?
|
|
205
|
+
def_delegator :@__getobj__, :model
|
|
206
|
+
def_delegator :@__getobj__, :has_event?
|
|
207
|
+
|
|
208
|
+
def_delegator :@__getobj__, :pending?
|
|
209
|
+
def_delegator :@__getobj__, :running?
|
|
210
|
+
def_delegator :@__getobj__, :success?
|
|
211
|
+
def_delegator :@__getobj__, :failed?
|
|
212
|
+
def_delegator :@__getobj__, :finished?
|
|
213
|
+
|
|
214
|
+
proxy :event
|
|
215
|
+
proxy :each_event
|
|
216
|
+
alias :each_plan_child :each_event
|
|
217
|
+
proxy :fullfills?
|
|
218
|
+
proxy :same_state?
|
|
219
|
+
|
|
220
|
+
# Create a new proxy representing +object+ in +transaction+
|
|
221
|
+
def initialize(object, transaction)
|
|
222
|
+
super(object, transaction)
|
|
223
|
+
|
|
224
|
+
@arguments = Roby::TaskArguments.new(self)
|
|
225
|
+
object.arguments.each do |key, value|
|
|
226
|
+
if value.kind_of?(Roby::PlanObject)
|
|
227
|
+
arguments.update!(key, transaction[value])
|
|
228
|
+
else
|
|
229
|
+
arguments.update!(key, value)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# There is no bound_events map in task proxies. The proxy instead
|
|
235
|
+
# enumerates the real task's events and create proxies when needed.
|
|
236
|
+
#
|
|
237
|
+
# #bound_events is not part of the public API anyways
|
|
238
|
+
def bound_events; {} end
|
|
239
|
+
|
|
240
|
+
def instantiate_model_event_relations # :nodoc:
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Transaction proxies are never executable
|
|
244
|
+
def executable?; false end
|
|
245
|
+
|
|
246
|
+
# Transaction proxies do not have history
|
|
247
|
+
def history; "" end
|
|
248
|
+
def plan=(new_plan) # :nodoc:
|
|
249
|
+
if new_plan && new_plan.plan != __getobj__.plan
|
|
250
|
+
raise "invalid plan #{new_plan}"
|
|
251
|
+
end
|
|
252
|
+
@plan = new_plan
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Perform the operations needed for the commit to be successful. In
|
|
256
|
+
# practice, it updates the task arguments as needed.
|
|
257
|
+
def commit_transaction
|
|
258
|
+
super
|
|
259
|
+
|
|
260
|
+
# Update the task arguments. The original
|
|
261
|
+
# Roby::Task#commit_transaction has already translated the proxy
|
|
262
|
+
# objects into real objects
|
|
263
|
+
arguments.each do |key, value|
|
|
264
|
+
__getobj__.arguments.update!(key, value)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Perform the operations needed for the transaction to be discarded.
|
|
269
|
+
def discard_transaction
|
|
270
|
+
clear_relations
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def method_missing(m, *args, &block) # :nodoc:
|
|
274
|
+
if m.to_s =~ /^(\w+)!$/ && has_event?($1.to_sym)
|
|
275
|
+
event($1.to_sym).call(*args)
|
|
276
|
+
elsif !Roby::Task.method_defined?(m)
|
|
277
|
+
__getobj__.send(m, *args, &block)
|
|
278
|
+
else
|
|
279
|
+
super
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def_delegator :@__getobj__, :owners
|
|
284
|
+
def_delegator :@__getobj__, :distribute?
|
|
285
|
+
|
|
286
|
+
# True if +peer+ has a representation of this object
|
|
287
|
+
def has_sibling?(peer)
|
|
288
|
+
plan.has_sibling?(peer)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
http://rubyforge.org/projects/roby
|
|
3
|
+
|
|
4
|
+
= Fault injection plugin for Roby
|
|
5
|
+
|
|
6
|
+
This is a fault injection plugin for the Roby robotic control framework. It
|
|
7
|
+
allows to test the management of rarely occuring events by simulating the
|
|
8
|
+
emission of those events. This plugin relies only on the core Roby library.
|
|
9
|
+
|
|
10
|
+
== Usage
|
|
11
|
+
|
|
12
|
+
The fault injection plugin can be used in a system to inject some spurious
|
|
13
|
+
events randomly. To set it up, one must call Application#add_fault_model
|
|
14
|
+
in the configuration files of the application. For instance,
|
|
15
|
+
|
|
16
|
+
Roby.app.add_fault_model P3d::Track,
|
|
17
|
+
:no_path, :blocked,
|
|
18
|
+
Roby::FaultInjection::Rate.new(500, 0.3)
|
|
19
|
+
|
|
20
|
+
Would inject events :no_path and :blocked randomly on any task of the P3d:Track
|
|
21
|
+
model. The probability distribution used is a rate distribution with MTTF of
|
|
22
|
+
500s and base probability of 0.3. See Roby::FaultInjection for the description
|
|
23
|
+
of the available probability distributions.
|
|
24
|
+
|
|
25
|
+
== Enabling the plugin
|
|
26
|
+
|
|
27
|
+
The plugin must be enabled in the configuration files (i.e. either in
|
|
28
|
+
<tt>config/init.rb</tt> or in one of the robot-specific files) through a call
|
|
29
|
+
to Roby.app.using:
|
|
30
|
+
|
|
31
|
+
Roby.app.using 'fault_injection'
|
|
32
|
+
|
|
33
|
+
== License:
|
|
34
|
+
|
|
35
|
+
This work is licensed under the CeCiLL-B license, which is a free software
|
|
36
|
+
license similar to the BSD license. See License.txt for details.
|
|
37
|
+
|