Statistics
| Branch: | Revision:

blinker / firefox.plugin / data / eyeTribe.js @ a03cd52e

History | View | Annotate | Download (18.676 KB)

1 a03cd52e Thies Pfeiffer
/*
2
 * Copyright 2015 Thies Pfeiffer and Dimitri Heil
3
 * Blinker is distributed under the terms of the GNU General Public License
4
 * 
5
 * This file is part of Blinker.
6
 * 
7
 * Blinker is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 * 
12
 * Blinker is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License
18
 * along with Blinker. If not, see <http://www.gnu.org/licenses/>.
19
 */
20
 
21
var eyeTribe = {
22
        
23
        /*
24
        *        set eyetribe calibration parameters according to the current browser-window size.
25
        */
26
        setCalibrationParameters: function()  {
27
                //console.log("eyeTribe.js :: "+"setCalibrationParameters()" );
28
29
        
30
        
31
32
                gc_left = window.innerWidth * 0.2;
33
                gc_right = window.innerWidth - gc_left;
34
                gc_top =         window.innerHeight * 0.2;
35
                gc_bottom = window.innerHeight - gc_top;
36
37
        
38
                //console.log("Setting calibration parameters...");
39
                topRow = Math.round(distanceFromBorder);
40
                //console.log("top row at: "+topRow);
41
                midRow = Math.round(window.innerHeight - (window.innerHeight / 2));
42
                //console.log("mid row at: "+midRow);
43
                bottomRow = Math.round(window.innerHeight - distanceFromBorder);
44
                //console.log("bottom row at: "+bottomRow);
45
46
                leftCol = Math.round(distanceFromBorder);
47
                //console.log("left col at: "+leftCol);
48
                midCol = Math.round(window.innerWidth - (window.innerWidth / 2));
49
                //console.log("mid col at: "+midCol);
50
                rightCol = Math.round(window.innerWidth - distanceFromBorder);
51
                //console.log("right col at: "+rightCol);
52
53
                while (calibrationArray.length > 0) {
54
                        calibrationArray.pop();
55
                }
56
57
                calibrationArray[0] = {
58
                                x: leftCol,
59
                                y: midRow
60
                        }; //midleft
61
                calibrationArray[1] = {
62
                                x: rightCol,
63
                                y: bottomRow
64
                        }; //bottomright
65
                calibrationArray[2] = {
66
                                x: midCol,
67
                                y: topRow
68
                        }; //midtop
69
                calibrationArray[3] = {
70
                                x: leftCol,
71
                                y: bottomRow
72
                        }; //bottomleft
73
                calibrationArray[4] = {
74
                                x: rightCol,
75
                                y: midRow
76
                        }; //midright
77
                calibrationArray[5] = {
78
                                x: leftCol,
79
                                y: topRow
80
                        }; //topleft
81
                calibrationArray[6] = {
82
                                x: midCol,
83
                                y: bottomRow
84
                        }; //midbottom
85
                calibrationArray[7] = {
86
                                x: rightCol,
87
                                y: topRow
88
                        }; //topright
89
                calibrationArray[8] = {
90
                                x: midCol,
91
                                y: midRow
92
                        }; //center
93
94
95
        },
96
        /*
97
        *        call a message parser according to the messages' content
98
        */
99
        parseMessage: function(message) {
100
        //console.log("eyeTribe.js :: "+"parseMessage()" +", message:" + message );
101
    try {
102
        eyeTrackingData = JSON.parse(message);
103
        if (eyeTrackingData.hasOwnProperty("statuscode")) {
104
            waitingForResponse = false;
105
            if (eyeTrackingData.statuscode != 200) {
106
                eyeTribe["parseError"](eyeTrackingData);
107
            }
108
109
        }
110
111
        switch (eyeTrackingData.category) {
112
            case "tracker":
113
                eyeTribe["parseTracker"](eyeTrackingData);
114
                break;
115
            case "calibration":
116
                    //console.log("eyeTribe.js :: "+"parseMessage()" +", message:" + message );
117
                eyeTribe["parseCalibration"](eyeTrackingData);
118
                break;
119
            case "heartbeat":
120
                eyeTribe["parseHeartbeat"](eyeTrackingData);
121
                break;
122
            default:
123
                break;
124
        }
125
126
    } catch (e) {
127
128
            console.log("error in file:" + e.fileName);
129
        console.log("error at line:" + e.lineNumber);
130
        console.log("error:" + e);
131
132
        console.log("error at message:" + message);
133
    }
134
},
135
        /*
136
        *        parse a eyetribe message with type: 'tracker'
137
        */
138
        parseTracker: function(eyeTrackingData) {
139
                //console.log("eyeTribe.js :: "+"parseTracker()" +", eyeTrackingData:" + eyeTrackingData );
140
                try {
141
                                switch (eyeTrackingData.request) {
142
                                        case "get":
143
                                                if (eyeTrackingData.values.trackerstate == 0) {
144
                                                        //console.log(JSON.stringify(eyeTrackingData));
145
                                                        eyeTrackerIsCalibrated = eyeTrackingData.values.iscalibrated;
146
                                                        eyeTrackerIsCalibrating = eyeTrackingData.values.iscalibrating;
147
                                                        calibrationResult = eyeTrackingData.values.calibresult;
148
149
                                                        if (firstRun) {
150
                                                                firstRun = false;
151
                                                                if (eyeTrackerIsCalibrating){
152
                                                                        eyeTribe["abortRunningCalibration"]();
153
                                                                }
154
                                                                eyeTribe["setTrackerSettings"]();
155
                                                        } 
156
                                                }
157
158
                                                if (eyeTrackerIsCalibrating) {
159
                                                        if (eyeTrackingData.values.hasOwnProperty("frame")) {
160
                                                                if ((eyeTrackingData.values.frame.lefteye.psize == 0) || (eyeTrackingData.values.frame.righteye.psize == 0)) {
161
                                                                        //$("#calibrationImage").css("display", "none");
162
                                                                        //window.clearTimeout(calibrationTimer);
163
                                                                        //startCalibrationPointTimer();
164
                                                                } else {
165
                                                                        //console.log("calibimage___________________________________________________");
166
                                                                        if ( $("#calibration_blackout" ).css("display") == "block"){
167
                                                                                $("#calibrationImage").css("display", "block");
168
                                                                        }
169
                                                                }
170
                                                        }
171
                                                }
172
173
                                                if (eyeTrackerIsCalibrated) {
174
                                                        if (eyeTrackingData.hasOwnProperty('values')) {
175
                                                                if (eyeTrackingData.values.hasOwnProperty("frame")) {
176
                                                                        //if new fixation status does not match the existing one                                
177
                                                                        if (gazeInformation.isFixation != eyeTrackingData.values.frame.fix) {
178
                                                                                //if the new status is TRUE
179
                                                                                if (eyeTrackingData.values.frame.fix == true) {
180
                                                                                        //set the startpoint for the fixation to get the fixationduration
181
                                                                                        //gazeInformation.fixationStart = Date.now();                                                
182
                                                                                }
183
                                                                        }
184
                                                                        
185
                                                                        
186
                                                                        if (blickBrowserSettings['eyeTribeAverage'] === true){
187
                                                                                avg = eyeTrackingData.values.frame.avg;
188
                                                                                calcGazePosition('{"x":'+avg.x+',"y":'+avg.y+'}');
189
                                                                                
190
                                                                        } else if (blickBrowserSettings['eyeTribeAverage'] === false) {
191
                                                                                raw = eyeTrackingData.values.frame.raw;
192
                                                                                calcGazePosition('{"x":'+raw.x+',"y":'+raw.y+'}');
193
                                                                        }
194
195
                                                                }
196
197
                                                        }
198
                                                } 
199
200
                                                if (eyeTrackerIsCalibrating == false && eyeTrackerIsCalibrated == false){
201
                                                        eyeTribe["initiateCalibration"]();
202
                                                }
203
                                                /*else {
204
                                                        if (eyeTrackerIsCalibrating == false){
205
                                                                eyeTribe["initiateCalibration"]();
206
                                                        }
207
                                                }*/
208
                                                break;
209
                                        case "set":
210
                                                if (eyeTrackingData.hasOwnProperty('statuscode')) {
211
                                                        //console.log(JSON.stringify(eyeTrackingData));
212
                                                }
213
                                                break;
214
                                        default: 
215
                                                break;
216
                                }
217
                        
218
219
                } catch (e) {
220
                        console.log("error at line:" + e.lineNumber);
221
                        console.log("error:" + e);
222
                        console.log("error at message:" + message);
223
                }
224
225
        },
226
        parseError: function(eyeTrackingData) {
227
                //console.log(JSON.stringify(eyeTrackingData));
228
        },
229
        /*
230
        *        Parse message of type: calibration
231
        */
232
        parseCalibration: function(eyeTrackingData) {
233
        //console.log("eyeTribe.js :: "+"parseCalibration()" +", eyeTrackingData:" + JSON.stringify(eyeTrackingData) );
234
    try {
235
236
        switch (eyeTrackingData.request) {
237
            case "clear":
238
                if (eyeTrackingData.statuscode == 200) {
239
                    console.log("Calibration cleared successfully.");
240
                    eyeTrackerIsCalibrated = false;
241
                    eyeTribe["initiateCalibration"]();
242
                    //eyeTribe["getTrackerStatus"]();
243
                } else {
244
                        console.log("Calibration NOT cleared: "+JSON.stringify(eyeTrackingData));
245
                }
246
                break;
247
            case "abort":
248
                if (eyeTrackingData.statuscode == 200) {
249
                    console.log("Running calibration aborted");
250
                    eyeTrackerIsCalibrating = false;
251
                    //eyeTribe["initiateCalibration"]();
252
                    eyeTribe["getTrackerStatus"]();
253
                } else {
254
                        //console.log("Calibration NOT aborted: "+JSON.stringify(eyeTrackingData));
255
                        eyeTribe["getTrackerStatus"]();
256
                }
257
                break;
258
            case "start":
259
                if (eyeTrackingData.statuscode == 200) {
260
                    eyeTribe["getTrackerStatus"]();
261
                    calibrationPointNumber = 0;
262
                    calibrationStart = Date.now();
263
                    eyeTribe["sendCalibrationPoint"](calibrationArray[calibrationPointNumber].x, calibrationArray[calibrationPointNumber].y);
264
265
                    calibrationPointNumber++;
266
                } else {
267
                        //console.log("Calibration NOT started: "+JSON.stringify(eyeTrackingData));
268
                }
269
                break;
270
            case "pointstart":
271
                if (eyeTrackingData.statuscode == 200) {
272
                    eyeTribe["startCalibrationPointTimer"]();
273
                } else {
274
                        //console.log("Pointstart NOT initiated: "+JSON.stringify(eyeTrackingData));
275
                }
276
                break;
277
            case "pointend":
278
                if (eyeTrackingData.statuscode == 200) {
279
                    if ((calibrationPointNumber == 9) && (eyeTrackingData.hasOwnProperty('values'))) {
280
                        var calibPoints = eyeTrackingData.values.calibresult.calibpoints;
281
                        for (var c = 0; c < 9; c++) {
282
                            //console.log("Point " + c + " state : " + calibPoints[c].state);
283
                            if (calibPoints[c].state != "2") {
284
                                //console.log("Calibrationpoint " + c + " was bad - putting it into recalibrationArray.");
285
                                recalibrationArray.push({
286
                                    x: calibPoints[c].cp.x,
287
                                    y: calibPoints[c].cp.y
288
                                });
289
                            }
290
                        }
291
                        //console.log("Calibrationresult is: " + eyeTrackingData.values.calibresult.result);
292
                        if (eyeTrackingData.values.calibresult.result == false) {
293
                            //console.log("Calibration was not successful recalibration of " + recalibrationArray.length + " point(s) needed.");
294
                            for (var r = 0; r < recalibrationArray.length; r++) {
295
                                //console.log("Sending Point for recalibration: " + recalibrationArray[r]);
296
                                eyeTribe["sendCalibrationPoint"](recalibrationArray[r].x, recalibrationArray[r].y);
297
                                recalibrationArray.splice(r, 1);
298
                            }
299
                        } else {
300
                                calibrationResult = eyeTrackingData.values.calibresult;
301
                            //alert("Kalibrierung war erfolgreich!");
302
                            $("#testingInformation").html($("#testingInformation").html()+"Calibration Duration: " + (Date.now() - calibrationStart)+"<br />");
303
                            $("#testingInformation").html($("#testingInformation").html()+"Calibration Result: " + calibrationResult.deg+"<br />");
304
                            console.log("Calibration Duration: " + (Date.now() - calibrationStart));
305
                            console.log("Calibration Accuracy: " + calibrationResult.deg );
306
      
307
                            $('body').css("overflowX",overflowXBeforeCalibration);
308
                            $('body').css("overflowY",overflowYBeforeCalibration);
309
                            $("#calibration_blackout").css("display", "none");
310
                            $("#calibrationImage").css("display", "none");
311
                            $("#calibrationImage").css("left", "-2000px");
312
                                                        
313
                                                        gazeCorrectionPointNr = 0;
314
315
                                                        if (blickBrowserSettings.checkCalibration){
316
                                    checkCalibration();
317
                            }
318
319
                            if (!blickBrowserSettings.checkCalibration){
320
                                    if (calibrationResult.deg < 0.5) {
321
                                            showNotification('star',"Calibration result: Very Good 5/5 stars.<br /><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i>");
322
323
                                    } else if (calibrationResult.deg < 0.7) {
324
                                            showNotification('star',"Calibration result: Good 4/5 stars.<br /><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i>");
325
                                        
326
                                    } else if (calibrationResult.deg < 1) {
327
                                            showNotification('star',"Calibration result: Moderate 3/5 stars.<br /><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i>");
328
                                        
329
                                    } else if (calibrationResult.deg < 1.5) {
330
                                            showNotification('star',"Calibration result: Not good 2/5 stars.<br /><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i>");
331
                                        
332
                                    } else if (calibrationResult.deg >= 1.5) {
333
                                            showNotification('star',"Calibration result: Bad 1/5 stars.<br /><i class=\"fa fa-star\"></i>");
334
                                        
335
                                    }
336
                                                        }
337
338
                            //bring settings to front
339
                            //$("#settings").css("zIndex", 16777273);
340
                            eyeTribe["getTrackerStatus"]();
341
                        }
342
                    } else if (calibrationPointNumber < 9) {
343
                        eyeTribe["sendCalibrationPoint"](calibrationArray[calibrationPointNumber].x, calibrationArray[calibrationPointNumber].y);
344
                        calibrationPointNumber++;
345
                    }
346
                } else {
347
                        //console.log("Pointend error: "+eyeTrackingData);
348
                }
349
                break;
350
351
352
            default:
353
                break;
354
355
        }
356
357
358
    } catch (e) {
359
        console.log("error at line:" + e.lineNumber);
360
        console.log("error:" + e);
361
        console.log("error at message:" + message);
362
    }
363
364
},        
365
        parseHeartbeat: function(eyeTrackingData) {
366
                try {
367
                        
368
                } catch (e) {
369
                        console.log("error at line:" + e.lineNumber);
370
                        console.log("error:" + e);
371
                        console.log("error at message:" + message);
372
                }
373
374
        },
375
        sendMessageToTracker: function(message) {
376
        //console.log("eyeTribe.js :: "+"sendMessageToTracker()" +", message:" + message );
377
                self.port.emit("sendToTracker", message);
378
                waitingForResponse = true;
379
        },
380
        startCalibration: function() {
381
382
383
                if (window.mozInnerScreenX < 5 && window.mozInnerScreenY < 5) {
384
                        //console.log("fullscreeen");
385
                        eyeTribe["setCalibrationParameters"]();
386
                        $("#calibration_blackout").css("display", "block");
387
                        //move settings to back
388
                        //$("#settings").css("zIndex", 0);
389
                        //console.log("Starting calibration");
390
                        overflowXBeforeCalibration = $('body').css("overflowX");
391
                        overflowYBeforeCalibration = $('body').css("overflowY");
392
                        window.scroll(0,0);
393
                        $('body').css("overflow","hidden");
394
                        //console.log("overflowXBeforeCalibrationw: "+overflowXBeforeCalibration);
395
                        //console.log("overflowYBeforeCalibrationw: "+overflowYBeforeCalibration);
396
                        $("#calibrationImage").css("display", "block");
397
                        if (!calibrationRequestSent) {
398
                                if (showFollowMeMessageAtCalibration) {
399
                                        $("#calibrationImage").notify("Follow Me!");
400
                                        showFollowMeMessageAtCalibration = false;
401
                                }
402
                                
403
                                    setTimeout(function() { 
404
                                        eyeTribe["sendCalibrationRequest"](9); 
405
                                },4000);
406
407
                                calibrationRequestSent = true;
408
                                
409
                                
410
                        }
411
                        setTimeout(function() { 
412
                                $.notify("3");
413
                                setTimeout(function() { 
414
                                $.notify("2");
415
                                setTimeout(function() { 
416
                                $.notify("1");
417
                        }, 3000);
418
                        }, 2000);
419
                        }, 1000);
420
                } else {                
421
                        if (showFullscreenMessageForCalibration){
422
                                $.notify("The Eyetracker is not calibrated.", {autoHide: true, className: 'error'});
423
                                $.notify("Please make sure that the browser is in FullScreen Mode (F11) \n and topBars are not visible to make sure \n the calibration can be initiated.", {autoHide: true, className: 'error'});
424
425
                                showFullscreenMessageForCalibration = false;
426
                        }        
427
428
                }
429
430
431
432
        },
433
        sendCalibrationRequest: function(points) {
434
                console.log("send calibration request to tracker");
435
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"start\",\"values\":{\"pointcount\": " + points + "}}");
436
        },
