roby 0.8.0 → 3.0.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.
- checksums.yaml +7 -0
- data/.deep-cover.rb +3 -0
- data/.gitattributes +1 -0
- data/.gitignore +24 -0
- data/.simplecov +10 -0
- data/.travis.yml +17 -0
- data/.yardopts +4 -0
- data/Gemfile +15 -0
- data/README.md +11 -0
- data/Rakefile +47 -177
- data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
- data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
- data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
- data/benchmark/{genom.rb → attic/genom.rb} +0 -0
- data/benchmark/attic/transactions.rb +62 -0
- data/benchmark/plan_basic_operations.rb +28 -0
- data/benchmark/relations/graph.rb +63 -0
- data/benchmark/ruby/identity.rb +18 -0
- data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
- data/benchmark/ruby/yield_vs_block.rb +35 -0
- data/benchmark/run +5 -0
- data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
- data/benchmark/transactions.rb +99 -51
- data/bin/roby +38 -197
- data/bin/roby-display +14 -0
- data/bin/roby-log +3 -176
- data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
- data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
- data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
- data/doc/guide/{src → attic}/abstraction/index.page +1 -1
- data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
- data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
- data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
- data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
- data/doc/guide/attic/cycle/error_handling.page +98 -0
- data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
- data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
- data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
- data/doc/guide/{src → attic}/cycle/index.page +1 -1
- data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
- data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
- data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
- data/doc/guide/attic/plans/building_plans.page +89 -0
- data/doc/guide/attic/plans/code.page +192 -0
- data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
- data/doc/guide/attic/plans/index.page +7 -0
- data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
- data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
- data/doc/guide/attic/plans/querying_plans.page +5 -0
- data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
- data/doc/guide/config.yaml +7 -4
- data/doc/guide/ext/extended_menu.rb +29 -0
- data/doc/guide/ext/init.rb +6 -0
- data/doc/guide/ext/rdoc_links.rb +7 -6
- data/doc/guide/src/advanced_concepts/history.page +5 -0
- data/doc/guide/src/advanced_concepts/index.page +11 -0
- data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
- data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
- data/doc/guide/src/advanced_concepts/transactions.page +5 -0
- data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
- data/doc/guide/src/base.template +96 -0
- data/doc/guide/src/basics_shell_header.txt +5 -7
- data/doc/guide/src/building/action_coordination.page +96 -0
- data/doc/guide/src/building/actions.page +124 -0
- data/doc/guide/src/building/file_layout.page +71 -0
- data/doc/guide/src/building/index.page +50 -0
- data/doc/guide/src/building/patterns.page +86 -0
- data/doc/guide/src/building/patterns_forwarding.png +0 -0
- data/doc/guide/src/building/patterns_forwarding.svg +277 -0
- data/doc/guide/src/building/runtime.page +95 -0
- data/doc/guide/src/building/task_models.page +94 -0
- data/doc/guide/src/building/tasks.page +284 -0
- data/doc/guide/src/concepts/error_handling.page +100 -0
- data/doc/guide/src/concepts/exception_propagation.png +0 -0
- data/doc/guide/src/concepts/exception_propagation.svg +445 -0
- data/doc/guide/src/concepts/execution.page +85 -0
- data/doc/guide/src/concepts/execution.png +0 -0
- data/doc/guide/src/concepts/execution.svg +573 -0
- data/doc/guide/src/concepts/execution_cycle.png +0 -0
- data/doc/guide/src/concepts/garbage_collection.page +57 -0
- data/doc/guide/src/concepts/index.page +27 -0
- data/doc/guide/src/concepts/plans.page +101 -0
- data/doc/guide/src/concepts/policy.page +31 -0
- data/doc/guide/src/concepts/reactor.page +61 -0
- data/doc/guide/src/concepts/simple_plan_example.png +0 -0
- data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
- data/doc/guide/src/default.template +9 -74
- data/doc/guide/src/event_relations/forward.page +71 -0
- data/doc/guide/src/event_relations/index.page +12 -0
- data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
- data/doc/guide/src/event_relations/signal.page +55 -0
- data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
- data/doc/guide/src/htmldoc.metainfo +21 -8
- data/doc/guide/src/index.page +8 -3
- data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
- data/doc/guide/src/installation/publications.page +14 -0
- data/doc/guide/src/{introduction → installation}/videos.page +14 -7
- data/doc/guide/src/interacting/index.page +16 -0
- data/doc/guide/src/interacting/run.page +33 -0
- data/doc/guide/src/interacting/shell.page +95 -0
- data/doc/guide/src/plugins/creating_plugins.page +72 -0
- data/doc/guide/src/plugins/index.page +27 -5
- data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
- data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
- data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
- data/doc/guide/src/style_screen.css +687 -0
- data/doc/guide/src/task_relations/dependency.page +107 -0
- data/doc/guide/src/task_relations/executed_by.page +77 -0
- data/doc/guide/src/task_relations/index.page +12 -0
- data/doc/guide/src/task_relations/new_relations.page +119 -0
- data/doc/guide/src/task_relations/planned_by.page +46 -0
- data/doc/guide/src/tutorial/app.page +117 -0
- data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
- data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
- data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
- data/doc/guide/src/tutorial/events.page +195 -0
- data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
- data/doc/guide/src/tutorial/index.page +13 -0
- data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
- data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/tutorial/relations_display.page +153 -0
- data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
- data/doc/guide/src/tutorial/shell.page +121 -0
- data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
- data/doc/guide/src/tutorial/tasks.page +374 -0
- data/lib/roby.rb +102 -47
- data/lib/roby/actions.rb +17 -0
- data/lib/roby/actions/action.rb +80 -0
- data/lib/roby/actions/interface.rb +45 -0
- data/lib/roby/actions/library.rb +23 -0
- data/lib/roby/actions/models/action.rb +224 -0
- data/lib/roby/actions/models/coordination_action.rb +58 -0
- data/lib/roby/actions/models/interface.rb +22 -0
- data/lib/roby/actions/models/interface_base.rb +294 -0
- data/lib/roby/actions/models/library.rb +12 -0
- data/lib/roby/actions/models/method_action.rb +90 -0
- data/lib/roby/actions/task.rb +114 -0
- data/lib/roby/and_generator.rb +125 -0
- data/lib/roby/app.rb +2795 -829
- data/lib/roby/app/autotest_console_reporter.rb +138 -0
- data/lib/roby/app/base.rb +21 -0
- data/lib/roby/app/cucumber.rb +2 -0
- data/lib/roby/app/cucumber/controller.rb +439 -0
- data/lib/roby/app/cucumber/helpers.rb +280 -0
- data/lib/roby/app/cucumber/world.rb +32 -0
- data/lib/roby/app/debug.rb +136 -0
- data/lib/roby/app/gen.rb +2 -0
- data/lib/roby/app/rake.rb +178 -38
- data/lib/roby/app/robot_config.rb +9 -0
- data/lib/roby/app/robot_names.rb +115 -0
- data/lib/roby/app/run.rb +3 -2
- data/lib/roby/app/scripts.rb +72 -0
- data/lib/roby/app/scripts/autotest.rb +173 -0
- data/lib/roby/app/scripts/display.rb +2 -0
- data/lib/roby/app/scripts/restart.rb +52 -0
- data/lib/roby/app/scripts/results.rb +17 -8
- data/lib/roby/app/scripts/run.rb +155 -24
- data/lib/roby/app/scripts/shell.rb +147 -62
- data/lib/roby/app/scripts/test.rb +107 -22
- data/lib/roby/app/test_reporter.rb +74 -0
- data/lib/roby/app/test_server.rb +159 -0
- data/lib/roby/app/vagrant.rb +47 -0
- data/lib/roby/backports.rb +16 -0
- data/lib/roby/cli/display.rb +190 -0
- data/lib/roby/cli/exceptions.rb +17 -0
- data/lib/roby/cli/gen/actions/class.rb +5 -0
- data/lib/roby/cli/gen/actions/test.rb +6 -0
- data/lib/roby/cli/gen/app/.yardopts +6 -0
- data/lib/roby/cli/gen/app/README.md +28 -0
- data/lib/roby/cli/gen/app/Rakefile +15 -0
- data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
- data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
- data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
- data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
- data/lib/roby/cli/gen/class/class.rb +6 -0
- data/lib/roby/cli/gen/class/test.rb +7 -0
- data/lib/roby/cli/gen/helpers.rb +203 -0
- data/lib/roby/cli/gen/module/module.rb +5 -0
- data/lib/roby/cli/gen/module/test.rb +6 -0
- data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
- data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
- data/lib/roby/cli/gen/task/class.rb +44 -0
- data/lib/roby/cli/gen/task/test.rb +6 -0
- data/lib/roby/cli/gen_main.rb +120 -0
- data/lib/roby/cli/log.rb +276 -0
- data/lib/roby/cli/log/flamegraph.html +499 -0
- data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
- data/lib/roby/cli/main.rb +153 -0
- data/lib/roby/coordination.rb +60 -0
- data/lib/roby/coordination/action_script.rb +25 -0
- data/lib/roby/coordination/action_state_machine.rb +125 -0
- data/lib/roby/coordination/actions.rb +106 -0
- data/lib/roby/coordination/base.rb +145 -0
- data/lib/roby/coordination/calculus.rb +40 -0
- data/lib/roby/coordination/child.rb +28 -0
- data/lib/roby/coordination/event.rb +29 -0
- data/lib/roby/coordination/fault_handler.rb +25 -0
- data/lib/roby/coordination/fault_handling_task.rb +13 -0
- data/lib/roby/coordination/fault_response_table.rb +110 -0
- data/lib/roby/coordination/models/action_script.rb +64 -0
- data/lib/roby/coordination/models/action_state_machine.rb +224 -0
- data/lib/roby/coordination/models/actions.rb +191 -0
- data/lib/roby/coordination/models/arguments.rb +55 -0
- data/lib/roby/coordination/models/base.rb +176 -0
- data/lib/roby/coordination/models/capture.rb +86 -0
- data/lib/roby/coordination/models/child.rb +35 -0
- data/lib/roby/coordination/models/event.rb +41 -0
- data/lib/roby/coordination/models/exceptions.rb +42 -0
- data/lib/roby/coordination/models/fault_handler.rb +219 -0
- data/lib/roby/coordination/models/fault_response_table.rb +77 -0
- data/lib/roby/coordination/models/root.rb +22 -0
- data/lib/roby/coordination/models/script.rb +283 -0
- data/lib/roby/coordination/models/task.rb +184 -0
- data/lib/roby/coordination/models/task_from_action.rb +50 -0
- data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
- data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
- data/lib/roby/coordination/models/task_from_variable.rb +27 -0
- data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
- data/lib/roby/coordination/models/variable.rb +32 -0
- data/lib/roby/coordination/script.rb +200 -0
- data/lib/roby/coordination/script_instruction.rb +12 -0
- data/lib/roby/coordination/task.rb +45 -0
- data/lib/roby/coordination/task_base.rb +69 -0
- data/lib/roby/coordination/task_script.rb +293 -0
- data/lib/roby/coordination/task_state_machine.rb +308 -0
- data/lib/roby/decision_control.rb +33 -21
- data/lib/roby/distributed_object.rb +76 -0
- data/lib/roby/droby.rb +17 -0
- data/lib/roby/droby/droby_id.rb +6 -0
- data/lib/roby/droby/enable.rb +153 -0
- data/lib/roby/droby/event_logger.rb +189 -0
- data/lib/roby/droby/event_logging.rb +57 -0
- data/lib/roby/droby/exceptions.rb +14 -0
- data/lib/roby/droby/identifiable.rb +22 -0
- data/lib/roby/droby/logfile.rb +141 -0
- data/lib/roby/droby/logfile/client.rb +176 -0
- data/lib/roby/droby/logfile/file_format.md +97 -0
- data/lib/roby/droby/logfile/index.rb +117 -0
- data/lib/roby/droby/logfile/reader.rb +139 -0
- data/lib/roby/droby/logfile/server.rb +199 -0
- data/lib/roby/droby/logfile/writer.rb +114 -0
- data/lib/roby/droby/marshal.rb +264 -0
- data/lib/roby/droby/marshallable.rb +12 -0
- data/lib/roby/droby/null_event_logger.rb +25 -0
- data/lib/roby/droby/object_manager.rb +205 -0
- data/lib/roby/droby/peer_id.rb +6 -0
- data/lib/roby/droby/plan_rebuilder.rb +373 -0
- data/lib/roby/droby/rebuilt_plan.rb +160 -0
- data/lib/roby/droby/remote_droby_id.rb +6 -0
- data/lib/roby/droby/timepoints.rb +205 -0
- data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
- data/lib/roby/droby/timepoints_ctf.rb +125 -0
- data/lib/roby/droby/v5.rb +14 -0
- data/lib/roby/droby/v5/builtin.rb +120 -0
- data/lib/roby/droby/v5/droby_class.rb +45 -0
- data/lib/roby/droby/v5/droby_constant.rb +81 -0
- data/lib/roby/droby/v5/droby_dump.rb +1026 -0
- data/lib/roby/droby/v5/droby_id.rb +44 -0
- data/lib/roby/droby/v5/droby_model.rb +82 -0
- data/lib/roby/droby/v5/peer_id.rb +10 -0
- data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
- data/lib/roby/event.rb +79 -957
- data/lib/roby/event_constraints.rb +835 -0
- data/lib/roby/event_generator.rb +1047 -0
- data/lib/roby/event_structure/causal_link.rb +6 -0
- data/lib/roby/event_structure/forwarding.rb +6 -0
- data/lib/roby/event_structure/precedence.rb +7 -0
- data/lib/roby/event_structure/signal.rb +8 -0
- data/lib/roby/event_structure/temporal_constraints.rb +640 -0
- data/lib/roby/exceptions.rb +446 -152
- data/lib/roby/executable_plan.rb +549 -0
- data/lib/roby/execution_engine.rb +1997 -950
- data/lib/roby/filter_generator.rb +26 -0
- data/lib/roby/gui/chronicle_view.rb +225 -0
- data/lib/roby/gui/chronicle_widget.rb +925 -0
- data/lib/roby/gui/dot_id.rb +11 -0
- data/lib/roby/gui/exception_view.rb +44 -0
- data/lib/roby/gui/log_display.rb +273 -0
- data/lib/roby/gui/model_views.rb +2 -0
- data/lib/roby/gui/model_views/action_interface.rb +53 -0
- data/lib/roby/gui/model_views/task.rb +47 -0
- data/lib/roby/gui/model_views/task.rhtml +41 -0
- data/lib/roby/gui/object_info_view.rb +89 -0
- data/lib/roby/gui/plan_dot_layout.rb +427 -0
- data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
- data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
- data/lib/roby/gui/relations_view.rb +278 -0
- data/lib/roby/gui/relations_view/relations.ui +139 -0
- data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
- data/lib/roby/gui/relations_view/relations_config.rb +292 -0
- data/lib/roby/gui/relations_view/relations_view.ui +53 -0
- data/lib/roby/gui/scheduler_view.css +24 -0
- data/lib/roby/gui/scheduler_view.rb +46 -0
- data/lib/roby/gui/scheduler_view.rhtml +53 -0
- data/lib/roby/gui/stepping.rb +93 -0
- data/lib/roby/gui/stepping.ui +181 -0
- data/lib/roby/gui/styles.rb +81 -0
- data/lib/roby/gui/task_display_configuration.rb +42 -0
- data/lib/roby/gui/task_state_at.rb +38 -0
- data/lib/roby/hooks.rb +26 -0
- data/lib/roby/interface.rb +136 -469
- data/lib/roby/interface/async.rb +20 -0
- data/lib/roby/interface/async/action_monitor.rb +188 -0
- data/lib/roby/interface/async/interface.rb +498 -0
- data/lib/roby/interface/async/job_monitor.rb +213 -0
- data/lib/roby/interface/async/log.rb +238 -0
- data/lib/roby/interface/async/new_job_listener.rb +79 -0
- data/lib/roby/interface/async/ui_connector.rb +183 -0
- data/lib/roby/interface/client.rb +553 -0
- data/lib/roby/interface/command.rb +24 -0
- data/lib/roby/interface/command_argument.rb +16 -0
- data/lib/roby/interface/command_library.rb +92 -0
- data/lib/roby/interface/droby_channel.rb +174 -0
- data/lib/roby/interface/exceptions.rb +22 -0
- data/lib/roby/interface/interface.rb +655 -0
- data/lib/roby/interface/job.rb +47 -0
- data/lib/roby/interface/rest.rb +10 -0
- data/lib/roby/interface/rest/api.rb +29 -0
- data/lib/roby/interface/rest/helpers.rb +24 -0
- data/lib/roby/interface/rest/server.rb +212 -0
- data/lib/roby/interface/server.rb +154 -0
- data/lib/roby/interface/shell_client.rb +468 -0
- data/lib/roby/interface/shell_subcommand.rb +24 -0
- data/lib/roby/interface/subcommand_client.rb +35 -0
- data/lib/roby/interface/tcp.rb +168 -0
- data/lib/roby/models/arguments.rb +112 -0
- data/lib/roby/models/plan_object.rb +83 -0
- data/lib/roby/models/task.rb +835 -0
- data/lib/roby/models/task_event.rb +62 -0
- data/lib/roby/models/task_service.rb +78 -0
- data/lib/roby/or_generator.rb +88 -0
- data/lib/roby/plan.rb +1751 -864
- data/lib/roby/plan_object.rb +611 -0
- data/lib/roby/plan_service.rb +200 -0
- data/lib/roby/promise.rb +332 -0
- data/lib/roby/queries.rb +23 -0
- data/lib/roby/queries/and_matcher.rb +32 -0
- data/lib/roby/queries/any.rb +27 -0
- data/lib/roby/queries/code_error_matcher.rb +58 -0
- data/lib/roby/queries/event_generator_matcher.rb +9 -0
- data/lib/roby/queries/execution_exception_matcher.rb +165 -0
- data/lib/roby/queries/index.rb +165 -0
- data/lib/roby/queries/localized_error_matcher.rb +149 -0
- data/lib/roby/queries/matcher_base.rb +107 -0
- data/lib/roby/queries/none.rb +27 -0
- data/lib/roby/queries/not_matcher.rb +30 -0
- data/lib/roby/queries/op_matcher.rb +8 -0
- data/lib/roby/queries/or_matcher.rb +30 -0
- data/lib/roby/queries/plan_object_matcher.rb +363 -0
- data/lib/roby/queries/query.rb +188 -0
- data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
- data/lib/roby/queries/task_matcher.rb +344 -0
- data/lib/roby/relations.rb +42 -678
- data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
- data/lib/roby/relations/directed_relation_support.rb +268 -0
- data/lib/roby/relations/event_relation_graph.rb +19 -0
- data/lib/roby/relations/fork_merge_visitor.rb +154 -0
- data/lib/roby/relations/graph.rb +533 -0
- data/lib/roby/relations/models/directed_relation_support.rb +11 -0
- data/lib/roby/relations/models/graph.rb +75 -0
- data/lib/roby/relations/models/task_relation_graph.rb +18 -0
- data/lib/roby/relations/space.rb +380 -0
- data/lib/roby/relations/task_relation_graph.rb +20 -0
- data/lib/roby/robot.rb +85 -38
- data/lib/roby/schedulers/basic.rb +155 -25
- data/lib/roby/schedulers/null.rb +20 -0
- data/lib/roby/schedulers/reporting.rb +31 -0
- data/lib/roby/schedulers/state.rb +129 -0
- data/lib/roby/schedulers/temporal.rb +91 -0
- data/lib/roby/singletons.rb +87 -0
- data/lib/roby/standalone.rb +4 -2
- data/lib/roby/standard_errors.rb +405 -82
- data/lib/roby/state.rb +6 -3
- data/lib/roby/state/conf_model.rb +5 -0
- data/lib/roby/state/events.rb +181 -95
- data/lib/roby/state/goal_model.rb +77 -0
- data/lib/roby/state/open_struct.rb +591 -0
- data/lib/roby/state/open_struct_model.rb +68 -0
- data/lib/roby/state/pos.rb +45 -45
- data/lib/roby/state/shapes.rb +11 -11
- data/lib/roby/state/state_model.rb +303 -0
- data/lib/roby/state/task.rb +43 -0
- data/lib/roby/support.rb +88 -148
- data/lib/roby/task.rb +1361 -1750
- data/lib/roby/task_arguments.rb +428 -0
- data/lib/roby/task_event.rb +127 -0
- data/lib/roby/task_event_generator.rb +337 -0
- data/lib/roby/task_service.rb +6 -0
- data/lib/roby/task_structure/conflicts.rb +104 -0
- data/lib/roby/task_structure/dependency.rb +932 -0
- data/lib/roby/task_structure/error_handling.rb +118 -0
- data/lib/roby/task_structure/executed_by.rb +234 -0
- data/lib/roby/task_structure/planned_by.rb +90 -0
- data/lib/roby/tasks/aggregator.rb +37 -0
- data/lib/roby/tasks/external_process.rb +275 -0
- data/lib/roby/tasks/group.rb +27 -0
- data/lib/roby/tasks/null.rb +19 -0
- data/lib/roby/tasks/parallel.rb +43 -0
- data/lib/roby/tasks/sequence.rb +88 -0
- data/lib/roby/tasks/simple.rb +21 -0
- data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
- data/lib/roby/tasks/timeout.rb +17 -0
- data/lib/roby/tasks/virtual.rb +55 -0
- data/lib/roby/template_plan.rb +7 -0
- data/lib/roby/test/aruba_minitest.rb +74 -0
- data/lib/roby/test/assertion.rb +16 -0
- data/lib/roby/test/assertions.rb +490 -0
- data/lib/roby/test/common.rb +368 -591
- data/lib/roby/test/dsl.rb +149 -0
- data/lib/roby/test/error.rb +18 -0
- data/lib/roby/test/event_reporter.rb +83 -0
- data/lib/roby/test/execution_expectations.rb +1134 -0
- data/lib/roby/test/expect_execution.rb +151 -0
- data/lib/roby/test/minitest_helpers.rb +166 -0
- data/lib/roby/test/roby_app_helpers.rb +200 -0
- data/lib/roby/test/run_planners.rb +155 -0
- data/lib/roby/test/self.rb +112 -0
- data/lib/roby/test/spec.rb +198 -0
- data/lib/roby/test/tasks/empty_task.rb +4 -4
- data/lib/roby/test/tasks/goto.rb +28 -27
- data/lib/roby/test/teardown_plans.rb +100 -0
- data/lib/roby/test/testcase.rb +239 -307
- data/lib/roby/test/tools.rb +159 -155
- data/lib/roby/test/validate_state_machine.rb +75 -0
- data/lib/roby/transaction.rb +1125 -0
- data/lib/roby/transaction/event_generator_proxy.rb +63 -0
- data/lib/roby/transaction/plan_object_proxy.rb +99 -0
- data/lib/roby/transaction/plan_service_proxy.rb +43 -0
- data/lib/roby/transaction/proxying.rb +120 -0
- data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
- data/lib/roby/transaction/task_proxy.rb +135 -0
- data/lib/roby/until_generator.rb +30 -0
- data/lib/roby/version.rb +5 -0
- data/lib/roby/yard.rb +169 -0
- data/lib/yard-roby.rb +1 -0
- data/manifest.xml +32 -6
- data/roby.gemspec +59 -0
- metadata +788 -587
- data/Manifest.txt +0 -321
- data/NOTES +0 -4
- data/README.txt +0 -166
- data/TODO.txt +0 -146
- data/app/README.txt +0 -24
- data/app/Rakefile +0 -8
- data/app/config/ROBOT.rb +0 -5
- data/app/config/init.rb +0 -33
- data/app/config/roby.yml +0 -3
- data/app/controllers/ROBOT.rb +0 -2
- data/app/planners/ROBOT/main.rb +0 -6
- data/app/planners/main.rb +0 -5
- data/app/scripts/distributed +0 -3
- data/app/scripts/generate/bookmarks +0 -3
- data/app/scripts/replay +0 -3
- data/app/scripts/results +0 -3
- data/app/scripts/run +0 -3
- data/app/scripts/server +0 -3
- data/app/scripts/shell +0 -3
- data/app/scripts/test +0 -3
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby-shell +0 -25
- data/doc/guide/src/basics/app.page +0 -139
- data/doc/guide/src/basics/index.page +0 -11
- 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_5.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/relations_display.page +0 -203
- data/doc/guide/src/basics/shell.page +0 -102
- data/doc/guide/src/default.css +0 -319
- data/doc/guide/src/introduction/index.page +0 -29
- data/doc/guide/src/introduction/publications.page +0 -14
- data/doc/guide/src/relations/dependency.page +0 -89
- data/doc/guide/src/relations/index.page +0 -12
- data/ext/droby/dump.cc +0 -175
- data/ext/droby/extconf.rb +0 -3
- data/ext/graph/algorithm.cc +0 -746
- data/ext/graph/extconf.rb +0 -7
- data/ext/graph/graph.cc +0 -575
- data/ext/graph/graph.hh +0 -183
- data/ext/graph/iterator_sequence.hh +0 -102
- data/ext/graph/undirected_dfs.hh +0 -226
- data/ext/graph/undirected_graph.hh +0 -421
- data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
- data/lib/roby/app/scripts/replay.rb +0 -31
- data/lib/roby/app/scripts/server.rb +0 -18
- data/lib/roby/basic_object.rb +0 -151
- data/lib/roby/config.rb +0 -14
- data/lib/roby/distributed.rb +0 -36
- data/lib/roby/distributed/base.rb +0 -448
- data/lib/roby/distributed/communication.rb +0 -875
- data/lib/roby/distributed/connection_space.rb +0 -616
- data/lib/roby/distributed/distributed_object.rb +0 -206
- data/lib/roby/distributed/drb.rb +0 -62
- data/lib/roby/distributed/notifications.rb +0 -531
- data/lib/roby/distributed/peer.rb +0 -555
- data/lib/roby/distributed/protocol.rb +0 -529
- data/lib/roby/distributed/proxy.rb +0 -343
- data/lib/roby/distributed/subscription.rb +0 -311
- data/lib/roby/distributed/transaction.rb +0 -498
- data/lib/roby/external_process_task.rb +0 -225
- data/lib/roby/graph.rb +0 -160
- data/lib/roby/log.rb +0 -3
- data/lib/roby/log/chronicle.rb +0 -303
- data/lib/roby/log/console.rb +0 -74
- data/lib/roby/log/data_stream.rb +0 -275
- data/lib/roby/log/dot.rb +0 -279
- data/lib/roby/log/event_stream.rb +0 -161
- data/lib/roby/log/file.rb +0 -396
- data/lib/roby/log/gui/basic_display.ui +0 -83
- data/lib/roby/log/gui/basic_display_ui.rb +0 -89
- data/lib/roby/log/gui/chronicle.rb +0 -26
- data/lib/roby/log/gui/chronicle_view.rb +0 -40
- data/lib/roby/log/gui/chronicle_view.ui +0 -70
- data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
- data/lib/roby/log/gui/data_displays.rb +0 -171
- data/lib/roby/log/gui/data_displays.ui +0 -155
- data/lib/roby/log/gui/data_displays_ui.rb +0 -146
- data/lib/roby/log/gui/notifications.rb +0 -26
- data/lib/roby/log/gui/relations.rb +0 -269
- data/lib/roby/log/gui/relations.ui +0 -123
- data/lib/roby/log/gui/relations_ui.rb +0 -120
- data/lib/roby/log/gui/relations_view.rb +0 -185
- data/lib/roby/log/gui/relations_view.ui +0 -149
- data/lib/roby/log/gui/relations_view_ui.rb +0 -144
- data/lib/roby/log/gui/replay.rb +0 -366
- data/lib/roby/log/gui/replay_controls.rb +0 -206
- data/lib/roby/log/gui/replay_controls.ui +0 -282
- data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
- data/lib/roby/log/gui/runtime.rb +0 -130
- data/lib/roby/log/hooks.rb +0 -186
- data/lib/roby/log/logger.rb +0 -203
- data/lib/roby/log/notifications.rb +0 -244
- data/lib/roby/log/plan_rebuilder.rb +0 -468
- data/lib/roby/log/relations.rb +0 -1084
- data/lib/roby/log/server.rb +0 -547
- data/lib/roby/log/sqlite.rb +0 -47
- data/lib/roby/log/timings.rb +0 -233
- data/lib/roby/plan-object.rb +0 -371
- data/lib/roby/planning.rb +0 -13
- data/lib/roby/planning/loops.rb +0 -309
- data/lib/roby/planning/model.rb +0 -1012
- data/lib/roby/planning/task.rb +0 -180
- data/lib/roby/query.rb +0 -655
- data/lib/roby/relations/conflicts.rb +0 -67
- data/lib/roby/relations/dependency.rb +0 -358
- data/lib/roby/relations/ensured.rb +0 -19
- data/lib/roby/relations/error_handling.rb +0 -22
- data/lib/roby/relations/events.rb +0 -7
- data/lib/roby/relations/executed_by.rb +0 -208
- data/lib/roby/relations/influence.rb +0 -10
- data/lib/roby/relations/planned_by.rb +0 -63
- data/lib/roby/state/information.rb +0 -55
- data/lib/roby/state/state.rb +0 -367
- data/lib/roby/task-operations.rb +0 -186
- data/lib/roby/task_index.rb +0 -80
- data/lib/roby/test/distributed.rb +0 -230
- data/lib/roby/test/tasks/simple_task.rb +0 -23
- data/lib/roby/transactions.rb +0 -507
- data/lib/roby/transactions/proxy.rb +0 -325
- data/plugins/fault_injection/History.txt +0 -4
- data/plugins/fault_injection/README.txt +0 -34
- data/plugins/fault_injection/Rakefile +0 -12
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +0 -52
- data/plugins/fault_injection/fault_injection.rb +0 -89
- data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
- data/plugins/subsystems/README.txt +0 -37
- data/plugins/subsystems/Rakefile +0 -13
- data/plugins/subsystems/app.rb +0 -182
- data/plugins/subsystems/test/app/README +0 -24
- data/plugins/subsystems/test/app/Rakefile +0 -8
- data/plugins/subsystems/test/app/config/app.yml +0 -71
- data/plugins/subsystems/test/app/config/init.rb +0 -12
- data/plugins/subsystems/test/app/config/roby.yml +0 -3
- data/plugins/subsystems/test/app/planners/main.rb +0 -20
- data/plugins/subsystems/test/app/scripts/distributed +0 -3
- data/plugins/subsystems/test/app/scripts/replay +0 -3
- data/plugins/subsystems/test/app/scripts/results +0 -3
- data/plugins/subsystems/test/app/scripts/run +0 -3
- data/plugins/subsystems/test/app/scripts/server +0 -3
- data/plugins/subsystems/test/app/scripts/shell +0 -3
- data/plugins/subsystems/test/app/scripts/test +0 -3
- data/plugins/subsystems/test/app/tasks/services.rb +0 -15
- data/plugins/subsystems/test/test_subsystems.rb +0 -78
- data/test/distributed/test_communication.rb +0 -195
- data/test/distributed/test_connection.rb +0 -284
- data/test/distributed/test_execution.rb +0 -378
- data/test/distributed/test_mixed_plan.rb +0 -341
- data/test/distributed/test_plan_notifications.rb +0 -238
- data/test/distributed/test_protocol.rb +0 -525
- data/test/distributed/test_query.rb +0 -106
- data/test/distributed/test_remote_plan.rb +0 -491
- data/test/distributed/test_transaction.rb +0 -466
- data/test/mockups/external_process +0 -28
- data/test/mockups/tasks.rb +0 -27
- data/test/planning/test_loops.rb +0 -432
- data/test/planning/test_model.rb +0 -427
- data/test/planning/test_task.rb +0 -126
- data/test/relations/test_conflicts.rb +0 -42
- data/test/relations/test_dependency.rb +0 -324
- data/test/relations/test_ensured.rb +0 -38
- data/test/relations/test_executed_by.rb +0 -224
- data/test/relations/test_planned_by.rb +0 -56
- data/test/suite_core.rb +0 -29
- data/test/suite_distributed.rb +0 -10
- data/test/suite_planning.rb +0 -4
- data/test/suite_relations.rb +0 -8
- data/test/tasks/test_external_process.rb +0 -126
- data/test/tasks/test_thread_task.rb +0 -70
- data/test/test_bgl.rb +0 -528
- data/test/test_event.rb +0 -969
- data/test/test_exceptions.rb +0 -591
- data/test/test_execution_engine.rb +0 -987
- data/test/test_gui.rb +0 -20
- data/test/test_interface.rb +0 -43
- data/test/test_log.rb +0 -125
- data/test/test_log_server.rb +0 -133
- data/test/test_plan.rb +0 -418
- data/test/test_query.rb +0 -424
- data/test/test_relations.rb +0 -260
- data/test/test_state.rb +0 -432
- data/test/test_support.rb +0 -16
- data/test/test_task.rb +0 -1181
- data/test/test_testcase.rb +0 -138
- data/test/test_transactions.rb +0 -610
- data/test/test_transactions_proxy.rb +0 -216
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Coordination
|
|
3
|
+
class ResolvingUnboundObject < RuntimeError; end
|
|
4
|
+
|
|
5
|
+
# Base functionality for task-like objects in coordination models
|
|
6
|
+
# (Task, Child)
|
|
7
|
+
class TaskBase
|
|
8
|
+
# @return [Base] the underlying execution context
|
|
9
|
+
attr_reader :execution_context
|
|
10
|
+
# @return [Coordination::Models::Task]
|
|
11
|
+
attr_reader :model
|
|
12
|
+
|
|
13
|
+
def initialize(execution_context, model)
|
|
14
|
+
@execution_context = execution_context
|
|
15
|
+
@model = model
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Method that must be reimplemented in the task objects actually
|
|
19
|
+
# used in the coordination primitives
|
|
20
|
+
def resolve
|
|
21
|
+
raise NotImplementedError, "#resolve must be reimplemented in objects meant to be used in the coordination primitives"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def find_child(role, child_model = nil)
|
|
25
|
+
child_model ||= model.find_child_model(role)
|
|
26
|
+
if !child_model
|
|
27
|
+
begin
|
|
28
|
+
task = self.resolve
|
|
29
|
+
if child_task = task.find_child_from_role(role)
|
|
30
|
+
child_model = child_task.model
|
|
31
|
+
end
|
|
32
|
+
rescue ResolvingUnboundObject
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if child = model.find_child(role, child_model)
|
|
37
|
+
execution_context.instance_for(child)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def find_event(symbol)
|
|
42
|
+
if event = model.find_event(symbol)
|
|
43
|
+
execution_context.instance_for(event)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def find_through_method_missing(m, args)
|
|
48
|
+
MetaRuby::DSLs.find_through_method_missing(
|
|
49
|
+
self, m, args,
|
|
50
|
+
'_child' => :find_child,
|
|
51
|
+
'_port' => :find_port,
|
|
52
|
+
'_event' => :find_event) || super
|
|
53
|
+
end
|
|
54
|
+
def has_through_method_missing?(m)
|
|
55
|
+
MetaRuby::DSLs.has_through_method_missing?(
|
|
56
|
+
self, m,
|
|
57
|
+
'_child' => :has_child?,
|
|
58
|
+
'_port' => :has_port?,
|
|
59
|
+
'_event' => :has_event?) || super
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
include MetaRuby::DSLs::FindThroughMethodMissing
|
|
63
|
+
|
|
64
|
+
def to_coordination_task(task_model); model.to_coordination_task(task_model) end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Coordination
|
|
3
|
+
extend Logger::Forward
|
|
4
|
+
extend Logger::Hierarchy
|
|
5
|
+
|
|
6
|
+
# Implementation of a task script
|
|
7
|
+
#
|
|
8
|
+
# The model-level accessors and API is described in {Models::Script}
|
|
9
|
+
class TaskScript < Base
|
|
10
|
+
extend Models::Script
|
|
11
|
+
include Script
|
|
12
|
+
|
|
13
|
+
attr_reader :definition_block
|
|
14
|
+
|
|
15
|
+
# @deprecated
|
|
16
|
+
#
|
|
17
|
+
# Use #root_task instead
|
|
18
|
+
def task
|
|
19
|
+
root_task
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def parse(&block)
|
|
23
|
+
@definition_block = block
|
|
24
|
+
instance_eval(&block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def bind(task)
|
|
28
|
+
result_model = self.class.superclass.new_submodel(root: model.root.model)
|
|
29
|
+
result = result_model.new(task)
|
|
30
|
+
result.parse(&definition_block)
|
|
31
|
+
result.prepare
|
|
32
|
+
result
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def resolve_instructions
|
|
36
|
+
super
|
|
37
|
+
model.each_task do |model_task|
|
|
38
|
+
script_task = instance_for(model_task)
|
|
39
|
+
if script_task.respond_to?(:task) && !script_task.task # Not bound ? Check if the model can be instanciated
|
|
40
|
+
task = model_task.instanciate(root_task.plan)
|
|
41
|
+
bind_coordination_task_to_instance(script_task, task, on_replace: :copy)
|
|
42
|
+
|
|
43
|
+
# Protect from scheduling until the start is executed
|
|
44
|
+
#
|
|
45
|
+
# #start_task will be called by the Start instruction
|
|
46
|
+
root_task.start_event.add_causal_link(task.start_event)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# Now, make the dependencies based on what we do / wait for with
|
|
50
|
+
# the tasks. Namely, we look at Start (dependency options) and
|
|
51
|
+
# Wait (success events)
|
|
52
|
+
instructions.each do |ins|
|
|
53
|
+
case ins
|
|
54
|
+
when Coordination::Models::Script::Start
|
|
55
|
+
task = ins.task.resolve
|
|
56
|
+
root_task.depends_on task, ins.dependency_options
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Resolve the given event object into a Coordination::Task and a
|
|
62
|
+
# Coordination::Models::Task
|
|
63
|
+
def resolve_task(task)
|
|
64
|
+
if root_task && task.kind_of?(Roby::Task)
|
|
65
|
+
root_task.plan.add(task)
|
|
66
|
+
model_task = Coordination::Models::Task.new(task.model)
|
|
67
|
+
script_task = instance_for(model_task)
|
|
68
|
+
bind_coordination_task_to_instance(script_task, task, on_replace: :copy)
|
|
69
|
+
else
|
|
70
|
+
model_task = self.model.task(task)
|
|
71
|
+
script_task = instance_for(model_task)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
return script_task, model_task
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Resolve the given event object into a Coordination::Event and a
|
|
78
|
+
# Coordination::Models::Event
|
|
79
|
+
def resolve_event(event)
|
|
80
|
+
if event.respond_to?(:to_sym)
|
|
81
|
+
symbol = event
|
|
82
|
+
if root_task
|
|
83
|
+
event = root_task.find_event(symbol)
|
|
84
|
+
else
|
|
85
|
+
event = model.root.find_event(symbol)
|
|
86
|
+
end
|
|
87
|
+
if !event
|
|
88
|
+
raise ArgumentError, "#{model.root} has no event called #{symbol}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
script_task, model_task = resolve_task(event.task)
|
|
92
|
+
model_event = model_task.find_event(event.symbol)
|
|
93
|
+
script_event = instance_for(model_event)
|
|
94
|
+
return script_event, model_event
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Start the given task at that point in the script, and wait for it
|
|
98
|
+
# to emit its start event
|
|
99
|
+
#
|
|
100
|
+
# @param [Task] task the task that should be started
|
|
101
|
+
# @param [Hash] dependency_options options that should be passed to
|
|
102
|
+
# TaskStructure::Dependency::Extension#depends_on
|
|
103
|
+
def start(task, explicit_start: false, **dependency_options)
|
|
104
|
+
task, model_task = resolve_task(task)
|
|
105
|
+
model.start(model_task, explicit_start: explicit_start, **dependency_options)
|
|
106
|
+
task
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @overload execute(task)
|
|
110
|
+
# Deploy and start the given task, and wait for it to finish
|
|
111
|
+
# successfully
|
|
112
|
+
#
|
|
113
|
+
# @overload execute { ... }
|
|
114
|
+
# Execute the content of the given block once
|
|
115
|
+
def execute(task = nil, &block)
|
|
116
|
+
if task
|
|
117
|
+
task, model_task = resolve_task(task)
|
|
118
|
+
model.execute(model_task)
|
|
119
|
+
task
|
|
120
|
+
else
|
|
121
|
+
model.instructions << BlockExecute.new(block)
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Wait for an event to be emitted
|
|
127
|
+
#
|
|
128
|
+
# @param [Hash] options
|
|
129
|
+
# @option options [Time,nil] after (nil) if set, only event
|
|
130
|
+
# emissions that happened after this value will make the script
|
|
131
|
+
# pass this instruction. The default of nil means "from the point
|
|
132
|
+
# of this instruction on"
|
|
133
|
+
#
|
|
134
|
+
# @example wait first_child.start_event
|
|
135
|
+
# Waits until start event has been emitted. Will wait forever if
|
|
136
|
+
# the start event has already been emitted
|
|
137
|
+
# @example wait first_child.start_event, after: Time.at(0)
|
|
138
|
+
# Waits for start event to be emitted. Will return immediately if
|
|
139
|
+
# it has already been emitted.
|
|
140
|
+
def wait(event, options = Hash.new)
|
|
141
|
+
event, model_event = resolve_event(event)
|
|
142
|
+
model.wait(model_event, options)
|
|
143
|
+
event
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# @deprecated
|
|
147
|
+
#
|
|
148
|
+
# Use wait(event after: Time.at(0)) instead
|
|
149
|
+
def wait_any(event, options = Hash.new)
|
|
150
|
+
wait(event, options.merge(after: Time.at(0)))
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Sleep for a given number of seconds
|
|
154
|
+
#
|
|
155
|
+
# @param [Float] seconds the number of seconds to stop the script
|
|
156
|
+
# execution
|
|
157
|
+
def sleep(seconds)
|
|
158
|
+
task = start(Tasks::Timeout.new(delay: seconds), explicit_start: true)
|
|
159
|
+
wait task.stop_event
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Emit the given event
|
|
163
|
+
def emit(event)
|
|
164
|
+
event, model_event = resolve_event(event)
|
|
165
|
+
model.emit(model_event)
|
|
166
|
+
event
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Executes the provided block once per execution cycle
|
|
170
|
+
#
|
|
171
|
+
# Call {#transition!} to quit the block
|
|
172
|
+
def poll(&block)
|
|
173
|
+
poll_until(poll_transition_event, &block)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Execute the provided block once per execution cycle, until the
|
|
177
|
+
# given event is emitted
|
|
178
|
+
def poll_until(event, &block)
|
|
179
|
+
event, model_event = resolve_event(event)
|
|
180
|
+
model.instructions << Script::Models::PollUntil.new(model_event, block)
|
|
181
|
+
event
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Quit a {#poll} block
|
|
185
|
+
def transition!
|
|
186
|
+
root_task.poll_transition_event.emit
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Execute the script instructions given as block. If they take more
|
|
190
|
+
# than the specified number of seconds, either generate an error or
|
|
191
|
+
# emit an event (and quit the block)
|
|
192
|
+
#
|
|
193
|
+
# @param [Hash] options
|
|
194
|
+
# @option options [Event] :event (nil) if set, the given event will
|
|
195
|
+
# be emitted when the timeout is reached. Otherwise, a
|
|
196
|
+
# Script::TimedOut exception is generated with the script's
|
|
197
|
+
# supporting task as origin
|
|
198
|
+
def timeout(seconds, options = Hash.new, &block)
|
|
199
|
+
timeout = timeout_start(seconds, options)
|
|
200
|
+
parse(&block)
|
|
201
|
+
timeout_stop(timeout)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Start a timeout operation. Usually not used directly
|
|
205
|
+
#
|
|
206
|
+
# @see timeout
|
|
207
|
+
def timeout_start(seconds, options = Hash.new)
|
|
208
|
+
options, timeout_options = Kernel.filter_options options, emit: nil
|
|
209
|
+
if event = options[:emit]
|
|
210
|
+
script_event, model_event = resolve_event(event)
|
|
211
|
+
end
|
|
212
|
+
model.timeout_start(seconds, timeout_options.merge(emit: model_event))
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Stop a timeout operation. Usually not used directly
|
|
216
|
+
#
|
|
217
|
+
# @see timeout
|
|
218
|
+
def timeout_stop(timeout)
|
|
219
|
+
model.timeout_stop(timeout)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Used by Script
|
|
223
|
+
def start_task(task, explicit_start: false)
|
|
224
|
+
root_task.start_event.remove_causal_link(task.resolve.start_event)
|
|
225
|
+
if explicit_start
|
|
226
|
+
task.resolve.start_event.call
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def respond_to_missing?(m, include_private)
|
|
231
|
+
if m =~ /_(?:event|child)$/
|
|
232
|
+
instance_for(model.root).respond_to?(m)
|
|
233
|
+
else super
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def method_missing(m, *args, &block)
|
|
238
|
+
if m =~ /_(?:event|child)$/
|
|
239
|
+
instance_for(model.root).send(m, *args, &block)
|
|
240
|
+
else super
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
class Task
|
|
247
|
+
Models::Task.inherited_attribute(:script, :scripts) { Array.new }
|
|
248
|
+
|
|
249
|
+
event :poll_transition
|
|
250
|
+
|
|
251
|
+
def self.create_script(*task, &block)
|
|
252
|
+
script_model = Coordination::TaskScript.new_submodel(root: self)
|
|
253
|
+
script = script_model.new(*task)
|
|
254
|
+
if block_given?
|
|
255
|
+
script.parse(&block)
|
|
256
|
+
end
|
|
257
|
+
script
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Adds a script that is going to be executed for every instance of this
|
|
261
|
+
# task model
|
|
262
|
+
def self.script(&block)
|
|
263
|
+
s = create_script(&block)
|
|
264
|
+
scripts << s
|
|
265
|
+
s
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
on :start do |event|
|
|
269
|
+
model.each_script do |s|
|
|
270
|
+
s = s.bind(self)
|
|
271
|
+
s.step
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Adds a task script that is going to be executed while this task
|
|
276
|
+
# instance runs.
|
|
277
|
+
def script(options = Hash.new, &block)
|
|
278
|
+
execute do |task|
|
|
279
|
+
script = model.create_script(task, &block)
|
|
280
|
+
script.prepare
|
|
281
|
+
script.step
|
|
282
|
+
end
|
|
283
|
+
model.create_script(self, &block)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def transition!
|
|
287
|
+
poll_transition_event.emit
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
require 'state_machine/machine'
|
|
2
|
+
|
|
3
|
+
module Roby
|
|
4
|
+
# Helper to get a more roby-like feeling to the state machine definitions
|
|
5
|
+
class StateMachineDefinitionContext
|
|
6
|
+
attr_reader :task_model
|
|
7
|
+
attr_reader :state_machine
|
|
8
|
+
|
|
9
|
+
def initialize(task_model, state_machine)
|
|
10
|
+
@task_model = task_model
|
|
11
|
+
@state_machine = state_machine
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def script_in_state(state, &block)
|
|
15
|
+
script_engine = task_model.create_script(&block)
|
|
16
|
+
|
|
17
|
+
state_machine.before_transition state_machine.any => state, do: lambda { |proxy|
|
|
18
|
+
proxy.instance_variable_set :@script_engine, nil
|
|
19
|
+
}
|
|
20
|
+
state_machine.state(state) do
|
|
21
|
+
define_method(:poll) do |task|
|
|
22
|
+
if !@script_engine
|
|
23
|
+
@script_engine = script_engine.bind(task)
|
|
24
|
+
@script_engine.prepare
|
|
25
|
+
@script_engine.step
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def poll_in_state(state, &block)
|
|
32
|
+
state_machine.state(state) do
|
|
33
|
+
define_method(:poll, &block)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def on(event, &block)
|
|
38
|
+
state_machine.event(event, &block)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def respond_to_missing?(m, include_private)
|
|
42
|
+
state_machine.respond_to?(m)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def method_missing(m, *args, &block)
|
|
46
|
+
state_machine.public_send(m, *args, &block)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The state machine that can be associate with a task
|
|
51
|
+
#
|
|
52
|
+
class TaskStateMachine
|
|
53
|
+
# The proxy object class the state machine is working on
|
|
54
|
+
attr_accessor :proxy
|
|
55
|
+
|
|
56
|
+
# Underlying state machine
|
|
57
|
+
attr_accessor :machine
|
|
58
|
+
|
|
59
|
+
# Existing transitions
|
|
60
|
+
# Transition comes with methods: event, from_name, to_name
|
|
61
|
+
attr_reader :transitions
|
|
62
|
+
|
|
63
|
+
# All state of the state machine
|
|
64
|
+
attr_reader :states
|
|
65
|
+
|
|
66
|
+
def initialize(machine)
|
|
67
|
+
# Required to initialize underlying state_machine
|
|
68
|
+
super()
|
|
69
|
+
|
|
70
|
+
@proxy = machine.owner_class.new
|
|
71
|
+
@machine = machine
|
|
72
|
+
|
|
73
|
+
update
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def update
|
|
77
|
+
@states = []
|
|
78
|
+
|
|
79
|
+
# introspect to retrieve all transactions of the statemachine
|
|
80
|
+
@transitions = []
|
|
81
|
+
collection = @machine.states
|
|
82
|
+
collection.each do |s_o|
|
|
83
|
+
collection.each do |s_i|
|
|
84
|
+
# status_transitions is added to TaskStateMachine using meta programming
|
|
85
|
+
transitions = proxy.status_transitions(from: s_o.name.to_sym, to: s_i.name.to_sym)
|
|
86
|
+
@transitions << transitions
|
|
87
|
+
end
|
|
88
|
+
@transitions.flatten!
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Infer all available states from existing transitions
|
|
92
|
+
@transitions.each do |t|
|
|
93
|
+
@states << t.from_name unless @states.index(t.from_name)
|
|
94
|
+
@states << t.to_name unless @states.index(t.to_name)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def initialize_copy(other)
|
|
99
|
+
other.name = name
|
|
100
|
+
other.proxy = name.new
|
|
101
|
+
other.machine = machine.dup
|
|
102
|
+
other.update
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def respond_to_missing?(m, include_private)
|
|
106
|
+
proxy.respond_to?(m) || super
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def method_missing(m, *args, &block)
|
|
110
|
+
# If proxy provides missing method, then use the proxy
|
|
111
|
+
if proxy.respond_to?(m)
|
|
112
|
+
proxy.public_send(m, *args, &block)
|
|
113
|
+
else
|
|
114
|
+
# otherwise pass it on
|
|
115
|
+
super
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Define general poll handler
|
|
120
|
+
def do_poll(task)
|
|
121
|
+
begin
|
|
122
|
+
proxy.poll(task)
|
|
123
|
+
rescue NoMethodError => e
|
|
124
|
+
# poll only if the state has a poll handler defined
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Identifies the current state given a list of subsequent events
|
|
129
|
+
# Provides a list with the most recent event being last in the list
|
|
130
|
+
#
|
|
131
|
+
def identify_state(event_list)
|
|
132
|
+
# initalize with all transitions possible
|
|
133
|
+
paths = {}
|
|
134
|
+
@transitions.each do |transition|
|
|
135
|
+
paths[transition] = []
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
paths = []
|
|
139
|
+
new_paths = []
|
|
140
|
+
initialized = false
|
|
141
|
+
|
|
142
|
+
while event_list.size > 0
|
|
143
|
+
current_event = event_list.first
|
|
144
|
+
# expand path
|
|
145
|
+
@transitions.each do |transition|
|
|
146
|
+
# Get transitions that match event
|
|
147
|
+
if current_event == transition.event()
|
|
148
|
+
# expand first set of transactions
|
|
149
|
+
if not initialized
|
|
150
|
+
new_paths << [ transition ]
|
|
151
|
+
else
|
|
152
|
+
# find transitions that lead to the last transition
|
|
153
|
+
paths.each do |path|
|
|
154
|
+
if path.last.from_name == transition.to_name
|
|
155
|
+
path << transition
|
|
156
|
+
new_paths << path
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
paths = new_paths
|
|
163
|
+
new_paths = []
|
|
164
|
+
initialized = true
|
|
165
|
+
event_list.delete_at(0)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
if paths.size == 1
|
|
169
|
+
# Retrieve last (by time) transitions target state
|
|
170
|
+
return paths[0].last.to_name
|
|
171
|
+
elsif paths.size > 0
|
|
172
|
+
throw "Event list is ambigious, requiring more events"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
throw "Event list is invalid"
|
|
176
|
+
end
|
|
177
|
+
end # module TaskStateHelper
|
|
178
|
+
|
|
179
|
+
# The TaskStateHelper allows to add a statemachine to
|
|
180
|
+
# a Roby::Task and allows the tracking of events within
|
|
181
|
+
# the 'running' state
|
|
182
|
+
module TaskStateHelper
|
|
183
|
+
# The default namespace that is added to statemachine methods, e.g.
|
|
184
|
+
# when action for transitions are defined
|
|
185
|
+
def namespace
|
|
186
|
+
@namespace ||= nil
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def namespace=(name)
|
|
190
|
+
@namespace=name
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Proxy object used in the definition of state machines on Roby::Task
|
|
194
|
+
class Proxy
|
|
195
|
+
def self.state_machine(*args, &block)
|
|
196
|
+
StateMachine::Machine.find_or_create(self, *args, &block)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# The state machine model that is running on all tasks of this task
|
|
201
|
+
# model
|
|
202
|
+
def state_machine
|
|
203
|
+
if @state_machine then @state_machine
|
|
204
|
+
elsif superclass.respond_to?(:state_machine)
|
|
205
|
+
superclass.state_machine
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Refine the running state of the Roby::Task
|
|
210
|
+
# using a state machine description. The initial
|
|
211
|
+
# state of the machine is set to 'running' by default.
|
|
212
|
+
#
|
|
213
|
+
# Example:
|
|
214
|
+
# refine_running_state do
|
|
215
|
+
# on :pause do
|
|
216
|
+
# transition [:running] => paused
|
|
217
|
+
# end
|
|
218
|
+
#
|
|
219
|
+
# on :resume do
|
|
220
|
+
# transition [:paused] => :running
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
# state :paused do
|
|
224
|
+
# def poll(task)
|
|
225
|
+
# sleep 4
|
|
226
|
+
# task.emit :resume
|
|
227
|
+
# end
|
|
228
|
+
# end
|
|
229
|
+
# end
|
|
230
|
+
#
|
|
231
|
+
# Events are translated into roby events
|
|
232
|
+
# and the statemachine in hooked into the
|
|
233
|
+
# on(:yourevent) {|context| ... }
|
|
234
|
+
# You can add additional event handlers as ususal
|
|
235
|
+
# using on(:yourevent) .. syntax
|
|
236
|
+
#
|
|
237
|
+
# The current status (substate of the running state)
|
|
238
|
+
# can be retrieved via
|
|
239
|
+
# yourtask.state_machine.status
|
|
240
|
+
#
|
|
241
|
+
def refine_running_state (*args, &block)
|
|
242
|
+
if args.last.kind_of?(Hash)
|
|
243
|
+
options = args.pop
|
|
244
|
+
end
|
|
245
|
+
options = Kernel.validate_options(options || Hash.new, namespace: nil)
|
|
246
|
+
|
|
247
|
+
if options.has_key?(:namespace)
|
|
248
|
+
self.namespace=options[:namespace]
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Check if a model of a class ancestor already exists
|
|
252
|
+
# If a parent_model exists, prepare the proxy class accordingly
|
|
253
|
+
# The proxy allows us to use the state_machine library even
|
|
254
|
+
# with instances
|
|
255
|
+
if parent_model = self.superclass.state_machine
|
|
256
|
+
proxy_model = Class.new(parent_model.owner_class)
|
|
257
|
+
else
|
|
258
|
+
proxy_model = Class.new(Proxy)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Create the state machine instance that will serve as base model
|
|
262
|
+
# for instances of the Roby::Task (or its subclasses) this machine
|
|
263
|
+
# is associated with The namespace allows to pre/postfix
|
|
264
|
+
# automatically generated functions, such as for sending events:
|
|
265
|
+
# <task>.state_machine.pause_<namespace>! or querying the status
|
|
266
|
+
# <task>.state_machine.<namespace>_paused? Note cannot use :state
|
|
267
|
+
# instead of :status here for yet unknown reason Changing the
|
|
268
|
+
# attribute :status also changes other method definitions, due to
|
|
269
|
+
# meta programming approach of the underlying library, e.g.
|
|
270
|
+
# status_transitions(from: ..., to: ...)
|
|
271
|
+
|
|
272
|
+
if self.namespace
|
|
273
|
+
machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running, namespace: self.namespace)
|
|
274
|
+
else
|
|
275
|
+
machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
machine_loader = StateMachineDefinitionContext.new(self, machine)
|
|
279
|
+
machine_loader.instance_eval(&block)
|
|
280
|
+
@state_machine = machine
|
|
281
|
+
|
|
282
|
+
import_events_to_roby(machine)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def import_events_to_roby(machine)
|
|
286
|
+
# Roby requires the self to be the subclassed Roby::Task
|
|
287
|
+
# Thus embed import into refine_running_state and using eval here
|
|
288
|
+
machine.events.each do |e|
|
|
289
|
+
if !has_event?(e.name)
|
|
290
|
+
event e.name, controlable: true
|
|
291
|
+
end
|
|
292
|
+
# when event is called transition the state_machine
|
|
293
|
+
on(e.name) do |event|
|
|
294
|
+
state_machine.send("#{e.name.to_sym}!")
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
class Task
|
|
301
|
+
extend TaskStateHelper
|
|
302
|
+
attr_reader :state_machine
|
|
303
|
+
|
|
304
|
+
# Setup is done in #initialize
|
|
305
|
+
# Polling is done in Task.do_poll
|
|
306
|
+
end
|
|
307
|
+
end # module Roby
|
|
308
|
+
|