-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
210 lines (171 loc) · 7.24 KB
/
index.js
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
"use strict";
const fs = require('fs')
const watch = require('node-watch')
const sgMail = require('@sendgrid/mail')
const sgKey = require('./sendgrid.js')
const firebase = require('firebase')
var config = {
apiKey: "AIzaSyAvaBf80ZrK7TH2xhpJ2S-zBFRyvVLdeFk",
authDomain: "halecoin-hackuci2018.firebaseapp.com",
databaseURL: "https://halecoin-hackuci2018.firebaseio.com",
projectId: "halecoin-hackuci2018",
storageBucket: "halecoin-hackuci2018.appspot.com",
messagingSenderId: "680173573393"
};
var fire = firebase.initializeApp(config);
var x = [1, 0, 1]
var y = [0, 1, 1]
var keypointNames = ["head", "neck",
"rshoulder", "relbow", "rhand",
"lshoulder", "lelbow", "lhand",
"rhip", "rknee", "rfoot",
"lhip", "lknee", "lfoot"]
var checkAverage = 0
var checkReset = true
var quickCount = 0
sgMail.setApiKey(sgKey.api_key)
watch('./openpose-json/', { filter: /\.json$/ }, function(evt, name) {
if(evt == 'update') {
// nice, new shit
fs.readFile(name, 'utf8', function (err, data) {
if (err) throw err; // lol
// parse if valid data
var raw = JSON.parse(data)
if(raw.people !== null && raw.people.length > 0 && raw.people[0].pose_keypoints !== null) {
raw = raw.people[0].pose_keypoints
var keypoints = []
while(raw.length != 0) {
var keypoint = []
keypoint.push(raw.shift()) // x coord
keypoint.push(raw.shift()) // y coord
keypoint.push(raw.shift()) // confidence
keypoints.push(keypoint)
}
var keypointMap = new Map()
keypointNames.forEach(function(item, index, array) {
keypointMap.set(item, keypoints[index])
})
var luarm = dirvec(keypointMap.get("lelbow"), keypointMap.get("lshoulder"))
var llarm = dirvec(keypointMap.get("lhand"), keypointMap.get("lelbow"))
var lside = dirvec(keypointMap.get("lshoulder"), keypointMap.get("lhip"))
var ruarm = dirvec(keypointMap.get("relbow"), keypointMap.get("rshoulder"))
var rlarm = dirvec(keypointMap.get("rhand"), keypointMap.get("relbow"))
var rside = dirvec(keypointMap.get("rshoulder"), keypointMap.get("rhip"))
var keyAngles = new Map()
keyAngles.set("lelbow", angle(reversed(luarm), llarm))
keyAngles.set("relbow", angle(reversed(ruarm), rlarm))
keyAngles.set("lshoulder", angle(reversed(lside), luarm))
keyAngles.set("rshoulder", angle(reversed(rside), ruarm))
keyAngles.set("lside", angle(reversed(lside), x))
keyAngles.set("rside", angle(reversed(rside), x))
var check = checkPushup(keyAngles)
checkAverage += check
checkAverage /= 2
console.log(check, checkAverage)
if(checkReset == true && checkAverage > 0.55) {
console.log("Pushup!")
checkReset = false
quickCount++
firebase.database().ref('pushUpCount').once('value').then(function(snapshot) {
fire.database().ref('pushUpCount').set(snapshot.val() + 1);
if(quickCount % 5 == 0) {
const msg = {
to: '[email protected]',
from: '[email protected]',
subject: 'HaleCoin Update!',
text: 'Congratulations! You just completed another 5 pushups! You now have ' + (snapshot.val() + 1) + ' pushups!'
}
sgMail.send(msg)
console.log("Sending mail...")
}
});
}
if(checkAverage < 0.2) {
checkReset = true
checkAverage = 0
}
}
});
}
})
// BS hardcoded function of doom and magic numbers
// BEWARE, READ AT YOUR OWN PERIL
// 0 for not in pushup/no confidence in detection, -ve value for up, +ve for down
// magnitude -> confidence
function checkPushup(keyAngles) {
var down = 0
// check for side in view
if(keyAngles.get("lside") == 0 && keyAngles.get("rside") == 0) return 0
var lside = keyAngles.get("lside")
var rside = keyAngles.get("rside")
if(lside[1] < 0.3 && rside[1] < 0.3) return 0 // not enough confidence
// check arm angles in view
if(keyAngles.get("lelbow") == 0 && keyAngles.get("relbow") == 0) return 0
var lelbow = keyAngles.get("lelbow")
var relbow = keyAngles.get("relbow")
if(lelbow[1] < 0.3 && relbow[1] < 0.3) return 0 // not enough confidence
// check shoulder angles in view
if(keyAngles.get("lshoulder") == 0 && keyAngles.get("rshoulder") == 0) return 0
var lshoulder = keyAngles.get("lshoulder")
var rshoulder = keyAngles.get("rshoulder")
if(lshoulder[1] < 0.3 && rshoulder[1] < 0.3) return 0 // not enough confidence
// check if in the horizontal position
if(lside[0] > Math.PI*3/4 && lside[0] < Math.PI) lside[0] = Math.PI - lside[0] // move angles
if(rside[0] > Math.PI*3/4 && rside[0] < Math.PI) rside[0] = Math.PI - rside[0] // into first quadrant
if(lside[0] > Math.PI/4 && rside[0] > Math.PI/4) return 0
/* // up confidence
if(lside != 0 && angleInThreshold(lside[0], Math.PI/6, 0.25)) up += lside[1] // body angle close to 30 deg
if(rside != 0 && angleInThreshold(rside[0], Math.PI/6, 0.25)) up += rside[1] // from horizontal
if(lshoulder != 0 && angleInThreshold(lshoulder[0], Math.PI/3, 0.25)) up += lshoulder[1] // shoulder angles close
if(rshoulder != 0 && angleInThreshold(rshoulder[0], Math.PI/3, 0.25)) up += rshoulder[1] // to 60 deg
if(lelbow != 0 && angleInThreshold(lelbow[0], Math.PI, 0.25)) up += lelbow[1] // elbow angles close
if(relbow != 0 && angleInThreshold(relbow[0], Math.PI, 0.25)) up += relbow[1] // to 180 deg */
// down confidence
var tempMax = 0
if(lside != 0 && lside[1] > 0.2 && angleInThreshold(lside[0], 0, 0.2)) tempMax = lside[1] / 2 // body angle close to
if(rside != 0 && rside[1] > 0.2 && angleInThreshold(rside[0], 0, 0.2)) tempMax = Math.max(tempMax, rside[1] / 2) // almost horizontal
down += tempMax
tempMax = 0
if(lshoulder != 0 && lshoulder[1] > 0.2 && angleInThreshold(lshoulder[0], 0, 0.25)) tempMax = lshoulder[1] // shoulder angles close
if(rshoulder != 0 && rshoulder[1] > 0.2 && angleInThreshold(rshoulder[0], 0, 0.25)) tempMax = Math.max(tempMax, rshoulder[1]) // to 0 deg
down += tempMax
tempMax = 0
if(lelbow != 0 && lelbow[1] > 0.2 && angleInThreshold(lelbow[0], Math.PI/2, 0.25)) tempMax = lelbow[1] // elbow angles close
if(relbow != 0 && relbow[1] > 0.2 && angleInThreshold(relbow[0], Math.PI/2, 0.25)) tempMax = Math.max(tempMax, relbow[1]) // to 90 deg
down += tempMax
return down
}
// processing functions
function angleInThreshold(angle, target, threshold) {
if(Math.abs(target - angle) < threshold) return true
else return false
}
function normalize(keypoint = null) {
if(keypoint !== null && keypoint.length == 3 && keypoint[2] != 0) {
var magnitude = Math.sqrt((keypoint[0] * keypoint[0]) + (keypoint[1] * keypoint[1]))
keypoint[0] /= magnitude
keypoint[1] /= magnitude
}
return keypoint
}
// returns [angle in rads, confidence]
function angle(dirvec1 = null, dirvec2 = null) {
if(dirvec1 !== null && dirvec2 !== null) {
var norm1 = normalize(dirvec1)
var norm2 = normalize(dirvec2)
var dot = (norm1[0] * norm2[0]) + (norm1[1] * norm2[1])
return [Math.acos(dot), Math.sqrt(dirvec1[2] * dirvec2[2])]
}
return 0
}
function dirvec(head = null, tail = null) {
if(head !== null && head[2] != 0 && tail !== null && tail[2] != 0) {
return normalize([ head[0] - tail[0], head[1] - tail[1], Math.sqrt(head[2] * tail[2]) ])
}
return null
}
function reversed(dirvec = null) {
if(dirvec != null && dirvec.length == 3) {
return [ dirvec[0] * -1, dirvec[1] * -1, dirvec[2] ]
}
}