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
data/lib/roby.rb
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
# [Roby] core namespace for the Roby kernel
|
|
4
4
|
# [Roby::Distributed] parts that are very specific to distributed plan management
|
|
5
5
|
# [Roby::Planning] basic tools for plan generation
|
|
6
|
-
# [Roby::Transactions] implementation of transactions
|
|
7
|
-
#
|
|
8
|
-
# [Roby::
|
|
6
|
+
# [Roby::Transactions] implementation of transactions. Transactions represent a
|
|
7
|
+
# change in the main plan, and can be distributed among different plan managers.
|
|
8
|
+
# [Roby::EventStructure] main namespace for event relations. The methods listed
|
|
9
|
+
# in the documentation of EventStructure are actually methods of Roby::EventGenerator
|
|
10
|
+
# [Roby::TaskStructure] main namespace for task relations. The methods listed in
|
|
11
|
+
# the documentation of TaskStructure are actually methods of Roby::Task
|
|
9
12
|
module Roby
|
|
10
13
|
class BasicObject; end
|
|
11
14
|
class PlanObject < BasicObject; end
|
|
@@ -15,28 +18,60 @@ module Roby
|
|
|
15
18
|
class Task < PlanObject; end
|
|
16
19
|
end
|
|
17
20
|
|
|
18
|
-
require '
|
|
19
|
-
require '
|
|
20
|
-
require '
|
|
21
|
-
require '
|
|
21
|
+
require 'drb'
|
|
22
|
+
require 'utilrb/weakref'
|
|
23
|
+
require 'pp'
|
|
24
|
+
require 'thread'
|
|
25
|
+
require 'set'
|
|
26
|
+
require 'yaml'
|
|
27
|
+
require 'utilrb/value_set'
|
|
28
|
+
require 'utilrb/object/attribute'
|
|
29
|
+
require 'utilrb/module/ancestor_p'
|
|
30
|
+
require 'utilrb/kernel/options'
|
|
31
|
+
require 'utilrb/module/attr_enumerable'
|
|
32
|
+
require 'utilrb/module/attr_predicate'
|
|
33
|
+
require 'utilrb/module/inherited_enumerable'
|
|
34
|
+
require 'utilrb/module/include'
|
|
35
|
+
require 'utilrb/kernel/arity'
|
|
36
|
+
require 'utilrb/kernel/swap'
|
|
37
|
+
require 'utilrb/exception/full_message'
|
|
38
|
+
require 'utilrb/unbound_method/call'
|
|
22
39
|
|
|
23
|
-
require 'roby/
|
|
24
|
-
require 'roby/
|
|
25
|
-
require 'roby/
|
|
26
|
-
require 'roby/
|
|
40
|
+
require 'roby/config.rb'
|
|
41
|
+
require 'roby/support.rb'
|
|
42
|
+
require 'roby/basic_object.rb'
|
|
43
|
+
require 'roby/standard_errors.rb'
|
|
44
|
+
require 'roby/exceptions.rb'
|
|
45
|
+
require 'roby_bgl'
|
|
46
|
+
require 'roby/graph.rb'
|
|
47
|
+
require 'roby/relations.rb'
|
|
27
48
|
|
|
28
|
-
require 'roby/
|
|
29
|
-
require 'roby/
|
|
30
|
-
require 'roby/
|
|
31
|
-
require 'roby/
|
|
32
|
-
require 'roby/relations/planned_by'
|
|
33
|
-
require 'roby/relations/executed_by'
|
|
34
|
-
require 'roby/relations/ensured'
|
|
49
|
+
require 'roby/plan-object.rb'
|
|
50
|
+
require 'roby/event.rb'
|
|
51
|
+
require 'roby/task.rb'
|
|
52
|
+
require 'roby/task-operations.rb'
|
|
35
53
|
|
|
36
|
-
require 'roby/
|
|
37
|
-
require 'roby/
|
|
54
|
+
require 'roby/relations/conflicts.rb'
|
|
55
|
+
require 'roby/relations/ensured.rb'
|
|
56
|
+
require 'roby/relations/error_handling.rb'
|
|
57
|
+
require 'roby/relations/events.rb'
|
|
58
|
+
require 'roby/relations/executed_by.rb'
|
|
59
|
+
require 'roby/relations/dependency.rb'
|
|
60
|
+
require 'roby/relations/influence.rb'
|
|
61
|
+
require 'roby/relations/planned_by.rb'
|
|
38
62
|
|
|
39
|
-
require 'roby/
|
|
63
|
+
require 'roby/task_index.rb'
|
|
64
|
+
require 'roby/plan.rb'
|
|
65
|
+
require 'roby/transactions/proxy.rb'
|
|
66
|
+
require 'roby/transactions.rb'
|
|
67
|
+
require 'roby/query.rb'
|
|
40
68
|
|
|
41
|
-
require 'roby/
|
|
69
|
+
require 'roby/distributed/base'
|
|
70
|
+
require 'roby/decision_control.rb'
|
|
71
|
+
require 'roby/execution_engine.rb'
|
|
72
|
+
require 'roby/app.rb'
|
|
73
|
+
|
|
74
|
+
require 'roby/robot.rb'
|
|
75
|
+
require 'roby/planning.rb'
|
|
76
|
+
require 'roby/state.rb'
|
|
42
77
|
|
data/lib/roby/app.rb
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'roby/distributed'
|
|
3
|
-
require 'roby/planning'
|
|
4
|
-
require 'roby/log'
|
|
5
|
-
require 'roby/log/event_stream'
|
|
6
|
-
|
|
7
|
-
require 'roby/robot'
|
|
8
|
-
require 'yaml'
|
|
9
|
-
|
|
1
|
+
require 'singleton'
|
|
10
2
|
module Roby
|
|
11
|
-
# Returns the only one Application object
|
|
12
|
-
def self.app; Application.instance end
|
|
13
|
-
|
|
14
3
|
# = Roby Applications
|
|
15
4
|
#
|
|
16
5
|
# There is one and only one Application object, which holds mainly the
|
|
@@ -56,6 +45,9 @@ module Roby
|
|
|
56
45
|
# Roby::Test::TestCase for a description of Roby-specific tests.
|
|
57
46
|
class Application
|
|
58
47
|
include Singleton
|
|
48
|
+
|
|
49
|
+
# A set of planners declared in this application
|
|
50
|
+
attr_reader :planners
|
|
59
51
|
|
|
60
52
|
# The plain option hash saved in config/app.yml
|
|
61
53
|
attr_reader :options
|
|
@@ -70,6 +62,9 @@ module Roby
|
|
|
70
62
|
# dir:: the log directory. Uses APP_DIR/log if not set
|
|
71
63
|
# filter_backtraces:: true if the framework code should be removed from the error backtraces
|
|
72
64
|
attr_reader :log
|
|
65
|
+
|
|
66
|
+
# ExecutionEngine setup
|
|
67
|
+
attr_reader :engine
|
|
73
68
|
|
|
74
69
|
# A [name, dir, file, module] array of available plugins, where 'name'
|
|
75
70
|
# is the plugin name, 'dir' the directory in which it is installed,
|
|
@@ -88,12 +83,10 @@ module Roby
|
|
|
88
83
|
# detected
|
|
89
84
|
attr_reader :droby
|
|
90
85
|
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
# from a task or event) is caught. Defaults to true.
|
|
96
|
-
attr_reader :control
|
|
86
|
+
# If true, abort if an unhandled exception is found
|
|
87
|
+
attr_predicate :abort_on_exception, true
|
|
88
|
+
# If true, abort if an application exception is found
|
|
89
|
+
attr_predicate :abort_on_application_exception, true
|
|
97
90
|
|
|
98
91
|
# An array of directories in which to search for plugins
|
|
99
92
|
attr_reader :plugin_dirs
|
|
@@ -117,13 +110,13 @@ module Roby
|
|
|
117
110
|
@log = Hash['events' => 'stats', 'levels' => Hash.new, 'filter_backtraces' => true]
|
|
118
111
|
@discovery = Hash.new
|
|
119
112
|
@droby = Hash['period' => 0.5, 'max_errors' => 1]
|
|
120
|
-
|
|
121
|
-
'abort_on_application_exception' => true ]
|
|
113
|
+
@engine = Hash.new
|
|
122
114
|
|
|
123
115
|
@automatic_testing = true
|
|
124
116
|
@testing_keep_logs = false
|
|
125
117
|
|
|
126
118
|
@plugin_dirs = []
|
|
119
|
+
@planners = []
|
|
127
120
|
end
|
|
128
121
|
|
|
129
122
|
# Adds +dir+ in the list of directories searched for plugins
|
|
@@ -207,7 +200,7 @@ module Roby
|
|
|
207
200
|
|
|
208
201
|
@options = options
|
|
209
202
|
|
|
210
|
-
load_option_hashes(options, %w{log
|
|
203
|
+
load_option_hashes(options, %w{log engine discovery droby})
|
|
211
204
|
call_plugins(:load, self, options)
|
|
212
205
|
end
|
|
213
206
|
|
|
@@ -349,7 +342,7 @@ module Roby
|
|
|
349
342
|
|
|
350
343
|
# Set up log levels
|
|
351
344
|
log['levels'].each do |name, value|
|
|
352
|
-
name = name.
|
|
345
|
+
name = name.camelcase(true)
|
|
353
346
|
if value =~ /^(\w+):(.+)$/
|
|
354
347
|
level, file = $1, $2
|
|
355
348
|
level = Logger.const_get(level)
|
|
@@ -367,19 +360,18 @@ module Roby
|
|
|
367
360
|
new_logger.level = level
|
|
368
361
|
new_logger.formatter = Roby.logger.formatter
|
|
369
362
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
end
|
|
363
|
+
mod = Kernel.constant(name)
|
|
364
|
+
if robot_name
|
|
365
|
+
new_logger.progname = "#{name} #{robot_name}"
|
|
366
|
+
else
|
|
367
|
+
new_logger.progname = name
|
|
368
|
+
end
|
|
369
|
+
mod.logger = new_logger
|
|
378
370
|
end
|
|
379
371
|
end
|
|
380
372
|
|
|
381
373
|
def setup_dirs
|
|
382
|
-
|
|
374
|
+
FileUtils.mkdir_p(log_dir) unless File.exists?(log_dir)
|
|
383
375
|
if File.directory?(libdir = File.join(APP_DIR, 'lib'))
|
|
384
376
|
if !$LOAD_PATH.include?(libdir)
|
|
385
377
|
$LOAD_PATH.unshift File.join(APP_DIR, 'lib')
|
|
@@ -397,22 +389,17 @@ module Roby
|
|
|
397
389
|
def require_models
|
|
398
390
|
# Require all common task models and the task models specific to
|
|
399
391
|
# this robot
|
|
400
|
-
|
|
401
|
-
|
|
392
|
+
list_dir('tasks') { |p| require(p) }
|
|
393
|
+
list_robotdir('tasks', 'ROBOT') { |p| require(p) }
|
|
402
394
|
|
|
403
395
|
# Load robot-specific configuration
|
|
404
|
-
|
|
405
|
-
models_search = [planner_dir]
|
|
396
|
+
models_search = ['planners']
|
|
406
397
|
if robot_name
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
end
|
|
413
|
-
else
|
|
414
|
-
require File.join(APP_DIR, "planners", "main")
|
|
415
|
-
end
|
|
398
|
+
models_search << File.join('planners', robot_name) << File.join('planners', robot_type)
|
|
399
|
+
file = robotfile('planners', 'ROBOT', 'main.rb')
|
|
400
|
+
end
|
|
401
|
+
file ||= File.join("planners", "main")
|
|
402
|
+
require file if File.file?(file)
|
|
416
403
|
|
|
417
404
|
# Load the other planners
|
|
418
405
|
models_search.each do |base_dir|
|
|
@@ -423,10 +410,19 @@ module Roby
|
|
|
423
410
|
end
|
|
424
411
|
end
|
|
425
412
|
end
|
|
413
|
+
|
|
414
|
+
# Set up the loaded plugins
|
|
415
|
+
call_plugins(:require_models, self)
|
|
426
416
|
end
|
|
427
417
|
|
|
428
418
|
def setup
|
|
419
|
+
if !Roby.plan
|
|
420
|
+
Roby.instance_variable_set :@plan, Plan.new
|
|
421
|
+
end
|
|
422
|
+
|
|
429
423
|
reset
|
|
424
|
+
require 'roby/planning'
|
|
425
|
+
require 'roby/interface'
|
|
430
426
|
|
|
431
427
|
$LOAD_PATH.unshift(APP_DIR) unless $LOAD_PATH.include?(APP_DIR)
|
|
432
428
|
|
|
@@ -448,14 +444,21 @@ module Roby
|
|
|
448
444
|
Object.const_set(:State, Roby::State)
|
|
449
445
|
end
|
|
450
446
|
|
|
447
|
+
# Set up the loaded plugins
|
|
448
|
+
call_plugins(:setup, self)
|
|
449
|
+
|
|
451
450
|
require_models
|
|
452
451
|
|
|
452
|
+
if file = robotfile(APP_DIR, 'config', "ROBOT.rb")
|
|
453
|
+
load file
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
|
|
453
457
|
# MainPlanner is always included in the planner list
|
|
454
|
-
|
|
458
|
+
if defined? MainPlanner
|
|
459
|
+
self.planners << MainPlanner
|
|
460
|
+
end
|
|
455
461
|
|
|
456
|
-
# Set up the loaded plugins
|
|
457
|
-
call_plugins(:setup, self)
|
|
458
|
-
|
|
459
462
|
# If we are in test mode, import the test extensions from plugins
|
|
460
463
|
if testing?
|
|
461
464
|
require 'roby/test/testcase'
|
|
@@ -468,6 +471,8 @@ module Roby
|
|
|
468
471
|
end
|
|
469
472
|
|
|
470
473
|
def run(&block)
|
|
474
|
+
setup_global_singletons
|
|
475
|
+
|
|
471
476
|
# Set up dRoby, setting an Interface object as front server, for shell access
|
|
472
477
|
host = droby['host'] || ""
|
|
473
478
|
if host !~ /:\d+$/
|
|
@@ -476,9 +481,9 @@ module Roby
|
|
|
476
481
|
|
|
477
482
|
if single? || !robot_name
|
|
478
483
|
host =~ /:(\d+)$/
|
|
479
|
-
DRb.start_service "druby://:#{$1 || '0'}", Interface.new(Roby.
|
|
484
|
+
DRb.start_service "druby://:#{$1 || '0'}", Interface.new(Roby.engine)
|
|
480
485
|
else
|
|
481
|
-
DRb.start_service "druby://#{host}", Interface.new(Roby.
|
|
486
|
+
DRb.start_service "druby://#{host}", Interface.new(Roby.engine)
|
|
482
487
|
droby_config = { :ring_discovery => !!discovery['ring'],
|
|
483
488
|
:name => robot_name,
|
|
484
489
|
:plan => Roby.plan,
|
|
@@ -492,7 +497,7 @@ module Roby
|
|
|
492
497
|
if discovery['ring']
|
|
493
498
|
Roby::Distributed.publish discovery['ring']
|
|
494
499
|
end
|
|
495
|
-
Roby
|
|
500
|
+
Roby.every(discovery['period'] || 0.5) do
|
|
496
501
|
Roby::Distributed.state.start_neighbour_discovery
|
|
497
502
|
end
|
|
498
503
|
end
|
|
@@ -500,27 +505,18 @@ module Roby
|
|
|
500
505
|
@robot_name ||= 'common'
|
|
501
506
|
@robot_type ||= 'common'
|
|
502
507
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
options = { :
|
|
508
|
+
engine_config = self.engine
|
|
509
|
+
engine = Roby.engine
|
|
510
|
+
options = { :cycle => engine_config['cycle'] || 0.1 }
|
|
506
511
|
|
|
507
|
-
# Add an executive if one is defined
|
|
508
|
-
if control_config['executive']
|
|
509
|
-
self.executive = control_config['executive']
|
|
510
|
-
end
|
|
511
|
-
|
|
512
512
|
if log['events']
|
|
513
513
|
require 'roby/log/file'
|
|
514
514
|
logfile = File.join(log_dir, robot_name)
|
|
515
|
-
logger = Roby::Log::FileLogger.new(logfile)
|
|
515
|
+
logger = Roby::Log::FileLogger.new(logfile, :plugins => plugins.map { |n, _| n })
|
|
516
516
|
logger.stats_mode = log['events'] == 'stats'
|
|
517
517
|
Roby::Log.add_logger logger
|
|
518
518
|
end
|
|
519
|
-
|
|
520
|
-
control_config['abort_on_exception']
|
|
521
|
-
control.abort_on_application_exception =
|
|
522
|
-
control_config['abort_on_application_exception']
|
|
523
|
-
control.run options
|
|
519
|
+
engine.run options
|
|
524
520
|
|
|
525
521
|
plugins = self.plugins.map { |_, mod| mod if mod.respond_to?(:run) }.compact
|
|
526
522
|
run_plugins(plugins, &block)
|
|
@@ -533,11 +529,11 @@ module Roby
|
|
|
533
529
|
end
|
|
534
530
|
end
|
|
535
531
|
def run_plugins(mods, &block)
|
|
536
|
-
|
|
532
|
+
engine = Roby.engine
|
|
537
533
|
|
|
538
534
|
if mods.empty?
|
|
539
535
|
yield
|
|
540
|
-
|
|
536
|
+
engine.join
|
|
541
537
|
else
|
|
542
538
|
mod = mods.shift
|
|
543
539
|
mod.run(self) do
|
|
@@ -546,30 +542,15 @@ module Roby
|
|
|
546
542
|
end
|
|
547
543
|
|
|
548
544
|
rescue Exception => e
|
|
549
|
-
if Roby.
|
|
550
|
-
|
|
551
|
-
|
|
545
|
+
if Roby.engine.running?
|
|
546
|
+
engine.quit
|
|
547
|
+
engine.join
|
|
552
548
|
raise e, e.message, e.backtrace
|
|
553
549
|
else
|
|
554
550
|
raise
|
|
555
551
|
end
|
|
556
552
|
end
|
|
557
553
|
|
|
558
|
-
attr_reader :executive
|
|
559
|
-
|
|
560
|
-
def executive=(name)
|
|
561
|
-
if executive
|
|
562
|
-
Control.event_processing.delete(executive.method(:initial_events))
|
|
563
|
-
@executive = nil
|
|
564
|
-
end
|
|
565
|
-
return unless name
|
|
566
|
-
|
|
567
|
-
full_name = "roby/executives/#{name}"
|
|
568
|
-
require full_name
|
|
569
|
-
@executive = full_name.camelize.constantize.new
|
|
570
|
-
Control.event_processing << executive.method(:initial_events)
|
|
571
|
-
end
|
|
572
|
-
|
|
573
554
|
def stop; call_plugins(:stop, self) end
|
|
574
555
|
|
|
575
556
|
DISCOVERY_TEMPLATE = [:droby, nil, nil]
|
|
@@ -583,7 +564,7 @@ module Roby
|
|
|
583
564
|
Thread.abort_on_exception = true
|
|
584
565
|
|
|
585
566
|
if !File.exists?(log_dir)
|
|
586
|
-
|
|
567
|
+
FileUtils.mkdir_p(log_dir)
|
|
587
568
|
end
|
|
588
569
|
|
|
589
570
|
unless single? || !discovery['tuplespace']
|
|
@@ -678,52 +659,49 @@ module Roby
|
|
|
678
659
|
call_plugins(:stop_server, self)
|
|
679
660
|
end
|
|
680
661
|
|
|
681
|
-
|
|
682
|
-
|
|
662
|
+
def list_dir(*path)
|
|
663
|
+
if !block_given?
|
|
664
|
+
return enum_for(:list_dir, *path)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
dirname = File.join(*path)
|
|
683
668
|
Dir.new(dirname).each do |file|
|
|
684
669
|
file = File.join(dirname, file)
|
|
685
|
-
|
|
686
|
-
|
|
670
|
+
if file =~ /\.rb$/ && File.file?(file)
|
|
671
|
+
file = file.gsub(/^#{Regexp.quote(APP_DIR)}\//, '')
|
|
672
|
+
yield(file)
|
|
673
|
+
end
|
|
687
674
|
end
|
|
688
|
-
|
|
675
|
+
end
|
|
689
676
|
|
|
690
677
|
# Require all files in the directories matching +pattern+. If +pattern+
|
|
691
678
|
# contains the word ROBOT, it is replaced by -- in order -- the robot
|
|
692
679
|
# name and then the robot type
|
|
693
|
-
def
|
|
680
|
+
def list_robotdir(*path, &block)
|
|
681
|
+
if !block_given?
|
|
682
|
+
return enum_for(:list_robotdir, *path)
|
|
683
|
+
end
|
|
684
|
+
|
|
694
685
|
return unless robot_name && robot_type
|
|
695
686
|
|
|
696
|
-
|
|
687
|
+
pattern = File.expand_path(File.join(*path), APP_DIR)
|
|
688
|
+
[robot_name, robot_type].uniq.each do |name|
|
|
697
689
|
dirname = pattern.gsub(/ROBOT/, name)
|
|
698
|
-
|
|
690
|
+
list_dir(dirname, &block) if File.directory?(dirname)
|
|
699
691
|
end
|
|
700
692
|
end
|
|
701
693
|
|
|
702
|
-
|
|
703
|
-
#
|
|
704
|
-
# See #require_robotfile
|
|
705
|
-
def load_robotfile(pattern)
|
|
706
|
-
require_robotfile(pattern, :load)
|
|
707
|
-
end
|
|
708
|
-
|
|
709
|
-
# Requires or loads (according to the value of +method+) the first file
|
|
710
|
-
# found matching +pattern+. +pattern+ can contain the word ROBOT, in
|
|
711
|
-
# which case the file is first checked against the robot name and then
|
|
712
|
-
# against the robot type
|
|
713
|
-
def require_robotfile(pattern, method = :require)
|
|
694
|
+
def robotfile(*path) # :nodoc
|
|
714
695
|
return unless robot_name && robot_type
|
|
715
696
|
|
|
697
|
+
pattern = File.join(*path)
|
|
716
698
|
robot_config = pattern.gsub(/ROBOT/, robot_name)
|
|
717
699
|
if File.file?(robot_config)
|
|
718
|
-
|
|
719
|
-
true
|
|
700
|
+
robot_config
|
|
720
701
|
else
|
|
721
702
|
robot_config = pattern.gsub(/ROBOT/, robot_type)
|
|
722
703
|
if File.file?(robot_config)
|
|
723
|
-
|
|
724
|
-
true
|
|
725
|
-
else
|
|
726
|
-
false
|
|
704
|
+
robot_config
|
|
727
705
|
end
|
|
728
706
|
end
|
|
729
707
|
end
|
|
@@ -738,6 +716,34 @@ module Roby
|
|
|
738
716
|
def single?; @single || discovery.empty? end
|
|
739
717
|
def single; @single = true end
|
|
740
718
|
|
|
719
|
+
def setup_global_singletons
|
|
720
|
+
if !Roby.plan
|
|
721
|
+
Roby.instance_variable_set :@plan, Plan.new
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
if !Roby.engine && Roby.plan.engine
|
|
725
|
+
# This checks coherence with Roby.control, and sets it
|
|
726
|
+
# accordingly
|
|
727
|
+
Roby.engine = Roby.plan.engine
|
|
728
|
+
elsif !Roby.control
|
|
729
|
+
Roby.control = DecisionControl.new
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
if !Roby.engine
|
|
733
|
+
Roby.engine = ExecutionEngine.new(Roby.plan, Roby.control)
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
if Roby.control != Roby.engine.control
|
|
737
|
+
raise "inconsistency between Roby.control and Roby.engine.control"
|
|
738
|
+
elsif Roby.engine != Roby.plan.engine
|
|
739
|
+
raise "inconsistency between Roby.engine and Roby.plan.engine"
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
if !Roby.engine.scheduler && Roby.scheduler
|
|
743
|
+
Roby.engine.scheduler = Roby.scheduler
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
|
|
741
747
|
# Guesses the type of +filename+ if it is a source suitable for
|
|
742
748
|
# data display in this application
|
|
743
749
|
def data_streams_of(filenames)
|
|
@@ -857,6 +863,20 @@ module Roby
|
|
|
857
863
|
end
|
|
858
864
|
end
|
|
859
865
|
|
|
866
|
+
@app = Application.instance
|
|
867
|
+
class << self
|
|
868
|
+
# The one and only Application object
|
|
869
|
+
attr_reader :app
|
|
870
|
+
|
|
871
|
+
# The scheduler object to be used during execution. See
|
|
872
|
+
# ExecutionEngine#scheduler.
|
|
873
|
+
#
|
|
874
|
+
# This is only used during the configuration of the application, and
|
|
875
|
+
# not afterwards. It is also possible to set per-engine through
|
|
876
|
+
# ExecutionEngine#scheduler=
|
|
877
|
+
attr_accessor :scheduler
|
|
878
|
+
end
|
|
879
|
+
|
|
860
880
|
# Load the plugins 'main' files
|
|
861
881
|
Roby.app.plugin_dir File.join(ROBY_ROOT_DIR, 'plugins')
|
|
862
882
|
if plugin_path = ENV['ROBY_PLUGIN_PATH']
|