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,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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+
|