-
Notifications
You must be signed in to change notification settings - Fork 0
/
seismometer.go
136 lines (111 loc) · 2.84 KB
/
seismometer.go
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
package main
import (
"fmt"
"git.sapienzaapps.it/SeismoCloud/seismocloud-sensor-raspberrypi/accelero"
"time"
)
type Seismometer interface {
StartSeismometer()
SetSigma(float64)
StopSeismometer()
}
type Detection struct {
Timestamp time.Time
Acceleration float64
OverThreshold bool
}
func CreateNewSeismometer(sigma float64) (Seismometer, error) {
s, e := accelero.NewADXL345Accelerometer()
if e != nil {
return nil, e
}
e = s.Start()
if e != nil {
return nil, e
}
t := time.NewTicker(50 * time.Millisecond)
avgX := NewRunningAvgFloat64()
avgY := NewRunningAvgFloat64()
avgZ := NewRunningAvgFloat64()
for i := 0; i < 100; i++ {
probe, _ := s.ProbeValue()
avgX.AddValue(probe.X)
avgY.AddValue(probe.Y)
avgZ.AddValue(probe.Z)
<-t.C
}
s.Stop()
return &SeismometerImpl{
quakeThreshold: 0,
active: false,
accelerometer: s,
sigma: sigma,
runningAVG: NewRunningAvgFloat64(),
normX: avgX.GetAverage(),
normY: avgY.GetAverage(),
normZ: avgZ.GetAverage(),
}, nil
}
type SeismometerImpl struct {
accelerometer accelero.Accelerometer
runningAVG RunningAvgFloat64
quakeThreshold float64
sigma float64
active bool
inEvent bool
lastEventWas int64
normX float64
normY float64
normZ float64
}
func (s *SeismometerImpl) StartSeismometer() {
s.active = true
go s.seismometer()
}
func (s *SeismometerImpl) SetSigma(sigma float64) {
s.sigma = sigma
}
func (s *SeismometerImpl) seismometer() {
t := time.NewTicker(50 * time.Millisecond)
fmt.Println("Seismometer started")
s.accelerometer.Start()
for s.active {
detectionAVG := s.runningAVG.GetAverage()
detectionStdDev := s.runningAVG.GetStandardDeviation()
probe, err := s.accelerometer.ProbeValue()
if err != nil {
panic(err)
}
probe.X = probe.X - s.normX
probe.Y = probe.Y - s.normY
probe.Z = probe.Z - s.normZ
accel := probe.GetTotalVector()
record := Detection{
Timestamp: time.Now(),
Acceleration: accel,
OverThreshold: accel > s.quakeThreshold,
}
s.runningAVG.AddValue(record.Acceleration)
s.quakeThreshold = s.runningAVG.GetAverage() + (s.runningAVG.GetStandardDeviation() * s.sigma)
if s.inEvent && time.Now().Unix()-s.lastEventWas >= 5 {
_ = ledset.Red(false)
s.inEvent = false
} else if s.inEvent && time.Now().Unix()-s.lastEventWas < 5 {
continue
}
if record.OverThreshold && !s.inEvent && s.runningAVG.Elements() > 2 {
log.Debugf("New Event: v:%f - thr:%f - iter:%f - avg:%f - stddev:%f", record.Acceleration, s.quakeThreshold,
s.sigma, detectionAVG, detectionStdDev)
_ = ledset.Red(true)
s.inEvent = true
s.lastEventWas = time.Now().Unix()
scs.Quake(time.Now(), probe.X, probe.Y, probe.Z)
}
<-t.C
}
t.Stop()
s.accelerometer.Stop()
}
func (s *SeismometerImpl) StopSeismometer() {
s.active = false
}