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,357 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tasks
|
|
3
|
+
sort_info: 200
|
|
4
|
+
--- pipeline:tags,markdown,blocks
|
|
5
|
+
{include_file: {filename: src/basics_shell_header.txt, escape_html: false}}
|
|
6
|
+
|
|
7
|
+
Definition of Tasks
|
|
8
|
+
-------------------
|
|
9
|
+
|
|
10
|
+
Unlike with event objects, which are usually created and parametrized on-the-fly, tasks are mostly first _defined_ and then _used_. To define a task, one creates a subclass of Roby::Task. In our examples, we'll take "the mother of all tasks in robotic systems": the MoveTo task.
|
|
11
|
+
|
|
12
|
+
{coderay:: ruby}
|
|
13
|
+
class MoveTo < Roby::Task
|
|
14
|
+
...
|
|
15
|
+
end
|
|
16
|
+
{coderay}
|
|
17
|
+
|
|
18
|
+
Then, to use it, one would do:
|
|
19
|
+
{coderay:: ruby}
|
|
20
|
+
plan.add(task = MoveTo.new)
|
|
21
|
+
{coderay}
|
|
22
|
+
|
|
23
|
+
As for events, the task must be included in a plan to be usable, which is done
|
|
24
|
+
by calling plan.add(). Don't forget that !
|
|
25
|
+
|
|
26
|
+
Parametrization
|
|
27
|
+
---------------
|
|
28
|
+
|
|
29
|
+
Obviously, a plain MoveTo task is nothing if the system does not know *where* to go to ... That is called parametrization and has to be declared in the task definition, using Task.argument
|
|
30
|
+
{coderay:: ruby}
|
|
31
|
+
>> class MoveTo < Roby::Task
|
|
32
|
+
?> argument :x
|
|
33
|
+
?> argument :y
|
|
34
|
+
>> end
|
|
35
|
+
{coderay}
|
|
36
|
+
|
|
37
|
+
Then, the arguments are provided at instanciation through an argument hash:
|
|
38
|
+
|
|
39
|
+
{coderay:: ruby}
|
|
40
|
+
>> task = MoveTo.new :x => 10, :y => 20
|
|
41
|
+
>> task.x
|
|
42
|
+
=> 10
|
|
43
|
+
>> task.y
|
|
44
|
+
=> 20
|
|
45
|
+
{coderay}
|
|
46
|
+
|
|
47
|
+
A task instance (i.e. the result of TaskClass.new) will *not* be usable unless
|
|
48
|
+
you initialize all its arguments. Such a task is called _partially
|
|
49
|
+
instanciated_:
|
|
50
|
+
|
|
51
|
+
{coderay:: ruby}
|
|
52
|
+
>> task = MoveTo.new
|
|
53
|
+
>> task.partially_instanciated?
|
|
54
|
+
=> true
|
|
55
|
+
>> task = MoveTo.new(:x => 10, :y => 10)
|
|
56
|
+
>> task.partially_instanciated?
|
|
57
|
+
=> false
|
|
58
|
+
{coderay}
|
|
59
|
+
|
|
60
|
+
Of course, it is possible to set default arguments by defining a #initialize
|
|
61
|
+
method (like with all Ruby classes)
|
|
62
|
+
{coderay:: ruby}
|
|
63
|
+
>> class MoveTo
|
|
64
|
+
?> argument :max_speed
|
|
65
|
+
?> def initialize(arguments)
|
|
66
|
+
?> arguments[:max_speed] ||= 1
|
|
67
|
+
?> super(arguments)
|
|
68
|
+
?> end
|
|
69
|
+
?> end
|
|
70
|
+
>> task = MoveTo.new(:x => 10, :y => 20)
|
|
71
|
+
>> task.max_speed
|
|
72
|
+
=> 1
|
|
73
|
+
>> task.partially_instanciated?
|
|
74
|
+
=> false
|
|
75
|
+
{coderay}
|
|
76
|
+
|
|
77
|
+
Task control and monitoring: defining events
|
|
78
|
+
--------------------------------------------
|
|
79
|
+
|
|
80
|
+
In Roby, tasks are a __collection of events__. Now that you know the basics
|
|
81
|
+
about events, the purpose of those events should be clear:
|
|
82
|
+
|
|
83
|
+
* the controllable events allow to change the process' behaviour (the obvious
|
|
84
|
+
one being "start" which allows to start the task)
|
|
85
|
+
* both contingent and controllable events allow to monitor the task's execution.
|
|
86
|
+
|
|
87
|
+
The basic task already defines four events:
|
|
88
|
+
* the *start* event
|
|
89
|
+
* the *stop* event
|
|
90
|
+
* the *success* event
|
|
91
|
+
* and finally the *failed* event
|
|
92
|
+
|
|
93
|
+
In the class definition, events are defined using Task#event. To define a
|
|
94
|
+
controllable event, simply associate a block. First, copy/paste the following code in a
|
|
95
|
+
my\_task.rb file.
|
|
96
|
+
|
|
97
|
+
{coderay:: ruby}
|
|
98
|
+
class MyTask < Roby::Task
|
|
99
|
+
event :start do
|
|
100
|
+
puts "start event called"
|
|
101
|
+
emit :start
|
|
102
|
+
end
|
|
103
|
+
event :controlable do
|
|
104
|
+
puts "controlable event called"
|
|
105
|
+
emit :controlable
|
|
106
|
+
end
|
|
107
|
+
event :contingent
|
|
108
|
+
|
|
109
|
+
on(:start) { puts "start event emitted" }
|
|
110
|
+
on(:controlable) { puts "controlable event emitted" }
|
|
111
|
+
on(:contingent) { puts "contingent event emitted" }
|
|
112
|
+
on(:failed) { puts "failed event emitted" }
|
|
113
|
+
on(:stop) { puts "stop event emitted" }
|
|
114
|
+
|
|
115
|
+
event :finished, :terminal => true
|
|
116
|
+
on(:finished) { puts "finished event emitted" }
|
|
117
|
+
end
|
|
118
|
+
{coderay}
|
|
119
|
+
|
|
120
|
+
Finally, an event can be *terminal*: its emission means the end of the task's
|
|
121
|
+
execution. __failed__ and __success__ are examples of terminal events. To declare a
|
|
122
|
+
terminal event, one does as for the "finished" event above.
|
|
123
|
+
|
|
124
|
+
Now, read that code into the ruby shell with
|
|
125
|
+
{coderay:: ruby}
|
|
126
|
+
>> source "my_task.rb"
|
|
127
|
+
{coderay}
|
|
128
|
+
|
|
129
|
+
Using task events
|
|
130
|
+
-----------------
|
|
131
|
+
The {rdoc_class: EventGenerator} class that defines the task event can be
|
|
132
|
+
accessed with Task#event. Then, you can manipulate them as for normal events:
|
|
133
|
+
{coderay:: ruby}
|
|
134
|
+
>> plan.add(task = MyTask.new)
|
|
135
|
+
>> ev = task.event(:start)
|
|
136
|
+
>> ev.call
|
|
137
|
+
start event called
|
|
138
|
+
start event emitted
|
|
139
|
+
>> task.running?
|
|
140
|
+
=> true
|
|
141
|
+
>> ev = task.event(:contingent)
|
|
142
|
+
>> ev.controlable?
|
|
143
|
+
=> false
|
|
144
|
+
>> ev.emit
|
|
145
|
+
contingent event emitted
|
|
146
|
+
{coderay}
|
|
147
|
+
|
|
148
|
+
Instead of calling #on, #signal, #emit and #call on the event object, one can use
|
|
149
|
+
shortcuts that are defined on {rdoc_class: Task}:
|
|
150
|
+
{coderay:: ruby}
|
|
151
|
+
# Same as task.event(:contingent).on { ... }
|
|
152
|
+
>> task.on(:contingent) { puts "contingent event emitted" }
|
|
153
|
+
# Same as task.event(:contingent).emit
|
|
154
|
+
>> task.emit(:contingent)
|
|
155
|
+
# There's two handlers now, so we should have two lines displayed
|
|
156
|
+
contingent event emitted
|
|
157
|
+
contingent event emitted
|
|
158
|
+
# Same as task.event(:controlable).call
|
|
159
|
+
>> task.controlable!
|
|
160
|
+
controlable event called
|
|
161
|
+
controlable event emitted
|
|
162
|
+
# Same as task.event(:contingent).signals task.event(:controlable)
|
|
163
|
+
>> task.signals(:contingent, task, :controlable)
|
|
164
|
+
>> task.emit :contingent
|
|
165
|
+
contingent event emitted
|
|
166
|
+
contingent event emitted
|
|
167
|
+
controlable event called
|
|
168
|
+
controlable event emitted
|
|
169
|
+
>> task.emit :finished
|
|
170
|
+
finished event emitted
|
|
171
|
+
stop event emitted
|
|
172
|
+
>> task.running?
|
|
173
|
+
=> false
|
|
174
|
+
{coderay}
|
|
175
|
+
|
|
176
|
+
Event classification: using the *forward* relation
|
|
177
|
+
--------------------------------------------------
|
|
178
|
+
As we in the above examples, it is possible to have terminal events, which are events
|
|
179
|
+
that end the task. Obviously, the "stop" event should be emitted when they are
|
|
180
|
+
emitted ("stop" represents the task end, does not it ?).
|
|
181
|
+
|
|
182
|
+
In a more generic way, these terminal events are likely to be either special
|
|
183
|
+
cases of the task success or of the task failure. Then, we actually need a way
|
|
184
|
+
to *classify* events: to say "success is a special case of stop, or
|
|
185
|
+
"wheel\_blocked is a special case of failed, which is a special case of
|
|
186
|
+
stop".
|
|
187
|
+
|
|
188
|
+
To represent this specific event relationship, Roby provides a *forward*
|
|
189
|
+
relation between events, which can be added as follows:
|
|
190
|
+
{coderay:: ruby}
|
|
191
|
+
>> class MyTask < Roby::Task
|
|
192
|
+
?> event :wheel_blocked
|
|
193
|
+
?> on(:wheel_blocked) { puts "wheel_blocked emitted" }
|
|
194
|
+
?> end
|
|
195
|
+
>> plan.add(task = MyTask.new)
|
|
196
|
+
>> task.start!
|
|
197
|
+
start event called
|
|
198
|
+
start event emitted
|
|
199
|
+
>> blocked = task.event(:wheel_blocked)
|
|
200
|
+
>> failed = task.event(:failed)
|
|
201
|
+
>> blocked.forward_to failed
|
|
202
|
+
>> task.emit :wheel_blocked
|
|
203
|
+
wheel_blocked emitted
|
|
204
|
+
stop event emitted
|
|
205
|
+
{coderay}
|
|
206
|
+
|
|
207
|
+
In practice, a _forward_ relation between two events a and b says "b should be
|
|
208
|
+
emitted when a is". Or "b is a superset of the situations that a represents".
|
|
209
|
+
|
|
210
|
+
This relation is also available on "plain" events (i.e. EventGenerator.new).
|
|
211
|
+
|
|
212
|
+
Task model and event relations
|
|
213
|
+
------------------------------
|
|
214
|
+
Until now, we only saw how to add relations between events of task instances.
|
|
215
|
+
Sometime (especially with forwarding relations), some relations should be
|
|
216
|
+
defined on _all_ the task instances of a given task class. To do that, use the
|
|
217
|
+
class methods <tt>signal</tt> and <tt>forward</tt> defined on {rdoc_class:
|
|
218
|
+
Task}:
|
|
219
|
+
|
|
220
|
+
{coderay:: ruby}
|
|
221
|
+
>> class MyTask < Roby::Task
|
|
222
|
+
?> signal :start => :controlable
|
|
223
|
+
?> forward :wheel_blocked => :failed
|
|
224
|
+
?> end
|
|
225
|
+
>> plan.add(task = MyTask.new)
|
|
226
|
+
>> task.start!
|
|
227
|
+
start event called
|
|
228
|
+
start event emitted
|
|
229
|
+
controlable event called
|
|
230
|
+
controlable event emitted
|
|
231
|
+
>> task.emit :wheel_blocked
|
|
232
|
+
wheel_blocked emitted
|
|
233
|
+
failed event emitted
|
|
234
|
+
stop event emitted
|
|
235
|
+
{coderay}
|
|
236
|
+
|
|
237
|
+
Tasks that terminates
|
|
238
|
+
---------------------
|
|
239
|
+
A very important characteristic of tasks is their ability to be _interrupted_
|
|
240
|
+
(or lack of). What is meant by that is that Roby should be able to stop some
|
|
241
|
+
(actually, most) tasks. In Roby, that ability is represented by giving a command
|
|
242
|
+
to the 'stop' event.
|
|
243
|
+
|
|
244
|
+
For most of the tasks, there is actually no need to perform specific actions.
|
|
245
|
+
Simply having Roby mark the task as 'stopped' is enough. For those tasks, using
|
|
246
|
+
the 'terminates' statement is enough:
|
|
247
|
+
|
|
248
|
+
{coderay:: ruby}
|
|
249
|
+
>> class MyTask
|
|
250
|
+
?> terminates
|
|
251
|
+
?> end
|
|
252
|
+
>> plan.add(task = MyTask.new)
|
|
253
|
+
>> task.start!
|
|
254
|
+
start event called
|
|
255
|
+
start event emitted
|
|
256
|
+
controlable event called
|
|
257
|
+
controlable event emitted
|
|
258
|
+
>> task.stop!
|
|
259
|
+
failed event emitted
|
|
260
|
+
stop event emitted
|
|
261
|
+
{coderay}
|
|
262
|
+
|
|
263
|
+
As you can see, 'terminates' is equivalent to
|
|
264
|
+
{coderay:: ruby}
|
|
265
|
+
>> class MyTask
|
|
266
|
+
?> event(:failed) { emit :failed }
|
|
267
|
+
?> event(:stop) { failed! }
|
|
268
|
+
?> end
|
|
269
|
+
{coderay}
|
|
270
|
+
|
|
271
|
+
Common errors when manipulating tasks
|
|
272
|
+
-------------------------------------
|
|
273
|
+
|
|
274
|
+
As for the event, a common error is to forget to include the task in a plan
|
|
275
|
+
before calling events on it:
|
|
276
|
+
|
|
277
|
+
{coderay:: ruby}
|
|
278
|
+
>> task = MyTask.new
|
|
279
|
+
>> task.start!
|
|
280
|
+
Roby::EventNotExecutable: start! called on MyTask{}:0x7f336c455af0[] but the task is in no plan
|
|
281
|
+
{coderay}
|
|
282
|
+
|
|
283
|
+
Another related error is to emit/call events other than "start" while the task is not yet running ...
|
|
284
|
+
|
|
285
|
+
{coderay:: ruby}
|
|
286
|
+
>> plan.add(task = MyTask.new)
|
|
287
|
+
>> task.controllable!
|
|
288
|
+
Roby::CommandFailed: controlable!() called by [] but the task has never been started
|
|
289
|
+
from (irb):30
|
|
290
|
+
>> task.emit :contingent
|
|
291
|
+
Roby::EmissionFailed: emit(contingent, []) called by [] but the task has never been started
|
|
292
|
+
from (irb):31
|
|
293
|
+
{coderay}
|
|
294
|
+
|
|
295
|
+
... or when it has stopped
|
|
296
|
+
|
|
297
|
+
{coderay:: ruby}
|
|
298
|
+
>> task.start!
|
|
299
|
+
>> task.stop!
|
|
300
|
+
>> task.controlable!
|
|
301
|
+
Roby::CommandFailed: controlable!() called by [] but the task has finished. Task has been terminated by [MyTask{}:0x7ff179064358[]/failed@7 [344917:00:42.215]:
|
|
302
|
+
from (irb):32
|
|
303
|
+
>> task.emit :contingent
|
|
304
|
+
Roby::EmissionFailed: emit(contingent, []) called by [] but the task has finished. Task has been terminated by [MyTask{}:0x7ff179064358[]/failed@7 [344917:00:42.215]: ].
|
|
305
|
+
from (irb):33
|
|
306
|
+
{coderay}
|
|
307
|
+
|
|
308
|
+
<div markdown="1" class="info">
|
|
309
|
+
In these messages, the notation
|
|
310
|
+
|
|
311
|
+
MyTask{}:0x7ff179064358[]
|
|
312
|
+
|
|
313
|
+
represents a task, the notation
|
|
314
|
+
|
|
315
|
+
MyTask{}:0x7ff179064358[]/failed
|
|
316
|
+
|
|
317
|
+
represents the event "failed" of the same task and finally
|
|
318
|
+
|
|
319
|
+
MyTask{}:0x7ff179064358[]/failed@7 [344917:00:42.215]
|
|
320
|
+
|
|
321
|
+
is an emitted event that has been generated by the "failed" event of the given
|
|
322
|
+
task. The time on the right is the time of emission, and the "@x" notation is
|
|
323
|
+
the propagation cycle (usually, you don't care about this but it is VERY useful
|
|
324
|
+
for debugging Roby itself).
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
Of course, as we saw at the beginning of this page, a task must be fully
|
|
328
|
+
instanciated to be started:
|
|
329
|
+
|
|
330
|
+
{coderay:: ruby}
|
|
331
|
+
>> class Bla < Roby::Task
|
|
332
|
+
>> argument :foo
|
|
333
|
+
>> end
|
|
334
|
+
>> plan.add(task = Bla.new)
|
|
335
|
+
>> task.start!
|
|
336
|
+
Roby::EventNotExecutable: start! called on Bar{}:0x7ff17901c1e8[] which is partially instanciated
|
|
337
|
+
The following arguments were not set:
|
|
338
|
+
foo
|
|
339
|
+
{coderay}
|
|
340
|
+
|
|
341
|
+
Summary
|
|
342
|
+
-------
|
|
343
|
+
|
|
344
|
+
What do we do know ?
|
|
345
|
+
|
|
346
|
+
* we know how the robot's situation is represented: through the *emission
|
|
347
|
+
of events*
|
|
348
|
+
* we know how the robot is controlled: through the call of *controlable
|
|
349
|
+
events*
|
|
350
|
+
* we know how to sort events in tasks, in order to represent the different
|
|
351
|
+
processes that run on the robot.
|
|
352
|
+
|
|
353
|
+
One important question is still left open: how all of this can be made into a
|
|
354
|
+
whole that allows to control a robot ? Right now, we only have an overview of
|
|
355
|
+
the basics of Roby plan. What follows will show what a *Roby application* is
|
|
356
|
+
made of.
|
|
357
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Code examples
|
|
2
|
+
-------------
|
|
3
|
+
This page includes code samples that you can try out in Ruby or Unix shells. See
|
|
4
|
+
[this page](code_examples.html) for explanations on the notation.
|
|
5
|
+
{.warning}
|
|
6
|
+
|
|
7
|
+
Moreover, to run the examples on this page, you must first set up your ruby
|
|
8
|
+
shell:
|
|
9
|
+
|
|
10
|
+
$ irb
|
|
11
|
+
{coderay:: ruby}
|
|
12
|
+
>> require 'roby/standalone'
|
|
13
|
+
>> include Roby
|
|
14
|
+
>> plan = Roby.plan
|
|
15
|
+
{coderay}
|
|
16
|
+
|
|
Binary file
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
<svg
|
|
4
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
5
|
+
xmlns:cc="http://web.resource.org/cc/"
|
|
6
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
10
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
11
|
+
width="744.09448819"
|
|
12
|
+
height="1052.3622047"
|
|
13
|
+
id="svg2"
|
|
14
|
+
sodipodi:version="0.32"
|
|
15
|
+
inkscape:version="0.45.1"
|
|
16
|
+
sodipodi:docbase="/home/doudou/laas/documents/production/thesis/figures/supervision"
|
|
17
|
+
sodipodi:docname="cycle-overview.svg"
|
|
18
|
+
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
|
19
|
+
<defs
|
|
20
|
+
id="defs4">
|
|
21
|
+
<marker
|
|
22
|
+
inkscape:stockid="Arrow1Lend"
|
|
23
|
+
orient="auto"
|
|
24
|
+
refY="0.0"
|
|
25
|
+
refX="0.0"
|
|
26
|
+
id="Arrow1Lend"
|
|
27
|
+
style="overflow:visible;">
|
|
28
|
+
<path
|
|
29
|
+
id="path3265"
|
|
30
|
+
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
|
31
|
+
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
|
|
32
|
+
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
|
33
|
+
</marker>
|
|
34
|
+
</defs>
|
|
35
|
+
<sodipodi:namedview
|
|
36
|
+
id="base"
|
|
37
|
+
pagecolor="#ffffff"
|
|
38
|
+
bordercolor="#666666"
|
|
39
|
+
borderopacity="1.0"
|
|
40
|
+
gridtolerance="10000"
|
|
41
|
+
guidetolerance="10"
|
|
42
|
+
objecttolerance="10"
|
|
43
|
+
inkscape:pageopacity="0.0"
|
|
44
|
+
inkscape:pageshadow="2"
|
|
45
|
+
inkscape:zoom="0.49497475"
|
|
46
|
+
inkscape:cx="818.39952"
|
|
47
|
+
inkscape:cy="483.78467"
|
|
48
|
+
inkscape:document-units="px"
|
|
49
|
+
inkscape:current-layer="layer1"
|
|
50
|
+
inkscape:window-width="1016"
|
|
51
|
+
inkscape:window-height="710"
|
|
52
|
+
inkscape:window-x="0"
|
|
53
|
+
inkscape:window-y="0" />
|
|
54
|
+
<metadata
|
|
55
|
+
id="metadata7">
|
|
56
|
+
<rdf:RDF>
|
|
57
|
+
<cc:Work
|
|
58
|
+
rdf:about="">
|
|
59
|
+
<dc:format>image/svg+xml</dc:format>
|
|
60
|
+
<dc:type
|
|
61
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
62
|
+
</cc:Work>
|
|
63
|
+
</rdf:RDF>
|
|
64
|
+
</metadata>
|
|
65
|
+
<g
|
|
66
|
+
inkscape:label="Layer 1"
|
|
67
|
+
inkscape:groupmode="layer"
|
|
68
|
+
id="layer1">
|
|
69
|
+
<g
|
|
70
|
+
id="g3241"
|
|
71
|
+
transform="translate(96.232983,-246.65343)">
|
|
72
|
+
<path
|
|
73
|
+
transform="matrix(0.516129,0,0,0.516129,82.148213,214.40589)"
|
|
74
|
+
d="M 324.25896 525.56763 A 78.286819 78.286819 0 1 1 167.68532,525.56763 A 78.286819 78.286819 0 1 1 324.25896 525.56763 z"
|
|
75
|
+
sodipodi:ry="78.286819"
|
|
76
|
+
sodipodi:rx="78.286819"
|
|
77
|
+
sodipodi:cy="525.56763"
|
|
78
|
+
sodipodi:cx="245.97214"
|
|
79
|
+
id="path3185"
|
|
80
|
+
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.63598328;fill-rule:evenodd;stroke:#000000;stroke-width:2.71250033;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
|
81
|
+
sodipodi:type="arc" />
|
|
82
|
+
<text
|
|
83
|
+
sodipodi:linespacing="125%"
|
|
84
|
+
id="text3187"
|
|
85
|
+
y="482.02158"
|
|
86
|
+
x="209.04053"
|
|
87
|
+
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
|
88
|
+
xml:space="preserve"><tspan
|
|
89
|
+
y="482.02158"
|
|
90
|
+
x="209.04053"
|
|
91
|
+
id="tspan3189"
|
|
92
|
+
sodipodi:role="line">1. Event</tspan><tspan
|
|
93
|
+
id="tspan3191"
|
|
94
|
+
y="494.52158"
|
|
95
|
+
x="209.04053"
|
|
96
|
+
sodipodi:role="line">Propagation</tspan></text>
|
|
97
|
+
</g>
|
|
98
|
+
<g
|
|
99
|
+
id="g3247"
|
|
100
|
+
transform="translate(90.900118,-242.41612)">
|
|
101
|
+
<path
|
|
102
|
+
transform="matrix(0.516129,0,0,0.516129,210.51882,259.86277)"
|
|
103
|
+
d="M 324.25896 525.56763 A 78.286819 78.286819 0 1 1 167.68532,525.56763 A 78.286819 78.286819 0 1 1 324.25896 525.56763 z"
|
|
104
|
+
sodipodi:ry="78.286819"
|
|
105
|
+
sodipodi:rx="78.286819"
|
|
106
|
+
sodipodi:cy="525.56763"
|
|
107
|
+
sodipodi:cx="245.97214"
|
|
108
|
+
id="path3193"
|
|
109
|
+
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.63598328;fill-rule:evenodd;stroke:#000000;stroke-width:2.71250033;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
|
110
|
+
sodipodi:type="arc" />
|
|
111
|
+
<text
|
|
112
|
+
sodipodi:linespacing="125%"
|
|
113
|
+
id="text3195"
|
|
114
|
+
y="527.47845"
|
|
115
|
+
x="337.41113"
|
|
116
|
+
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
|
117
|
+
xml:space="preserve"><tspan
|
|
118
|
+
id="tspan3199"
|
|
119
|
+
y="527.47845"
|
|
120
|
+
x="337.41113"
|
|
121
|
+
sodipodi:role="line">2. Error</tspan><tspan
|
|
122
|
+
id="tspan3203"
|
|
123
|
+
y="539.97845"
|
|
124
|
+
x="337.41113"
|
|
125
|
+
sodipodi:role="line">Handling</tspan></text>
|
|
126
|
+
</g>
|
|
127
|
+
<g
|
|
128
|
+
id="g3253"
|
|
129
|
+
transform="translate(97.432971,-240.67052)">
|
|
130
|
+
<path
|
|
131
|
+
transform="matrix(0.516129,0,0,0.516129,99.320817,339.66483)"
|
|
132
|
+
d="M 324.25896 525.56763 A 78.286819 78.286819 0 1 1 167.68532,525.56763 A 78.286819 78.286819 0 1 1 324.25896 525.56763 z"
|
|
133
|
+
sodipodi:ry="78.286819"
|
|
134
|
+
sodipodi:rx="78.286819"
|
|
135
|
+
sodipodi:cy="525.56763"
|
|
136
|
+
sodipodi:cx="245.97214"
|
|
137
|
+
id="path3205"
|
|
138
|
+
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.63598328;fill-rule:evenodd;stroke:#000000;stroke-width:2.71250033;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
|
139
|
+
sodipodi:type="arc" />
|
|
140
|
+
<text
|
|
141
|
+
sodipodi:linespacing="125%"
|
|
142
|
+
id="text3207"
|
|
143
|
+
y="607.28052"
|
|
144
|
+
x="226.21313"
|
|
145
|
+
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
|
146
|
+
xml:space="preserve"><tspan
|
|
147
|
+
id="tspan3211"
|
|
148
|
+
y="607.28052"
|
|
149
|
+
x="226.21313"
|
|
150
|
+
sodipodi:role="line">3. Garbage</tspan><tspan
|
|
151
|
+
id="tspan3215"
|
|
152
|
+
y="619.78052"
|
|
153
|
+
x="226.21313"
|
|
154
|
+
sodipodi:role="line">Collection</tspan></text>
|
|
155
|
+
</g>
|
|
156
|
+
<path
|
|
157
|
+
style="opacity:1;color:#000000;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
|
158
|
+
d="M 341.12139,257.78591 L 387.27981,274.13091"
|
|
159
|
+
id="path3235"
|
|
160
|
+
inkscape:connector-type="polyline" />
|
|
161
|
+
<path
|
|
162
|
+
style="opacity:1;color:#000000;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
|
163
|
+
d="M 396.23341,313.66319 L 353.30654,347.3016"
|
|
164
|
+
id="path3237"
|
|
165
|
+
inkscape:connector-type="polyline" />
|
|
166
|
+
<path
|
|
167
|
+
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
|
168
|
+
d="M 311.55238,327.38282 L 305.65081,284.33607"
|
|
169
|
+
id="path3239"
|
|
170
|
+
inkscape:connector-type="polyline" />
|
|
171
|
+
<flowRoot
|
|
172
|
+
xml:space="preserve"
|
|
173
|
+
id="flowRoot2185"
|
|
174
|
+
style="text-align:justify;text-anchor:start"
|
|
175
|
+
transform="translate(9.0913726,-136.3706)"><flowRegion
|
|
176
|
+
id="flowRegion2187"><rect
|
|
177
|
+
id="rect2189"
|
|
178
|
+
width="183.84776"
|
|
179
|
+
height="61.619305"
|
|
180
|
+
x="56.568542"
|
|
181
|
+
y="346.26556"
|
|
182
|
+
style="text-align:justify;text-anchor:start" /></flowRegion><flowPara
|
|
183
|
+
id="flowPara2195">determine what events should be emitted and/or called, and propagate the events in the event relation graphs.</flowPara></flowRoot> <flowRoot
|
|
184
|
+
xml:space="preserve"
|
|
185
|
+
id="flowRoot2201"
|
|
186
|
+
transform="translate(38.056586,-153.1509)"
|
|
187
|
+
style="text-align:end;text-anchor:end"><flowRegion
|
|
188
|
+
id="flowRegion2203"><rect
|
|
189
|
+
id="rect2205"
|
|
190
|
+
width="192.20023"
|
|
191
|
+
height="60.052284"
|
|
192
|
+
x="389.91888"
|
|
193
|
+
y="363.43814"
|
|
194
|
+
style="text-align:end;text-anchor:end" /></flowRegion><flowPara
|
|
195
|
+
id="flowPara2209">detect errors as violation of the constraints defined by the relation graphs, and try to recover from them.</flowPara></flowRoot> <flowRoot
|
|
196
|
+
xml:space="preserve"
|
|
197
|
+
id="flowRoot2213"
|
|
198
|
+
style="text-align:justify;text-anchor:start"
|
|
199
|
+
transform="translate(-114.08627,-193.1509)"><flowRegion
|
|
200
|
+
id="flowRegion2215"><rect
|
|
201
|
+
id="rect2217"
|
|
202
|
+
width="272.14285"
|
|
203
|
+
height="47.142876"
|
|
204
|
+
x="318.57144"
|
|
205
|
+
y="606.64789"
|
|
206
|
+
style="text-align:justify;text-anchor:start" /></flowRegion><flowPara
|
|
207
|
+
id="flowPara2223">kill and remove the tasks that are either not useful for the completion of the robot goals, or for which errors have not been recovered.</flowPara></flowRoot> </g>
|
|
208
|
+
</svg>
|