roby 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,11 @@
|
|
1
|
+
---
|
2
|
+
title: Introduction
|
3
|
+
sort_info: 0
|
4
|
+
--- name:content pipeline:tags,markdown,blocks
|
5
|
+
This section will present the basics of plan management using Roby. You will
|
6
|
+
learn the following things:
|
7
|
+
* the two core objects used in Roby to represent the robot's actions
|
8
|
+
* what is a Roby application and how create one
|
9
|
+
* how it is possible to interact with a running Roby application
|
10
|
+
* how to build complex actions from simple ones
|
11
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
title: Overview of Plan Objects
|
3
|
+
sort_info: 50
|
4
|
+
--- pipeline:tags,rdoc
|
5
|
+
There are two basic objects in Roby plans, both objects being equally important.
|
6
|
+
* *events*. They are both the basic command interface and the way to follow what
|
7
|
+
happens in and outside of the robot.
|
8
|
+
* *tasks*. They represent the multiple processes that run on the robot: both the
|
9
|
+
robot physical actions and the robot's internal processing.
|
10
|
+
|
11
|
+
== Events
|
12
|
+
The first use of events is the representation of milestones in the robot's
|
13
|
+
execution. For instance, a +reached_waypoint+ event would be _emitted_ when the
|
14
|
+
robot reaches its assigned waypoint. Accordingly, a +detected_object+ event
|
15
|
+
would be emitted when a visual object detection algorithm finds something.
|
16
|
+
|
17
|
+
The second use of events is that, some of them (the "controllable ones") allow
|
18
|
+
to _make_ things happen. I.e. they allow to make a specific event happen. The
|
19
|
+
set of controllable events therefore represents the basic commands that can be
|
20
|
+
sent to the robot's software.
|
21
|
+
|
22
|
+
The event command is then the mean to make a specific event happen <i>with
|
23
|
+
certainty</i>. For instance, +reached_waypoint+ cannot have a command, as
|
24
|
+
navigation is not a certain endeavour. Same thing for an hypothetical
|
25
|
+
+detected_object+ of a searching robot. But a +stop_moving+ event could have a
|
26
|
+
command. Then, by calling the command, the Roby controller would require the
|
27
|
+
robot to "stop moving !". When the robot actually performed that action, it will
|
28
|
+
inform the rest of the system that it stopped moving by emitting the event.
|
29
|
+
|
30
|
+
== Tasks
|
31
|
+
To represent more complex actions, that cannot be represented by the simple
|
32
|
+
event command/emission scheme, Roby has a concept of <b>task</b>. A task
|
33
|
+
represents a long-standing process, which can be supervised along its execution.
|
34
|
+
One important "feature" of the task concept is that <i>a task can fail</i>.
|
35
|
+
|
36
|
+
For instance, the basic task ({rdoc_class: Task}) has four default events:
|
37
|
+
* a +start+ event
|
38
|
+
* a +stop+ event
|
39
|
+
* a +success+ event
|
40
|
+
* and finally a +failed+ event
|
41
|
+
|
42
|
+
On the one hand, a nominal execution of this task would be:
|
43
|
+
* the +start+ event is emitted
|
44
|
+
* the +success+ event is emitted
|
45
|
+
* the +stop+ event is emitted
|
46
|
+
|
47
|
+
On the other hand, a failed execution would be:
|
48
|
+
* the +start+ event is emitted
|
49
|
+
* the +failed+ event is emitted
|
50
|
+
* the +stop+ event is emitted
|
51
|
+
|
52
|
+
Then, a bit more complex task could be allow interruption. For this new task, we
|
53
|
+
would need a new event (+interrupt+) and a command. One way to do it would be
|
54
|
+
to have a _controllable_ +interrupt+ _event_ in the task. Its (interrupted)
|
55
|
+
execution would then be
|
56
|
+
* the +start+ event is emitted
|
57
|
+
* the command of the +interrupt+ event is called
|
58
|
+
* the +interrupt+ event is emitted
|
59
|
+
* the +stop+ event is emitted
|
60
|
+
|
61
|
+
Another way to see it would be that an interruption command is a way to require
|
62
|
+
that the task stops. Therefore, one could want the following execution instead:
|
63
|
+
* the +start+ event is emitted
|
64
|
+
* the command of the +stop+ event is called
|
65
|
+
* the +interrupt+ event is emitted
|
66
|
+
* the +stop+ event is emitted
|
67
|
+
|
68
|
+
The second way is the actual convention for interruptible tasks in Roby. It is
|
69
|
+
important, as -- as we will see later -- an important feature is that Roby stops
|
70
|
+
tasks for you.
|
71
|
+
|
@@ -0,0 +1,203 @@
|
|
1
|
+
---
|
2
|
+
title: Using Plan Display
|
3
|
+
sort_info: 600
|
4
|
+
--- pipeline:tags,markdown
|
5
|
+
|
6
|
+
What we will see in this page is how to trace the execution flow (the flow of
|
7
|
+
events), and understand a bit more how the plans you will build are actually
|
8
|
+
executed by the system. We will re-use the planned\_move planning action we just
|
9
|
+
built.
|
10
|
+
|
11
|
+
Getting a log file
|
12
|
+
------------------
|
13
|
+
|
14
|
+
Plan execution logs are expensive from a CPU point of view, so they are disabled
|
15
|
+
by default. Enable them back by editing config/app.yml and uncomment
|
16
|
+
"events: true" around line 23.
|
17
|
+
|
18
|
+
Now, run again the controller
|
19
|
+
|
20
|
+
# scripts/run goForward
|
21
|
+
|
22
|
+
and in the shell, do
|
23
|
+
|
24
|
+
>> planned_move! :x => 10, :y => 10
|
25
|
+
=> MoveTo{goal => Vector3D(x=10.000000,y=10.000000,z=0.000000)}:0x4840c8d8[]
|
26
|
+
>>
|
27
|
+
!task MoveTo{goal => Vector3D(x=10.000000,y=10.000000,z=0.000000)}:0x4840c8d8[] finished successfully
|
28
|
+
|
29
|
+
Finally, let's save the log files for further analysis (otherwise, one could
|
30
|
+
destroy them by restarting the controller).
|
31
|
+
|
32
|
+
# scripts/results planned_move
|
33
|
+
moving /home/doudou/dev/first_app/log to /home/doudou/dev/roby-tutorials/results/20080502-planned_move
|
34
|
+
|
35
|
+
"scripts/results" copies all files in "log/" into a subdirectory
|
36
|
+
of the result dir (by default APP\_DIR/results, but can be changed in
|
37
|
+
"config/app.yml"). The target directory name is generated following a pattern of
|
38
|
+
"current\_date-name\_provided\_on\_command\_line".
|
39
|
+
|
40
|
+
Displaying the log file
|
41
|
+
-----------------------
|
42
|
+
Go in the directory where the results are (see <tt>scripts/results</tt> output).
|
43
|
+
On my machine, the command would look like this:
|
44
|
+
|
45
|
+
$ cd /home/doudou/dev/roby-tutorials/results/20080502-planned_move
|
46
|
+
$ ls
|
47
|
+
goForward-events.log
|
48
|
+
goForward-index.log
|
49
|
+
|
50
|
+
If you look into it, two PathPlan files are present: <tt>PathPlan-events.log</tt> and
|
51
|
+
"PathPlan-index.log". The first one includes a trace of everything that
|
52
|
+
happens in the Roby controller which has been traced. The second one can
|
53
|
+
actually be generated from data in the first one. It is simply used to speed up
|
54
|
+
operations.
|
55
|
+
|
56
|
+
The data in the event log can be used to display the plan operations in a GUI.
|
57
|
+
For that, you need to have installed [Ruby/Qt4](http://korundum.rubyforge.org), as
|
58
|
+
the GUI is written using Qt and Ruby.
|
59
|
+
|
60
|
+
To start it, simply do the following in the directory of the log files:
|
61
|
+
|
62
|
+
$ roby-log replay goForward
|
63
|
+
|
64
|
+
The following window should appear:
|
65
|
+
|
66
|
+
![](log_replay/roby_log_main_window.png)
|
67
|
+
|
68
|
+
This window is separated in three:
|
69
|
+
|
70
|
+
* the toplevel part ("Data sources") is the list of data sources defined for
|
71
|
+
this project. It is for instance possible to have a synchronized display of
|
72
|
+
the logs of two different Roby controllers -- for multi-robot setup.
|
73
|
+
* the second part ("Displays") is the set of displays defined. More about that later.
|
74
|
+
* the third part ("Play") is the replay controls: play, fast forward, position, ...
|
75
|
+
|
76
|
+
Right now, we will be looking at the plan structure and execution trace. The
|
77
|
+
"Relations" display is designed for that. Let's add one by clicking on the
|
78
|
+
"Add" button just next to the display type combo. The configuration options
|
79
|
+
appear (including the data source associated with the display), and a new
|
80
|
+
window:
|
81
|
+
|
82
|
+
![](log_replay/roby_log_relation_window.png)
|
83
|
+
|
84
|
+
This display will show two things: the task structure (i.e. how tasks are
|
85
|
+
related to each other) and the event propagation (i.e. how events call and/or
|
86
|
+
emit each other). The set of task relations to display has to be selected on
|
87
|
+
the configuration part of the relation display, including the colors for each
|
88
|
+
displayed relation. For our purposes, we only need the "Hierarchy" and the
|
89
|
+
"PlannedBy" relations, so check them in the display configuration, as it is done
|
90
|
+
one the image above.
|
91
|
+
|
92
|
+
Moreover,
|
93
|
+
* go in the "View" menu of the relation display and uncheck "Hide
|
94
|
+
finalized", that will be useful for later.
|
95
|
+
* go in the "Task labels" and uncheck "Ownership". Ownership is only useful for
|
96
|
+
multi-robot plans.
|
97
|
+
|
98
|
+
**Very important note** your own display may not look exactly like the ones
|
99
|
+
displayed here. Some of the features showed here (like threaded planning) are
|
100
|
+
asynchronous and as such the exact displays depend on the execution timing. Note
|
101
|
+
that, even though it is the case, the robot _behaviour_ remains unchanged.
|
102
|
+
{.warning}
|
103
|
+
|
104
|
+
Startup of the "planned\_move!" action
|
105
|
+
---------------------------------------
|
106
|
+
|
107
|
+
Let's get to the first task-related events. Click on the 'Step' button until
|
108
|
+
something appears on the display. It should look like the next image:
|
109
|
+
|
110
|
+
![](log_replay/goForward_1.png)
|
111
|
+
|
112
|
+
The displays shows two plans (black boxes). The left one is the plan as it is
|
113
|
+
being executed. The right one is called a _transaction_ and allows to build a
|
114
|
+
new plan without interfering with the execution. You don't really need to know
|
115
|
+
how it works, only that it does the job. The task description includes the task
|
116
|
+
model and the task owners (which is only useful in multi-robot setup). The
|
117
|
+
_Task labels_ menu allows to customize that.
|
118
|
+
|
119
|
+
The left part is a representation of the plan built when the planned\_move!
|
120
|
+
command is entered in the shell. It consists of a generic task (Roby::Task)
|
121
|
+
which is planned\_by a Roby::PlanningTask. This is how Roby handles action
|
122
|
+
requests from the shell: (i) it searches a planner defined for that robot with
|
123
|
+
the specific action and (ii) generates the plan representing the planning
|
124
|
+
process _in a separate thread_.
|
125
|
+
|
126
|
+
Once that initial plan has been built, the Roby::PlanningTask task has been
|
127
|
+
started. The various cases of event propagation are represented in different
|
128
|
+
ways, based on whether or not the event is controlable or contingent, if it has been
|
129
|
+
called and/or emitted. Finally, two different arrow representations are used for
|
130
|
+
signalling (plain) and forwarding (dotted):
|
131
|
+
|
132
|
+
![](log_replay/roby_replay_event_representation.png)
|
133
|
+
|
134
|
+
A note about propagation representation: it would be useless to represent all
|
135
|
+
the event propagation from the beginning of the execution to the current point.
|
136
|
+
The display therefore represents only the propagations that have taken place
|
137
|
+
_since the last display point_. It means that, if you go forward 10
|
138
|
+
seconds, it will display 10 seconds worth of propagation. In our case, we
|
139
|
+
displayed only the first execution cycle and we see that, in this cycle, the
|
140
|
+
planning task "start" event has been called and emitted.
|
141
|
+
|
142
|
+
The MoveTo plan
|
143
|
+
---------------
|
144
|
+
|
145
|
+
Advance again using 'Step' until the display looks like this:
|
146
|
+
|
147
|
+
![](log_replay/goForward_2.png)
|
148
|
+
|
149
|
+
The MoveTo action has been planned and the executed plan is modified to reflect
|
150
|
+
that. The MoveTo action itself is then started, and that is propagated to the
|
151
|
+
ComputePath 'start' event through the signalling relation that was established
|
152
|
+
in planned\_move.
|
153
|
+
|
154
|
+
Next execution step gives us the following:
|
155
|
+
|
156
|
+
![](log_replay/goForward_3.png)
|
157
|
+
|
158
|
+
ComputePath emitted its "success" event. We see here that the emission of the
|
159
|
+
"success" event of that task does not mean 'the plan modification has just took
|
160
|
+
place' but instead that 'it has taken place some time earlier'.
|
161
|
+
|
162
|
+
The ComputePath task has also finished generating the path, which is why
|
163
|
+
ExecutePath is started. Here, the dotted lines between the events
|
164
|
+
represent a forwarding relation between them, while the plain lines
|
165
|
+
represent signal relations.
|
166
|
+
|
167
|
+
Finally, light grey here represents tasks that have finished with the "success"
|
168
|
+
event. Tasks whose "failed" event has been emitted are represented in red.
|
169
|
+
|
170
|
+
To finish: the garbage collection process
|
171
|
+
-----------------------------------------
|
172
|
+
|
173
|
+
Advance a few steps further, until something more happens. You should see
|
174
|
+
something like this:
|
175
|
+
|
176
|
+
![](log_replay/goForward_5.png)
|
177
|
+
|
178
|
+
Here, ExecutePath has finished its execution with success and MoveTo is therefore
|
179
|
+
finished as well -- per the forwarding relation between those two events. Note
|
180
|
+
that the tasks are now in a dark grey instead than a light one.
|
181
|
+
|
182
|
+
The mission of the robot, MoveTo, is therefore finished. From the plan
|
183
|
+
management point of view, it makes keeping a reference to it useless. In the
|
184
|
+
same way, the tasks that were in the plan for the purpose of fullfilling that
|
185
|
+
mission are rendered useless as well and can also be removed. The process which
|
186
|
+
removes those tasks is called the <i>garbage collection process</i> and runs at
|
187
|
+
the end of the execution cycle.
|
188
|
+
|
189
|
+
The general idea is to kill and remove from the plan the tasks that are not
|
190
|
+
useful for the achievement of the robot's missions. The "important" tasks for
|
191
|
+
the robot is defined by the set of its missions. These are added by calling
|
192
|
+
Plan#add\_mission instead of the Plan#add that we were using until now. Note
|
193
|
+
that, by calling the action through the shell, #add\_mission has been called
|
194
|
+
automatically by the framework.
|
195
|
+
|
196
|
+
Then, the task relations are used to determine what are the tasks, in the plan,
|
197
|
+
which are actually useful for those "important" tasks. This is based on the
|
198
|
+
convention that if a <tt>a=>b</tt> relation exists, then "b" is useful for "a".
|
199
|
+
|
200
|
+
The remaining tasks, i.e. the tasks that are not useful, are killed (if possible)
|
201
|
+
and removed from the plan. When it is done, the task is said to be finalized and
|
202
|
+
are displayed in dark grey (if they are not hidden in the View menu).
|
203
|
+
|
Binary file
|
@@ -0,0 +1,102 @@
|
|
1
|
+
---
|
2
|
+
title: Interactive Shell
|
3
|
+
sort_info: 400
|
4
|
+
--- pipeline:tags,markdown,blocks
|
5
|
+
|
6
|
+
As we saw earlier, the execution of Roby applications is done by an _event
|
7
|
+
loop_. The reactivity of the supervision system obviously depend on the
|
8
|
+
non-interruption of that event loop. Therefore, in a Roby application, the user
|
9
|
+
runs a remote shell that is used to send specific commands to the Roby
|
10
|
+
application itself.
|
11
|
+
|
12
|
+
{include_file: {filename: src/basics_shell_header.txt, escape_html: false}}
|
13
|
+
|
14
|
+
Planners
|
15
|
+
--------
|
16
|
+
Right now, we saw two different places where code is stored:
|
17
|
+
1. the tasks/ files, where task models are defined
|
18
|
+
2. the controllers/ files, which is the startup code for the application
|
19
|
+
|
20
|
+
What we will see in this section is a third component: the **planners**. These
|
21
|
+
planners define the aggregate actions that the robot knows about. As we will see
|
22
|
+
later, they also are the user interface of the robot.
|
23
|
+
|
24
|
+
Exporting actions to the user's shell
|
25
|
+
-------------------------------------
|
26
|
+
|
27
|
+
Edit planners/goForward/main.rb and edit so that it looks like this:
|
28
|
+
|
29
|
+
{coderay:: ruby}
|
30
|
+
require 'planners/main'
|
31
|
+
class MainPlanner
|
32
|
+
method(:move) do
|
33
|
+
GoForward.new :speed => arguments[:speed]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
{coderay}
|
37
|
+
|
38
|
+
That exports a very simple action to the user's shell. Now, we can try out the
|
39
|
+
Roby shell. First, remove the last three lines in controllers/goForward.rb so
|
40
|
+
that it looks like this:
|
41
|
+
|
42
|
+
{coderay:: ruby}
|
43
|
+
# Define the original value of x
|
44
|
+
State.pos.x = 0
|
45
|
+
|
46
|
+
# Will display the value of x every 1 second
|
47
|
+
Roby.every(1) do
|
48
|
+
puts State.pos.x
|
49
|
+
end
|
50
|
+
{coderay}
|
51
|
+
|
52
|
+
Now, start the roby application in one console:
|
53
|
+
|
54
|
+
$ scripts/run goForward
|
55
|
+
44848:44:51.498 (Roby) GC.enable does not accept an argument. GC will not be controlled by Roby
|
56
|
+
344848:44:51.581 (goForward) loaded Roby 0.7.90 on ruby 1.8.7 (2008-08-11 patchlevel 72) [powerpc-linux]
|
57
|
+
344848:44:51.603 (goForward) loading controller file /home/doudou/dev/roby-tutorials/controllers/goForward.rb
|
58
|
+
344848:44:51.605 (goForward) done initialization
|
59
|
+
0
|
60
|
+
0
|
61
|
+
|
62
|
+
Finally, start the shell in another console:
|
63
|
+
|
64
|
+
$ scripts/shell
|
65
|
+
localhost:48902 >
|
66
|
+
|
67
|
+
The new prompt you get is a Ruby prompt (i.e. you should type Ruby code in it).
|
68
|
+
Some special commands are available to interact with the Roby controller. For
|
69
|
+
instance:
|
70
|
+
|
71
|
+
{coderay:: ruby}
|
72
|
+
> actions
|
73
|
+
=> [move]
|
74
|
+
{coderay}
|
75
|
+
|
76
|
+
The 'action' command lists the available planning methods that are exported
|
77
|
+
through the MainPlanner class. Let's try it (**notice the '!' at the end of
|
78
|
+
move!**):
|
79
|
+
|
80
|
+
{coderay:: ruby}
|
81
|
+
> task = move! :speed => 1
|
82
|
+
=> GoForward{speed => 1}:0x48410aa8[]
|
83
|
+
> task.running?
|
84
|
+
=> true
|
85
|
+
> task.stop!
|
86
|
+
=> []
|
87
|
+
!task GoForward{speed => 1}:0x4850ddb0[] failed
|
88
|
+
!task GoForward{speed => 1}:0x4850ddb0[] stopped by user request
|
89
|
+
> task.running?
|
90
|
+
=> false
|
91
|
+
{coderay}
|
92
|
+
|
93
|
+
The new task is running just after it has been added ! In Roby, a new task, when
|
94
|
+
added in the main plan, becomes eligible for _scheduling_, i.e. a special
|
95
|
+
component tries to find the best time to start it (which, in our case, is
|
96
|
+
"now"). We'll see more about this later.
|
97
|
+
{: .warning}
|
98
|
+
|
99
|
+
You can see that the action method returns the task that the planning method has
|
100
|
+
returned. Even though we are on a remote shell, the returned task object
|
101
|
+
supports sending commands, checking its status, emitting events, ...
|
102
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
title: Summary
|
3
|
+
sort_info: 900
|
4
|
+
--- pipeline:tags,rdoc,blocks
|
5
|
+
|
6
|
+
|
7
|
+
* *events* allow you to represent the robot's situations and the commands that the
|
8
|
+
robot accepts
|
9
|
+
* the _Signal_ relation represents reactions: it calls the command of the
|
10
|
+
target when the source is emitted.
|
11
|
+
* the _Forwarding_ relation represents generalization: it emits the target
|
12
|
+
event when the source is emitted, and therefore the _situation_ of the
|
13
|
+
target is a superset of the _situation_ of the source.
|
14
|
+
* event handlers allow to call arbitrary code blocks when an event is emitted.
|
15
|
+
* *tasks* allow you to represent the processes that run on the robot.
|
16
|
+
* the _Hierarchy_ relation represents dependencies between tasks.
|
17
|
+
* <b>a Roby application</b> allows you to build a controller for a robot
|
18
|
+
* the task models are put in the tasks/ subdirectory
|
19
|
+
* the startup code is put in the robot's controllers/ file
|
20
|
+
* a Roby shell allows to interact with a running application
|
21
|
+
* planning methods can be defined in planners/ROBOT_NAME/main.rb. Those
|
22
|
+
methods define the set of actions that is exported to the Roby shell
|
23
|
+
* it is possible to log execution traces and replay them using
|
24
|
+
<tt>roby-log</tt>
|
25
|
+
* <b>error handling</b>
|
26
|
+
* errors in user code are harmless to the Roby application as a whole
|
27
|
+
* the hierarchy relation allows to automatically detect failed dependencies
|
28
|
+
* three means exist to repair errors:
|
29
|
+
- in event handlers
|
30
|
+
- using plan repairs
|
31
|
+
- using exception handlers
|
32
|
+
|