roby 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -5
- data/Manifest.txt +91 -16
- data/README.txt +24 -24
- data/Rakefile +92 -64
- data/app/config/app.yml +42 -43
- data/app/config/init.rb +26 -0
- data/benchmark/alloc_misc.rb +123 -0
- data/benchmark/discovery_latency.rb +67 -0
- data/benchmark/garbage_collection.rb +48 -0
- data/benchmark/genom.rb +31 -0
- data/benchmark/transactions.rb +62 -0
- data/bin/roby +1 -1
- data/bin/roby-log +16 -6
- data/doc/guide/.gitignore +2 -0
- data/doc/guide/config.yaml +34 -0
- data/doc/guide/ext/init.rb +14 -0
- data/doc/guide/ext/previous_next.rb +40 -0
- data/doc/guide/ext/rdoc_links.rb +33 -0
- data/doc/guide/index.rdoc +16 -0
- data/doc/guide/overview.rdoc +62 -0
- data/doc/guide/plan_modifications.rdoc +67 -0
- data/doc/guide/src/abstraction/achieve_with.page +8 -0
- data/doc/guide/src/abstraction/forwarding.page +8 -0
- data/doc/guide/src/abstraction/hierarchy.page +19 -0
- data/doc/guide/src/abstraction/index.page +28 -0
- data/doc/guide/src/abstraction/task_models.page +13 -0
- data/doc/guide/src/basics.template +6 -0
- data/doc/guide/src/basics/app.page +139 -0
- data/doc/guide/src/basics/code_examples.page +33 -0
- data/doc/guide/src/basics/dry.page +69 -0
- data/doc/guide/src/basics/errors.page +443 -0
- data/doc/guide/src/basics/events.page +179 -0
- data/doc/guide/src/basics/hierarchy.page +275 -0
- data/doc/guide/src/basics/index.page +11 -0
- data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_4.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/basics/plan_objects.page +71 -0
- data/doc/guide/src/basics/relations_display.page +203 -0
- data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
- data/doc/guide/src/basics/shell.page +102 -0
- data/doc/guide/src/basics/summary.page +32 -0
- data/doc/guide/src/basics/tasks.page +357 -0
- data/doc/guide/src/basics_shell_header.txt +16 -0
- data/doc/guide/src/cycle/cycle-overview.png +0 -0
- data/doc/guide/src/cycle/cycle-overview.svg +208 -0
- data/doc/guide/src/cycle/error_handling.page +168 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
- data/doc/guide/src/cycle/garbage_collection.page +10 -0
- data/doc/guide/src/cycle/index.page +23 -0
- data/doc/guide/src/cycle/propagation.page +154 -0
- data/doc/guide/src/cycle/propagation_diamond.png +0 -0
- data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
- data/doc/guide/src/default.css +319 -0
- data/doc/guide/src/default.template +74 -0
- data/doc/guide/src/htmldoc.metainfo +20 -0
- data/doc/guide/src/htmldoc.virtual +18 -0
- data/doc/guide/src/images/bodybg.png +0 -0
- data/doc/guide/src/images/contbg.png +0 -0
- data/doc/guide/src/images/footerbg.png +0 -0
- data/doc/guide/src/images/gradient1.png +0 -0
- data/doc/guide/src/images/gradient2.png +0 -0
- data/doc/guide/src/index.page +7 -0
- data/doc/guide/src/introduction/index.page +29 -0
- data/doc/guide/src/introduction/install.page +133 -0
- data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
- data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
- data/doc/guide/src/plugins/fault_tolerance.page +44 -0
- data/doc/guide/src/plugins/index.page +11 -0
- data/doc/guide/src/plugins/subsystems.page +45 -0
- data/doc/guide/src/relations/dependency.page +89 -0
- data/doc/guide/src/relations/index.page +12 -0
- data/doc/misc/update_github +24 -0
- data/doc/tutorials/02-GoForward.rdoc +3 -3
- data/ext/graph/graph.cc +46 -0
- data/lib/roby.rb +57 -22
- data/lib/roby/app.rb +132 -112
- data/lib/roby/app/plugins/rake.rb +21 -0
- data/lib/roby/app/rake.rb +0 -7
- data/lib/roby/app/run.rb +1 -1
- data/lib/roby/app/scripts/distributed.rb +1 -2
- data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
- data/lib/roby/app/scripts/results.rb +2 -1
- data/lib/roby/app/scripts/run.rb +6 -2
- data/lib/roby/app/scripts/shell.rb +11 -11
- data/lib/roby/config.rb +1 -1
- data/lib/roby/decision_control.rb +62 -3
- data/lib/roby/distributed.rb +4 -0
- data/lib/roby/distributed/base.rb +8 -0
- data/lib/roby/distributed/communication.rb +12 -8
- data/lib/roby/distributed/connection_space.rb +61 -44
- data/lib/roby/distributed/distributed_object.rb +1 -1
- data/lib/roby/distributed/notifications.rb +22 -30
- data/lib/roby/distributed/peer.rb +13 -8
- data/lib/roby/distributed/proxy.rb +5 -5
- data/lib/roby/distributed/subscription.rb +4 -4
- data/lib/roby/distributed/transaction.rb +3 -3
- data/lib/roby/event.rb +176 -110
- data/lib/roby/exceptions.rb +12 -4
- data/lib/roby/execution_engine.rb +1604 -0
- data/lib/roby/external_process_task.rb +225 -0
- data/lib/roby/graph.rb +0 -6
- data/lib/roby/interface.rb +221 -137
- data/lib/roby/log/console.rb +5 -3
- data/lib/roby/log/data_stream.rb +94 -16
- data/lib/roby/log/dot.rb +8 -8
- data/lib/roby/log/event_stream.rb +13 -3
- data/lib/roby/log/file.rb +43 -18
- data/lib/roby/log/gui/basic_display_ui.rb +89 -0
- data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
- data/lib/roby/log/gui/data_displays.rb +4 -5
- data/lib/roby/log/gui/data_displays_ui.rb +146 -0
- data/lib/roby/log/gui/relations.rb +18 -18
- data/lib/roby/log/gui/relations_ui.rb +120 -0
- data/lib/roby/log/gui/relations_view_ui.rb +144 -0
- data/lib/roby/log/gui/replay.rb +41 -13
- data/lib/roby/log/gui/replay_controls.rb +3 -0
- data/lib/roby/log/gui/replay_controls.ui +133 -110
- data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
- data/lib/roby/log/hooks.rb +19 -18
- data/lib/roby/log/logger.rb +7 -6
- data/lib/roby/log/notifications.rb +4 -4
- data/lib/roby/log/plan_rebuilder.rb +20 -22
- data/lib/roby/log/relations.rb +44 -16
- data/lib/roby/log/server.rb +1 -4
- data/lib/roby/log/timings.rb +88 -19
- data/lib/roby/plan-object.rb +135 -11
- data/lib/roby/plan.rb +408 -224
- data/lib/roby/planning/loops.rb +32 -25
- data/lib/roby/planning/model.rb +157 -51
- data/lib/roby/planning/task.rb +47 -20
- data/lib/roby/query.rb +128 -92
- data/lib/roby/relations.rb +254 -136
- data/lib/roby/relations/conflicts.rb +6 -9
- data/lib/roby/relations/dependency.rb +358 -0
- data/lib/roby/relations/ensured.rb +0 -1
- data/lib/roby/relations/error_handling.rb +0 -1
- data/lib/roby/relations/events.rb +0 -2
- data/lib/roby/relations/executed_by.rb +26 -11
- data/lib/roby/relations/planned_by.rb +14 -14
- data/lib/roby/robot.rb +46 -0
- data/lib/roby/schedulers/basic.rb +34 -0
- data/lib/roby/standalone.rb +4 -0
- data/lib/roby/standard_errors.rb +21 -15
- data/lib/roby/state/events.rb +5 -4
- data/lib/roby/support.rb +107 -6
- data/lib/roby/task-operations.rb +23 -19
- data/lib/roby/task.rb +522 -148
- data/lib/roby/task_index.rb +80 -0
- data/lib/roby/test/common.rb +283 -44
- data/lib/roby/test/distributed.rb +53 -37
- data/lib/roby/test/testcase.rb +9 -204
- data/lib/roby/test/tools.rb +3 -3
- data/lib/roby/transactions.rb +154 -111
- data/lib/roby/transactions/proxy.rb +40 -7
- data/manifest.xml +20 -0
- data/plugins/fault_injection/README.txt +0 -3
- data/plugins/fault_injection/Rakefile +2 -8
- data/plugins/fault_injection/app.rb +1 -1
- data/plugins/fault_injection/fault_injection.rb +3 -3
- data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
- data/plugins/subsystems/README.txt +0 -3
- data/plugins/subsystems/Rakefile +2 -7
- data/plugins/subsystems/app.rb +27 -16
- data/plugins/subsystems/test/app/config/init.rb +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +1 -1
- data/plugins/subsystems/test/app/tasks/services.rb +1 -1
- data/plugins/subsystems/test/test_subsystems.rb +23 -16
- data/test/distributed/test_communication.rb +32 -15
- data/test/distributed/test_connection.rb +28 -26
- data/test/distributed/test_execution.rb +59 -54
- data/test/distributed/test_mixed_plan.rb +34 -34
- data/test/distributed/test_plan_notifications.rb +26 -26
- data/test/distributed/test_protocol.rb +57 -48
- data/test/distributed/test_query.rb +11 -7
- data/test/distributed/test_remote_plan.rb +71 -71
- data/test/distributed/test_transaction.rb +50 -47
- data/test/mockups/external_process +28 -0
- data/test/planning/test_loops.rb +163 -119
- data/test/planning/test_model.rb +3 -3
- data/test/planning/test_task.rb +27 -7
- data/test/relations/test_conflicts.rb +3 -3
- data/test/relations/test_dependency.rb +324 -0
- data/test/relations/test_ensured.rb +2 -2
- data/test/relations/test_executed_by.rb +94 -19
- data/test/relations/test_planned_by.rb +11 -9
- data/test/suite_core.rb +6 -3
- data/test/suite_distributed.rb +1 -0
- data/test/suite_planning.rb +1 -0
- data/test/suite_relations.rb +2 -2
- data/test/tasks/test_external_process.rb +126 -0
- data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
- data/test/test_bgl.rb +21 -1
- data/test/test_event.rb +229 -155
- data/test/test_exceptions.rb +79 -80
- data/test/test_execution_engine.rb +987 -0
- data/test/test_gui.rb +1 -1
- data/test/test_interface.rb +11 -5
- data/test/test_log.rb +18 -7
- data/test/test_log_server.rb +1 -0
- data/test/test_plan.rb +229 -395
- data/test/test_query.rb +193 -35
- data/test/test_relations.rb +88 -8
- data/test/test_state.rb +55 -37
- data/test/test_support.rb +1 -1
- data/test/test_task.rb +371 -218
- data/test/test_testcase.rb +32 -16
- data/test/test_transactions.rb +211 -170
- data/test/test_transactions_proxy.rb +37 -19
- metadata +169 -71
- data/.gitignore +0 -29
- data/doc/styles/allison.css +0 -314
- data/doc/styles/allison.js +0 -316
- data/doc/styles/allison.rb +0 -276
- data/doc/styles/jamis.rb +0 -593
- data/lib/roby/control.rb +0 -746
- data/lib/roby/executives/simple.rb +0 -30
- data/lib/roby/propagation.rb +0 -562
- data/lib/roby/relations/hierarchy.rb +0 -239
- data/lib/roby/transactions/updates.rb +0 -139
- data/test/relations/test_hierarchy.rb +0 -158
- data/test/test_control.rb +0 -399
- data/test/test_propagation.rb +0 -210
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'roby/task'
|
|
2
|
-
|
|
3
1
|
module Roby::TaskStructure
|
|
4
2
|
relation :PlannedBy, :child_name => :planning_task,
|
|
5
3
|
:parent_name => :planned_task, :noinfo => true, :single_child => true do
|
|
@@ -21,7 +19,7 @@ module Roby::TaskStructure
|
|
|
21
19
|
|
|
22
20
|
# Returns a set of PlanningFailedError exceptions for all abstract tasks
|
|
23
21
|
# for which planning has failed
|
|
24
|
-
def PlannedBy.
|
|
22
|
+
def PlannedBy.check_structure(plan)
|
|
25
23
|
result = []
|
|
26
24
|
Roby::TaskStructure::PlannedBy.each_edge do |planned_task, planning_task, _|
|
|
27
25
|
next unless plan == planning_task.plan && planning_task.failed?
|
|
@@ -43,21 +41,23 @@ module Roby
|
|
|
43
41
|
|
|
44
42
|
def initialize(planned_task, planning_task)
|
|
45
43
|
@planned_task = planned_task
|
|
46
|
-
super(planning_task.
|
|
44
|
+
super(planning_task.failure_event)
|
|
47
45
|
end
|
|
46
|
+
def pretty_print(pp)
|
|
47
|
+
pp.text "failed to plan "
|
|
48
|
+
planned_task.pretty_print(pp)
|
|
49
|
+
pp.breakable
|
|
50
|
+
pp.breakable
|
|
51
|
+
pp.text "the following planning task failed with the #{failure_point.symbol} event"
|
|
52
|
+
pp.breakable
|
|
53
|
+
failed_task.pretty_print(pp)
|
|
54
|
+
pp.breakable
|
|
48
55
|
|
|
49
|
-
def message # :nodoc:
|
|
50
|
-
msg = "failed to plan #{planned_task}.planned_by(#{failed_task}): failed with #{failure_point.symbol}"
|
|
51
56
|
if failure_point.context
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
else
|
|
55
|
-
msg << "(" << failure_point.context.first.to_s << ")"
|
|
56
|
-
end
|
|
57
|
+
pp.breakable
|
|
58
|
+
failure_point.context.first.pretty_print(pp)
|
|
57
59
|
end
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
+
end
|
|
60
61
|
end
|
|
61
|
-
Control.structure_checks << TaskStructure::PlannedBy.method(:check_planning)
|
|
62
62
|
end
|
|
63
63
|
|
data/lib/roby/robot.rb
CHANGED
|
@@ -3,5 +3,51 @@ module Robot
|
|
|
3
3
|
attr_accessor :logger
|
|
4
4
|
end
|
|
5
5
|
extend Logger::Forward
|
|
6
|
+
|
|
7
|
+
def self.prepare_action(name, arguments)
|
|
8
|
+
# Check if +name+ is a planner method, and in that case
|
|
9
|
+
# add a planning method for it and plan it
|
|
10
|
+
planner_model = Roby.app.planners.find do |planner_model|
|
|
11
|
+
planner_model.has_method?(name)
|
|
12
|
+
end
|
|
13
|
+
if !planner_model
|
|
14
|
+
raise ArgumentError, "no such planning method #{name}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
m = planner_model.model_of(name, arguments)
|
|
18
|
+
|
|
19
|
+
# HACK: m.returns should not be nil, but it sometimes happen
|
|
20
|
+
returns_model = (m.returns if m && m.returns) || Task
|
|
21
|
+
|
|
22
|
+
if returns_model.kind_of?(Roby::TaskModelTag)
|
|
23
|
+
task = Roby::Task.new
|
|
24
|
+
task.extend returns_model
|
|
25
|
+
else
|
|
26
|
+
# Create an abstract task which will be planned
|
|
27
|
+
task = returns_model.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
planner = Roby::PlanningTask.new(:planner_model => planner_model, :method_name => name, :method_options => arguments)
|
|
31
|
+
task.planned_by planner
|
|
32
|
+
return task, planner
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.method_missing(name, *args)
|
|
36
|
+
if name.to_s =~ /!$/
|
|
37
|
+
name = $`.to_sym
|
|
38
|
+
else
|
|
39
|
+
super
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if args.size > 1
|
|
43
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1) in #{name}!"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
options = args.first || {}
|
|
47
|
+
task, planner = Robot.prepare_action(name, options)
|
|
48
|
+
Roby.plan.add_mission(task)
|
|
49
|
+
|
|
50
|
+
return task, planner
|
|
51
|
+
end
|
|
6
52
|
end
|
|
7
53
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Schedulers
|
|
3
|
+
class Basic
|
|
4
|
+
attr_reader :query
|
|
5
|
+
attr_reader :include_children
|
|
6
|
+
def initialize(include_children = false)
|
|
7
|
+
@include_children = include_children
|
|
8
|
+
@query = Roby.plan.find_tasks.
|
|
9
|
+
executable.
|
|
10
|
+
pending.
|
|
11
|
+
self_owned
|
|
12
|
+
end
|
|
13
|
+
def initial_events
|
|
14
|
+
for task in query.reset
|
|
15
|
+
if !(task.event(:start).root? && task.event(:start).controlable?)
|
|
16
|
+
next
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
root_task =
|
|
20
|
+
if task.root?(TaskStructure::Dependency)
|
|
21
|
+
true
|
|
22
|
+
else
|
|
23
|
+
task.planned_tasks.all? { |t| !t.executable? }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if root_task || (include_children && task.parents.any? { |t| t.running? })
|
|
27
|
+
task.start!
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
data/lib/roby/standard_errors.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'pp'
|
|
2
1
|
module Roby
|
|
3
2
|
# This kind of errors are generated during the plan execution, allowing to
|
|
4
3
|
# blame a fault on a plan object (#failure_point). The precise failure
|
|
@@ -76,6 +75,11 @@ module Roby
|
|
|
76
75
|
# Raised when a consistency check failed in the Roby propagation code
|
|
77
76
|
class PropagationError < InternalError; end
|
|
78
77
|
|
|
78
|
+
# Some operations need to be performed in the control thread, and some
|
|
79
|
+
# other (namely blocking operations) must not. This exception is raised
|
|
80
|
+
# when this constraint is not met.
|
|
81
|
+
class PhaseMismatch < RuntimeError; end
|
|
82
|
+
|
|
79
83
|
# Some operations need to be performed in the control thread, and some
|
|
80
84
|
# other (namely blocking operations) must not. This exception is raised
|
|
81
85
|
# when this constraint is not met.
|
|
@@ -136,21 +140,25 @@ module Roby
|
|
|
136
140
|
# Raised when an event has become unreachable while other parts of the plan
|
|
137
141
|
# where waiting for its emission.
|
|
138
142
|
class UnreachableEvent < LocalizedError
|
|
139
|
-
#
|
|
140
|
-
|
|
143
|
+
# Why did the generator become unreachable
|
|
144
|
+
attr_reader :reason
|
|
145
|
+
|
|
141
146
|
# Create an UnreachableEvent error for the given +generator+. +reason+
|
|
142
147
|
# is supposed to be either nil or a plan object which is the reason why
|
|
143
148
|
# +generator+ has become unreachable.
|
|
144
149
|
def initialize(generator, reason)
|
|
145
|
-
|
|
146
|
-
super(
|
|
150
|
+
@reason = reason
|
|
151
|
+
super(generator)
|
|
147
152
|
end
|
|
148
153
|
|
|
149
154
|
def pretty_print(pp) # :nodoc:
|
|
150
|
-
pp.text "#{
|
|
151
|
-
if
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
pp.text "#{failed_generator} has become unreachable"
|
|
156
|
+
if reason
|
|
157
|
+
reason = [*reason]
|
|
158
|
+
reason.each do |e|
|
|
159
|
+
pp.breakable
|
|
160
|
+
e.pretty_print(pp)
|
|
161
|
+
end
|
|
154
162
|
end
|
|
155
163
|
end
|
|
156
164
|
end
|
|
@@ -180,12 +188,10 @@ module Roby
|
|
|
180
188
|
attr_reader :from
|
|
181
189
|
# The task which should have replaced #from
|
|
182
190
|
attr_reader :to
|
|
183
|
-
# A description of the replacement failure
|
|
184
|
-
attr_reader :error
|
|
185
191
|
|
|
186
192
|
# Create a new InvalidReplace object
|
|
187
|
-
def initialize(from, to
|
|
188
|
-
@from, @to
|
|
193
|
+
def initialize(from, to)
|
|
194
|
+
@from, @to = from, to
|
|
189
195
|
end
|
|
190
196
|
def pretty_print(pp) # :nodoc:
|
|
191
197
|
pp.text "invalid replacement: #{message}"
|
|
@@ -202,7 +208,7 @@ module Roby
|
|
|
202
208
|
class MissionFailedError < LocalizedError
|
|
203
209
|
# Create a new MissionFailedError for the given mission
|
|
204
210
|
def initialize(task)
|
|
205
|
-
super(task.
|
|
211
|
+
super(task.failure_event || task)
|
|
206
212
|
end
|
|
207
213
|
|
|
208
214
|
def pretty_print(pp)
|
|
@@ -213,6 +219,6 @@ module Roby
|
|
|
213
219
|
|
|
214
220
|
# Exception raised in threads which are waiting for the control thread
|
|
215
221
|
# See for instance Roby.execute
|
|
216
|
-
class
|
|
222
|
+
class ExecutionQuitError < RuntimeError; end
|
|
217
223
|
end
|
|
218
224
|
|
data/lib/roby/state/events.rb
CHANGED
|
@@ -61,15 +61,16 @@ module Roby
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
# Registered on
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
# Registered on the execution engines to call the #poll method of state
|
|
65
|
+
# events
|
|
66
|
+
def self.poll_state_events(plan) # :nodoc:
|
|
67
|
+
for ev in plan.free_events
|
|
67
68
|
if ev.kind_of?(StateEvent) && ev.enabled?
|
|
68
69
|
ev.poll
|
|
69
70
|
end
|
|
70
71
|
end
|
|
71
72
|
end
|
|
72
|
-
Roby::
|
|
73
|
+
Roby::ExecutionEngine.propagation_handlers << Roby.method(:poll_state_events)
|
|
73
74
|
|
|
74
75
|
# A state event is an event which emits when some parameters over the state
|
|
75
76
|
# are reached. See DeltaEvent and TimePointEvent.
|
data/lib/roby/support.rb
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
require 'active_support/inflector'
|
|
2
|
-
class String # :nodoc: all
|
|
3
|
-
include ActiveSupport::CoreExtensions::String::Inflections
|
|
4
|
-
end
|
|
5
|
-
|
|
6
1
|
require 'roby/config'
|
|
2
|
+
require 'facets/string/camelcase'
|
|
3
|
+
require 'facets/string/snakecase'
|
|
7
4
|
require 'facets/kernel/constant'
|
|
8
5
|
require 'utilrb/enumerable'
|
|
9
6
|
require 'utilrb/time/to_hms'
|
|
@@ -45,11 +42,11 @@ module Enumerable
|
|
|
45
42
|
end
|
|
46
43
|
|
|
47
44
|
class Module
|
|
48
|
-
# Defines a new constant under a given module
|
|
49
45
|
# :call-seq
|
|
50
46
|
# define_under(name, value) -> value
|
|
51
47
|
# define_under(name) { ... } -> value
|
|
52
48
|
#
|
|
49
|
+
# Defines a new constant under a given module
|
|
53
50
|
# In the first form, the method gets its value from its argument.
|
|
54
51
|
# In the second case, it calls the provided block
|
|
55
52
|
def define_under(name, value = nil)
|
|
@@ -88,5 +85,109 @@ module Roby
|
|
|
88
85
|
|
|
89
86
|
extend Logger::Hierarchy
|
|
90
87
|
extend Logger::Forward
|
|
88
|
+
|
|
89
|
+
class Pool < Queue
|
|
90
|
+
def initialize(klass)
|
|
91
|
+
@klass = klass
|
|
92
|
+
super()
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def pop
|
|
96
|
+
value = super(true) rescue nil
|
|
97
|
+
value || @klass.new
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
@mutexes = Pool.new(Mutex)
|
|
102
|
+
@condition_variables = Pool.new(ConditionVariable)
|
|
103
|
+
class << self
|
|
104
|
+
# A pool of mutexes (as a Queue)
|
|
105
|
+
attr_reader :mutexes
|
|
106
|
+
# A pool of condition variables (as a Queue)
|
|
107
|
+
attr_reader :condition_variables
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# call-seq:
|
|
111
|
+
# condition_variable => cv
|
|
112
|
+
# condition_variable(true) => cv, mutex
|
|
113
|
+
# condition_variable { |cv| ... } => value returned by the block
|
|
114
|
+
# condition_variable(true) { |cv, mutex| ... } => value returned by the block
|
|
115
|
+
#
|
|
116
|
+
# Get a condition variable object from the Roby.condition_variables
|
|
117
|
+
# pool and, if mutex is not true, a Mutex object
|
|
118
|
+
#
|
|
119
|
+
# If a block is given, the two objects are yield and returned into the
|
|
120
|
+
# pool after the block has returned. In that case, the method returns
|
|
121
|
+
# the value returned by the block
|
|
122
|
+
def self.condition_variable(mutex = false)
|
|
123
|
+
cv = condition_variables.pop
|
|
124
|
+
|
|
125
|
+
if block_given?
|
|
126
|
+
begin
|
|
127
|
+
if mutex
|
|
128
|
+
mt = mutexes.pop
|
|
129
|
+
yield(cv, mt)
|
|
130
|
+
else
|
|
131
|
+
yield(cv)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
ensure
|
|
135
|
+
return_condition_variable(cv, mt)
|
|
136
|
+
end
|
|
137
|
+
else
|
|
138
|
+
if mutex
|
|
139
|
+
return cv, mutexes.pop
|
|
140
|
+
else
|
|
141
|
+
return cv
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Returns a ConditionVariable and optionally a Mutex into the
|
|
147
|
+
# Roby.condition_variables and Roby.mutexes pools
|
|
148
|
+
def self.return_condition_variable(cv, mutex = nil)
|
|
149
|
+
condition_variables.push cv
|
|
150
|
+
if mutex
|
|
151
|
+
mutexes.push mutex
|
|
152
|
+
end
|
|
153
|
+
nil
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
@global_lock = Mutex.new
|
|
157
|
+
class << self
|
|
158
|
+
# This Mutex object is locked during the event propagation loop, and
|
|
159
|
+
# unlock while this loop is sleeping. It is used to wait for the
|
|
160
|
+
# availability of the main plan.
|
|
161
|
+
attr_reader :global_lock
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def self.taken_global_lock?; Thread.current[:global_lock_taken] end
|
|
165
|
+
|
|
166
|
+
# Implements a recursive behaviour on Roby.mutex
|
|
167
|
+
def self.synchronize
|
|
168
|
+
if Thread.current[:global_lock_taken]
|
|
169
|
+
yield
|
|
170
|
+
else
|
|
171
|
+
global_lock.lock
|
|
172
|
+
begin
|
|
173
|
+
Thread.current[:global_lock_taken] = true
|
|
174
|
+
yield
|
|
175
|
+
ensure
|
|
176
|
+
Thread.current[:global_lock_taken] = false
|
|
177
|
+
global_lock.unlock
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class << self
|
|
183
|
+
attr_accessor :enable_deprecation_warnings
|
|
184
|
+
end
|
|
185
|
+
@enable_deprecation_warnings = true
|
|
186
|
+
|
|
187
|
+
def self.warn_deprecated(msg)
|
|
188
|
+
if enable_deprecation_warnings
|
|
189
|
+
Roby.warn "Deprecation Warning: #{msg} at #{caller[1]}"
|
|
190
|
+
end
|
|
191
|
+
end
|
|
91
192
|
end
|
|
92
193
|
|
data/lib/roby/task-operations.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'roby/task'
|
|
2
|
-
|
|
3
1
|
module Roby
|
|
4
2
|
module TaskOperations
|
|
5
3
|
def +(task)
|
|
@@ -60,31 +58,34 @@ module Roby
|
|
|
60
58
|
def to_task(task = nil)
|
|
61
59
|
return super() unless task
|
|
62
60
|
task = task.new unless task.kind_of?(Roby::Task)
|
|
63
|
-
@tasks.each { |t| task.
|
|
61
|
+
@tasks.each { |t| task.depends_on t }
|
|
64
62
|
|
|
65
|
-
task.
|
|
66
|
-
@tasks.last.
|
|
63
|
+
task.signals(:start, @tasks.first, :start)
|
|
64
|
+
@tasks.last.forward_to(:success, task, :success)
|
|
67
65
|
|
|
68
66
|
delete
|
|
69
67
|
|
|
70
68
|
task
|
|
71
69
|
end
|
|
70
|
+
def child_of(task = nil)
|
|
71
|
+
to_task(task)
|
|
72
|
+
end
|
|
72
73
|
|
|
73
74
|
def connect_start(task)
|
|
74
75
|
if old = @tasks.first
|
|
75
76
|
event(:start).remove_signal old.event(:start)
|
|
76
|
-
task.
|
|
77
|
+
task.signals(:success, old, :start)
|
|
77
78
|
end
|
|
78
79
|
|
|
79
|
-
event(:start).
|
|
80
|
+
event(:start).signals task.event(:start)
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
def connect_stop(task)
|
|
83
84
|
if old = @tasks.last
|
|
84
|
-
old.
|
|
85
|
+
old.signals(:success, task, :start)
|
|
85
86
|
old.event(:success).remove_forwarding event(:success)
|
|
86
87
|
end
|
|
87
|
-
task.
|
|
88
|
+
task.forward_to(:success, self, :success)
|
|
88
89
|
end
|
|
89
90
|
private :connect_stop, :connect_start
|
|
90
91
|
|
|
@@ -94,7 +95,7 @@ module Roby
|
|
|
94
95
|
connect_stop(task) if @tasks.empty?
|
|
95
96
|
|
|
96
97
|
@tasks.unshift(task)
|
|
97
|
-
|
|
98
|
+
depends_on task
|
|
98
99
|
self
|
|
99
100
|
end
|
|
100
101
|
|
|
@@ -104,7 +105,7 @@ module Roby
|
|
|
104
105
|
connect_stop(task)
|
|
105
106
|
|
|
106
107
|
@tasks << task
|
|
107
|
-
|
|
108
|
+
depends_on task
|
|
108
109
|
self
|
|
109
110
|
end
|
|
110
111
|
|
|
@@ -121,16 +122,19 @@ module Roby
|
|
|
121
122
|
super
|
|
122
123
|
|
|
123
124
|
@children_success = Roby::AndGenerator.new
|
|
124
|
-
@children_success.
|
|
125
|
+
@children_success.forward_to event(:success)
|
|
125
126
|
end
|
|
126
127
|
|
|
128
|
+
def child_of(task = nil)
|
|
129
|
+
to_task(task)
|
|
130
|
+
end
|
|
127
131
|
def to_task(task = nil)
|
|
128
132
|
return super() unless task
|
|
129
133
|
|
|
130
134
|
task = task.new unless task.kind_of?(Roby::Task)
|
|
131
135
|
@tasks.each do |t|
|
|
132
|
-
task.
|
|
133
|
-
task.
|
|
136
|
+
task.depends_on t
|
|
137
|
+
task.signals(:start, t, :start)
|
|
134
138
|
end
|
|
135
139
|
task.event(:success).emit_on children_success
|
|
136
140
|
|
|
@@ -143,8 +147,8 @@ module Roby
|
|
|
143
147
|
raise "trying to change a running parallel task" if running?
|
|
144
148
|
@tasks << task
|
|
145
149
|
|
|
146
|
-
|
|
147
|
-
|
|
150
|
+
signals(:start, task, :start)
|
|
151
|
+
depends_on task
|
|
148
152
|
children_success << task.event(:success)
|
|
149
153
|
|
|
150
154
|
self
|
|
@@ -162,10 +166,10 @@ module Roby
|
|
|
162
166
|
|
|
163
167
|
success = AndGenerator.new
|
|
164
168
|
tasks.each do |task|
|
|
165
|
-
|
|
166
|
-
task.event(:success).
|
|
169
|
+
depends_on task
|
|
170
|
+
task.event(:success).signals success
|
|
167
171
|
end
|
|
168
|
-
success.
|
|
172
|
+
success.forward_to event(:success)
|
|
169
173
|
end
|
|
170
174
|
|
|
171
175
|
event :start do
|