437
        sendCalibrationPoint: function(x, y) {
438
                $("#calibrationImage").css("display", "block");
439
                $("#calibrationImage").animate({
440
                        left: "+" + (x - calibrationIconSizeHalf),
441
                        top: "+" + (y - calibrationIconSizeHalf)
442
                }, 750);
443
                console.log("message:" + "{'category':'calibration','request':'pointstart','values':{'x': " + x + ",'y':" + y + "}}");
444
                setTimeout(function() {
445
                        eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"pointstart\",\"values\":{\"x\": " + x + ",\"y\":" + y + "}}");
446
                }, 700);
447
        },
448
        sendCalibrationPointend:function() {
449
                console.log("Sending Calibration Pointend.");
450
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"pointend\"}");
451
        },
452
        startCalibrationPointTimer:function() {
453
                console.log("Started PointCounter.");
454
                calibrationTimer = setTimeout(function() {
455
                        eyeTribe["sendCalibrationPointend"]();
456
                }, 3000);
457
        },        
458
        clearCurrentCalibration:function() {
459
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"clear\"}");
460
        },
461
        abortRunningCalibration:function() {
462
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"abort\"}");
463
        },
464
        getTrackerStatus:function() {
465
                var preferences =
466
                        '{"category": "tracker",' + '"request": "get",' + '"values": [' + '"push",' + '"heartbeatinterval",' + '"version",' + '"trackerstate",' + '"framerate",' + '"iscalibrated",' + '"iscalibrating",' + '"calibresult",' + '"frame",' + '"screenindex",' + '"screenresw",' + '"screenresh",' + '"screenpsyw",' + '"screenpsyh"]' + '}'
467
                eyeTribe["sendMessageToTracker"](preferences);
468
        },
469
        setTrackerSettings:function() {
470
                var preferences =
471
                        '{"category": "tracker",' + '"request": "set",' + '"values": {' + '"push":true,' + '"version":1,' + '"screenindex":0,' + '"screenresw":' + screen.width + ',' + '"screenresh":' + screen.height + ',' + '"screenpsyw":0.' + blickBrowserSettings['physicalScreenWidth'] + ',' + '"screenpsyh":0.' + blickBrowserSettings['physicalScreenHeight'] + '}' + '}'
472
                console.log(preferences);
473
                eyeTribe["sendMessageToTracker"](preferences);
474
        },
475
        initiateCalibration:function(){                
476
                
477
                if (eyeTrackerIsCalibrating) {
478
                        eyeTribe["abortRunningCalibration"]();
479
                }
480
                if (eyeTrackerIsCalibrated) {
481
                        eyeTribe["clearCurrentCalibration"]();
482
                }
483
                if (firstRun == false && eyeTrackerIsCalibrated == false && eyeTrackerIsCalibrating == false) {
484
                        //document.getElementById('calibrate').checked = false;
485
                        eyeTribe["startCalibration"]();
486
                }                
487
        }        
488
}