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.
Files changed (240) hide show
  1. data/.gitignore +29 -0
  2. data/History.txt +4 -0
  3. data/License-fr.txt +519 -0
  4. data/License.txt +515 -0
  5. data/Manifest.txt +245 -0
  6. data/NOTES +4 -0
  7. data/README.txt +163 -0
  8. data/Rakefile +161 -0
  9. data/TODO.txt +146 -0
  10. data/app/README.txt +24 -0
  11. data/app/Rakefile +8 -0
  12. data/app/config/ROBOT.rb +5 -0
  13. data/app/config/app.yml +91 -0
  14. data/app/config/init.rb +7 -0
  15. data/app/config/roby.yml +3 -0
  16. data/app/controllers/.gitattributes +0 -0
  17. data/app/controllers/ROBOT.rb +2 -0
  18. data/app/data/.gitattributes +0 -0
  19. data/app/planners/ROBOT/main.rb +6 -0
  20. data/app/planners/main.rb +5 -0
  21. data/app/scripts/distributed +3 -0
  22. data/app/scripts/generate/bookmarks +3 -0
  23. data/app/scripts/replay +3 -0
  24. data/app/scripts/results +3 -0
  25. data/app/scripts/run +3 -0
  26. data/app/scripts/server +3 -0
  27. data/app/scripts/shell +3 -0
  28. data/app/scripts/test +3 -0
  29. data/app/tasks/.gitattributes +0 -0
  30. data/app/tasks/ROBOT/.gitattributes +0 -0
  31. data/bin/roby +210 -0
  32. data/bin/roby-log +168 -0
  33. data/bin/roby-shell +25 -0
  34. data/doc/images/event_generalization.png +0 -0
  35. data/doc/images/exception_propagation_1.png +0 -0
  36. data/doc/images/exception_propagation_2.png +0 -0
  37. data/doc/images/exception_propagation_3.png +0 -0
  38. data/doc/images/exception_propagation_4.png +0 -0
  39. data/doc/images/exception_propagation_5.png +0 -0
  40. data/doc/images/replay_handler_error.png +0 -0
  41. data/doc/images/replay_handler_error_0.png +0 -0
  42. data/doc/images/replay_handler_error_1.png +0 -0
  43. data/doc/images/roby_cycle_overview.png +0 -0
  44. data/doc/images/roby_replay_02.png +0 -0
  45. data/doc/images/roby_replay_03.png +0 -0
  46. data/doc/images/roby_replay_04.png +0 -0
  47. data/doc/images/roby_replay_event_representation.png +0 -0
  48. data/doc/images/roby_replay_first_state.png +0 -0
  49. data/doc/images/roby_replay_relations.png +0 -0
  50. data/doc/images/roby_replay_startup.png +0 -0
  51. data/doc/images/task_event_generalization.png +0 -0
  52. data/doc/papers.rdoc +11 -0
  53. data/doc/styles/allison.css +314 -0
  54. data/doc/styles/allison.js +316 -0
  55. data/doc/styles/allison.rb +276 -0
  56. data/doc/styles/jamis.rb +593 -0
  57. data/doc/tutorials/01-GettingStarted.rdoc +86 -0
  58. data/doc/tutorials/02-GoForward.rdoc +220 -0
  59. data/doc/tutorials/03-PlannedPath.rdoc +268 -0
  60. data/doc/tutorials/04-EventPropagation.rdoc +236 -0
  61. data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
  62. data/doc/tutorials/06-Overview.rdoc +40 -0
  63. data/doc/videos.rdoc +69 -0
  64. data/ext/droby/dump.cc +175 -0
  65. data/ext/droby/extconf.rb +3 -0
  66. data/ext/graph/algorithm.cc +746 -0
  67. data/ext/graph/extconf.rb +7 -0
  68. data/ext/graph/graph.cc +529 -0
  69. data/ext/graph/graph.hh +183 -0
  70. data/ext/graph/iterator_sequence.hh +102 -0
  71. data/ext/graph/undirected_dfs.hh +226 -0
  72. data/ext/graph/undirected_graph.hh +421 -0
  73. data/lib/roby.rb +41 -0
  74. data/lib/roby/app.rb +870 -0
  75. data/lib/roby/app/rake.rb +56 -0
  76. data/lib/roby/app/run.rb +14 -0
  77. data/lib/roby/app/scripts/distributed.rb +13 -0
  78. data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
  79. data/lib/roby/app/scripts/replay.rb +31 -0
  80. data/lib/roby/app/scripts/results.rb +15 -0
  81. data/lib/roby/app/scripts/run.rb +26 -0
  82. data/lib/roby/app/scripts/server.rb +18 -0
  83. data/lib/roby/app/scripts/shell.rb +88 -0
  84. data/lib/roby/app/scripts/test.rb +40 -0
  85. data/lib/roby/basic_object.rb +151 -0
  86. data/lib/roby/config.rb +5 -0
  87. data/lib/roby/control.rb +747 -0
  88. data/lib/roby/decision_control.rb +17 -0
  89. data/lib/roby/distributed.rb +32 -0
  90. data/lib/roby/distributed/base.rb +440 -0
  91. data/lib/roby/distributed/communication.rb +871 -0
  92. data/lib/roby/distributed/connection_space.rb +592 -0
  93. data/lib/roby/distributed/distributed_object.rb +206 -0
  94. data/lib/roby/distributed/drb.rb +62 -0
  95. data/lib/roby/distributed/notifications.rb +539 -0
  96. data/lib/roby/distributed/peer.rb +550 -0
  97. data/lib/roby/distributed/protocol.rb +529 -0
  98. data/lib/roby/distributed/proxy.rb +343 -0
  99. data/lib/roby/distributed/subscription.rb +311 -0
  100. data/lib/roby/distributed/transaction.rb +498 -0
  101. data/lib/roby/event.rb +897 -0
  102. data/lib/roby/exceptions.rb +234 -0
  103. data/lib/roby/executives/simple.rb +30 -0
  104. data/lib/roby/graph.rb +166 -0
  105. data/lib/roby/interface.rb +390 -0
  106. data/lib/roby/log.rb +3 -0
  107. data/lib/roby/log/chronicle.rb +303 -0
  108. data/lib/roby/log/console.rb +72 -0
  109. data/lib/roby/log/data_stream.rb +197 -0
  110. data/lib/roby/log/dot.rb +279 -0
  111. data/lib/roby/log/event_stream.rb +151 -0
  112. data/lib/roby/log/file.rb +340 -0
  113. data/lib/roby/log/gui/basic_display.ui +83 -0
  114. data/lib/roby/log/gui/chronicle.rb +26 -0
  115. data/lib/roby/log/gui/chronicle_view.rb +40 -0
  116. data/lib/roby/log/gui/chronicle_view.ui +70 -0
  117. data/lib/roby/log/gui/data_displays.rb +172 -0
  118. data/lib/roby/log/gui/data_displays.ui +155 -0
  119. data/lib/roby/log/gui/notifications.rb +26 -0
  120. data/lib/roby/log/gui/relations.rb +248 -0
  121. data/lib/roby/log/gui/relations.ui +123 -0
  122. data/lib/roby/log/gui/relations_view.rb +185 -0
  123. data/lib/roby/log/gui/relations_view.ui +149 -0
  124. data/lib/roby/log/gui/replay.rb +327 -0
  125. data/lib/roby/log/gui/replay_controls.rb +200 -0
  126. data/lib/roby/log/gui/replay_controls.ui +259 -0
  127. data/lib/roby/log/gui/runtime.rb +130 -0
  128. data/lib/roby/log/hooks.rb +185 -0
  129. data/lib/roby/log/logger.rb +202 -0
  130. data/lib/roby/log/notifications.rb +244 -0
  131. data/lib/roby/log/plan_rebuilder.rb +470 -0
  132. data/lib/roby/log/relations.rb +1056 -0
  133. data/lib/roby/log/server.rb +550 -0
  134. data/lib/roby/log/sqlite.rb +47 -0
  135. data/lib/roby/log/timings.rb +164 -0
  136. data/lib/roby/plan-object.rb +247 -0
  137. data/lib/roby/plan.rb +762 -0
  138. data/lib/roby/planning.rb +13 -0
  139. data/lib/roby/planning/loops.rb +302 -0
  140. data/lib/roby/planning/model.rb +906 -0
  141. data/lib/roby/planning/task.rb +151 -0
  142. data/lib/roby/propagation.rb +562 -0
  143. data/lib/roby/query.rb +619 -0
  144. data/lib/roby/relations.rb +583 -0
  145. data/lib/roby/relations/conflicts.rb +70 -0
  146. data/lib/roby/relations/ensured.rb +20 -0
  147. data/lib/roby/relations/error_handling.rb +23 -0
  148. data/lib/roby/relations/events.rb +9 -0
  149. data/lib/roby/relations/executed_by.rb +193 -0
  150. data/lib/roby/relations/hierarchy.rb +239 -0
  151. data/lib/roby/relations/influence.rb +10 -0
  152. data/lib/roby/relations/planned_by.rb +63 -0
  153. data/lib/roby/robot.rb +7 -0
  154. data/lib/roby/standard_errors.rb +218 -0
  155. data/lib/roby/state.rb +5 -0
  156. data/lib/roby/state/events.rb +221 -0
  157. data/lib/roby/state/information.rb +55 -0
  158. data/lib/roby/state/pos.rb +110 -0
  159. data/lib/roby/state/shapes.rb +32 -0
  160. data/lib/roby/state/state.rb +353 -0
  161. data/lib/roby/support.rb +92 -0
  162. data/lib/roby/task-operations.rb +182 -0
  163. data/lib/roby/task.rb +1618 -0
  164. data/lib/roby/test/common.rb +399 -0
  165. data/lib/roby/test/distributed.rb +214 -0
  166. data/lib/roby/test/tasks/empty_task.rb +9 -0
  167. data/lib/roby/test/tasks/goto.rb +36 -0
  168. data/lib/roby/test/tasks/simple_task.rb +23 -0
  169. data/lib/roby/test/testcase.rb +519 -0
  170. data/lib/roby/test/tools.rb +160 -0
  171. data/lib/roby/thread_task.rb +87 -0
  172. data/lib/roby/transactions.rb +462 -0
  173. data/lib/roby/transactions/proxy.rb +292 -0
  174. data/lib/roby/transactions/updates.rb +139 -0
  175. data/plugins/fault_injection/History.txt +4 -0
  176. data/plugins/fault_injection/README.txt +37 -0
  177. data/plugins/fault_injection/Rakefile +18 -0
  178. data/plugins/fault_injection/TODO.txt +0 -0
  179. data/plugins/fault_injection/app.rb +52 -0
  180. data/plugins/fault_injection/fault_injection.rb +89 -0
  181. data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
  182. data/plugins/subsystems/README.txt +40 -0
  183. data/plugins/subsystems/Rakefile +18 -0
  184. data/plugins/subsystems/app.rb +171 -0
  185. data/plugins/subsystems/test/app/README +24 -0
  186. data/plugins/subsystems/test/app/Rakefile +8 -0
  187. data/plugins/subsystems/test/app/config/app.yml +71 -0
  188. data/plugins/subsystems/test/app/config/init.rb +9 -0
  189. data/plugins/subsystems/test/app/config/roby.yml +3 -0
  190. data/plugins/subsystems/test/app/planners/main.rb +20 -0
  191. data/plugins/subsystems/test/app/scripts/distributed +3 -0
  192. data/plugins/subsystems/test/app/scripts/replay +3 -0
  193. data/plugins/subsystems/test/app/scripts/results +3 -0
  194. data/plugins/subsystems/test/app/scripts/run +3 -0
  195. data/plugins/subsystems/test/app/scripts/server +3 -0
  196. data/plugins/subsystems/test/app/scripts/shell +3 -0
  197. data/plugins/subsystems/test/app/scripts/test +3 -0
  198. data/plugins/subsystems/test/app/tasks/services.rb +15 -0
  199. data/plugins/subsystems/test/test_subsystems.rb +71 -0
  200. data/test/distributed/test_communication.rb +178 -0
  201. data/test/distributed/test_connection.rb +282 -0
  202. data/test/distributed/test_execution.rb +373 -0
  203. data/test/distributed/test_mixed_plan.rb +341 -0
  204. data/test/distributed/test_plan_notifications.rb +238 -0
  205. data/test/distributed/test_protocol.rb +516 -0
  206. data/test/distributed/test_query.rb +102 -0
  207. data/test/distributed/test_remote_plan.rb +491 -0
  208. data/test/distributed/test_transaction.rb +463 -0
  209. data/test/mockups/tasks.rb +27 -0
  210. data/test/planning/test_loops.rb +380 -0
  211. data/test/planning/test_model.rb +427 -0
  212. data/test/planning/test_task.rb +106 -0
  213. data/test/relations/test_conflicts.rb +42 -0
  214. data/test/relations/test_ensured.rb +38 -0
  215. data/test/relations/test_executed_by.rb +149 -0
  216. data/test/relations/test_hierarchy.rb +158 -0
  217. data/test/relations/test_planned_by.rb +54 -0
  218. data/test/suite_core.rb +24 -0
  219. data/test/suite_distributed.rb +9 -0
  220. data/test/suite_planning.rb +3 -0
  221. data/test/suite_relations.rb +8 -0
  222. data/test/test_bgl.rb +508 -0
  223. data/test/test_control.rb +399 -0
  224. data/test/test_event.rb +894 -0
  225. data/test/test_exceptions.rb +592 -0
  226. data/test/test_interface.rb +37 -0
  227. data/test/test_log.rb +114 -0
  228. data/test/test_log_server.rb +132 -0
  229. data/test/test_plan.rb +584 -0
  230. data/test/test_propagation.rb +210 -0
  231. data/test/test_query.rb +266 -0
  232. data/test/test_relations.rb +180 -0
  233. data/test/test_state.rb +414 -0
  234. data/test/test_support.rb +16 -0
  235. data/test/test_task.rb +938 -0
  236. data/test/test_testcase.rb +122 -0
  237. data/test/test_thread_task.rb +73 -0
  238. data/test/test_transactions.rb +569 -0
  239. data/test/test_transactions_proxy.rb +198 -0
  240. 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,4 @@
1
+ === 0.1 / 2008-04-15
2
+
3
+ * First public release, along with Roby 0.7
4
+
@@ -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
+