-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathTODO
More file actions
431 lines (288 loc) · 11.8 KB
/
Copy pathTODO
File metadata and controls
431 lines (288 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
Publishing RedShift
===================
core for 1.3 release
clean up world (save/load etc)
tracer
event value conditions in sync clause?
sync :client => check(:accept){|val| val==self}
# from sync-queue.rb
doc, tutorial, web site
clean up tests, examples
user tools
zeno and other debuggers
shell
visualization interfaces: tkar, gnuplot, opengl
benchmarks
- compare with stateflow and simulink examples
- try to scale these examples up
- compare with Ptolemy -- ask devs for good benchmarks
packaging and project mgmt
- windows w/ several compilers
notify
- shift-dev folks, hs researchers (e.g., Joao Hispanha, Ed Lee)
- contacts who have expressed interest in redshift or shift
- others:
http://www.dis.anl.gov/exp/cas/index.html
http://www.artcompsci.org
Sylvain Joyeux (esp. re: distributed simulation)
Martin Fowler (see http://martinfowler.com/dslwip/)
publicize
- http://path.berkeley.edu/shift/
(this is still the first google hit for "hybrid system simulation")
- ruby-talk, sciruby
- comp.simulation, comp.soft-sys.(matlab|ptolemy), scs.org
- paper?
funding
- nsf or sbir
- need to emphasize research goals:
- distributed hybrid simulation
- further optimizations like strict
- approach potential users in industry
- GM, with wrapping for CarSim dll
long-term goals
- multiple clocks and threshold crossing detection, as in:
http://repository.upenn.edu/ese_papers/123/
- vector-valued signals
- need proper C parsing first
- user-friendly interface and related tools
- distributed simulation (HLA. CERTI?)
- library of integrators/flows and components
- jruby/jvm port (and use duby for actions etc)
- import models from simulink, Ptolemy, HSIF, etc.
- interface at run time with simulink etc.
- redshift as simulink block
- rt code generation?
- HLA support for interoperability
backronym: Ruby-based Efficient Deterministic SHIFT
To do
=====
Project
Subversion, gems, etc.
Docs and tutorial
Bugs
Make sure the arrays used internally are not shared:
call rb_ary_modify() before setting len or etc.
what happens if an exception (or throw or break) happens inside
of a block during discrete_update? (e.g. an action, reset, or
guard block)
Syntax
better sync syntax to avoid the :l=>:e, :l=>:f prob
sync {l.e, l.f} ?
should define, for each link, a TransitionParser method which returns
a dummy link object that responds to #event and returns
a dummy event that responds to #==(value) so that you can write
guard link_var.some_event == 123
instead of
[:link_var, :some_event, 123]
should be possible to allow:
reset x => ... instead of reset :x => ...
replace strictly_* with strict_* and alias back for compat
express flows, guards, etc, in ruby syntax and use something to parse:
nodedump/nodewrap
ripper
"expansion.rb"
vars are class methods returning Var obejcts
resets and even assignment to cont-vars can use '<<'
equations can use '=='
reset syntax:
reset do
x 3
y "x+2"
z { (x-y).abs }
check for symbol conflicts
user attributes may conflict with Component's attrs
ditto for flows and other methods defined in subclasses
can we 'hook' method def and attr def to check for conflict?
or just use a consistent naming scheme to keep internals separate?
flow /Foo.*/ ...
matches on name of states
Semantics
export event _to_ comp? and sync on event alone w/o link?
export [:e, 4] => :lnk # sender
sync :e # receiver
add check for values of event after sync
(and then repeat sync loop)
"sync :l => {:e => 3}" or better syntax
option to initialize all float vars to NaN?
ideas from Verilog?
ideas from DEVS? (http://moncs.cs.mcgill.ca/people/tfeng/thesis/node12.html)
"Buffer" could be used for:
- recurrence relations/ difference equations:
recurrence " x = x[-0.1] + x[-0.2] "
- input data (possibly interpolated) from table/file/etc
- output to data (or file) faster than ruby array of double
( record " expr " => file ? )
Use NArray of doubles for this?
Better: array of ptr to 1K blocks of float/double
Per state syntax:
some_state.record var => "expr"
var refers to array of bocks of raw data
expr is evaled after discrete update
- need a language for piping data streams:
src | x | integrate | ... | dst
register event observers:
on comp=>event do ... end
Does permissive make sense?
inheritance among states:
"state Foo has everything that Bar has, plus ...."
a transition that can happen only once per discrete step, to easily
prevent zeno pb (useful for utility transitions, such as output)
better: a "pre-strict" var that can only get reset once per step
per-state strictness?
if guard "strictvar && something" is checked and strictvar is false,
then the guard doesn't need to be checked again, regardless of "something"
similarly for: guard "strictvar"; guard "something"
"finalizers" for components -- called when component exits, world
is finalized, or app quits
more generally, code that executes when a given state is entered:
state Exit do
# do some finalization stuff here
end
Or:
entering SomeState do...end
exiting SomeState do...end
Maybe this is better handled by adding another state (PreSomeState)
abstract classes (no code generated)
input events (in place of interrupts?)
as opposed to normal events, which are output (pull vs. push)
but does this mean arriving events are queued?
this would be useful for timers so that client component doesn't
have to manage a ref to the timer
wait/sleep
in a transition, saying "sleep n" says that the component will not
check guards for the rest of that discrete update and for n time units.
exception handler clauses in transitions (or use interrupts?)
on LockFailed { |var, value| ... }
state stack:
a transition (or interrupt) can push the current state or pop back
to a previously saved state (like Kader's idea)
syntax:
transition ... do
push [or pop, in which case the dest. state is ignored]
end
interrupts
a way of enabling a transition without evaluating guards
-faster
can do sender-receiver, rather than broadcast
can register with global interrupt manager
notify after T seconds
notify when global event happens (like what?)
receive in any state, switch to new state optional (push ok)
synchronous in the sense that no other components act in between
the send and receive, and the receiver action happens before the
sender action finishes (?)
but not parallel assignment
based on methods
in sender's action clause: 'x.foo args'
in receiver:
interrupt :foo => NewState do
action { |args| ...}
event ...
end
signals
maybe better than interrupts, more general
transition ... do
signal value => receiver_collection, ...
end
on value do ... end
is this better than a simple method call?
yes: can implement queue
discrete evolution
more flexibility:
start actions as well as finish actions
(before/after)
enter and exit blocks for each state
start_when and finish_when to implement sync
transitions like in statechart
parametric transitions?
attach :all, ...
syncronization
explicit?
exceptions
catch them if they arise in action
pass them on to handler where?
might be better not to raise or rb_raise, but to call redshift_error on the
world class, which the class could override as needed
Component#teardown called after exit
maybe #setup should only be called at last moment before running,
so that setup clauses can be added later
Implementation
use static functions where possible
decouple expr code from particular states/transitions so that
two state can share code
changing state name doesn't cause (much) recompile
etc.
option to dump all C code to one file (amalgam), so compiler can optimize more
improve performance of event and local storage by using native (NVector)
where possible, but keeping ruby array for ruby values
remove -g (if not debug) from CFLAGS
add -march=i686 -msse2 -mfpmath=sse (keep -fPIC?)
or whatever current hw is (how to determine that?)
possible to use only 1 tmp value for rk4?
optimization: no ContState object, just a pointer in the comp. shadow struct
could point to area at end of component's shadow struct
revert to on-demand var evaluation during continuous update?
optimization: transitive closure of strict sleep, based on declaration
that prevents setters
optimization: weaken "strict" so that resets can apply at end of
discrete update, but still get all the optimizations (see bench/discrete.rb)
- a new kind of flow that applies an "impulse" to a strict var at the
beginning of the next cont step, or
- a declaration that a var becomes strict for the rest of the discrete
step
Allow c-coded actions:
transition do
action " func(self, x*2, lnk.y) "
end
cdef <<END
func(SelfShadowClass *self, double arg1, double arg2) {
...
}
END
Debug mode that uses hooks to add extra checking:
- rollover check for d_tick, step_count
- check_strict (and make it *not* the default)
Instead of caching flow function in each cont var, maybe just have pointer
to a single per state object? This can also have the outgoing transitions,
and so __update_cache can be somewhat faster.
share mark and free funcs where possible (e.g., guards)
guards should not be written in numerical order (".._0", "..._1"), but
in a more meaningful way so that changing order doesn't force recompile
unified internal repr. for phases
insert a mnemonic for quick detection of phase type in discrete update
distribute Init_clib better
break flow-gen.rb and world-gen.rb into several files each
flow-gen files can be loaded on demand as flow types are needed
most of world-gen can be a .c file used as a template
optimization
profiling
use valgrind, gprof, etc. to profile the C code
compare with shift, matlab
compile time error checking:
translate C compiler error (e.g. bad result type in expr) to ruby exception
run time error checking
more 'if $DEBUG ...' checks
catch definition of flows after commit, etc.
exception handling
syntax and math errors, esp. in flows, guards
use Exception classes
error messages
Current file/line position must be saved by many constructs, e.g. reset,
so that it can be shown later if there is an error message
use ", []" to avoid showing backtrace when it is not helpful
exceptions in C code sometimes don't give symbolic info, like var names
check against ruby 1.9
replace RARRAY(x)->len with RARRAY_LEN(x)
libtcc backend
dot backend (see file in lib dir)
optimization: split diff_list for different integrators, so comps with
only euler flows don't get iterated over as much
User interface
yaml and pp outputs
Tools
profiler mixin for World (also an executable script?)
debugger mixin for World (also an executable script?)
generalize the irb-shell.rb and TO4230 shells, and make RedShift::Shell
use this in ZenoDebugger, too
can this be a mixin for World
general vis interface using TkCanvas/tkar or opengl