62 lines
1.5 KiB
Smalltalk
62 lines
1.5 KiB
Smalltalk
Object subclass:#Integrator
|
|
instanceVariableNames:'tickRate input s thread'
|
|
classVariableNames:''
|
|
poolDictionaries:''
|
|
category:'Rosetta'
|
|
|
|
instance methods:
|
|
|
|
input:aFunctionOfT
|
|
input := aFunctionOfT.
|
|
|
|
startWithTickRate:r
|
|
"setup and start sampling"
|
|
tickRate := r.
|
|
s := 0.
|
|
thread := [ self integrateLoop ] fork.
|
|
|
|
stop
|
|
"stop and return the 'final' output"
|
|
thread terminate.
|
|
^ s
|
|
|
|
integrateLoop
|
|
"no need for any locks
|
|
- the assignment to s is atomic in Smallalk; its either done or not, when terminated, so who cares"
|
|
|
|
|tBegin tPrev tNow kPrev kNow deltaT delta|
|
|
|
|
tBegin := tPrev := Timestamp nowWithMilliseconds.
|
|
kPrev := input value:0.
|
|
|
|
[true] whileTrue:[
|
|
Delay waitForSeconds: tickRate.
|
|
tNow := Timestamp nowWithMilliseconds.
|
|
kNow := input value:(tNow millisecondDeltaFrom:tBegin) / 1000.
|
|
|
|
deltaT := (tNow millisecondDeltaFrom:tPrev) / 1000.
|
|
delta := (kPrev + kNow) * deltaT / 2.
|
|
|
|
s := s + delta.
|
|
tPrev := tNow. kPrev := kNow.
|
|
].
|
|
|
|
class methods:
|
|
|
|
example
|
|
#( 0.5 0.1 0.05 0.01 0.005 0.001 0.0005 ) do:[:sampleRate |
|
|
|i|
|
|
|
|
i := Integrator new.
|
|
i input:[:t | (2 * Float pi * 0.5 * t) sin].
|
|
i startWithTickRate:sampleRate.
|
|
|
|
Delay waitForSeconds:2.
|
|
i input:[:t | 0].
|
|
Delay waitForSeconds:0.5.
|
|
|
|
Transcript
|
|
show:'Sample rate: '; showCR:sampleRate;
|
|
showCR:(i stop).
|
|
].
|