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
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
io = STDOUT
|
|
6
|
+
common = false
|
|
7
|
+
parser = OptionParser.new do |opt|
|
|
8
|
+
opt.on("--common") { common = true }
|
|
9
|
+
opt.on("--error") { exit(1) }
|
|
10
|
+
opt.on("--stderr") { io = STDERR }
|
|
11
|
+
opt.on("--no-output") { io = nil }
|
|
12
|
+
opt.on("--block") do
|
|
13
|
+
sleep
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
parser.parse! ARGV
|
|
17
|
+
|
|
18
|
+
if common
|
|
19
|
+
STDOUT.puts "O: FIRST LINE"
|
|
20
|
+
STDERR.puts "E: FIRST LINE"
|
|
21
|
+
STDOUT.puts "O: SECOND LINE"
|
|
22
|
+
STDERR.puts "E: SECOND LINE"
|
|
23
|
+
|
|
24
|
+
elsif io
|
|
25
|
+
io.puts "FIRST LINE"
|
|
26
|
+
io.puts "SECOND LINE"
|
|
27
|
+
end
|
|
28
|
+
exit 0
|
data/test/planning/test_loops.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
3
|
require 'roby/planning'
|
|
4
4
|
|
|
@@ -8,6 +8,7 @@ require 'roby/test/tasks/simple_task'
|
|
|
8
8
|
class TC_PlanningLoop < Test::Unit::TestCase
|
|
9
9
|
include Roby::Planning
|
|
10
10
|
include Roby::Test
|
|
11
|
+
include Roby::Test::Assertions
|
|
11
12
|
|
|
12
13
|
# The planner model
|
|
13
14
|
attr_reader :planner_model
|
|
@@ -19,6 +20,7 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
19
20
|
|
|
20
21
|
def setup
|
|
21
22
|
super
|
|
23
|
+
Roby.app.filter_backtraces = false
|
|
22
24
|
|
|
23
25
|
task_model = @task_model = Class.new(SimpleTask)
|
|
24
26
|
pattern_id = 0
|
|
@@ -33,7 +35,8 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
33
35
|
:planning_owners => nil,
|
|
34
36
|
:planner_model => planner_model,
|
|
35
37
|
:planned_model => SimpleTask,
|
|
36
|
-
:
|
|
38
|
+
:planning_method => "task",
|
|
39
|
+
:method_name => 'task',
|
|
37
40
|
:method_options => {} }
|
|
38
41
|
end
|
|
39
42
|
|
|
@@ -44,7 +47,7 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
44
47
|
|
|
45
48
|
# Prepare the default plan for all planning loop tests
|
|
46
49
|
def prepare_plan(loop_options = {})
|
|
47
|
-
plan.
|
|
50
|
+
plan.add_mission(main_task = Roby::Task.new)
|
|
48
51
|
loop_task_options = planning_task_options.merge(loop_options)
|
|
49
52
|
loop_planner = PlanningLoop.new(loop_task_options)
|
|
50
53
|
main_task.planned_by loop_planner
|
|
@@ -52,6 +55,11 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
52
55
|
return main_task, loop_planner
|
|
53
56
|
end
|
|
54
57
|
|
|
58
|
+
def wait_for_planning_end(planning_task)
|
|
59
|
+
planning_task.thread.join
|
|
60
|
+
process_events
|
|
61
|
+
end
|
|
62
|
+
|
|
55
63
|
# Waits for +planning_task+ to finish and returns the planned result
|
|
56
64
|
def planning_task_result(planning_task)
|
|
57
65
|
assert(planning_task)
|
|
@@ -214,92 +222,126 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
214
222
|
|
|
215
223
|
# Test periodic loop tasks with zero lookahead
|
|
216
224
|
def test_periodic_zero_lookahead
|
|
217
|
-
|
|
218
|
-
|
|
225
|
+
FlexMock.use(Time) do |time_proxy|
|
|
226
|
+
current_time = Time.now + 5
|
|
227
|
+
time_proxy.should_receive(:now).and_return { current_time }
|
|
219
228
|
|
|
220
|
-
|
|
221
|
-
|
|
229
|
+
main_task, loop_planner = prepare_plan :period => 0.5, :lookahead => 0
|
|
230
|
+
loop_planner.start!
|
|
222
231
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
assert_equal(1, loop_planner.patterns.size)
|
|
226
|
-
first_planner = loop_planner.last_planning_task
|
|
227
|
-
first_task = planning_task_result(first_planner)
|
|
228
|
-
assert_equal(1, first_task.arguments[:id])
|
|
232
|
+
# Zero lookahead: no children until we call #loop_start!
|
|
233
|
+
assert(main_task.children.empty?)
|
|
229
234
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
sleep(0.6)
|
|
237
|
-
process_events
|
|
238
|
-
assert_equal(2, main_task.children.to_a.size)
|
|
239
|
-
assert(second_planner = loop_planner.last_planning_task)
|
|
240
|
-
assert(second_planner.running?)
|
|
241
|
-
second_task = planning_task_result(second_planner)
|
|
242
|
-
assert(second_task.running?)
|
|
243
|
-
assert_equal(1, main_task.children.to_a.size)
|
|
244
|
-
|
|
245
|
-
# And queue one other. The second call to #loop_start! should be
|
|
246
|
-
# completely ignored because there is already one pending pattern.
|
|
247
|
-
loop_planner.loop_start!(:id => 3)
|
|
248
|
-
loop_planner.loop_start!(:id => 4)
|
|
249
|
-
assert_equal(2, main_task.children.to_a.size)
|
|
250
|
-
third_planner = loop_planner.last_planning_task
|
|
251
|
-
third_task = planning_task_result(third_planner)
|
|
252
|
-
assert_equal(3, third_task.arguments[:id])
|
|
235
|
+
# Start a first pattern
|
|
236
|
+
loop_planner.loop_start!(:id => 1)
|
|
237
|
+
assert_equal(1, loop_planner.patterns.size)
|
|
238
|
+
first_planner = loop_planner.last_planning_task
|
|
239
|
+
first_task = planning_task_result(first_planner)
|
|
240
|
+
assert_equal(1, first_task.arguments[:id])
|
|
253
241
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
242
|
+
# Check the normal behaviour: a new pattern is to be added only when
|
|
243
|
+
# the first pattern has finished AND the period has occured.
|
|
244
|
+
assert(first_task.running?)
|
|
245
|
+
assert_equal([first_task], main_task.children.to_a)
|
|
246
|
+
first_task.success!
|
|
247
|
+
assert_equal([first_task], main_task.children.to_a)
|
|
248
|
+
current_time += 0.6
|
|
249
|
+
process_events
|
|
250
|
+
second_proxy_task = main_task.children.to_a.first
|
|
251
|
+
assert(second_proxy_task != first_task)
|
|
252
|
+
assert_equal(1, main_task.children.to_a.size)
|
|
253
|
+
assert(second_planner = loop_planner.last_planning_task)
|
|
254
|
+
assert(second_planner.running?)
|
|
255
|
+
second_task = planning_task_result(second_planner)
|
|
256
|
+
assert(second_task.running?)
|
|
257
|
+
assert_equal([second_task], main_task.children.to_a)
|
|
258
|
+
|
|
259
|
+
# And queue one other. The second call to #loop_start! should be
|
|
260
|
+
# completely ignored because there is already one pending pattern.
|
|
261
|
+
loop_planner.loop_start!(:id => 3)
|
|
262
|
+
loop_planner.loop_start!(:id => 4)
|
|
263
|
+
assert_equal(2, main_task.children.to_a.size)
|
|
264
|
+
assert(main_task.children.to_a.include?(second_task))
|
|
265
|
+
third_planner = loop_planner.last_planning_task
|
|
266
|
+
third_task = planning_task_result(third_planner)
|
|
267
|
+
assert_equal(3, third_task.arguments[:id])
|
|
268
|
+
assert_equal([second_task, third_task].to_value_set, main_task.children.to_value_set)
|
|
269
|
+
|
|
270
|
+
# Check the dynamic behaviour
|
|
271
|
+
# - the 3rd task should start as soon as the 2nd has: the call to
|
|
272
|
+
# #loop_start! should have done that for us.
|
|
273
|
+
assert(second_task.running?)
|
|
274
|
+
assert(third_task.pending?)
|
|
275
|
+
second_task.success!
|
|
276
|
+
assert(second_task.success?)
|
|
277
|
+
process_events
|
|
278
|
+
assert_equal([third_task], main_task.children.to_a)
|
|
279
|
+
assert(third_task.running?)
|
|
280
|
+
third_task.success!
|
|
281
|
+
assert(third_task.success?)
|
|
282
|
+
end
|
|
264
283
|
end
|
|
265
284
|
|
|
266
285
|
def test_reinit_periodic
|
|
286
|
+
Roby.app.abort_on_exception = false
|
|
267
287
|
main_task, loop_planner = prepare_plan :period => 0.5, :lookahead => 3
|
|
268
288
|
|
|
269
|
-
FlexMock.use do |
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
289
|
+
FlexMock.use(Time) do |time_proxy|
|
|
290
|
+
current_time = Time.now + 5
|
|
291
|
+
time_proxy.should_receive(:now).and_return { current_time }
|
|
292
|
+
FlexMock.use do |mock|
|
|
293
|
+
mock.should_receive(:started).twice
|
|
294
|
+
task_model.on(:start) { mock.started }
|
|
295
|
+
|
|
296
|
+
loop_planner.start!
|
|
297
|
+
planners = loop_planner.patterns.reverse.map { |t, _| t }
|
|
298
|
+
tasks = planners.map { |p| planning_task_result(p) }
|
|
299
|
+
assert_equal 3, tasks.size
|
|
300
|
+
assert_equal tasks.to_value_set, main_task.children.to_value_set
|
|
301
|
+
|
|
302
|
+
loop_planner.loop_start!
|
|
303
|
+
assert(tasks[0].running?)
|
|
304
|
+
# First task is started, one pattern should be planning for the
|
|
305
|
+
# sake of the lookahead
|
|
306
|
+
assert_equal 1, (main_task.children.to_value_set - tasks.to_value_set).size
|
|
307
|
+
assert_equal 4, loop_planner.patterns.size
|
|
308
|
+
|
|
309
|
+
current_planning_task = loop_planner.patterns.first.first
|
|
310
|
+
original_patterns = loop_planner.patterns.dup
|
|
311
|
+
|
|
312
|
+
# reinit should remove all children and recreate the structure
|
|
313
|
+
# for three patterns
|
|
314
|
+
loop_planner.reinit!
|
|
315
|
+
process_events
|
|
316
|
+
assert(!loop_planner.event(:reinit).happened?)
|
|
317
|
+
assert(tasks[0].running?)
|
|
318
|
+
process_events
|
|
319
|
+
assert(!tasks[0].running?)
|
|
320
|
+
# if we're lucky, the planning task is not finished yet and
|
|
321
|
+
# therefore the loop planner should not have emitted :reinit yet
|
|
322
|
+
# either
|
|
323
|
+
if current_planning_task.running?
|
|
324
|
+
wait_for_planning_end current_planning_task
|
|
325
|
+
assert(loop_planner.reinit_event.last.time >= current_planning_task.stop_event.last.time)
|
|
326
|
+
end
|
|
327
|
+
# Wait for the planning task to finish if it is not yet finished
|
|
328
|
+
assert_equal 3, (loop_planner.patterns - original_patterns).size
|
|
329
|
+
assert_equal 3, loop_planner.patterns.size
|
|
330
|
+
assert_equal 3, main_task.children.to_a.size
|
|
331
|
+
assert_equal 3, (main_task.children.to_value_set - tasks.to_value_set).size
|
|
332
|
+
|
|
333
|
+
new_planners = loop_planner.patterns.reverse.map { |t, _| t }
|
|
334
|
+
new_tasks = new_planners.map { |p| planning_task_result(p) }
|
|
335
|
+
|
|
336
|
+
new_tasks.each do |t|
|
|
337
|
+
assert(!tasks.include?(t))
|
|
338
|
+
end
|
|
339
|
+
# ... but the first pattern should be GCed right now, and the next
|
|
340
|
+
# pattern started
|
|
341
|
+
process_events
|
|
342
|
+
assert(new_tasks[0].running?)
|
|
296
343
|
end
|
|
297
|
-
|
|
298
|
-
# ... but the first pattern should be GCed right now, and the next
|
|
299
|
-
# pattern started
|
|
300
|
-
process_events
|
|
301
|
-
assert(new_tasks[0].running?)
|
|
302
|
-
end
|
|
344
|
+
end
|
|
303
345
|
end
|
|
304
346
|
|
|
305
347
|
#def test_planning_loop_reinit_zero_lookahead
|
|
@@ -311,7 +353,7 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
311
353
|
# end
|
|
312
354
|
# end
|
|
313
355
|
|
|
314
|
-
# plan.
|
|
356
|
+
# plan.add_mission(main_task = Roby::Task.new)
|
|
315
357
|
# loop_planner = PlanningLoop.new :period => nil, :lookahead => 0,
|
|
316
358
|
# :planner_model => planner_model, :planned_model => Roby::Task,
|
|
317
359
|
# :method_name => :task, :method_options => {}
|
|
@@ -342,47 +384,49 @@ class TC_PlanningLoop < Test::Unit::TestCase
|
|
|
342
384
|
# end
|
|
343
385
|
#end
|
|
344
386
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
387
|
+
def test_make_loop
|
|
388
|
+
planner_model = Class.new(Planning::Planner) do
|
|
389
|
+
include Test::Unit::Assertions
|
|
390
|
+
|
|
391
|
+
@result_task = nil
|
|
392
|
+
attr_reader :result_task
|
|
393
|
+
method(:task) { @result_task = SimpleTask.new(:id => arguments[:task_id])}
|
|
394
|
+
method(:looping_tasks) do
|
|
395
|
+
t1 = make_loop(:period => 0, :child_argument => 2) do
|
|
396
|
+
# arguments of 'my_looping_task' shall be forwarded
|
|
397
|
+
raise unless arguments[:parent_argument] == 1
|
|
398
|
+
raise unless arguments[:child_argument] == 2
|
|
399
|
+
task(:task_id => 'first_loop')
|
|
400
|
+
end
|
|
401
|
+
t2 = make_loop do
|
|
402
|
+
task(:task_id => 'second_loop')
|
|
403
|
+
end
|
|
404
|
+
# Make sure the two loops are different
|
|
405
|
+
assert(t1.method_options[:id] != t2.method_options[:id])
|
|
406
|
+
[t1, t2]
|
|
407
|
+
end
|
|
408
|
+
end
|
|
367
409
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
410
|
+
planner = planner_model.new(plan)
|
|
411
|
+
t1, t2 = planner.looping_tasks(:parent_argument => 1)
|
|
412
|
+
assert(t1.fully_instanciated?, t1.arguments.keys - t1.class.arguments.to_a)
|
|
413
|
+
assert(t2.fully_instanciated?)
|
|
414
|
+
plan.add_mission(t1)
|
|
415
|
+
plan.add_mission(t2)
|
|
372
416
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
417
|
+
t1.start!
|
|
418
|
+
planned_task = planning_task_result(t1.last_planning_task)
|
|
419
|
+
assert_equal('first_loop', planned_task.arguments[:id])
|
|
376
420
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
421
|
+
t2.start!
|
|
422
|
+
planned_task = planning_task_result(t2.last_planning_task)
|
|
423
|
+
assert_equal('second_loop', planned_task.arguments[:id])
|
|
380
424
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
425
|
+
t3 = planner.make_loop(:period => 0, :parent_argument => 1, :child_argument => 2) do
|
|
426
|
+
task(:task_id => 'third_loop')
|
|
427
|
+
end
|
|
428
|
+
plan.add_mission(t3)
|
|
429
|
+
t3.start!
|
|
430
|
+
assert_equal('third_loop', planning_task_result(t3.last_planning_task).arguments[:id])
|
|
431
|
+
end
|
|
388
432
|
end
|
data/test/planning/test_model.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
3
|
require 'roby/planning'
|
|
4
4
|
|
|
@@ -115,7 +115,7 @@ class TC_Planner < Test::Unit::TestCase
|
|
|
115
115
|
planner = model.new(plan)
|
|
116
116
|
assert_raises(NotFound) { planner.empty_set }
|
|
117
117
|
|
|
118
|
-
plan.
|
|
118
|
+
plan.add_mission(task = task_model.new)
|
|
119
119
|
found_task = nil
|
|
120
120
|
assert_nothing_raised { found_task = planner.empty_set }
|
|
121
121
|
assert_equal(found_task, task)
|
|
@@ -126,7 +126,7 @@ class TC_Planner < Test::Unit::TestCase
|
|
|
126
126
|
planner = planner_model.new(plan)
|
|
127
127
|
result = planner.send(method, options)
|
|
128
128
|
result.each do |task|
|
|
129
|
-
planner.plan.
|
|
129
|
+
planner.plan.add_mission(task)
|
|
130
130
|
end
|
|
131
131
|
assert_equal(size, planner.plan.size, planner.plan.known_tasks.to_a.inspect)
|
|
132
132
|
|
data/test/planning/test_task.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
3
|
require 'roby/planning'
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ class TC_PlanningTask < Test::Unit::TestCase
|
|
|
11
11
|
|
|
12
12
|
def planning_task_result(planning_task)
|
|
13
13
|
assert(planning_task)
|
|
14
|
-
plan.
|
|
14
|
+
plan.add_permanent(planning_task)
|
|
15
15
|
planning_task.start! if planning_task.pending?
|
|
16
16
|
planning_task.thread.join
|
|
17
17
|
process_events
|
|
@@ -33,7 +33,7 @@ class TC_PlanningTask < Test::Unit::TestCase
|
|
|
33
33
|
planning_task = PlanningTask.new(:planner_model => planner, :method_name => :task,
|
|
34
34
|
:method_options => { :bla => 42 },
|
|
35
35
|
:blo => 84)
|
|
36
|
-
plan.
|
|
36
|
+
plan.add_mission(planned_task = Task.new)
|
|
37
37
|
planned_task.planned_by planning_task
|
|
38
38
|
|
|
39
39
|
planning_task.start!(42)
|
|
@@ -67,7 +67,7 @@ class TC_PlanningTask < Test::Unit::TestCase
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
planning_task = PlanningTask.new(:planner_model => planner, :method_name => :interruptible)
|
|
70
|
-
plan.
|
|
70
|
+
plan.add_permanent(planning_task)
|
|
71
71
|
planning_task.start!
|
|
72
72
|
loop { sleep 0.1 ; break if started }
|
|
73
73
|
planning_task.stop!
|
|
@@ -85,13 +85,13 @@ class TC_PlanningTask < Test::Unit::TestCase
|
|
|
85
85
|
planner = Class.new(Planning::Planner) do
|
|
86
86
|
method(:test_task) do
|
|
87
87
|
result_task = SimpleTask.new(:id => arguments[:task_id])
|
|
88
|
-
result_task.
|
|
89
|
-
plan.
|
|
88
|
+
result_task.depends_on replan_task(:task_id => arguments[:task_id] + 1)
|
|
89
|
+
plan.add_permanent(result_task)
|
|
90
90
|
result_task
|
|
91
91
|
end
|
|
92
92
|
end.new(plan)
|
|
93
93
|
|
|
94
|
-
plan.
|
|
94
|
+
plan.add_permanent(task = planner.test_task(:task_id => 100))
|
|
95
95
|
assert_kind_of(SimpleTask, task)
|
|
96
96
|
assert_equal(100, task.arguments[:id])
|
|
97
97
|
|
|
@@ -103,4 +103,24 @@ class TC_PlanningTask < Test::Unit::TestCase
|
|
|
103
103
|
assert_kind_of(SimpleTask, new_task, planning_task)
|
|
104
104
|
assert_equal(101, new_task.arguments[:id])
|
|
105
105
|
end
|
|
106
|
+
|
|
107
|
+
def test_method_object
|
|
108
|
+
planner_model = Class.new(Planning::Planner)
|
|
109
|
+
|
|
110
|
+
FlexMock.use do |mock|
|
|
111
|
+
mock.should_receive(:method_called).with(:context => nil, :arg => 10).once
|
|
112
|
+
|
|
113
|
+
body = lambda do
|
|
114
|
+
mock.method_called(arguments)
|
|
115
|
+
Roby::Task.new(:id => 'result_of_lambda')
|
|
116
|
+
end
|
|
117
|
+
m = FreeMethod.new 'test_object', {:id => 10}, body
|
|
118
|
+
planning_task = PlanningTask.new(:planner_model => planner_model, :planning_method => m, :arg => 10)
|
|
119
|
+
plan.add_permanent(planning_task)
|
|
120
|
+
planning_task.start!
|
|
121
|
+
new_task = planning_task_result(planning_task)
|
|
122
|
+
assert_equal 'result_of_lambda', new_task.arguments[:id]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
106
125
|
end
|
|
126
|
+
|