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/bin/roby
CHANGED
data/bin/roby-log
CHANGED
|
@@ -75,13 +75,24 @@ when "stats"
|
|
|
75
75
|
filename = if ARGV[0] == "--csv"
|
|
76
76
|
do_csv = true
|
|
77
77
|
ARGV[1]
|
|
78
|
-
|
|
78
|
+
elsif ARGV[0] == "--help"
|
|
79
|
+
puts "roby-log stats [--csv]"
|
|
80
|
+
puts " displays statistics about the execution timings"
|
|
81
|
+
puts " if the --csv option is given, a table with all"
|
|
82
|
+
puts " the timings is output on stdout instead"
|
|
83
|
+
exit(0)
|
|
84
|
+
else
|
|
79
85
|
ARGV[0]
|
|
80
86
|
end
|
|
81
87
|
io = Roby::Log.open(filename)
|
|
82
88
|
|
|
83
89
|
cycle_count = io.index_data.size
|
|
84
|
-
|
|
90
|
+
timespan = io.range
|
|
91
|
+
puts "#{cycle_count} cycles between #{timespan.first.to_hms} and #{timespan.last.to_hms}"
|
|
92
|
+
cpu_time = io.index_data.inject(0) { |old, info| old + info[:cpu_time] } / 1000
|
|
93
|
+
real_time = timespan.last - timespan.first
|
|
94
|
+
ratio = cpu_time / real_time
|
|
95
|
+
puts "Time: %.2fs CPU / %.2fs real (%i%% CPU use)" % [cpu_time, real_time, ratio * 100]
|
|
85
96
|
|
|
86
97
|
if io.index_data.first.has_key?(:event_count)
|
|
87
98
|
min, max = nil
|
|
@@ -116,13 +127,12 @@ when "replay"
|
|
|
116
127
|
stream.open
|
|
117
128
|
main.add_stream(stream)
|
|
118
129
|
end
|
|
119
|
-
else
|
|
120
|
-
STDERR.puts parser
|
|
121
|
-
exit(0)
|
|
122
130
|
end
|
|
123
131
|
else
|
|
124
132
|
remaining.each do |file|
|
|
125
|
-
|
|
133
|
+
if !File.exists?(file)
|
|
134
|
+
STDERR.puts "WARN: #{file} does not exist"
|
|
135
|
+
elsif streams = Roby.app.data_streams_of([file])
|
|
126
136
|
streams.each do |s|
|
|
127
137
|
s.open
|
|
128
138
|
main.add_stream(s)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# This is the YAML configuration file for webgen used to set configuration options.
|
|
2
|
+
#
|
|
3
|
+
# The general syntax is:
|
|
4
|
+
#
|
|
5
|
+
# configuration.option.name: value
|
|
6
|
+
#
|
|
7
|
+
# For example, to set a different default language, you would do:
|
|
8
|
+
#
|
|
9
|
+
# website.lang: de
|
|
10
|
+
#
|
|
11
|
+
# Have a look at the documentation of the individual configuration options to see
|
|
12
|
+
# the allowed format of the values. Since this is a YAML file, you can easily set
|
|
13
|
+
# configuration options to strings, integers, dates, arrays, hashes and more.
|
|
14
|
+
#
|
|
15
|
+
# The available configuration options can be listed using the `webgen config`
|
|
16
|
+
# command, for example: `webgen config sourcehandler` will list all options starting
|
|
17
|
+
# with sourcehandler.
|
|
18
|
+
default_processing_pipeline:
|
|
19
|
+
Page: rdoc,tags,blocks
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
default_meta_info:
|
|
23
|
+
Webgen::SourceHandler::Page:
|
|
24
|
+
in_menu: true
|
|
25
|
+
|
|
26
|
+
tag.menu.nested: false
|
|
27
|
+
|
|
28
|
+
tag.breadcrumbtrail.omit_index_path: true
|
|
29
|
+
|
|
30
|
+
rdoclinks.base_url: /api
|
|
31
|
+
rdoclinks.base_module: Roby
|
|
32
|
+
|
|
33
|
+
tag.coderay.line_numbers: false
|
|
34
|
+
tag.coderay.lang: ruby
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# = webgen extensions directory
|
|
2
|
+
#
|
|
3
|
+
# All init.rb files anywhere under this directory get automatically loaded on a webgen run. This
|
|
4
|
+
# allows you to add your own extensions to webgen or to modify webgen's core!
|
|
5
|
+
#
|
|
6
|
+
# If you don't need this feature you can savely delete this file and the directory in which it is!
|
|
7
|
+
#
|
|
8
|
+
# The +config+ variable below can be used to access the Webgen::Configuration object for the current
|
|
9
|
+
# website.
|
|
10
|
+
config = Webgen::WebsiteAccess.website.config
|
|
11
|
+
|
|
12
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
13
|
+
require 'ext/rdoc_links'
|
|
14
|
+
require 'ext/previous_next'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'webgen/tag'
|
|
2
|
+
class PrevNextTag
|
|
3
|
+
include Webgen::Tag::Base
|
|
4
|
+
|
|
5
|
+
def call(tag, body, context)
|
|
6
|
+
node = context.content_node
|
|
7
|
+
while !node.is_file?
|
|
8
|
+
node = node.parent
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
siblings = node.parent.children.sort
|
|
12
|
+
siblings.delete_if { |n| !n.meta_info['in_menu'] }
|
|
13
|
+
prev, _ = siblings.
|
|
14
|
+
enum_for(:each_cons, 2).
|
|
15
|
+
find { |prev, this| this == node }
|
|
16
|
+
_, nxt = siblings.
|
|
17
|
+
enum_for(:each_cons, 2).
|
|
18
|
+
find { |this, nxt| this == node }
|
|
19
|
+
|
|
20
|
+
content = if tag == "next" && nxt
|
|
21
|
+
node.link_to(nxt)
|
|
22
|
+
elsif tag == "previous" && prev
|
|
23
|
+
node.link_to(prev)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if content
|
|
27
|
+
if !body.empty?
|
|
28
|
+
body.gsub '%', content
|
|
29
|
+
else
|
|
30
|
+
content
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
config = Webgen::WebsiteAccess.website.config
|
|
37
|
+
config['contentprocessor.tags.map']['previous'] = 'PrevNextTag'
|
|
38
|
+
config['contentprocessor.tags.map']['next'] = 'PrevNextTag'
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'webgen/tag'
|
|
2
|
+
class RdocLinks
|
|
3
|
+
include Webgen::Tag::Base
|
|
4
|
+
|
|
5
|
+
def call(tag, body, context)
|
|
6
|
+
name = param('rdoclinks.name')
|
|
7
|
+
if base_module = param('rdoclinks.base_module')
|
|
8
|
+
name = base_module + "::" + name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
if name =~ /(?:\.|#)(\w+)$/
|
|
12
|
+
class_name = $`
|
|
13
|
+
method_name = $1
|
|
14
|
+
else
|
|
15
|
+
class_name = name
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
path = class_name.split('::')
|
|
19
|
+
path[-1] += ".html"
|
|
20
|
+
url = "#{param('rdoclinks.base_url')}/#{path.join("/")}"
|
|
21
|
+
|
|
22
|
+
"<a href=\"#{context.ref_node.route_to(url)}\">#{param('rdoclinks.name')}</a>"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
config = Webgen::WebsiteAccess.website.config
|
|
27
|
+
config.rdoclinks.name "", :mandatory => 'default'
|
|
28
|
+
config.rdoclinks.base_webgen "", :mandatory => false
|
|
29
|
+
config.rdoclinks.base_url "", :mandatory => false
|
|
30
|
+
config.rdoclinks.base_module nil, :mandatory => false
|
|
31
|
+
config.rdoclinks.full_name false, :mandatory => false
|
|
32
|
+
config['contentprocessor.tags.map']['rdoc_class'] = 'RdocLinks'
|
|
33
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
= Roby's User's Guide
|
|
2
|
+
|
|
3
|
+
This guide is *definitely* a work in progress -- actually it is for now an
|
|
4
|
+
embryo of a user's guide, but things should improve ...
|
|
5
|
+
|
|
6
|
+
For people which want to extend Roby, see {this
|
|
7
|
+
guide}[link:files/doc/extending/index_rdoc.html]
|
|
8
|
+
|
|
9
|
+
== Table of Contents
|
|
10
|
+
|
|
11
|
+
* {Table of Contents}[link:files/doc/using/index_rdoc.html]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
* {Overview}[link:files/doc/using/overview_rdoc.html]
|
|
15
|
+
* {Plan modifications}[link:files/doc/using/plan_modifications_rdoc.html]
|
|
16
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
= Overview
|
|
2
|
+
|
|
3
|
+
This page describes the various components that form a Roby application. It is
|
|
4
|
+
meant to be an "entry point" for people to understand what classes are there
|
|
5
|
+
for. This describes the software architecture of the upcoming v0.8.
|
|
6
|
+
|
|
7
|
+
== Life and death of a Roby Controller
|
|
8
|
+
|
|
9
|
+
One Roby::Application instance is created per Roby controller. This class sets
|
|
10
|
+
up the various central objects (Roby::Plan, Roby::ExecutionEngine and Roby::DecisionControl, see
|
|
11
|
+
below), starts the execution engine and loads the relevant configuration files.
|
|
12
|
+
|
|
13
|
+
A Roby controller offers a DRb main server which is a Roby::Interface instance.
|
|
14
|
+
The best way to interact through this channel is to use a Roby::RemoteInterface
|
|
15
|
+
instance, which handles some custom marshalling/demarshalling of data, offering
|
|
16
|
+
a transparent interface to the remote controller. The <tt>scripts/shell</tt>
|
|
17
|
+
default script sets this up properly.
|
|
18
|
+
|
|
19
|
+
A Roby controller will shut down in the following conditions:
|
|
20
|
+
* CTRL+C is hit in the controller's main terminal
|
|
21
|
+
* the 'exit' command is sent through the remote shell
|
|
22
|
+
* a framework exception is detected, meaning an exception which is not part of
|
|
23
|
+
the plan-based error recovery mechanism (everything but event commands, event
|
|
24
|
+
handlers and polling blocks).
|
|
25
|
+
|
|
26
|
+
== Plan execution
|
|
27
|
+
|
|
28
|
+
The plan representation and the plan execution is handled by three objects:
|
|
29
|
+
* a Roby::Plan object which manages the various tasks and events which describe the
|
|
30
|
+
system's plan.
|
|
31
|
+
* an Roby::ExecutionEngine object which manipulates that Roby::Plan object. It propagates
|
|
32
|
+
events according to a set of "initial event", a set of events that are
|
|
33
|
+
considered to be emitted. They can be generated by external communication (for
|
|
34
|
+
instance from external robotic control frameworks like GenoM or Orocos), or
|
|
35
|
+
internally by the scheduler object (see ExecutionEngine#scheduler). The engine
|
|
36
|
+
is also responsible for reaction to errors and for the garbage collection
|
|
37
|
+
mechanism, through which tasks that are useless for the system's goals are
|
|
38
|
+
automatically killed and removed.
|
|
39
|
+
* a Roby::DecisionControl object which handles runtime error resolution (i.e.
|
|
40
|
+
situations which require choosing between multiple course of action). For
|
|
41
|
+
instance, if a signal leads to a task conflict -- i.e. if the signal would
|
|
42
|
+
start a task which conflicts with another task -- the DecisionControl#conflict
|
|
43
|
+
method is called. The default policy is to postpone starting the new task
|
|
44
|
+
until all the conflicting tasks are stopped. Other policies could be to raise
|
|
45
|
+
an error for instance.
|
|
46
|
+
|
|
47
|
+
The three "main" instances of these objects -- i.e. the ones that are supposed
|
|
48
|
+
to interact directly with the underlying robotic system -- are available
|
|
49
|
+
through the Roby.plan, Roby.engine and Roby.control attributes. These
|
|
50
|
+
attributes are set up at application start by Roby::Application#run (see below).
|
|
51
|
+
This is for an easy access in the main controller, but the architecture allows
|
|
52
|
+
to run multiple plans in parallel by binding those three different objects
|
|
53
|
+
yourself.
|
|
54
|
+
|
|
55
|
+
== A note about multi-robot systems
|
|
56
|
+
|
|
57
|
+
Until now, the Roby plan manager is able to run <b>bi-robot</b> plans, i.e.
|
|
58
|
+
plans where only two robots are interacting with each other. Extending that to
|
|
59
|
+
multi-robot is definitely on the TODO list of the project, but unfortunately it
|
|
60
|
+
will wait until multi-robot is back at the the center of my research. If you are
|
|
61
|
+
interested in doing it, of course, feel free to contact me ;-)
|
|
62
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
= Plan representation and modifications to plans
|
|
2
|
+
|
|
3
|
+
Understanding the plan model, and how to modify it, is central to the use of
|
|
4
|
+
Roby. In effect, the plan *is* the information on which the controller bases
|
|
5
|
+
itself to control the robot ...
|
|
6
|
+
|
|
7
|
+
== Plan objects
|
|
8
|
+
In Roby, plans are made of tasks and events. See {my
|
|
9
|
+
papers}[link:files/doc/papers_rdoc.html] for an in-depth description of the
|
|
10
|
+
model.
|
|
11
|
+
|
|
12
|
+
On the one hand, Roby::EventGenerator instances represent the plan's _possible_
|
|
13
|
+
events. This is by contrast to the Roby::Event class, whose instances represent
|
|
14
|
+
the <em>actual events</em>. In other words, an Event instance represent an
|
|
15
|
+
event which has already been emitted while an EventGenerator instance
|
|
16
|
+
represents a source of events, therefore a kind of events that could possibly
|
|
17
|
+
be emitted.
|
|
18
|
+
|
|
19
|
+
On the other hand, instances of Roby::Task represent the activities of the
|
|
20
|
+
system. Special subclasses of Roby::EventGenerator and Roby::Event are used in
|
|
21
|
+
tasks, to represent some particular properties of task's events:
|
|
22
|
+
Roby::TaskEventGenerator and Roby::TaskEvent.
|
|
23
|
+
|
|
24
|
+
== Plan relations
|
|
25
|
+
Roby::EventGenerator instances can be linked to each other through the use of
|
|
26
|
+
<em>event relations</em>, as Roby::Task can be linked through the use of <em>task relations</em>.
|
|
27
|
+
Task and event relations are defined in the Roby::EventStructure and
|
|
28
|
+
Roby::TaskStructure relation spaces (Roby::RelationSpace instances), through the use of
|
|
29
|
+
Roby::RelationSpace#relation. Each relation object (for instance
|
|
30
|
+
Roby::EventStructure::Signal or Roby::TaskStructure::Hierarchy) is an instance
|
|
31
|
+
of the Roby::RelationGraph class.
|
|
32
|
+
|
|
33
|
+
In order to be managed in these relations, tasks and events
|
|
34
|
+
include the Roby::DirectedRelationSupport mixin to provide the basic
|
|
35
|
+
management tools needed by the RelationGraph instances. Moreover, all relation
|
|
36
|
+
types define specific methods which allow to more directly modify the relation
|
|
37
|
+
(like #add_signal, #each_parent or #parents in Hierarchy). See RelationSpace#relation
|
|
38
|
+
for details. Due to issues with Ruby's documentation system, those methods are
|
|
39
|
+
listed in
|
|
40
|
+
|
|
41
|
+
=== Plan modification
|
|
42
|
+
Modifying the plan therefore boils down to two things:
|
|
43
|
+
1. adding and removing tasks and events in the plan
|
|
44
|
+
2. adding and removing relations between objects of the same type (between tasks
|
|
45
|
+
or between events).
|
|
46
|
+
|
|
47
|
+
The first point is done by the following methods:
|
|
48
|
+
* Roby::Plan#discover: simply add tasks and events
|
|
49
|
+
* Roby::Plan#add_mission: adds special tasks, called missions. Missions are the
|
|
50
|
+
tasks the robot is supposed to execute. They are not subject to the plan's
|
|
51
|
+
garbage collection, and the tasks that are useful to them are not either.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
To ease the plan management process, some synthetic
|
|
55
|
+
operations are defined on Roby::Plan:
|
|
56
|
+
* the _replacement_ operation: Roby::Plan#replace_task and
|
|
57
|
+
Roby::Plan#replace. #replace_task(a, b) will replace +a+ by +b+ in the plan.
|
|
58
|
+
It means that the operators will add to +b+ all the children and parents of +a+
|
|
59
|
+
in all relations, and do the same with +b+ and +a+'s events. Moreover, it will
|
|
60
|
+
remove them from +a+. #replace(a, b) will do the same, but constraining itself
|
|
61
|
+
to the _parents_ of +b+ and +b+'s events. It therefore replaces +a+ and its
|
|
62
|
+
generated subplan (i.e. +a+ and all children of +a+) by +b+ and its subplan.
|
|
63
|
+
* the _respawning_ operation: a given task is replaced by a new task of the same
|
|
64
|
+
kind and with the same parameters. This is used mainly to workaround a
|
|
65
|
+
"fragile" task which crashed spuriously.
|
|
66
|
+
|
|
67
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Abstraction as task dependencies
|
|
3
|
+
sort_info: 200
|
|
4
|
+
--- name:content pipeline:tags,markdown,blocks
|
|
5
|
+
|
|
6
|
+
Dependency relations
|
|
7
|
+
--------------------
|
|
8
|
+
* Dependency is also a refinement relation
|
|
9
|
+
* the syntax and other concepts
|
|
10
|
+
- depends\_on :model
|
|
11
|
+
- fullfilled\_model
|
|
12
|
+
- fullfilled\_events
|
|
13
|
+
|
|
14
|
+
Plan modifications and model abstraction
|
|
15
|
+
----------------------------------------
|
|
16
|
+
|
|
17
|
+
* the replace operator
|
|
18
|
+
* semantics of the :returns flag in this context
|
|
19
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Representing Abstraction
|
|
3
|
+
routed_title: Representing Abstraction
|
|
4
|
+
sort_info: 0
|
|
5
|
+
--- name:content pipeline:tags,markdown,blocks
|
|
6
|
+
Being able to abstract away the little details of execution is crucial. Indeed,
|
|
7
|
+
it allows to apply high-level reasoning algorithms, that are not able to take
|
|
8
|
+
into account too much details.
|
|
9
|
+
|
|
10
|
+
Roby offers a unique ability: to link in the same plan the high-level parts of
|
|
11
|
+
the plan and the low-level ones. What this section will present is how, using
|
|
12
|
+
Roby's plan model, one can represent the _mechanism_ of abstraction. In other
|
|
13
|
+
words, what are the details that are lost in the abstraction mechanism.
|
|
14
|
+
|
|
15
|
+
More specifically, we will see the following:
|
|
16
|
+
|
|
17
|
+
* the object-oriented nature of Roby's plan model: how task models are related
|
|
18
|
+
to each other, and the notion of abstract models.
|
|
19
|
+
* how the hierarchy relation uses this OO principles to not over-constrain the
|
|
20
|
+
plan. We will see that the hierarchy relation can be used to precisely
|
|
21
|
+
represent what is _needed_ and not only what _is_.
|
|
22
|
+
* how the execution flow of the low-level parts of the plan can be linked to the
|
|
23
|
+
higher-level execution flow by means of the _forwarding_ relation.
|
|
24
|
+
* how it is possible to cleanly (and easily) build event commands using tasks
|
|
25
|
+
|
|
26
|
+
To understand the content of this section, we will assume that you read and
|
|
27
|
+
understood the [basics](../basics/index.html).
|
|
28
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Task Models
|
|
3
|
+
sort_info: 100
|
|
4
|
+
--- name:content pipeline:tags,markdown,blocks
|
|
5
|
+
|
|
6
|
+
* relationship between models
|
|
7
|
+
- semantics of subclasses
|
|
8
|
+
- rules of subclasses
|
|
9
|
+
- the TaskModelTag hack
|
|
10
|
+
* abstract models
|
|
11
|
+
- why is it useful => abstract actions that have to be chosen later on.
|
|
12
|
+
- syntax
|
|
13
|
+
- the :returns flag in planning models => example
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: A First Roby Application
|
|
3
|
+
sort_info: 300
|
|
4
|
+
--- pipeline:tags,markdown,blocks
|
|
5
|
+
|
|
6
|
+
This page will present another facet of Roby. What we saw until now is how,
|
|
7
|
+
in Roby, one can represent the task actions and build plans that describe the
|
|
8
|
+
task execution. What we will see here is how Roby tie the different models
|
|
9
|
+
together to offer an application environment.
|
|
10
|
+
|
|
11
|
+
{include_file: {filename: src/basics_shell_header.txt, escape_html: false}}
|
|
12
|
+
|
|
13
|
+
Creation
|
|
14
|
+
--------
|
|
15
|
+
|
|
16
|
+
Go into a *regular shell* (i.e. not the Ruby shell) and create a new directory.
|
|
17
|
+
That directory will become your first Roby application by running "roby init":
|
|
18
|
+
|
|
19
|
+
$ mkdir first_app
|
|
20
|
+
$ cd first_app
|
|
21
|
+
$ roby init
|
|
22
|
+
creating tasks/
|
|
23
|
+
creating tasks/.gitattributes
|
|
24
|
+
creating scripts/
|
|
25
|
+
creating scripts/test
|
|
26
|
+
creating scripts/shell
|
|
27
|
+
creating scripts/server
|
|
28
|
+
creating scripts/run
|
|
29
|
+
creating scripts/results
|
|
30
|
+
creating scripts/replay
|
|
31
|
+
creating scripts/generate/
|
|
32
|
+
creating scripts/generate/bookmarks
|
|
33
|
+
creating scripts/distributed
|
|
34
|
+
creating planners/
|
|
35
|
+
creating planners/main.rb
|
|
36
|
+
creating data/
|
|
37
|
+
creating data/.gitattributes
|
|
38
|
+
creating controllers/
|
|
39
|
+
creating controllers/.gitattributes
|
|
40
|
+
creating config/
|
|
41
|
+
creating config/roby.yml
|
|
42
|
+
creating config/init.rb
|
|
43
|
+
creating config/app.yml
|
|
44
|
+
creating Rakefile
|
|
45
|
+
creating README.txt
|
|
46
|
+
|
|
47
|
+
There's a lot of stuff created, but don't worry we'll learn what this is all
|
|
48
|
+
about later on. Right now, we're only interested in two small parts of it:
|
|
49
|
+
|
|
50
|
+
* the tasks/ directory, which is where task models (task classes) should be
|
|
51
|
+
defined
|
|
52
|
+
* the robot's controllers. These files contain the code that is run when the
|
|
53
|
+
application is started.
|
|
54
|
+
|
|
55
|
+
The goForward robot
|
|
56
|
+
-------------------
|
|
57
|
+
As an introduction, we will create a simulated robot controller which makes the
|
|
58
|
+
robot go forward at constant speed.
|
|
59
|
+
|
|
60
|
+
First, let's create the files specific to this robot
|
|
61
|
+
|
|
62
|
+
$ roby robot goForward
|
|
63
|
+
creating planners/goForward/
|
|
64
|
+
creating planners/goForward/main.rb
|
|
65
|
+
creating tasks/goForward/
|
|
66
|
+
creating tasks/goForward/.gitattributes
|
|
67
|
+
creating controllers/goForward.rb
|
|
68
|
+
creating config/goForward.rb
|
|
69
|
+
|
|
70
|
+
Let's define the task model. Edit tasks/go\_forward.rb and add
|
|
71
|
+
|
|
72
|
+
{coderay:: ruby}
|
|
73
|
+
class GoForward < Roby::Task
|
|
74
|
+
# The GoForward task needs the robot speed to be specified
|
|
75
|
+
arguments :speed
|
|
76
|
+
|
|
77
|
+
# Block called at every execution loop if the task is running. It simulates
|
|
78
|
+
# the robot moving at the specified speed.
|
|
79
|
+
poll do
|
|
80
|
+
State.pos.x += speed
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# This task does not need any specific action to stop
|
|
84
|
+
terminates
|
|
85
|
+
end
|
|
86
|
+
{coderay}
|
|
87
|
+
|
|
88
|
+
In the controller file, controllers/goForward.rb, we add the code that
|
|
89
|
+
should run at startup:
|
|
90
|
+
|
|
91
|
+
{coderay:: ruby}
|
|
92
|
+
# Define the original value of x
|
|
93
|
+
State.pos.x = 0
|
|
94
|
+
|
|
95
|
+
# Will display the value of x every 1 second
|
|
96
|
+
Roby.every(1) do
|
|
97
|
+
puts State.pos.x
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Create the task and start moving !
|
|
101
|
+
Roby.plan.insert(go = GoForward.new(:speed => 0.1))
|
|
102
|
+
puts "Going forward at speed #{go.speed}"
|
|
103
|
+
go.start!
|
|
104
|
+
{coderay}
|
|
105
|
+
|
|
106
|
+
You can then start the robot controller with scripts/run and stop it with CTRL+C.
|
|
107
|
+
|
|
108
|
+
$ scripts/run goForward
|
|
109
|
+
335705:25:08.324 (goForward) loading controller file /home/doudou/dev/roby-tutorials/controllers/goForward.rb
|
|
110
|
+
Going forward at speed 0.1
|
|
111
|
+
335705:25:08.356 (goForward) done initialization
|
|
112
|
+
0
|
|
113
|
+
0.9
|
|
114
|
+
1.9
|
|
115
|
+
2.9
|
|
116
|
+
335705:25:16.449 (Roby) received interruption request
|
|
117
|
+
335705:25:16.524 (Roby) control quitting. Waiting for 1 tasks to finish (1 tasks still in plan)
|
|
118
|
+
|
|
119
|
+
Broken down explanation
|
|
120
|
+
-----------------------
|
|
121
|
+
* the Roby::State object holds all the configuration and state data that
|
|
122
|
+
represents the robot's state. In our case, we initialize the robot's position
|
|
123
|
+
in the controller file, and then update it when the robot moves.
|
|
124
|
+
|
|
125
|
+
* to understand the meaning of the __poll__ statement, you have to understand
|
|
126
|
+
the idea behind Roby's execution model. Roby relies on a _synchronous_
|
|
127
|
+
execution model, which is basically a two-steps loops (a more detailed
|
|
128
|
+
explanation will come later). This two-steps loops is basically:
|
|
129
|
+
1. gather all events that have occured since the last loop
|
|
130
|
+
2. propagate to those events through the signal and forward relations
|
|
131
|
+
|
|
132
|
+
In practice, this event loop runs with a fixed period which is by default
|
|
133
|
+
100ms. This period can be changed in the configuration file config/app.yml.
|
|
134
|
+
|
|
135
|
+
Now, what is the role of __poll__ here ? The block given to +poll+ is executed
|
|
136
|
+
at each execution cycle _while the task is running_. It can therefore be
|
|
137
|
+
used to _implement_ the actual task functionality (or to check the state of
|
|
138
|
+
external processes, ...)
|
|
139
|
+
|