roby 0.7
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/.gitignore +29 -0
- data/History.txt +4 -0
- data/License-fr.txt +519 -0
- data/License.txt +515 -0
- data/Manifest.txt +245 -0
- data/NOTES +4 -0
- data/README.txt +163 -0
- data/Rakefile +161 -0
- data/TODO.txt +146 -0
- data/app/README.txt +24 -0
- data/app/Rakefile +8 -0
- data/app/config/ROBOT.rb +5 -0
- data/app/config/app.yml +91 -0
- data/app/config/init.rb +7 -0
- data/app/config/roby.yml +3 -0
- data/app/controllers/.gitattributes +0 -0
- data/app/controllers/ROBOT.rb +2 -0
- data/app/data/.gitattributes +0 -0
- data/app/planners/ROBOT/main.rb +6 -0
- data/app/planners/main.rb +5 -0
- data/app/scripts/distributed +3 -0
- data/app/scripts/generate/bookmarks +3 -0
- data/app/scripts/replay +3 -0
- data/app/scripts/results +3 -0
- data/app/scripts/run +3 -0
- data/app/scripts/server +3 -0
- data/app/scripts/shell +3 -0
- data/app/scripts/test +3 -0
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby +210 -0
- data/bin/roby-log +168 -0
- data/bin/roby-shell +25 -0
- data/doc/images/event_generalization.png +0 -0
- data/doc/images/exception_propagation_1.png +0 -0
- data/doc/images/exception_propagation_2.png +0 -0
- data/doc/images/exception_propagation_3.png +0 -0
- data/doc/images/exception_propagation_4.png +0 -0
- data/doc/images/exception_propagation_5.png +0 -0
- data/doc/images/replay_handler_error.png +0 -0
- data/doc/images/replay_handler_error_0.png +0 -0
- data/doc/images/replay_handler_error_1.png +0 -0
- data/doc/images/roby_cycle_overview.png +0 -0
- data/doc/images/roby_replay_02.png +0 -0
- data/doc/images/roby_replay_03.png +0 -0
- data/doc/images/roby_replay_04.png +0 -0
- data/doc/images/roby_replay_event_representation.png +0 -0
- data/doc/images/roby_replay_first_state.png +0 -0
- data/doc/images/roby_replay_relations.png +0 -0
- data/doc/images/roby_replay_startup.png +0 -0
- data/doc/images/task_event_generalization.png +0 -0
- data/doc/papers.rdoc +11 -0
- data/doc/styles/allison.css +314 -0
- data/doc/styles/allison.js +316 -0
- data/doc/styles/allison.rb +276 -0
- data/doc/styles/jamis.rb +593 -0
- data/doc/tutorials/01-GettingStarted.rdoc +86 -0
- data/doc/tutorials/02-GoForward.rdoc +220 -0
- data/doc/tutorials/03-PlannedPath.rdoc +268 -0
- data/doc/tutorials/04-EventPropagation.rdoc +236 -0
- data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
- data/doc/tutorials/06-Overview.rdoc +40 -0
- data/doc/videos.rdoc +69 -0
- data/ext/droby/dump.cc +175 -0
- data/ext/droby/extconf.rb +3 -0
- data/ext/graph/algorithm.cc +746 -0
- data/ext/graph/extconf.rb +7 -0
- data/ext/graph/graph.cc +529 -0
- data/ext/graph/graph.hh +183 -0
- data/ext/graph/iterator_sequence.hh +102 -0
- data/ext/graph/undirected_dfs.hh +226 -0
- data/ext/graph/undirected_graph.hh +421 -0
- data/lib/roby.rb +41 -0
- data/lib/roby/app.rb +870 -0
- data/lib/roby/app/rake.rb +56 -0
- data/lib/roby/app/run.rb +14 -0
- data/lib/roby/app/scripts/distributed.rb +13 -0
- data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
- data/lib/roby/app/scripts/replay.rb +31 -0
- data/lib/roby/app/scripts/results.rb +15 -0
- data/lib/roby/app/scripts/run.rb +26 -0
- data/lib/roby/app/scripts/server.rb +18 -0
- data/lib/roby/app/scripts/shell.rb +88 -0
- data/lib/roby/app/scripts/test.rb +40 -0
- data/lib/roby/basic_object.rb +151 -0
- data/lib/roby/config.rb +5 -0
- data/lib/roby/control.rb +747 -0
- data/lib/roby/decision_control.rb +17 -0
- data/lib/roby/distributed.rb +32 -0
- data/lib/roby/distributed/base.rb +440 -0
- data/lib/roby/distributed/communication.rb +871 -0
- data/lib/roby/distributed/connection_space.rb +592 -0
- data/lib/roby/distributed/distributed_object.rb +206 -0
- data/lib/roby/distributed/drb.rb +62 -0
- data/lib/roby/distributed/notifications.rb +539 -0
- data/lib/roby/distributed/peer.rb +550 -0
- data/lib/roby/distributed/protocol.rb +529 -0
- data/lib/roby/distributed/proxy.rb +343 -0
- data/lib/roby/distributed/subscription.rb +311 -0
- data/lib/roby/distributed/transaction.rb +498 -0
- data/lib/roby/event.rb +897 -0
- data/lib/roby/exceptions.rb +234 -0
- data/lib/roby/executives/simple.rb +30 -0
- data/lib/roby/graph.rb +166 -0
- data/lib/roby/interface.rb +390 -0
- data/lib/roby/log.rb +3 -0
- data/lib/roby/log/chronicle.rb +303 -0
- data/lib/roby/log/console.rb +72 -0
- data/lib/roby/log/data_stream.rb +197 -0
- data/lib/roby/log/dot.rb +279 -0
- data/lib/roby/log/event_stream.rb +151 -0
- data/lib/roby/log/file.rb +340 -0
- data/lib/roby/log/gui/basic_display.ui +83 -0
- data/lib/roby/log/gui/chronicle.rb +26 -0
- data/lib/roby/log/gui/chronicle_view.rb +40 -0
- data/lib/roby/log/gui/chronicle_view.ui +70 -0
- data/lib/roby/log/gui/data_displays.rb +172 -0
- data/lib/roby/log/gui/data_displays.ui +155 -0
- data/lib/roby/log/gui/notifications.rb +26 -0
- data/lib/roby/log/gui/relations.rb +248 -0
- data/lib/roby/log/gui/relations.ui +123 -0
- data/lib/roby/log/gui/relations_view.rb +185 -0
- data/lib/roby/log/gui/relations_view.ui +149 -0
- data/lib/roby/log/gui/replay.rb +327 -0
- data/lib/roby/log/gui/replay_controls.rb +200 -0
- data/lib/roby/log/gui/replay_controls.ui +259 -0
- data/lib/roby/log/gui/runtime.rb +130 -0
- data/lib/roby/log/hooks.rb +185 -0
- data/lib/roby/log/logger.rb +202 -0
- data/lib/roby/log/notifications.rb +244 -0
- data/lib/roby/log/plan_rebuilder.rb +470 -0
- data/lib/roby/log/relations.rb +1056 -0
- data/lib/roby/log/server.rb +550 -0
- data/lib/roby/log/sqlite.rb +47 -0
- data/lib/roby/log/timings.rb +164 -0
- data/lib/roby/plan-object.rb +247 -0
- data/lib/roby/plan.rb +762 -0
- data/lib/roby/planning.rb +13 -0
- data/lib/roby/planning/loops.rb +302 -0
- data/lib/roby/planning/model.rb +906 -0
- data/lib/roby/planning/task.rb +151 -0
- data/lib/roby/propagation.rb +562 -0
- data/lib/roby/query.rb +619 -0
- data/lib/roby/relations.rb +583 -0
- data/lib/roby/relations/conflicts.rb +70 -0
- data/lib/roby/relations/ensured.rb +20 -0
- data/lib/roby/relations/error_handling.rb +23 -0
- data/lib/roby/relations/events.rb +9 -0
- data/lib/roby/relations/executed_by.rb +193 -0
- data/lib/roby/relations/hierarchy.rb +239 -0
- data/lib/roby/relations/influence.rb +10 -0
- data/lib/roby/relations/planned_by.rb +63 -0
- data/lib/roby/robot.rb +7 -0
- data/lib/roby/standard_errors.rb +218 -0
- data/lib/roby/state.rb +5 -0
- data/lib/roby/state/events.rb +221 -0
- data/lib/roby/state/information.rb +55 -0
- data/lib/roby/state/pos.rb +110 -0
- data/lib/roby/state/shapes.rb +32 -0
- data/lib/roby/state/state.rb +353 -0
- data/lib/roby/support.rb +92 -0
- data/lib/roby/task-operations.rb +182 -0
- data/lib/roby/task.rb +1618 -0
- data/lib/roby/test/common.rb +399 -0
- data/lib/roby/test/distributed.rb +214 -0
- data/lib/roby/test/tasks/empty_task.rb +9 -0
- data/lib/roby/test/tasks/goto.rb +36 -0
- data/lib/roby/test/tasks/simple_task.rb +23 -0
- data/lib/roby/test/testcase.rb +519 -0
- data/lib/roby/test/tools.rb +160 -0
- data/lib/roby/thread_task.rb +87 -0
- data/lib/roby/transactions.rb +462 -0
- data/lib/roby/transactions/proxy.rb +292 -0
- data/lib/roby/transactions/updates.rb +139 -0
- data/plugins/fault_injection/History.txt +4 -0
- data/plugins/fault_injection/README.txt +37 -0
- data/plugins/fault_injection/Rakefile +18 -0
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +52 -0
- data/plugins/fault_injection/fault_injection.rb +89 -0
- data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
- data/plugins/subsystems/README.txt +40 -0
- data/plugins/subsystems/Rakefile +18 -0
- data/plugins/subsystems/app.rb +171 -0
- data/plugins/subsystems/test/app/README +24 -0
- data/plugins/subsystems/test/app/Rakefile +8 -0
- data/plugins/subsystems/test/app/config/app.yml +71 -0
- data/plugins/subsystems/test/app/config/init.rb +9 -0
- data/plugins/subsystems/test/app/config/roby.yml +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +20 -0
- data/plugins/subsystems/test/app/scripts/distributed +3 -0
- data/plugins/subsystems/test/app/scripts/replay +3 -0
- data/plugins/subsystems/test/app/scripts/results +3 -0
- data/plugins/subsystems/test/app/scripts/run +3 -0
- data/plugins/subsystems/test/app/scripts/server +3 -0
- data/plugins/subsystems/test/app/scripts/shell +3 -0
- data/plugins/subsystems/test/app/scripts/test +3 -0
- data/plugins/subsystems/test/app/tasks/services.rb +15 -0
- data/plugins/subsystems/test/test_subsystems.rb +71 -0
- data/test/distributed/test_communication.rb +178 -0
- data/test/distributed/test_connection.rb +282 -0
- data/test/distributed/test_execution.rb +373 -0
- data/test/distributed/test_mixed_plan.rb +341 -0
- data/test/distributed/test_plan_notifications.rb +238 -0
- data/test/distributed/test_protocol.rb +516 -0
- data/test/distributed/test_query.rb +102 -0
- data/test/distributed/test_remote_plan.rb +491 -0
- data/test/distributed/test_transaction.rb +463 -0
- data/test/mockups/tasks.rb +27 -0
- data/test/planning/test_loops.rb +380 -0
- data/test/planning/test_model.rb +427 -0
- data/test/planning/test_task.rb +106 -0
- data/test/relations/test_conflicts.rb +42 -0
- data/test/relations/test_ensured.rb +38 -0
- data/test/relations/test_executed_by.rb +149 -0
- data/test/relations/test_hierarchy.rb +158 -0
- data/test/relations/test_planned_by.rb +54 -0
- data/test/suite_core.rb +24 -0
- data/test/suite_distributed.rb +9 -0
- data/test/suite_planning.rb +3 -0
- data/test/suite_relations.rb +8 -0
- data/test/test_bgl.rb +508 -0
- data/test/test_control.rb +399 -0
- data/test/test_event.rb +894 -0
- data/test/test_exceptions.rb +592 -0
- data/test/test_interface.rb +37 -0
- data/test/test_log.rb +114 -0
- data/test/test_log_server.rb +132 -0
- data/test/test_plan.rb +584 -0
- data/test/test_propagation.rb +210 -0
- data/test/test_query.rb +266 -0
- data/test/test_relations.rb +180 -0
- data/test/test_state.rb +414 -0
- data/test/test_support.rb +16 -0
- data/test/test_task.rb +938 -0
- data/test/test_testcase.rb +122 -0
- data/test/test_thread_task.rb +73 -0
- data/test/test_transactions.rb +569 -0
- data/test/test_transactions_proxy.rb +198 -0
- metadata +570 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<ui version="4.0" >
|
|
2
|
+
<class>RelationsView</class>
|
|
3
|
+
<widget class="QMainWindow" name="RelationsView" >
|
|
4
|
+
<property name="geometry" >
|
|
5
|
+
<rect>
|
|
6
|
+
<x>0</x>
|
|
7
|
+
<y>0</y>
|
|
8
|
+
<width>800</width>
|
|
9
|
+
<height>600</height>
|
|
10
|
+
</rect>
|
|
11
|
+
</property>
|
|
12
|
+
<property name="windowTitle" >
|
|
13
|
+
<string>MainWindow</string>
|
|
14
|
+
</property>
|
|
15
|
+
<widget class="QWidget" name="centralwidget" >
|
|
16
|
+
<layout class="QVBoxLayout" >
|
|
17
|
+
<item>
|
|
18
|
+
<widget class="QGraphicsView" name="graphics" >
|
|
19
|
+
<property name="renderHints" >
|
|
20
|
+
<set>QPainter::Antialiasing|QPainter::TextAntialiasing</set>
|
|
21
|
+
</property>
|
|
22
|
+
</widget>
|
|
23
|
+
</item>
|
|
24
|
+
</layout>
|
|
25
|
+
</widget>
|
|
26
|
+
<widget class="QMenuBar" name="menubar" >
|
|
27
|
+
<property name="geometry" >
|
|
28
|
+
<rect>
|
|
29
|
+
<x>0</x>
|
|
30
|
+
<y>0</y>
|
|
31
|
+
<width>800</width>
|
|
32
|
+
<height>29</height>
|
|
33
|
+
</rect>
|
|
34
|
+
</property>
|
|
35
|
+
<widget class="QMenu" name="menuView" >
|
|
36
|
+
<property name="title" >
|
|
37
|
+
<string>View</string>
|
|
38
|
+
</property>
|
|
39
|
+
<addaction name="actionKeepSignals" />
|
|
40
|
+
<addaction name="actionHideFinalized" />
|
|
41
|
+
<addaction name="actionShowAll" />
|
|
42
|
+
<addaction name="actionRedraw" />
|
|
43
|
+
<addaction name="separator" />
|
|
44
|
+
<addaction name="actionZoom" />
|
|
45
|
+
<addaction name="actionUnzoom" />
|
|
46
|
+
<addaction name="actionFit" />
|
|
47
|
+
<addaction name="separator" />
|
|
48
|
+
<addaction name="actionSVGExport" />
|
|
49
|
+
<addaction name="actionPrint" />
|
|
50
|
+
</widget>
|
|
51
|
+
<widget class="QMenu" name="menuTask_labels" >
|
|
52
|
+
<property name="title" >
|
|
53
|
+
<string>Task labels</string>
|
|
54
|
+
</property>
|
|
55
|
+
<widget class="QMenu" name="menuRemovedPrefixes" >
|
|
56
|
+
<property name="title" >
|
|
57
|
+
<string>Removed prefixes</string>
|
|
58
|
+
</property>
|
|
59
|
+
<addaction name="actionPrefixAdd" />
|
|
60
|
+
<addaction name="separator" />
|
|
61
|
+
</widget>
|
|
62
|
+
<addaction name="actionOwnership" />
|
|
63
|
+
<addaction name="menuRemovedPrefixes" />
|
|
64
|
+
</widget>
|
|
65
|
+
<addaction name="menuView" />
|
|
66
|
+
<addaction name="menuTask_labels" />
|
|
67
|
+
</widget>
|
|
68
|
+
<action name="actionShowAll" >
|
|
69
|
+
<property name="text" >
|
|
70
|
+
<string>Show All</string>
|
|
71
|
+
</property>
|
|
72
|
+
</action>
|
|
73
|
+
<action name="actionRedraw" >
|
|
74
|
+
<property name="text" >
|
|
75
|
+
<string>Redaw</string>
|
|
76
|
+
</property>
|
|
77
|
+
</action>
|
|
78
|
+
<action name="actionZoom" >
|
|
79
|
+
<property name="text" >
|
|
80
|
+
<string>Zoom +</string>
|
|
81
|
+
</property>
|
|
82
|
+
</action>
|
|
83
|
+
<action name="actionUnzoom" >
|
|
84
|
+
<property name="text" >
|
|
85
|
+
<string>Zoom -</string>
|
|
86
|
+
</property>
|
|
87
|
+
</action>
|
|
88
|
+
<action name="actionFit" >
|
|
89
|
+
<property name="text" >
|
|
90
|
+
<string>Fit</string>
|
|
91
|
+
</property>
|
|
92
|
+
</action>
|
|
93
|
+
<action name="actionOwnership" >
|
|
94
|
+
<property name="checkable" >
|
|
95
|
+
<bool>true</bool>
|
|
96
|
+
</property>
|
|
97
|
+
<property name="checked" >
|
|
98
|
+
<bool>true</bool>
|
|
99
|
+
</property>
|
|
100
|
+
<property name="text" >
|
|
101
|
+
<string>Ownership</string>
|
|
102
|
+
</property>
|
|
103
|
+
</action>
|
|
104
|
+
<action name="actionPrefixAdd" >
|
|
105
|
+
<property name="text" >
|
|
106
|
+
<string>Add...</string>
|
|
107
|
+
</property>
|
|
108
|
+
</action>
|
|
109
|
+
<action name="actionSVGExport" >
|
|
110
|
+
<property name="text" >
|
|
111
|
+
<string>SVG Export</string>
|
|
112
|
+
</property>
|
|
113
|
+
</action>
|
|
114
|
+
<action name="actionPrint" >
|
|
115
|
+
<property name="text" >
|
|
116
|
+
<string>Print</string>
|
|
117
|
+
</property>
|
|
118
|
+
</action>
|
|
119
|
+
<action name="actionKeepSignals" >
|
|
120
|
+
<property name="checkable" >
|
|
121
|
+
<bool>true</bool>
|
|
122
|
+
</property>
|
|
123
|
+
<property name="checked" >
|
|
124
|
+
<bool>false</bool>
|
|
125
|
+
</property>
|
|
126
|
+
<property name="text" >
|
|
127
|
+
<string>Keep signals</string>
|
|
128
|
+
</property>
|
|
129
|
+
</action>
|
|
130
|
+
<action name="actionBookmarksAdd" >
|
|
131
|
+
<property name="text" >
|
|
132
|
+
<string>Add ...</string>
|
|
133
|
+
</property>
|
|
134
|
+
</action>
|
|
135
|
+
<action name="actionHideFinalized" >
|
|
136
|
+
<property name="checkable" >
|
|
137
|
+
<bool>true</bool>
|
|
138
|
+
</property>
|
|
139
|
+
<property name="checked" >
|
|
140
|
+
<bool>true</bool>
|
|
141
|
+
</property>
|
|
142
|
+
<property name="text" >
|
|
143
|
+
<string>Hide Finalized</string>
|
|
144
|
+
</property>
|
|
145
|
+
</action>
|
|
146
|
+
</widget>
|
|
147
|
+
<resources/>
|
|
148
|
+
<connections/>
|
|
149
|
+
</ui>
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
require 'Qt4'
|
|
2
|
+
require 'roby/app'
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
require 'roby/log/gui/replay_controls'
|
|
6
|
+
require 'roby/log/gui/data_displays'
|
|
7
|
+
|
|
8
|
+
# This class is a data stream list model for offline replay:
|
|
9
|
+
# it holds a list of log file which can then be used for
|
|
10
|
+
# display by log/replay
|
|
11
|
+
class OfflineStreamListModel < DataStreamListModel
|
|
12
|
+
def edit(stream)
|
|
13
|
+
dir = if !stream || stream.files.empty? then ""
|
|
14
|
+
else File.dirname(stream.files.first) end
|
|
15
|
+
|
|
16
|
+
newfiles = Qt::FileDialog.get_open_file_names nil, "New data stream", dir
|
|
17
|
+
return if newfiles.empty?
|
|
18
|
+
if !newfiles.empty?
|
|
19
|
+
if newstream = Roby.app.data_stream(newfiles)
|
|
20
|
+
return newstream
|
|
21
|
+
else
|
|
22
|
+
Qt::MessageBox.warning nil, "Add data stream", "Cannot determine data stream type for #{newfiles.join(", ")}"
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Replay < Qt::MainWindow
|
|
30
|
+
attr_reader :streams
|
|
31
|
+
attr_reader :streams_model
|
|
32
|
+
|
|
33
|
+
# The widget which controls the data stream => display mapping, and display
|
|
34
|
+
# control
|
|
35
|
+
attr_reader :ui_displays
|
|
36
|
+
# The widget which hold the replay controls (play, pause, ...)
|
|
37
|
+
attr_reader :ui_controls
|
|
38
|
+
|
|
39
|
+
# The set of bookmarks as a name => time map
|
|
40
|
+
attr_reader :bookmarks
|
|
41
|
+
|
|
42
|
+
KEY_GOTO = Qt::KeySequence.new('g')
|
|
43
|
+
|
|
44
|
+
# True if we should start playing right away
|
|
45
|
+
attr_accessor :play_now
|
|
46
|
+
# The log directory, or Roby.app.log_dir
|
|
47
|
+
attr_accessor :log_dir
|
|
48
|
+
# Set to a time at which we should go to
|
|
49
|
+
attr_accessor :initial_time
|
|
50
|
+
# A set of procs which are to be called to set up the display
|
|
51
|
+
attr_accessor :initial_setup
|
|
52
|
+
|
|
53
|
+
def initialize
|
|
54
|
+
super()
|
|
55
|
+
@play_speed = 1.0
|
|
56
|
+
@play_now = nil
|
|
57
|
+
@logdir = nil
|
|
58
|
+
@goto = nil
|
|
59
|
+
@initial_setup = []
|
|
60
|
+
@bookmarks = Hash.new
|
|
61
|
+
|
|
62
|
+
# Create the vertical layout for this window
|
|
63
|
+
central_widget = Qt::Widget.new(self)
|
|
64
|
+
self.central_widget = central_widget
|
|
65
|
+
layout = Qt::VBoxLayout.new(central_widget)
|
|
66
|
+
layout.spacing = 6
|
|
67
|
+
layout.margin = 0
|
|
68
|
+
|
|
69
|
+
# Add support for the data streams and display setup
|
|
70
|
+
@streams = Array.new
|
|
71
|
+
@streams_model = OfflineStreamListModel.new(streams)
|
|
72
|
+
displays_holder = Qt::Widget.new(central_widget)
|
|
73
|
+
layout.add_widget displays_holder
|
|
74
|
+
@ui_displays = Ui_DataDisplays.new
|
|
75
|
+
ui_displays.setupUi(displays_holder)
|
|
76
|
+
ui_displays.streams.model = streams_model
|
|
77
|
+
connect(ui_displays.add_stream, SIGNAL("clicked()"), self, SLOT("add_stream()"))
|
|
78
|
+
connect(ui_displays.remove_stream, SIGNAL("clicked()"), self, SLOT("remove_stream()"))
|
|
79
|
+
connect(ui_displays.display_add, SIGNAL("clicked()"), self, SLOT("add_display()"))
|
|
80
|
+
|
|
81
|
+
controls_holder = Qt::Widget.new(central_widget)
|
|
82
|
+
@ui_controls = Ui::ReplayControls.new
|
|
83
|
+
ui_controls.setupUi(self, controls_holder)
|
|
84
|
+
layout.add_widget controls_holder
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def play_speed=(value)
|
|
88
|
+
ui_controls.speed.text = value.to_s
|
|
89
|
+
@play_speed = value
|
|
90
|
+
|
|
91
|
+
if play_timer
|
|
92
|
+
play_timer.stop
|
|
93
|
+
play_timer.start(Integer(time_slice * 1000))
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
def time_slice
|
|
97
|
+
if play_speed < 1
|
|
98
|
+
BASE_TIME_SLICE / play_speed
|
|
99
|
+
else
|
|
100
|
+
BASE_TIME_SLICE
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def displayed_streams
|
|
105
|
+
streams.find_all do |s|
|
|
106
|
+
s.displayed?
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Time of the first known sample
|
|
111
|
+
attr_reader :first_sample
|
|
112
|
+
# Time of the last known sample
|
|
113
|
+
attr_reader :last_sample
|
|
114
|
+
|
|
115
|
+
def seek(time, integrate = true)
|
|
116
|
+
if time && !first_sample
|
|
117
|
+
seek(nil)
|
|
118
|
+
elsif time && first_sample && time < first_sample
|
|
119
|
+
time = nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
displayed_streams.each { |s| s.prepare_seek(time) }
|
|
123
|
+
if !time || time == Time.at(0)
|
|
124
|
+
min, max = displayed_streams.inject([nil, nil]) do |(min, max), stream|
|
|
125
|
+
stream_min, stream_max = stream.range
|
|
126
|
+
if !min || stream_min < min
|
|
127
|
+
min = stream_min
|
|
128
|
+
end
|
|
129
|
+
if !max || stream_max > max
|
|
130
|
+
max = stream_max
|
|
131
|
+
end
|
|
132
|
+
[min, max]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
@first_sample = @time = min
|
|
136
|
+
@last_sample = max
|
|
137
|
+
|
|
138
|
+
ui_controls.progress.minimum = min.to_i
|
|
139
|
+
ui_controls.progress.maximum = max.to_i
|
|
140
|
+
ui_controls.update_bookmarks_menu
|
|
141
|
+
else
|
|
142
|
+
play_until time, integrate
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
update_time_display
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def update_time_display
|
|
149
|
+
ui_controls.time_lcd.display(((self.time - first_sample) * 1000.0).round / 1000.0)
|
|
150
|
+
ui_controls.progress.value = self.time.to_i
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
attr_reader :time
|
|
154
|
+
|
|
155
|
+
def next_time
|
|
156
|
+
displayed_streams.
|
|
157
|
+
map { |s| s.next_time }.
|
|
158
|
+
compact.min
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
BASE_TIME_SLICE = 0.5
|
|
162
|
+
attr_reader :play_timer, :play_speed
|
|
163
|
+
def play
|
|
164
|
+
seek(nil) unless first_sample
|
|
165
|
+
|
|
166
|
+
@play_timer = Qt::Timer.new(self)
|
|
167
|
+
connect(play_timer, SIGNAL("timeout()"), self, SLOT("play_step_timer()"))
|
|
168
|
+
play_timer.start(Integer(time_slice * 1000))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def stop
|
|
172
|
+
if play_timer
|
|
173
|
+
ui_controls.play.checked = false
|
|
174
|
+
play_timer.stop
|
|
175
|
+
@play_timer = nil
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def play_step
|
|
180
|
+
seek(nil) unless first_sample
|
|
181
|
+
play_until(next_time)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def play_step_timer
|
|
185
|
+
start = Time.now
|
|
186
|
+
play_until(time + time_slice * play_speed)
|
|
187
|
+
end
|
|
188
|
+
slots 'play_step_timer()'
|
|
189
|
+
|
|
190
|
+
def play_until(max_time, integrate = true)
|
|
191
|
+
start_at = Time.now
|
|
192
|
+
displayed_streams.inject(timeline = []) do |timeline, s|
|
|
193
|
+
if s.next_time
|
|
194
|
+
timeline << [s.next_time, s]
|
|
195
|
+
end
|
|
196
|
+
timeline
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
if timeline.empty?
|
|
200
|
+
stop
|
|
201
|
+
return
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
updated_streams = Set.new
|
|
205
|
+
|
|
206
|
+
timeline.sort_by { |t, _| t }
|
|
207
|
+
while !timeline.empty? && (timeline[0][0] - max_time) < 0.001
|
|
208
|
+
@time, stream = timeline.first
|
|
209
|
+
|
|
210
|
+
stream.advance
|
|
211
|
+
stream.clear_integrated unless integrate
|
|
212
|
+
updated_streams << stream
|
|
213
|
+
if next_time = stream.next_time
|
|
214
|
+
timeline[0] = [next_time, stream]
|
|
215
|
+
else
|
|
216
|
+
timeline.shift
|
|
217
|
+
end
|
|
218
|
+
timeline.sort_by { |t, _| t }
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
replayed = Time.now
|
|
222
|
+
|
|
223
|
+
updated_streams.each do |stream|
|
|
224
|
+
stream.display
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
STDERR.puts "replay #{replayed - start_at}, display #{Time.now-replayed}"
|
|
228
|
+
|
|
229
|
+
if timeline.empty? then stop
|
|
230
|
+
else @time = max_time
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
if time > last_sample
|
|
234
|
+
@last_sample = time
|
|
235
|
+
|
|
236
|
+
time_display = time.to_i
|
|
237
|
+
if ui_controls.progress.maximum < time_display
|
|
238
|
+
ui_controls.progress.maximum = (first_sample + (last_sample - first_sample) * 4 / 3).to_i
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
update_time_display
|
|
242
|
+
|
|
243
|
+
rescue Exception => e
|
|
244
|
+
message = "<html>#{Qt.escape(e.message)}<ul><li>#{e.backtrace.join("</li><li>")}</li></ul></html>"
|
|
245
|
+
Qt::MessageBox.critical self, "Replay failure", message
|
|
246
|
+
stop
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def add_stream(stream = nil)
|
|
250
|
+
streams_model.add_new(stream)
|
|
251
|
+
end
|
|
252
|
+
slots 'add_stream()'
|
|
253
|
+
|
|
254
|
+
def remove_stream
|
|
255
|
+
index = ui_displays.streams.current_index.row
|
|
256
|
+
streams.removeRow(index, Qt::ModelIndex.new)
|
|
257
|
+
end
|
|
258
|
+
slots 'remove_stream()'
|
|
259
|
+
|
|
260
|
+
def add_display(kind = nil)
|
|
261
|
+
ui_displays.add_display(streams_model, kind)
|
|
262
|
+
end
|
|
263
|
+
slots 'add_display()'
|
|
264
|
+
|
|
265
|
+
def self.setup(argv)
|
|
266
|
+
replay = self.new
|
|
267
|
+
|
|
268
|
+
parser = OptionParser.new do |opt|
|
|
269
|
+
Ui_DataDisplays::DISPLAYS.each_value do |config_ui|
|
|
270
|
+
config_ui.setup_optparse(opt, replay)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
opt.on("--logdir=DIR", String, "the log directory in which we initialize the data streams") do |dir|
|
|
274
|
+
replay.log_dir = dir
|
|
275
|
+
end
|
|
276
|
+
opt.on("--play", "start playing after loading the event log") do
|
|
277
|
+
replay.play_now = true
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
opt.on("--speed=SPEED", Integer, "play speed") do |speed|
|
|
281
|
+
replay.play_speed = speed
|
|
282
|
+
end
|
|
283
|
+
opt.on("--goto=TIME", String, "go to TIME before playing normally. Time is given relatively to the simulation start") do |goto|
|
|
284
|
+
replay.initial_time = goto
|
|
285
|
+
end
|
|
286
|
+
opt.on('--bookmarks=FILE', String, "load the bookmarks in FILE") do |file|
|
|
287
|
+
replay.ui_controls.load_bookmarks(file)
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
args = argv.dup
|
|
291
|
+
parser.parse!(args)
|
|
292
|
+
|
|
293
|
+
yield(replay, parser, args) if block_given?
|
|
294
|
+
|
|
295
|
+
replay
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def setup
|
|
299
|
+
initial_setup.each do |prc|
|
|
300
|
+
prc.call(self)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
show
|
|
304
|
+
if initial_time
|
|
305
|
+
seek(nil)
|
|
306
|
+
|
|
307
|
+
seek_time = if initial_time[0] == ?@
|
|
308
|
+
Time.from_hms(initial_time[1..-1])
|
|
309
|
+
else
|
|
310
|
+
first_sample + (Time.from_hms(initial_time) - Time.at(0))
|
|
311
|
+
end
|
|
312
|
+
seek(seek_time, false)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
if play_now
|
|
316
|
+
ui_controls.play.checked = true
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
if $0 == __FILE__
|
|
322
|
+
a = Qt::Application.new(ARGV)
|
|
323
|
+
w = Replay.new
|
|
324
|
+
w.show
|
|
325
|
+
a.exec
|
|
326
|
+
end
|
|
327
|
+
|