roby 0.7

Sign up to get free protection for your applications and to get access to all the features.
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
data/TODO.txt ADDED
@@ -0,0 +1,146 @@
1
+ = TODO
2
+
3
+ == Refactoring
4
+ === Small stuff
5
+ * remote_id => network_id
6
+ * incremental_dump? => dump_reference?
7
+
8
+ === Big stuff
9
+ * fix the Roby singleton methods/Roby::Control/Roby::Propagation mess. Maybe move
10
+ all the execution-related stuff in a subclass of Plan, MainPlan. That would allow
11
+ per-MainPlan execution management and in the end having multiple executable
12
+ plan in the same plan manager (I'm thinking bi-simulation)
13
+ * have separate relation graphs in each Plan object. That would be possible
14
+ if we don't allow anymore to change any event or task relations if the task
15
+ is not included in a plan, which would greatly simply logging-related stuff
16
+ (for instance, rebuilding a representation of plans from logged data).
17
+ Moreover, we would not have tasks hanging around anymore because they have
18
+ never been removed from any plan.
19
+ * in dRoby, separate the implementation of the RX/TX and
20
+ connection/disconnection protocol, including the management of the TX queue
21
+ (callbacks, synchronous/asynchronous).
22
+ * have a thread-safe handling of transactions. This requires a few things:
23
+ - separate relation graphs: have one relation graph per plan object: see previous
24
+ point.
25
+ - stop using method forwarding, which is not the good way to do that.
26
+ Instead, do as for distributed: update the task status in the transaction
27
+ thread. Need to define a notion of "transaction thread" and how messages
28
+ can get propagated there, though.
29
+
30
+ == Core
31
+ * dynamic parameters. State prediction in both plan and transaction context:
32
+ allow to predict the effect of changing the value of dynamic parameters in
33
+ transaction context.
34
+
35
+ * when predicates like happened? are called in a propagation context, and
36
+ we don't know the result yet (happened? = false), register a continuation and
37
+ its dependency on the event. Include this continuation in the event set and
38
+ sort it accordingly.
39
+
40
+ * in #replace, use Hierarchy#fullfilled_events to check that
41
+ all needed events are provided. If some are missing, use define_event to try
42
+ to add a new one dynamically
43
+
44
+ * when replacing an event generator, what to do with its handlers ?
45
+ - either we discard them, because some handlers are used in a specific way
46
+ - either we apply them on the new task
47
+ - unfortunately there is no good answer... Both are useful and it is
48
+ difficult (if not impossible) to know what to do. Having no solution for
49
+ this problem reduces the usefulness of event handlers greatly.
50
+
51
+ * Need to tag relations with a name so that we can find what is what (kind of
52
+ 'roles'). For instance, in PlanningLoop, we would tag the seeds (i.e. the
53
+ planned tasks) with a certain name which would allow to add any child without
54
+ the loop code noticing
55
+
56
+ * add a multiplicity parameter for hierarchy relations which tells
57
+ how many child task of a given kind are expected by the parent task. Add a
58
+ 'realized_by' transition for that. For instance, in case of
59
+ Pom::Localization, we can tell that the task expects at least one
60
+ Pom::Estimator. If the last estimator breaks, we can repair the plan online
61
+ by adding a transition.
62
+
63
+ * we NEED plan merging: if we reuse a task which is already running, it should
64
+ be transparent for the new process: this new task tree will call start!, but
65
+ the task is running. Moreover, if it is synchronizing on the start event, it
66
+ should appear "as if" the event has been emitted
67
+
68
+ * Check the capability we have to put every application block in transaction
69
+ context. This would allow for instance to discard **all** plan modification
70
+ done by an exception handler (or plan command, event handler, you get my
71
+ drift) if an exception is raised. I think it would be a worthy feature [This
72
+ can't be done because of the transaction creation cost]
73
+
74
+ * Kill local tasks that are in force_gc even if they have parents, if their
75
+ parents are remote tasks
76
+
77
+ * rename Roby::TaskModelTag::argument into 'arguments' (beware of name clash
78
+ with the accessor)
79
+
80
+ * Fix transaction proxying. Better use the same kind of model than in dRoby:
81
+ create slightly modified tasks of the same model than the proxied event, do
82
+ not proxy task events
83
+
84
+ * Find a way to remove the "return unless proxying?" in top of proxy_code. It sucks
85
+
86
+ * fix handling of execution agents: we should re-spawn the execution agents
87
+ only if there is an execution agent model on the task model. We currently use
88
+ respawn on the execution agent instance. The problem lies in, for instance,
89
+ ConnectionTask which are respawned for all pending remote tasks.
90
+ ConnectionTask should never be created because of the exected_by relation.
91
+
92
+ == Planning
93
+ * fix memory leak regarding planning loops: for now, make_loop creates a new
94
+ planning method each time make_loop is called. The problem is that the
95
+ created method should actually be local to the planner object, not the
96
+ planner model (we are doing the latter right now).
97
+
98
+ == Distributed
99
+ * extension of communication to really have a multi-robot system. It is for now
100
+ too much peer-to-peer
101
+ - a pDB should always send the messages about objects it owns. For now, we
102
+ check two things: that the involved objects are owned and that the message
103
+ comes from the inside (we never forward a message coming from outside).
104
+ There is a synchronization problem here:
105
+
106
+ A sends a message M about a joint ab object to B
107
+ B does not send the message to C
108
+ but B can send other messages to C, including the /consequences/ of the M message
109
+
110
+ Result: C knows about the consequences of M, but not about M itself.
111
+
112
+ The solution is to mark all messages with an UID, and forward new messages
113
+ when we decode them (in PeerServer#demux)
114
+ - make sure unknown models are properly handled in 3-peers scenario. In
115
+ particular, the following situation should work
116
+
117
+ peer 1 and 2 know about a SpecificModel task model
118
+ peer 3 does not
119
+
120
+ If 1 sees tasks of 2 *through* the plan of 3, and if these tasks are of the
121
+ SpecificModel model, then they should be instances of the SpecificModel
122
+ class
123
+
124
+ * There is a race condition when removing objects: if a peer A is building a
125
+ transaction involving tasks from a peer B, and if the peer B removes the
126
+ tasks, then there is a race condition between the time B sends the
127
+ transaction and the time it processes the remove_object update from A. The
128
+ net effect is that when the transaction sibling is created, some tasks it
129
+ includes do not exist anymore. It is more general, since the same problem
130
+ exists when wrapping tasks in a transaction for instance.
131
+
132
+ I don't think we should really fix the race condition per se. We should in
133
+ general check if the object has not been removed when A processes updates
134
+ from B and have some ways to feedback B from A.
135
+
136
+ * Better handling of errors during transactions, better management of new
137
+ peers, ... DecisionControl should really be the central component handling
138
+ all that. Moreover, defining management policies for distributed transactions
139
+ should also be defined.
140
+
141
+ == UI
142
+ * log snapshot: build a set of logging messages which represent the current
143
+ state of the plan. Useful for display (it would allow to seek a lot faster)
144
+ and for runtime display of the plan state (send the snapshot on connection)
145
+
146
+ vim: tw=100
data/app/README.txt ADDED
@@ -0,0 +1,24 @@
1
+ == Directories
2
+ A basic Roby application has the following directories:
3
+ config:: configuration files. config/init.rb is the main configuration file (loaded
4
+ by all robots). Robot-specific configuration is in config/ROBOTNAME.rb.
5
+ The main Roby configuration file is config/roby.yml. The default file
6
+ describes all available configuration options.
7
+ planners:: planner models. Global planners (shared by all robots) are in
8
+ planners/. Robot-specific planners are in planners/ROBOTNAME/
9
+ controllers:: robot controllers. These files are supposed to start the basic robot
10
+ services, to make the robot ready. A robot shall have a controllers/ROBOTNAME.rb
11
+ file which does that.
12
+ tasks:: task models
13
+ data:: where all data files are. See #find_data.
14
+ scripts:: various scripts needed to run and debug a Roby application
15
+
16
+ The basic directory structure, and the global files, are installed by <tt>roby init</tt>. Basic
17
+ robot files can be added by <tt>roby robot ROBOTNAME</tt>
18
+
19
+ == Genom/Pocosim integration
20
+ An application can use the Genom/Pocosim integration by calling <tt>roby init --module genom</tt>.
21
+ The following files and directories are added:
22
+ config/ROBOTNAME-genom.rb:: Genom-specific configuration for ROBOTNAME
23
+ tasks/genom/:: per-Genom module tasks
24
+
data/app/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/rdoctask'
2
+
3
+ Rake::RDocTask.new('doc') do |doc|
4
+ doc.rdoc_files.include 'README'
5
+ doc.rdoc_files.include 'tasks/**/*.rb'
6
+ doc.rdoc_files.include 'planners/**/*.rb'
7
+ doc.rdoc_files.include 'controllers/**/*.rb'
8
+ end
@@ -0,0 +1,5 @@
1
+ # Add robot-specific configuration here. This file is loaded after config/init.rb
2
+ # and after Roby has been set up
3
+ Roby::State.update do |s|
4
+ end
5
+
@@ -0,0 +1,91 @@
1
+ # Control configuration
2
+ control:
3
+ # Abort if a task/event exception is not caught
4
+ # abort_on_exception: false
5
+ # Abort if an application exception occurs
6
+ # abort_on_application_exception: false
7
+
8
+ # The executive. Set to 'none' to disable.
9
+ # The executive object determines, in the current plan, what are
10
+ # the tasks which must be started. The 'simple' executive starts
11
+ # all tasks that have no predecessors.
12
+ executive: simple
13
+
14
+ # The length of a cycle (in seconds)
15
+ # cycle: 0.1
16
+
17
+ # Logging configuration
18
+ log:
19
+ # Where log files go
20
+ # dir: log/
21
+
22
+ # Log system events (default: false)
23
+ # events: true
24
+
25
+ # Disables the log server (default: enabled)
26
+ # server: false
27
+ #
28
+ # ... or configure it
29
+ # server:
30
+ # # The port to listen on (for service discovery)
31
+ # port: 48933
32
+ # # The discovery period
33
+ # period: 10
34
+
35
+ # Logging levels. It is a hash of component_name: level (where level is one
36
+ # of DEBUG, INFO, WARN and FATAL). The output can be redirected in a file
37
+ # using level:filename, in which case 'filename' is relative to the log
38
+ # directory. Any occurence of 'ROBOT' in filename is replaced by the robot
39
+ # name
40
+ #
41
+ # levels:
42
+ # roby: INFO
43
+ # roby/planning: DEBUG
44
+ # roby/distributed: DEBUG:ROBOT-distributed.log
45
+ # genom: INFO
46
+
47
+ # dRoby neighbour discovery
48
+ discovery:
49
+ # The host:port at which we can connect to a discovery tuplespace
50
+ # (default: no discovery tuplespace)
51
+ # tuplespace: "localhost:29568"
52
+ # The port at which we do ring discovery (default: disabled)
53
+ # ring: 42865
54
+
55
+ # dRoby host configuration
56
+ droby:
57
+ # How many errors are allowed before disconnecting from a peer
58
+ # max_errors: 1
59
+ # The ring discovery period if we do ring discovery
60
+ # period: 0.5
61
+ # The hostname at the dRoby server must listen to. It is either
62
+ # 'host:port', or just ':port'
63
+ # host: ":48902"
64
+
65
+ # Genom configuration
66
+ genom:
67
+ # The memory size allocated for H2
68
+ # mem_size: 4000000
69
+ # If true, do not remove H2 devices when the application quit
70
+ # keep_h2: false
71
+
72
+ # Pocosim configuration
73
+ pocosim:
74
+ # The host of the GDHE display
75
+ # display: localhost
76
+
77
+ # An initialization script to display the scene on GDHE. The file is searched
78
+ # in the data/ director
79
+ # gdhe: lousa.gdhe
80
+
81
+ # The Gazebo world file for pocosim/gazebo simulations. The file is searched
82
+ # in the data/ directory
83
+ # gazebo: lousa.world
84
+
85
+ # Per-robot configuration. In these, you can override global options, or set
86
+ # new options.
87
+ # dala:
88
+ # droby:
89
+ # host: ":1287"
90
+
91
+ # vim: sw=2
@@ -0,0 +1,7 @@
1
+ # This file is called to do application-global configuration. For configuration
2
+ # specific to a robot, edit config/NAME.rb, where NAME is the robot name.
3
+ #
4
+ # Enable some of the standard plugins
5
+ # Roby.app.using 'fault_injection'
6
+ # Roby.app.using 'subsystems'
7
+
@@ -0,0 +1,3 @@
1
+ # DO NOT CHANGE THIS FILE
2
+ # It is automatically updated by the roby tool. Any change will be erased
3
+ plugins: []
File without changes
@@ -0,0 +1,2 @@
1
+ # This is the robot controller. This file is required last, after Roby has been
2
+ # fully set up. If you have to initialize some services at startup, to it here
File without changes
@@ -0,0 +1,6 @@
1
+ require 'planners/main'
2
+
3
+ class MainPlanner
4
+ # Add here robot-specific methods for MainPlanner
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+ # The main planner. A planner of this model is automatically added in the
2
+ # Interface planner list.
3
+ class MainPlanner < Roby::Planning::Planner
4
+ end
5
+
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/distributed'
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/generate/bookmarks'
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/replay'
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/results'
data/app/scripts/run ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/run'
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/server'
data/app/scripts/shell ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/shell'
data/app/scripts/test ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+ APP_DIR = File.expand_path('..', File.dirname(__FILE__))
3
+ require 'roby/app/scripts/test'
File without changes
File without changes
data/bin/roby ADDED
@@ -0,0 +1,210 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ APP_DIR = Dir.pwd
4
+
5
+ require 'optparse'
6
+ require 'ostruct'
7
+ require 'fileutils'
8
+ require 'yaml'
9
+ require 'find'
10
+
11
+ require 'roby/app'
12
+
13
+ MODES = %w{init robot}
14
+ config = OpenStruct.new
15
+ parser = OptionParser.new do |opt|
16
+ opt.banner = "Usage: roby mode [options]"
17
+ opt.on_tail('-h', '--help', 'this help message') do
18
+ if !config.mode
19
+ global_help(opt)
20
+ end
21
+ STDERR.puts opt
22
+ exit
23
+ end
24
+ end
25
+
26
+ def global_help(opt)
27
+ opt.separator ""
28
+ opt.separator " Available modes:"
29
+ opt.separator " init creates new roby application, or adds the files needed by plugins"
30
+ opt.separator " robot creates a new robot type in this application"
31
+ opt.separator ""
32
+ opt.separator " roby <mode> --help displays mode-specific help"
33
+ opt.separator ""
34
+ opt.separator " Global options"
35
+ end
36
+
37
+ def mode_init(opt, config)
38
+ config.enabled_plugins = []
39
+
40
+ opt.banner = "Usage: roby [global options] init [options]"
41
+ opt.separator ""
42
+ opt.separator " Creates an application template in the current directory, or"
43
+ opt.separator " installs the files needed by a specific plugin in an already"
44
+ opt.separator " existing application"
45
+ opt.separator ""
46
+ opt.separator " Available options"
47
+ known_plugins = Roby.app.available_plugins.map { |name, _, _| name }
48
+ opt.on('-p', '--plugin NAME,NAME', Array, "install the files needed by the given plugins. Known plugins are: #{known_plugins.join(", ")}") do |new_plugins|
49
+ new_plugins.each do |name|
50
+ if !known_plugins.include?(name)
51
+ STDERR.puts "unknown plugin #{name}. Known plugins are #{known_plugins}"
52
+ end
53
+ config.enabled_plugins << name
54
+ end
55
+ end
56
+
57
+ opt.separator ""
58
+ opt.separator " Global options"
59
+ end
60
+ def mode_robot(opt, config)
61
+ opt.banner = "Usage: roby [global options] robot NAME"
62
+ opt.separator ""
63
+ opt.separator " Creates the template for a new robot type"
64
+ opt.separator ""
65
+ opt.separator " Global options"
66
+ end
67
+
68
+ remaining = []
69
+ parser.order(ARGV) do |arg|
70
+ if !config.mode
71
+ begin
72
+ send("mode_#{arg}", parser, config)
73
+ config.mode = arg
74
+ rescue NoMethodError
75
+ STDERR.puts "Invalid mode of operation '#{arg}'. Valid modes are: #{MODES.join(", ")}"
76
+ STDERR.puts parser
77
+ exit(1)
78
+ end
79
+ else
80
+ remaining << arg
81
+ end
82
+ end
83
+
84
+ module Roby
85
+ class Installer
86
+ # The directory in which we are installing
87
+ attr_reader :app_dir
88
+
89
+ # The configuration hash saved in config/roby.yml
90
+ attr_reader :config
91
+
92
+ def config_path; File.join(app_dir, 'config', 'roby.yml') end
93
+ def installed_plugins; config['plugins'] || [] end
94
+
95
+ def check_plugins(plugins)
96
+ if name = plugins.find { |name| !Roby.app.defined_plugin?(name) }
97
+ known_plugins = Roby.app.available_plugins.map { |name, _| name }
98
+ raise ArgumentError, "unknown plugin #{name}. Available plugins are #{known_plugins.join(", ")}"
99
+ end
100
+ end
101
+
102
+ def initialize(app_dir)
103
+ @app_dir = File.expand_path(app_dir)
104
+
105
+ # Read the application configuration from config/roby.yml if the file exists,
106
+ @config = if File.file?(config_path)
107
+ YAML.load_file(config_path)
108
+ else
109
+ Hash['plugins', []]
110
+ end
111
+ check_plugins(config['plugins'])
112
+ end
113
+
114
+ def save_config
115
+ File.open(config_path, 'w') do |io|
116
+ io << YAML.dump(config)
117
+ end
118
+ end
119
+
120
+ # Install the template files for a core Roby application and the provided
121
+ # plugins
122
+ def install(plugins)
123
+ check_plugins(plugins)
124
+ install_dir(plugins) do |file|
125
+ next if file =~ /ROBOT/
126
+ file
127
+ end
128
+
129
+ config['plugins'] |= plugins
130
+ save_config
131
+ end
132
+
133
+ # Installs the template files for a new robot named +name+
134
+ def robot(name)
135
+ install_dir(installed_plugins) do |file|
136
+ next if file !~ /ROBOT/
137
+ file.gsub /ROBOT/, name
138
+ end
139
+ end
140
+
141
+ # Copies the template files into the application directory, without erasing
142
+ # already existing files. +plugins+ is the list of plugins we should copy
143
+ # files from
144
+ def install_dir(plugins = [], &filter)
145
+ Installer.copy_tree(File.join(Roby::ROBY_ROOT_DIR, 'app'), app_dir, &filter)
146
+ plugins.each do |enabled_name|
147
+ plugin_desc = Roby.app.available_plugins.find { |name, dir, _, _| enabled_name == name }
148
+
149
+ plugin_app_dir = File.join(plugin_desc[1], 'app')
150
+ next unless File.directory?(plugin_app_dir)
151
+ Installer.copy_tree(plugin_app_dir, app_dir, &filter)
152
+ end
153
+ end
154
+
155
+ # Copy all files that are in +basedir+ into +destdir+. If a block is given,
156
+ # it is called with each file relative path. The block must then return the
157
+ # destination name, or nil if the file is to be skipped.
158
+ def self.copy_tree(basedir, destdir)
159
+ basedir = File.expand_path(basedir)
160
+ destdir = File.expand_path(destdir)
161
+
162
+ Find.find(basedir) do |file|
163
+ relative = file.gsub /#{Regexp.quote("#{basedir}")}\/?/, ''
164
+ relative = yield(relative) if block_given?
165
+ # The block can return nil if the file shouldn't be installed
166
+ next unless relative
167
+
168
+ destfile = File.join(destdir, relative)
169
+ if File.directory?(file)
170
+ if !File.exists?(destfile)
171
+ puts "creating #{relative}/"
172
+ Dir.mkdir destfile
173
+ elsif !File.directory?(destfile)
174
+ STDERR.puts "#{destfile} exists but it is not a directory"
175
+ exit(1)
176
+ end
177
+ else
178
+ if !File.exists?(destfile)
179
+ FileUtils.cp file, destfile
180
+ puts "creating #{relative}"
181
+ elsif !File.file?(destfile)
182
+ STDERR.puts "#{destfile} exists but it is not a file"
183
+ exit(1)
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ if !config.mode
192
+ global_help(parser)
193
+ STDERR.puts parser
194
+ exit
195
+ end
196
+
197
+ installer = Roby::Installer.new(APP_DIR)
198
+ if config.mode == 'init'
199
+ installer.install(config.enabled_plugins)
200
+
201
+ elsif config.mode == 'robot'
202
+ unless robotname = remaining.shift
203
+ STDERR.puts "No robot name given on command line"
204
+ STDERR.puts parser
205
+ exit(1)
206
+ end
207
+
208
+ installer.robot(robotname)
209
+ end
210
+