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/console.rb
CHANGED
@@ -30,14 +30,16 @@ module Roby::Log
|
|
30
30
|
def arg_to_s(arg)
|
31
31
|
case arg
|
32
32
|
when Time then Time.at(arg - @reftime).to_hms
|
33
|
-
when Array then arg.map(
|
33
|
+
when Array then arg.map { |v| arg_to_s(v) }.to_s
|
34
34
|
when Hash then arg.map { |k, v| [arg_to_s(k), arg_to_s(v)].join(" => ") }.to_s
|
35
35
|
else arg.to_s
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
|
40
|
-
|
40
|
+
def logs_message?(m); true end
|
41
|
+
def close; end
|
42
|
+
def dump_method(m, time, *args) # :nodoc:
|
41
43
|
@reftime ||= time
|
42
44
|
|
43
45
|
args.map! { |a| arg_to_s(a) }
|
@@ -65,7 +67,7 @@ module Roby::Log
|
|
65
67
|
private :display
|
66
68
|
|
67
69
|
Roby::Log.each_hook do |klass, m|
|
68
|
-
define_method(m) { |args|
|
70
|
+
define_method(m) { |time, args| dump_method(m, time, args) }
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
data/lib/roby/log/data_stream.rb
CHANGED
@@ -46,6 +46,12 @@ module Roby::Log
|
|
46
46
|
@decoders = []
|
47
47
|
end
|
48
48
|
|
49
|
+
def each_sample
|
50
|
+
while sample = read_and_decode
|
51
|
+
yield(sample)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
49
55
|
def to_s; "#{name} [#{type}]" end
|
50
56
|
def open; end
|
51
57
|
def close; end
|
@@ -62,7 +68,9 @@ module Roby::Log
|
|
62
68
|
def read_all; end
|
63
69
|
|
64
70
|
def read_and_decode
|
65
|
-
|
71
|
+
if raw = read
|
72
|
+
self.class.decode(raw)
|
73
|
+
end
|
66
74
|
end
|
67
75
|
|
68
76
|
# The [min, max] range of available samples. Initially
|
@@ -100,12 +108,21 @@ module Roby::Log
|
|
100
108
|
super if defined? super
|
101
109
|
end
|
102
110
|
|
103
|
-
# Do a read
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
111
|
+
# Do a read and decode the data
|
112
|
+
#
|
113
|
+
# It returns false if no decoders have found interesting updates in the
|
114
|
+
# decoded data, and true otherwise. The method relies on the decoder's
|
115
|
+
# #process method to return true/false when required.
|
116
|
+
#
|
117
|
+
# See DataDecoder#process
|
118
|
+
def advance
|
119
|
+
if data = read_and_decode
|
120
|
+
!decoders.find_all do |dec|
|
121
|
+
dec.process(data)
|
122
|
+
end.empty?
|
123
|
+
else
|
124
|
+
raise EOFError
|
125
|
+
end
|
109
126
|
end
|
110
127
|
|
111
128
|
def init(data)
|
@@ -115,13 +132,26 @@ module Roby::Log
|
|
115
132
|
self.class.decode(data)
|
116
133
|
end
|
117
134
|
|
135
|
+
# Displays may have the ability to not display a per-cycle information,
|
136
|
+
# but to add information as it is coming over. This call asks them to
|
137
|
+
# remove the information integrated until now.
|
138
|
+
#
|
139
|
+
# It forwards the call to the decoders' #clear_integrated call. These
|
140
|
+
# methods should return true if a change has been needed on any of their
|
141
|
+
# display, and false otherwise.
|
118
142
|
def clear_integrated
|
119
|
-
decoders.
|
143
|
+
!decoders.find_all do |decoder|
|
120
144
|
decoder.clear_integrated
|
121
|
-
end
|
145
|
+
end.empty?
|
122
146
|
end
|
123
147
|
|
124
148
|
# Update the displays
|
149
|
+
#
|
150
|
+
# It returns false if all decoders have reported that no display update
|
151
|
+
# was required, and true otherwise. The method relies on the decoder's
|
152
|
+
# #display method to return true/false when required.
|
153
|
+
#
|
154
|
+
# See DataDecoder#display
|
125
155
|
def display
|
126
156
|
decoders.each do |decoder|
|
127
157
|
decoder.display
|
@@ -137,10 +167,16 @@ module Roby::Log
|
|
137
167
|
def hash; [name, type].hash end
|
138
168
|
end
|
139
169
|
|
170
|
+
# In the data flow model we're using, a data decoder gets data from a
|
171
|
+
# DataStream object and builds a representation that can be used by
|
172
|
+
# displays.
|
140
173
|
class DataDecoder
|
141
174
|
# The set of displays attached to this decoder
|
142
175
|
attr_reader :displays
|
176
|
+
# The decoder name
|
143
177
|
attr_reader :name
|
178
|
+
|
179
|
+
# The DataStream object we're getting our data from
|
144
180
|
attr_accessor :stream
|
145
181
|
|
146
182
|
def initialize(name)
|
@@ -148,24 +184,54 @@ module Roby::Log
|
|
148
184
|
@displays = []
|
149
185
|
end
|
150
186
|
|
187
|
+
# Clear the stream data
|
151
188
|
def clear
|
152
189
|
displays.each { |d| d.clear }
|
153
190
|
end
|
154
191
|
|
192
|
+
# Displays may have the ability to not display a per-cycle information,
|
193
|
+
# but to add information as it is coming over. This call asks them to
|
194
|
+
# remove the information integrated until now.
|
195
|
+
#
|
196
|
+
# It forwards the call to the displays' #clear_integrated call(if any). These
|
197
|
+
# methods should return true if a change has been needed on any of their
|
198
|
+
# display, and false otherwise.
|
155
199
|
def clear_integrated
|
156
|
-
displays.
|
157
|
-
|
158
|
-
|
200
|
+
!displays.find_all do |display|
|
201
|
+
if display.respond_to?(:clear_integrated)
|
202
|
+
display.clear_integrated
|
203
|
+
end
|
204
|
+
end.empty?
|
159
205
|
end
|
160
206
|
|
161
|
-
#
|
207
|
+
# Updates the displays that are associated with this decoder. Returns
|
208
|
+
# true if one of the displays have been changed, and false otherwise.
|
209
|
+
#
|
210
|
+
# It relies on the display's #update method to return true if something
|
211
|
+
# has changed on the display and false otherwise.
|
162
212
|
def display
|
163
|
-
displays.
|
213
|
+
!displays.find_all do |display|
|
164
214
|
display.update
|
165
|
-
end
|
215
|
+
end.empty?
|
166
216
|
end
|
167
217
|
end
|
168
218
|
|
219
|
+
# This module gets mixed-in the display classes. It creates the necessary
|
220
|
+
# stream => decoder => display link, reusing (if possible) a decoder that
|
221
|
+
# already exists.
|
222
|
+
#
|
223
|
+
# One should use it that way:
|
224
|
+
#
|
225
|
+
# class Display
|
226
|
+
# include DataDisplay
|
227
|
+
# decoder DecoderClass
|
228
|
+
# end
|
229
|
+
#
|
230
|
+
# Then, one can do
|
231
|
+
# display = Display.new
|
232
|
+
# display.stream = data_stream
|
233
|
+
#
|
234
|
+
# and leave the rest to the DataDisplay implementation.
|
169
235
|
module DataDisplay
|
170
236
|
module ClassExtension
|
171
237
|
def decoder(new_type = nil)
|
@@ -177,11 +243,23 @@ module Roby::Log
|
|
177
243
|
end
|
178
244
|
end
|
179
245
|
|
246
|
+
# The decoder object. That object gets data from a DataStream object and
|
247
|
+
# decodes it into the format required by the display.
|
248
|
+
#
|
249
|
+
# Examples: PlanRebuilder
|
180
250
|
attr_reader :decoder
|
181
251
|
attr_reader :main
|
252
|
+
|
253
|
+
# The configuration UI object. Usually a subclass of Qt::Widget
|
182
254
|
attr_accessor :config_ui
|
183
|
-
def splat?; true end
|
184
255
|
|
256
|
+
|
257
|
+
def splat? #:nodoc:
|
258
|
+
true
|
259
|
+
end
|
260
|
+
|
261
|
+
# Sets the data stream that this display listens to. It creates or gets
|
262
|
+
# the decoder that is necessary between the raw stream and the display
|
185
263
|
def stream=(data_stream)
|
186
264
|
if decoder
|
187
265
|
clear
|
data/lib/roby/log/dot.rb
CHANGED
@@ -33,11 +33,11 @@ module Roby
|
|
33
33
|
trsc.to_dot(display, io, level + 1)
|
34
34
|
end
|
35
35
|
|
36
|
-
relations_to_dot(display, io,
|
36
|
+
relations_to_dot(display, io, Roby::Log::RelationsDisplay.all_task_relations, known_tasks)
|
37
37
|
end
|
38
38
|
|
39
|
-
def each_displayed_relation(display,
|
40
|
-
|
39
|
+
def each_displayed_relation(display, relations, objects)
|
40
|
+
relations.each do |rel|
|
41
41
|
next unless display.relation_enabled?(rel)
|
42
42
|
|
43
43
|
objects.each do |from|
|
@@ -60,8 +60,8 @@ module Roby
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def relations_to_dot(display, io,
|
64
|
-
each_displayed_relation(display,
|
63
|
+
def relations_to_dot(display, io, all_relations, objects)
|
64
|
+
each_displayed_relation(display, all_relations, objects) do |rel, from, to|
|
65
65
|
from_id, to_id = from.dot_id, to.dot_id
|
66
66
|
if from_id && to_id
|
67
67
|
io << " #{from_id} -> #{to_id}\n"
|
@@ -71,8 +71,8 @@ module Roby
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def layout_relations(positions, display,
|
75
|
-
each_displayed_relation(display,
|
74
|
+
def layout_relations(positions, display, all_relations, objects)
|
75
|
+
each_displayed_relation(display, all_relations, objects) do |rel, from, to|
|
76
76
|
display.task_relation(from, to, rel, from[to, rel])
|
77
77
|
end
|
78
78
|
end
|
@@ -114,7 +114,7 @@ module Roby
|
|
114
114
|
transactions.each do |trsc|
|
115
115
|
trsc.apply_layout(bounding_rects, positions, display, max_depth)
|
116
116
|
end
|
117
|
-
layout_relations(positions, display,
|
117
|
+
layout_relations(positions, display, Roby::Log::RelationsDisplay.all_task_relations, known_tasks)
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
@@ -17,7 +17,11 @@ module Roby
|
|
17
17
|
attr_reader :start_cycle
|
18
18
|
# A [min, max] array of the minimum and maximum times for this
|
19
19
|
# stream
|
20
|
-
def range
|
20
|
+
def range
|
21
|
+
if range = logfile.range
|
22
|
+
[start_time, logfile.range.last]
|
23
|
+
end
|
24
|
+
end
|
21
25
|
|
22
26
|
def initialize(basename, file = nil)
|
23
27
|
super(basename, "roby-events")
|
@@ -104,6 +108,10 @@ module Roby
|
|
104
108
|
reinit!
|
105
109
|
end
|
106
110
|
|
111
|
+
if current_cycle >= index_data.size
|
112
|
+
return
|
113
|
+
end
|
114
|
+
|
107
115
|
start_pos = index_data[current_cycle][:pos]
|
108
116
|
end_pos = if index_data.size > current_cycle + 1
|
109
117
|
index_data[current_cycle + 1][:pos]
|
@@ -128,8 +136,10 @@ module Roby
|
|
128
136
|
rescue EOFError
|
129
137
|
end
|
130
138
|
|
131
|
-
# Unmarshalls one cycle of data returned by #read
|
132
|
-
|
139
|
+
# Unmarshalls one cycle of data returned by #read
|
140
|
+
#
|
141
|
+
# In the case of the event stream, this is one array dumped with
|
142
|
+
# Marshal.dump
|
133
143
|
def self.decode(data)
|
134
144
|
Marshal.load(data)
|
135
145
|
end
|
data/lib/roby/log/file.rb
CHANGED
@@ -10,8 +10,10 @@ module Roby::Log
|
|
10
10
|
attr_reader :index_data
|
11
11
|
attr_reader :basename
|
12
12
|
def range
|
13
|
-
|
14
|
-
|
13
|
+
if !index_data.empty?
|
14
|
+
[Time.at(*index_data.first[:start]),
|
15
|
+
Time.at(*index_data.last[:start]) + index_data.last[:end]]
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
def initialize(file, allow_old_format = false, force_rebuild_index = false)
|
@@ -30,6 +32,14 @@ module Roby::Log
|
|
30
32
|
FileLogger.check_format(@event_io)
|
31
33
|
end
|
32
34
|
|
35
|
+
@event_io.rewind
|
36
|
+
file_header = Marshal.load(@event_io)
|
37
|
+
if file_header[:plugins]
|
38
|
+
file_header[:plugins].each do |plugin_name|
|
39
|
+
Roby.app.using plugin_name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
33
43
|
index_path = "#{basename}-index.log"
|
34
44
|
if force_rebuild_index || !File.file?(index_path)
|
35
45
|
rebuild_index
|
@@ -88,8 +98,13 @@ module Roby::Log
|
|
88
98
|
return false
|
89
99
|
end
|
90
100
|
|
91
|
-
|
92
|
-
|
101
|
+
stats = cycle.last[0].dup
|
102
|
+
stats.delete(:state)
|
103
|
+
index = index.dup
|
104
|
+
index.delete(:state)
|
105
|
+
if stats != index
|
106
|
+
STDERR.puts stats.inspect
|
107
|
+
STDERR.puts index.inspect
|
93
108
|
return false
|
94
109
|
end
|
95
110
|
end
|
@@ -127,7 +142,7 @@ module Roby::Log
|
|
127
142
|
|
128
143
|
# A logger object which marshals all available events in two files. The
|
129
144
|
# event log is the full log, the index log contains only the timings given
|
130
|
-
# to
|
145
|
+
# to ExecutionEngine#cycle_end, along with the corresponding position in the event
|
131
146
|
# log file.
|
132
147
|
#
|
133
148
|
# You can use FileLogger.replay(io) to send the events back into the
|
@@ -151,19 +166,28 @@ module Roby::Log
|
|
151
166
|
# StringIO object on which we dump the data
|
152
167
|
attr_reader :dump_io
|
153
168
|
|
154
|
-
def initialize(basename)
|
169
|
+
def initialize(basename, options)
|
155
170
|
@current_pos = 0
|
156
171
|
@dump_io = StringIO.new('', 'w')
|
157
172
|
@current_cycle = Array.new
|
158
173
|
@event_log = File.open("#{basename}-events.log", 'w')
|
159
174
|
event_log.sync = true
|
160
|
-
FileLogger.write_header(@event_log)
|
175
|
+
FileLogger.write_header(@event_log, options)
|
161
176
|
@index_log = File.open("#{basename}-index.log", 'w')
|
162
177
|
index_log.sync = true
|
163
178
|
end
|
164
179
|
|
165
180
|
attr_accessor :stats_mode
|
166
181
|
def splat?; false end
|
182
|
+
def logs_message?(m)
|
183
|
+
m == :cycle_end || !stats_mode
|
184
|
+
end
|
185
|
+
|
186
|
+
def close
|
187
|
+
dump_method(:cycle_end, Time.now, [])
|
188
|
+
@event_log.close
|
189
|
+
@index_log.close
|
190
|
+
end
|
167
191
|
|
168
192
|
def dump_method(m, time, args)
|
169
193
|
if m == :cycle_end || !stats_mode
|
@@ -172,7 +196,7 @@ module Roby::Log
|
|
172
196
|
if m == :cycle_end
|
173
197
|
info = args.first
|
174
198
|
info[:pos] = event_log.tell
|
175
|
-
info[:event_count] = current_cycle.size
|
199
|
+
info[:event_count] = current_cycle.size / 4
|
176
200
|
Marshal.dump(current_cycle, event_log)
|
177
201
|
|
178
202
|
dump_io.truncate(0)
|
@@ -184,13 +208,16 @@ module Roby::Log
|
|
184
208
|
end
|
185
209
|
|
186
210
|
rescue
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
211
|
+
current_cycle.each_slice(4) do |m, sec, usec, args|
|
212
|
+
unless (Marshal.dump(args) rescue nil)
|
213
|
+
args.each do |obj|
|
214
|
+
unless (Marshal.dump(obj) rescue nil)
|
215
|
+
puts "cannot dump the following object in #{m}(#{args.join(", ")}):"
|
216
|
+
pp obj
|
217
|
+
end
|
218
|
+
end
|
192
219
|
end
|
193
|
-
|
220
|
+
end
|
194
221
|
end
|
195
222
|
|
196
223
|
Roby::Log.each_hook do |klass, m|
|
@@ -209,8 +236,6 @@ module Roby::Log
|
|
209
236
|
loop do
|
210
237
|
cycle = Marshal.load(event_log)
|
211
238
|
info = cycle.last.last
|
212
|
-
info[:pos] = current_pos
|
213
|
-
info[:event_count] = cycle.size
|
214
239
|
|
215
240
|
dump_io.truncate(0)
|
216
241
|
dump_io.seek(0)
|
@@ -262,8 +287,8 @@ module Roby::Log
|
|
262
287
|
end
|
263
288
|
end
|
264
289
|
|
265
|
-
def self.write_header(io)
|
266
|
-
header = { :log_format => FORMAT_VERSION }
|
290
|
+
def self.write_header(io, options = Hash.new)
|
291
|
+
header = { :log_format => FORMAT_VERSION }.merge(options)
|
267
292
|
Marshal.dump(header, io)
|
268
293
|
end
|
269
294
|
|
@@ -0,0 +1,89 @@
|
|
1
|
+
=begin
|
2
|
+
** Form generated from reading ui file 'basic_display.ui'
|
3
|
+
**
|
4
|
+
** Created: Mon Jan 25 15:21:37 2010
|
5
|
+
** by: Qt User Interface Compiler version 4.5.3
|
6
|
+
**
|
7
|
+
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
8
|
+
=end
|
9
|
+
|
10
|
+
class Ui_BasicDisplayConfig
|
11
|
+
attr_reader :gridLayout
|
12
|
+
attr_reader :gridLayout1
|
13
|
+
attr_reader :label
|
14
|
+
attr_reader :close
|
15
|
+
attr_reader :spacerItem
|
16
|
+
attr_reader :stream
|
17
|
+
|
18
|
+
def setupUi(basicDisplayConfig)
|
19
|
+
if basicDisplayConfig.objectName.nil?
|
20
|
+
basicDisplayConfig.objectName = "basicDisplayConfig"
|
21
|
+
end
|
22
|
+
basicDisplayConfig.resize(333, 77)
|
23
|
+
@gridLayout = Qt::GridLayout.new(basicDisplayConfig)
|
24
|
+
@gridLayout.spacing = 6
|
25
|
+
@gridLayout.margin = 9
|
26
|
+
@gridLayout.objectName = "gridLayout"
|
27
|
+
@gridLayout1 = Qt::GridLayout.new()
|
28
|
+
@gridLayout1.spacing = 6
|
29
|
+
@gridLayout1.margin = 0
|
30
|
+
@gridLayout1.objectName = "gridLayout1"
|
31
|
+
@label = Qt::Label.new(basicDisplayConfig)
|
32
|
+
@label.objectName = "label"
|
33
|
+
@sizePolicy = Qt::SizePolicy.new(1, 5)
|
34
|
+
@sizePolicy.setHorizontalStretch(0)
|
35
|
+
@sizePolicy.setVerticalStretch(0)
|
36
|
+
@sizePolicy.heightForWidth = @label.sizePolicy.hasHeightForWidth
|
37
|
+
@label.sizePolicy = @sizePolicy
|
38
|
+
|
39
|
+
@gridLayout1.addWidget(@label, 1, 0, 1, 1)
|
40
|
+
|
41
|
+
@close = Qt::PushButton.new(basicDisplayConfig)
|
42
|
+
@close.objectName = "close"
|
43
|
+
|
44
|
+
@gridLayout1.addWidget(@close, 0, 2, 1, 1)
|
45
|
+
|
46
|
+
@spacerItem = Qt::SpacerItem.new(161, 20, Qt::SizePolicy::Expanding, Qt::SizePolicy::Minimum)
|
47
|
+
|
48
|
+
@gridLayout1.addItem(@spacerItem, 0, 0, 1, 2)
|
49
|
+
|
50
|
+
@stream = Qt::ComboBox.new(basicDisplayConfig)
|
51
|
+
@stream.objectName = "stream"
|
52
|
+
@sizePolicy1 = Qt::SizePolicy.new(3, 0)
|
53
|
+
@sizePolicy1.setHorizontalStretch(0)
|
54
|
+
@sizePolicy1.setVerticalStretch(0)
|
55
|
+
@sizePolicy1.heightForWidth = @stream.sizePolicy.hasHeightForWidth
|
56
|
+
@stream.sizePolicy = @sizePolicy1
|
57
|
+
|
58
|
+
@gridLayout1.addWidget(@stream, 1, 1, 1, 2)
|
59
|
+
|
60
|
+
|
61
|
+
@gridLayout.addLayout(@gridLayout1, 0, 0, 1, 1)
|
62
|
+
|
63
|
+
|
64
|
+
retranslateUi(basicDisplayConfig)
|
65
|
+
|
66
|
+
Qt::MetaObject.connectSlotsByName(basicDisplayConfig)
|
67
|
+
end # setupUi
|
68
|
+
|
69
|
+
def setup_ui(basicDisplayConfig)
|
70
|
+
setupUi(basicDisplayConfig)
|
71
|
+
end
|
72
|
+
|
73
|
+
def retranslateUi(basicDisplayConfig)
|
74
|
+
basicDisplayConfig.windowTitle = Qt::Application.translate("BasicDisplayConfig", "Form", nil, Qt::Application::UnicodeUTF8)
|
75
|
+
@label.text = Qt::Application.translate("BasicDisplayConfig", "Data stream", nil, Qt::Application::UnicodeUTF8)
|
76
|
+
@close.text = Qt::Application.translate("BasicDisplayConfig", "Close", nil, Qt::Application::UnicodeUTF8)
|
77
|
+
end # retranslateUi
|
78
|
+
|
79
|
+
def retranslate_ui(basicDisplayConfig)
|
80
|
+
retranslateUi(basicDisplayConfig)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
module Ui
|
86
|
+
class BasicDisplayConfig < Ui_BasicDisplayConfig
|
87
|
+
end
|
88
|
+
end # module Ui
|
89
|
+
|