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
data/lib/roby/log/relations.rb
CHANGED
@@ -419,6 +419,18 @@ module Roby
|
|
419
419
|
|
420
420
|
include TaskDisplaySupport
|
421
421
|
|
422
|
+
def self.all_task_relations
|
423
|
+
if @all_task_relations
|
424
|
+
@all_task_relations
|
425
|
+
else
|
426
|
+
result = []
|
427
|
+
ObjectSpace.each_object(Roby::RelationSpace) do |space|
|
428
|
+
result.concat(space.relations) if space.applied.find { |t| t <= Roby::Task }
|
429
|
+
end
|
430
|
+
@all_task_relations = result
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
422
434
|
attr_reader :ui, :scene
|
423
435
|
|
424
436
|
# A [DRbObject, DRbObject] => GraphicsItem mapping of arrows
|
@@ -510,25 +522,31 @@ module Roby
|
|
510
522
|
obj
|
511
523
|
end
|
512
524
|
|
525
|
+
# Initializes the display with the data already decoded from the
|
526
|
+
# given data stream, and binds this display to the stream.
|
513
527
|
def stream=(data_stream)
|
514
528
|
super
|
515
529
|
|
516
530
|
# Initialize the display ...
|
517
531
|
decoder.plans.each do |plan|
|
518
|
-
|
519
|
-
|
532
|
+
added_tasks(Time.now, plan, plan.known_tasks)
|
533
|
+
added_events(Time.now, plan, plan.free_events)
|
520
534
|
end
|
521
535
|
display
|
522
536
|
end
|
523
537
|
|
524
538
|
def [](item); graphics[item] end
|
539
|
+
|
540
|
+
# Returns a canvas object that represents this relation
|
525
541
|
def task_relation(from, to, rel, info)
|
526
542
|
arrow(from, to, rel, info, TASK_LAYER)
|
527
543
|
end
|
544
|
+
# Returns a canvas object that represents this relation
|
528
545
|
def event_relation(form, to, rel, info)
|
529
546
|
arrow(from, to, rel, info, EVENT_LAYER)
|
530
547
|
end
|
531
548
|
|
549
|
+
# Creates or reuses an arrow object to represent the given relation
|
532
550
|
def arrow(from, to, rel, info, base_layer)
|
533
551
|
id = [from, to, rel]
|
534
552
|
unless item = arrows[id]
|
@@ -589,9 +607,14 @@ module Roby
|
|
589
607
|
COLORS[current_color]
|
590
608
|
end
|
591
609
|
|
610
|
+
# True if this relation should be displayed
|
592
611
|
def relation_enabled?(relation); @enabled_relations.include?(relation) end
|
612
|
+
# True if this relation should be used for layout
|
613
|
+
#
|
614
|
+
# See also #relation_enabled?, #layout_relation, #ignore_relation
|
593
615
|
def layout_relation?(relation); relation_enabled?(relation) || @layout_relations.include?(relation) end
|
594
616
|
|
617
|
+
# Display this relation
|
595
618
|
def enable_relation(relation)
|
596
619
|
return if relation_enabled?(relation)
|
597
620
|
@enabled_relations << relation
|
@@ -602,11 +625,17 @@ module Roby
|
|
602
625
|
end
|
603
626
|
end
|
604
627
|
|
628
|
+
# The set of relations that should be displayed
|
605
629
|
attr_reader :enabled_relations
|
630
|
+
|
631
|
+
# Use this relation for layout but not for display
|
632
|
+
#
|
633
|
+
# See also #ignore_relation
|
606
634
|
def layout_relation(relation)
|
607
635
|
disable_relation(relation)
|
608
636
|
@layout_relations << relation
|
609
637
|
end
|
638
|
+
# Don't use this relation at all
|
610
639
|
def ignore_relation(relation)
|
611
640
|
disable_relation(relation)
|
612
641
|
@layout_relations.delete(relation)
|
@@ -756,19 +785,22 @@ module Roby
|
|
756
785
|
end
|
757
786
|
|
758
787
|
def clear_integrated
|
759
|
-
|
760
|
-
|
761
|
-
|
788
|
+
unless keep_signals
|
789
|
+
last_propagated_events, @propagated_events = propagated_events, Array.new
|
790
|
+
last_execution_events, @execution_events =
|
791
|
+
execution_events.partition { |fired, ev| fired }
|
792
|
+
end
|
793
|
+
!(last_propagated_events.empty? && last_execution_events.empty?)
|
762
794
|
end
|
763
795
|
|
796
|
+
# Update the display with new data that has come from the data
|
797
|
+
# stream.
|
798
|
+
#
|
799
|
+
# It would be too complex at this stage to know if the plan has been
|
800
|
+
# updated, so the method always returns true
|
764
801
|
def update
|
765
802
|
return unless decoder
|
766
803
|
|
767
|
-
if keep_signals
|
768
|
-
@execution_events = @last_execution_events.concat(execution_events)
|
769
|
-
@propagated_events.concat @last_propagated_events
|
770
|
-
end
|
771
|
-
|
772
804
|
update_prefixes_removal
|
773
805
|
clear_flashing_objects
|
774
806
|
|
@@ -912,11 +944,7 @@ module Roby
|
|
912
944
|
end
|
913
945
|
end
|
914
946
|
|
915
|
-
|
916
|
-
@last_execution_events, @execution_events =
|
917
|
-
execution_events.partition { |fired, ev| fired }
|
918
|
-
|
919
|
-
postponed_events.clear
|
947
|
+
true
|
920
948
|
end
|
921
949
|
|
922
950
|
def remove_graphics(item, scene = nil)
|
@@ -995,7 +1023,7 @@ module Roby
|
|
995
1023
|
def removed_event_child(time, parent, rel, child)
|
996
1024
|
remove_graphics(arrows.delete([local_event(parent), local_event(child), rel]))
|
997
1025
|
end
|
998
|
-
def
|
1026
|
+
def added_tasks(time, plan, tasks)
|
999
1027
|
tasks.each do |obj|
|
1000
1028
|
obj.flags[:pending] = true if obj.respond_to?(:flags)
|
1001
1029
|
task = local_task(obj)
|
data/lib/roby/log/server.rb
CHANGED
@@ -47,9 +47,6 @@ module Roby
|
|
47
47
|
discovered_displays = Array.new
|
48
48
|
@available_servers = Array.new
|
49
49
|
|
50
|
-
# Add disable_discovery in the list of finalizers
|
51
|
-
Control.finalizers << method(:disable_discovery)
|
52
|
-
|
53
50
|
@discovery_thread = Thread.new do
|
54
51
|
begin
|
55
52
|
loop do
|
@@ -75,7 +72,7 @@ module Roby
|
|
75
72
|
|
76
73
|
# Stops the discovery thread if it is running
|
77
74
|
def self.disable_discovery
|
78
|
-
|
75
|
+
Roby.engine.finalizers.delete(method(:disable_discovery))
|
79
76
|
if @discovery_thread
|
80
77
|
@discovery_thread.raise Interrupt, "quitting"
|
81
78
|
@discovery_thread.join
|
data/lib/roby/log/timings.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module Roby
|
2
4
|
module Log
|
3
5
|
class Timings
|
4
6
|
REF_TIMING = :start
|
5
7
|
ALL_TIMINGS = [ :real_start, :events,
|
6
8
|
:structure_check, :exception_propagation,
|
7
|
-
:exceptions_fatal, :garbage_collect,
|
8
|
-
:
|
9
|
+
:exceptions_fatal, :garbage_collect,
|
10
|
+
:ruby_gc, :expected_sleep, :sleep, :end ]
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
DELTAS = [:cpu_time]
|
13
|
-
ALL_NUMERIC_FIELDS = NUMERIC_FIELDS + DELTAS
|
12
|
+
ALL_NUMERIC_FIELDS = [:cycle_index, :live_objects, :object_allocation, :heap_slots,
|
13
|
+
:log_queue_size, :plan_task_count, :plan_event_count, :cpu_time]
|
14
14
|
|
15
15
|
ALL_FIELDS = ALL_TIMINGS + ALL_NUMERIC_FIELDS + [:event_count, :pos]
|
16
16
|
|
@@ -23,7 +23,86 @@ module Roby
|
|
23
23
|
end
|
24
24
|
def rewind; logfile.rewind end
|
25
25
|
|
26
|
-
|
26
|
+
# Read the logfile index, extract statistic information from it and
|
27
|
+
# yield them cycle-by-cycle. The format of +timings+ is the
|
28
|
+
# following:
|
29
|
+
#
|
30
|
+
# [start, real_start, events,
|
31
|
+
# structure_check, exception_propagation,
|
32
|
+
# exceptions_fatal, garbage_collect,
|
33
|
+
# ruby_gc, expected_sleep, sleep, end]
|
34
|
+
#
|
35
|
+
# where +start+ is the target start time of the cycle as a Time
|
36
|
+
# object. The rest of the values are floating-point values which
|
37
|
+
# represent offset from +start+ if +cumulative+ is true or offset
|
38
|
+
# from the previous one if +cumulative+ is false. Therefore, in the
|
39
|
+
# latter case, the values represent the actual duration of each
|
40
|
+
# phase in the execution engine.
|
41
|
+
#
|
42
|
+
# The phases are as follows:
|
43
|
+
# real_start::
|
44
|
+
# the actual starting time. It allows to see the offset due (for
|
45
|
+
# instance) to the uncertainty in sleep
|
46
|
+
# events::
|
47
|
+
# event propagation phase, including the propagation of dRoby
|
48
|
+
# events (events coming from remote hosts)
|
49
|
+
# structure_check::
|
50
|
+
# first structure checking pass
|
51
|
+
# exception_propagation::
|
52
|
+
# exception propagation phase
|
53
|
+
# exceptions_fatal::
|
54
|
+
# second structure checking pass, and propagation of the fatal
|
55
|
+
# errors (i.e. killing the involved tasks)
|
56
|
+
# garbage_collect::
|
57
|
+
# Roby's garbage collection pass
|
58
|
+
# ruby_gc::
|
59
|
+
# if GC.enable accepts a true/false argument, Roby will
|
60
|
+
# explicitely allow the GC to run only at a specific point, and
|
61
|
+
# monitor its execution time. This is the result. Note that Roby
|
62
|
+
# issues a warning at startup if it is not the case.
|
63
|
+
# expected_sleep::
|
64
|
+
# how much time Roby wanted to sleep (i.e. how many milliseconds
|
65
|
+
# were given to the sleep() call)
|
66
|
+
# sleep::
|
67
|
+
# how much time Roby actually slept
|
68
|
+
# end::
|
69
|
+
# end of the cycle
|
70
|
+
#
|
71
|
+
# The second array that is yield, +numeric+, contains non-timing
|
72
|
+
# statistics. Its format is:
|
73
|
+
#
|
74
|
+
# [cycle_index, live_objects, object_allocation, log_queue_size,
|
75
|
+
# plan_task_count, plan_event_count, cpu_time]
|
76
|
+
#
|
77
|
+
# where
|
78
|
+
#
|
79
|
+
# cycle_index::
|
80
|
+
# The index of this cycle. Note that some number can be missing: if one
|
81
|
+
# cycle takes more than two time its allocated period, then +cycle_index+ is
|
82
|
+
# updated to reflect the cycles that have been missed.
|
83
|
+
# live_objects::
|
84
|
+
# The count of allocated objects at the end of the cycle. It is only valid
|
85
|
+
# on Ruby interpreters that have been patched to report this value
|
86
|
+
# efficiently.
|
87
|
+
# object_allocation::
|
88
|
+
# How many objects have been allocated during this cycle. This is valid only
|
89
|
+
# if Ruby GC is controlled by Roby (see the description of +ruby_gc+ above).
|
90
|
+
# Otherwise, it will be invalid in cycles where the Ruby GC ran, as the
|
91
|
+
# statistics can't correct the objects freed by Ruby's GC.
|
92
|
+
# log_queue_size::
|
93
|
+
# The logger runs in a thread separated from the execution engine, and a
|
94
|
+
# fixed-size queue is used to communicate between the threads. This value is
|
95
|
+
# the size of the queue at the end of the cycle (after sleep()). It is
|
96
|
+
# mainly used for debugging purposes: if this queue is almost full, then the
|
97
|
+
# execution engine thread will probably be interrupted to let the log thread
|
98
|
+
# empty the queue.
|
99
|
+
# plan_task_count::
|
100
|
+
# The count of tasks in the plan at the end of the cycle.
|
101
|
+
# plan_event_count::
|
102
|
+
# The count of free events in the plan at the end of the cycle.
|
103
|
+
# cpu_time::
|
104
|
+
# The CPU time taken by the Roby controller for this cycle.
|
105
|
+
def each_cycle(cumulative = false) # :yield:numeric, timings
|
27
106
|
last_deltas = Hash.new
|
28
107
|
for data in logfile.index_data[1..-1]
|
29
108
|
result = []
|
@@ -54,18 +133,8 @@ module Roby
|
|
54
133
|
end
|
55
134
|
end
|
56
135
|
|
57
|
-
numeric = data.values_at(*
|
58
|
-
|
59
|
-
value = if old_value = last_deltas[name]
|
60
|
-
data[name] - old_value
|
61
|
-
else
|
62
|
-
0
|
63
|
-
end
|
64
|
-
last_deltas[name] = data[name]
|
65
|
-
value
|
66
|
-
end
|
67
|
-
|
68
|
-
yield(numeric + deltas, result)
|
136
|
+
numeric = data.values_at(*ALL_NUMERIC_FIELDS)
|
137
|
+
yield(numeric, result)
|
69
138
|
end
|
70
139
|
|
71
140
|
rescue ArgumentError => e
|
data/lib/roby/plan-object.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'roby/relations'
|
2
|
-
require 'roby/distributed/base'
|
3
|
-
require 'roby/basic_object'
|
4
|
-
|
5
1
|
module Roby
|
6
2
|
# Base class for all objects which are included in a plan.
|
7
3
|
class PlanObject < BasicObject
|
@@ -10,6 +6,9 @@ module Roby
|
|
10
6
|
# The plan this object belongs to
|
11
7
|
attr_reader :plan
|
12
8
|
|
9
|
+
# The engine which acts on +plan+ (if there is one)
|
10
|
+
def engine; plan.engine end
|
11
|
+
|
13
12
|
# The place where this object has been removed from its plan. Once an
|
14
13
|
# object is removed from its plan, it cannot be added back again.
|
15
14
|
attr_accessor :removed_at
|
@@ -29,6 +28,109 @@ module Roby
|
|
29
28
|
@plan = new_plan
|
30
29
|
end
|
31
30
|
|
31
|
+
# The propagation engine object for this. For PlanObject instances, it
|
32
|
+
# is always the plan itself.
|
33
|
+
def propagation_engine
|
34
|
+
plan
|
35
|
+
end
|
36
|
+
|
37
|
+
# If +self+ is a transaction proxy, returns the underlying plan object,
|
38
|
+
# regardless of how many transactions there is on the stack. Otherwise,
|
39
|
+
# return self.
|
40
|
+
def real_object
|
41
|
+
result = self
|
42
|
+
while result.respond_to?(:__getobj__)
|
43
|
+
result = result.__getobj__
|
44
|
+
end
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the stack of transactions/plans this object is part of,
|
49
|
+
# starting with self.plan.
|
50
|
+
def transaction_stack
|
51
|
+
result = [plan]
|
52
|
+
obj = self
|
53
|
+
while obj.respond_to?(:__getobj__)
|
54
|
+
obj = obj.__getobj__
|
55
|
+
result << obj.plan
|
56
|
+
end
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
# call-seq:
|
61
|
+
# merged_relation(:each_child_object, false, Dependency) do |parent, child|
|
62
|
+
# end
|
63
|
+
# merged_relation(:each_child_object, true, Dependency) do |child|
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Behaves like +enumerator+, but merges all the changes that underlying
|
67
|
+
# transactions may have applied. I.e. it is equivalent to applying
|
68
|
+
# +enumerator+ on the plan that would be the result of the application
|
69
|
+
# of the whole transaction stack
|
70
|
+
#
|
71
|
+
# If +instrusive+ is false, the edges are yielded at the level they
|
72
|
+
# appear. I.e. both the parent and the child are given, and [parent,
|
73
|
+
# child] may be part of a parent plan of self.plan.
|
74
|
+
#
|
75
|
+
# If +instrusive+ is true, the related objects are recursively added to
|
76
|
+
# all transactions in the transaction stack, and are given at the end.
|
77
|
+
# I.e. only the related object is yield, and it is guaranteed to be
|
78
|
+
# included in self.plan.
|
79
|
+
def merged_relations(enumerator, intrusive, *args, &block)
|
80
|
+
if !block_given?
|
81
|
+
return enum_for(:merged_relations, enumerator, intrusive, *args)
|
82
|
+
end
|
83
|
+
|
84
|
+
plan_chain = self.transaction_stack
|
85
|
+
object = self.real_object
|
86
|
+
|
87
|
+
pending = Array.new
|
88
|
+
while plan_chain.size > 1
|
89
|
+
plan = plan_chain.pop
|
90
|
+
next_plan = plan_chain.last
|
91
|
+
|
92
|
+
# Objects that are in +plan+ but not in +next_plan+ are
|
93
|
+
# automatically added, as +next_plan+ is not able to change
|
94
|
+
# them. Those that are included in +next_plan+ are handled
|
95
|
+
# later.
|
96
|
+
new_objects = Array.new
|
97
|
+
object.send(enumerator, *args) do |related_object, _|
|
98
|
+
next if next_plan[related_object, false]
|
99
|
+
|
100
|
+
if !intrusive
|
101
|
+
yield(object, related_object)
|
102
|
+
else
|
103
|
+
new_objects << related_object
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Here, pending contains objects from the previous plan (i.e. in
|
108
|
+
# plan.plan). Proxy them in +plan+.
|
109
|
+
#
|
110
|
+
# It is important to do that *after* we enumerated the relations
|
111
|
+
# that exist in +plan+ (above), as it reduces the number of
|
112
|
+
# relations at each level.
|
113
|
+
pending.map! { |t| plan[t] }
|
114
|
+
# And add the new objects that we just discovered
|
115
|
+
pending.concat(new_objects)
|
116
|
+
|
117
|
+
if next_plan
|
118
|
+
object = next_plan[object]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
if intrusive
|
123
|
+
send(enumerator, *args, &block)
|
124
|
+
for related_object in pending
|
125
|
+
yield(self.plan[related_object])
|
126
|
+
end
|
127
|
+
else
|
128
|
+
send(enumerator, *args) do |related_object, _|
|
129
|
+
yield(self, related_object)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
32
134
|
# A three-state flag with the following values:
|
33
135
|
# nil:: the object is executable if its plan is
|
34
136
|
# true:: the object is executable
|
@@ -68,9 +170,9 @@ module Roby
|
|
68
170
|
elsif other.plan && plan
|
69
171
|
raise RuntimeError, "cannot add a relation between two objects from different plans. #{self} is from #{plan} and #{other} is from #{other.plan}"
|
70
172
|
elsif plan
|
71
|
-
self.plan.
|
173
|
+
self.plan.add(other)
|
72
174
|
elsif other.plan
|
73
|
-
other.plan.
|
175
|
+
other.plan.add(self)
|
74
176
|
end
|
75
177
|
end
|
76
178
|
protected :synchronize_plan
|
@@ -233,15 +335,37 @@ module Roby
|
|
233
335
|
end
|
234
336
|
end
|
235
337
|
|
236
|
-
#
|
237
|
-
#
|
238
|
-
|
239
|
-
|
338
|
+
# Hook called when a new child is added to this object in the given
|
339
|
+
# relations and with the given information object.
|
340
|
+
def adding_child_object(child, relations, info)
|
341
|
+
super if defined? super
|
342
|
+
return if !plan
|
343
|
+
|
344
|
+
for trsc in plan.transactions
|
345
|
+
next unless trsc.proxying?
|
346
|
+
if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
|
347
|
+
trsc.adding_plan_relation(parent_proxy, child_proxy, relations, info)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
240
351
|
|
352
|
+
# Hook called when a child of this object is being removed from the
|
353
|
+
# given relations.
|
354
|
+
def removing_child_object(child, relations)
|
241
355
|
unless read_write? || child.read_write?
|
242
356
|
raise OwnershipError, "cannot remove a relation between two objects we don't own"
|
243
357
|
end
|
244
|
-
|
358
|
+
|
359
|
+
super if defined? super
|
360
|
+
return if !plan
|
361
|
+
|
362
|
+
for trsc in plan.transactions
|
363
|
+
next unless trsc.proxying?
|
364
|
+
if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
|
365
|
+
trsc.removing_plan_relation(parent_proxy, child_proxy, relations)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
245
369
|
end
|
246
370
|
end
|
247
371
|
|