Statistics
| Branch: | Revision:

blinker / firefox.plugin / data / eyetracker / eyetribe / eyeTribe.js @ 76dd22bd

History | View | Annotate | Download (19.168 KB)

1
/*
2
 * Copyright 2015 Thies Pfeiffer and Dimitri Heil and Kevin Taron
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

    
22
var eyeTribe = {
23
        
24
        /*
25
        *        set eyetribe calibration parameters according to the current browser-window size.
26
        */
27
        setCalibrationParameters: function()  {
28
                //console.log("eyeTribe.js :: "+"setCalibrationParameters()" );
29

    
30
        
31
        
32

    
33
                gc_left = window.innerWidth * 0.2;
34
                gc_right = window.innerWidth - gc_left;
35
                gc_top =         window.innerHeight * 0.2;
36
                gc_bottom = window.innerHeight - gc_top;
37

    
38
        
39
                //console.log("Setting calibration parameters...");
40
                topRow = Math.round(distanceFromBorder);
41
                //console.log("top row at: "+topRow);
42
                midRow = Math.round(window.innerHeight - (window.innerHeight / 2));
43
                //console.log("mid row at: "+midRow);
44
                bottomRow = Math.round(window.innerHeight - distanceFromBorder);
45
                //console.log("bottom row at: "+bottomRow);
46

    
47
                leftCol = Math.round(distanceFromBorder);
48
                //console.log("left col at: "+leftCol);
49
                midCol = Math.round(window.innerWidth - (window.innerWidth / 2));
50
                //console.log("mid col at: "+midCol);
51
                rightCol = Math.round(window.innerWidth - distanceFromBorder);
52
                //console.log("right col at: "+rightCol);
53

    
54
                while (calibrationArray.length > 0) {
55
                        calibrationArray.pop();
56
                }
57

    
58
                calibrationArray[0] = {
59
                                x: leftCol,
60
                                y: midRow
61
                        }; //midleft
62
                calibrationArray[1] = {
63
                                x: rightCol,
64
                                y: bottomRow
65
                        }; //bottomright
66
                calibrationArray[2] = {
67
                                x: midCol,
68
                                y: topRow
69
                        }; //midtop
70
                calibrationArray[3] = {
71
                                x: leftCol,
72
                                y: bottomRow
73
                        }; //bottomleft
74
                calibrationArray[4] = {
75
                                x: rightCol,
76
                                y: midRow
77
                        }; //midright
78
                calibrationArray[5] = {
79
                                x: leftCol,
80
                                y: topRow
81
                        }; //topleft
82
                calibrationArray[6] = {
83
                                x: midCol,
84
                                y: bottomRow
85
                        }; //midbottom
86
                calibrationArray[7] = {
87
                                x: rightCol,
88
                                y: topRow
89
                        }; //topright
90
                calibrationArray[8] = {
91
                                x: midCol,
92
                                y: midRow
93
                        }; //center
94

    
95

    
96
        },
97
        /*
98
        *        call a message parser according to the messages' content
99
        */
100
        parseMessage: function(message) {
101
        //console.log("eyeTribe.js :: "+"parseMessage()" +", message:" + message );
102
    try {
103
        eyeTrackingData = JSON.parse(message);
104
        if (eyeTrackingData.hasOwnProperty("statuscode")) {
105
            waitingForResponse = false;
106
            if (eyeTrackingData.statuscode != 200) {
107
                eyeTribe["parseError"](eyeTrackingData);
108
            }
109

    
110
        }
111

    
112
        switch (eyeTrackingData.category) {
113
            case "tracker":
114
                eyeTribe["parseTracker"](eyeTrackingData);
115
                break;
116
            case "calibration":
117
                    //console.log("eyeTribe.js :: "+"parseMessage()" +", message:" + message );
118
                eyeTribe["parseCalibration"](eyeTrackingData);
119
                break;
120
            case "heartbeat":
121
                eyeTribe["parseHeartbeat"](eyeTrackingData);
122
                break;
123
            default:
124
                break;
125
        }
126

    
127
    } catch (e) {
128

    
129
            console.log("error in file:" + e.fileName);
130
        console.log("error at line:" + e.lineNumber);
131
        console.log("error:" + e);
132

    
133
        console.log("error at message:" + message);
134
    }
135
},
136
        /*
137
        *        parse a eyetribe message with type: 'tracker'
138
        */
139
        parseTracker: function(eyeTrackingData) {
140
                //console.log("eyeTribe.js :: "+"parseTracker()" +", eyeTrackingData:" + eyeTrackingData );
141
                try {
142
                                switch (eyeTrackingData.request) {
143
                                        case "get":
144
                                                if (eyeTrackingData.values.trackerstate == 0) {
145
                                                        //console.log(JSON.stringify(eyeTrackingData));
146
                                                        eyeTrackerIsCalibrated = eyeTrackingData.values.iscalibrated;
147
                                                        eyeTrackerIsCalibrating = eyeTrackingData.values.iscalibrating;
148
                                                        calibrationResult = eyeTrackingData.values.calibresult;
149

    
150
                                                        if (firstRun) {
151
                                                                firstRun = false;
152
                                                                if (eyeTrackerIsCalibrating){
153
                                                                        eyeTribe["abortRunningCalibration"]();
154
                                                                }
155
                                                                eyeTribe["setTrackerSettings"]();
156
                                                        } 
157
                                                }
158

    
159
                                                if (eyeTrackerIsCalibrating) {
160
                                                        if (eyeTrackingData.values.hasOwnProperty("frame")) {
161
                                                                if ((eyeTrackingData.values.frame.lefteye.psize == 0) || (eyeTrackingData.values.frame.righteye.psize == 0)) {
162
                                                                        //$("#calibrationImage").css("display", "none");
163
                                                                        //window.clearTimeout(calibrationTimer);
164
                                                                        //startCalibrationPointTimer();
165
                                                                } else {
166
                                                                        //console.log("calibimage___________________________________________________");
167
                                                                        if ( $("#calibration_blackout" ).css("display") == "block"){
168
                                                                                $("#calibrationImage").css("display", "block");
169
                                                                        }
170
                                                                }
171
                                                        }
172
                                                }
173

    
174
                                                if (eyeTrackerIsCalibrated) {
175
                                                        if (eyeTrackingData.hasOwnProperty('values')) {
176
                                                                if (eyeTrackingData.values.hasOwnProperty("frame")) {
177
                                                                        //if new fixation status does not match the existing one                                
178
                                                                        if (gazeInformation.isFixation != eyeTrackingData.values.frame.fix) {
179
                                                                                //if the new status is TRUE
180
                                                                                if (eyeTrackingData.values.frame.fix == true) {
181
                                                                                        //set the startpoint for the fixation to get the fixationduration
182
                                                                                        //gazeInformation.fixationStart = Date.now();                                                
183
                                                                                }
184
                                                                        }
185
                                                                        
186
                                                                        
187
                                                                        if (blickBrowserSettings['eyeTribeAverage'] === true){
188
                                                                                avg = eyeTrackingData.values.frame.avg;
189
                                                                                calcGazePosition('{"x":'+avg.x+',"y":'+avg.y+'}');
190
                                                                                
191
                                                                        } else if (blickBrowserSettings['eyeTribeAverage'] === false) {
192
                                                                                raw = eyeTrackingData.values.frame.raw;
193
                                                                                calcGazePosition('{"x":'+raw.x+',"y":'+raw.y+'}');
194
                                                                        }
195

    
196
                                                                }
197

    
198
                                                        }
199
                                                } 
200

    
201
                                                if (eyeTrackerIsCalibrating == false && eyeTrackerIsCalibrated == false){
202
                                                        eyeTribe["initiateCalibration"]();
203
                                                }
204
                                                /*else {
205
                                                        if (eyeTrackerIsCalibrating == false){
206
                                                                eyeTribe["initiateCalibration"]();
207
                                                        }
208
                                                }*/
209
                                                break;
210
                                        case "set":
211
                                                if (eyeTrackingData.hasOwnProperty('statuscode')) {
212
                                                        //console.log(JSON.stringify(eyeTrackingData));
213
                                                }
214
                                                break;
215
                                        default: 
216
                                                break;
217
                                }
218
                        
219

    
220
                } catch (e) {
221
                        console.log("error at line:" + e.lineNumber);
222
                        console.log("error:" + e);
223
                        console.log("error at message:" + message);
224
                }
225

    
226
        },
227
        parseError: function(eyeTrackingData) {
228
                //console.log(JSON.stringify(eyeTrackingData));
229
        },
230
        /*
231
        *        Parse message of type: calibration
232
        */
233
        parseCalibration: function(eyeTrackingData) {
234
        //console.log("eyeTribe.js :: "+"parseCalibration()" +", eyeTrackingData:" + JSON.stringify(eyeTrackingData) );
235
    try {
236

    
237
        switch (eyeTrackingData.request) {
238
            case "clear":
239
                if (eyeTrackingData.statuscode == 200) {
240
                    console.log("Calibration cleared successfully.");
241
                    eyeTrackerIsCalibrated = false;
242
                    eyeTribe["initiateCalibration"]();
243
                    //eyeTribe["getTrackerStatus"]();
244
                } else {
245
                        console.log("Calibration NOT cleared: "+JSON.stringify(eyeTrackingData));
246
                }
247
                break;
248
            case "abort":
249
                if (eyeTrackingData.statuscode == 200) {
250
                    console.log("Running calibration aborted");
251
                    eyeTrackerIsCalibrating = false;
252
                    //eyeTribe["initiateCalibration"]();
253
                    eyeTribe["getTrackerStatus"]();
254
                } else {
255
                        //console.log("Calibration NOT aborted: "+JSON.stringify(eyeTrackingData));
256
                        eyeTribe["getTrackerStatus"]();
257
                }
258
                break;
259
            case "start":
260
                if (eyeTrackingData.statuscode == 200) {
261
                    eyeTribe["getTrackerStatus"]();
262
                    calibrationPointNumber = 0;
263
                    calibrationStart = Date.now();
264
                    eyeTribe["sendCalibrationPoint"](calibrationArray[calibrationPointNumber].x, calibrationArray[calibrationPointNumber].y);
265

    
266
                    calibrationPointNumber++;
267
                } else {
268
                        //console.log("Calibration NOT started: "+JSON.stringify(eyeTrackingData));
269
                }
270
                break;
271
            case "pointstart":
272
                if (eyeTrackingData.statuscode == 200) {
273
                    eyeTribe["startCalibrationPointTimer"]();
274
                } else {
275
                        //console.log("Pointstart NOT initiated: "+JSON.stringify(eyeTrackingData));
276
                }
277
                break;
278
            case "pointend":
279
                if (eyeTrackingData.statuscode == 200) {
280
                    if ((calibrationPointNumber == 9) && (eyeTrackingData.hasOwnProperty('values'))) {
281
                        var calibPoints = eyeTrackingData.values.calibresult.calibpoints;
282
                        for (var c = 0; c < 9; c++) {
283
                            //console.log("Point " + c + " state : " + calibPoints[c].state);
284
                            if (calibPoints[c].state != "2") {
285
                                //console.log("Calibrationpoint " + c + " was bad - putting it into recalibrationArray.");
286
                                recalibrationArray.push({
287
                                    x: calibPoints[c].cp.x,
288
                                    y: calibPoints[c].cp.y
289
                                });
290
                            }
291
                        }
292
                        //console.log("Calibrationresult is: " + eyeTrackingData.values.calibresult.result);
293
                        if (eyeTrackingData.values.calibresult.result == false) {
294
                            //console.log("Calibration was not successful recalibration of " + recalibrationArray.length + " point(s) needed.");
295
                            for (var r = 0; r < recalibrationArray.length; r++) {
296
                                //console.log("Sending Point for recalibration: " + recalibrationArray[r]);
297
                                eyeTribe["sendCalibrationPoint"](recalibrationArray[r].x, recalibrationArray[r].y);
298
                                recalibrationArray.splice(r, 1);
299
                            }
300
                        } else {
301
                                calibrationResult = eyeTrackingData.values.calibresult;
302
                            //alert("Kalibrierung war erfolgreich!");
303
                            $("#testingInformation").html($("#testingInformation").html()+"Calibration Duration: " + (Date.now() - calibrationStart)+"<br />");
304
                            $("#testingInformation").html($("#testingInformation").html()+"Calibration Result: " + calibrationResult.deg+"<br />");
305
                            console.log("Calibration Duration: " + (Date.now() - calibrationStart));
306
                            console.log("Calibration Accuracy: " + calibrationResult.deg );
307
      
308
                            $('body').css("overflowX",overflowXBeforeCalibration);
309
                            $('body').css("overflowY",overflowYBeforeCalibration);
310
                            $("#calibration_blackout").css("display", "none");
311
                            $("#calibrationImage").css("display", "none");
312
                            $("#calibrationImage").css("left", "-2000px");
313
                                                        
314
                                                        gazeCorrectionPointNr = 0;
315

    
316
                                                        if (blickBrowserSettings.checkCalibration){
317
                                    checkCalibration();
318
                            }
319

    
320
                            if (!blickBrowserSettings.checkCalibration){
321
                                    if (calibrationResult.deg < 0.5) {
322
                                            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>");
323

    
324
                                    } else if (calibrationResult.deg < 0.7) {
325
                                            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>");
326
                                        
327
                                    } else if (calibrationResult.deg < 1) {
328
                                            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>");
329
                                        
330
                                    } else if (calibrationResult.deg < 1.5) {
331
                                            showNotification('star',"Calibration result: Not good 2/5 stars.<br /><i class=\"fa fa-star\"></i><i class=\"fa fa-star\"></i>");
332
                                        
333
                                    } else if (calibrationResult.deg >= 1.5) {
334
                                            showNotification('star',"Calibration result: Bad 1/5 stars.<br /><i class=\"fa fa-star\"></i>");
335
                                        
336
                                    }
337
                                                        }
338

    
339
                            //bring settings to front
340
                            //$("#settings").css("zIndex", 16777273);
341
                            eyeTribe["getTrackerStatus"]();
342
                        }
343
                    } else if (calibrationPointNumber < 9) {
344
                        eyeTribe["sendCalibrationPoint"](calibrationArray[calibrationPointNumber].x, calibrationArray[calibrationPointNumber].y);
345
                        calibrationPointNumber++;
346
                    }
347
                } else {
348
                        //console.log("Pointend error: "+eyeTrackingData);
349
                }
350
                break;
351

    
352

    
353
            default:
354
                break;
355

    
356
        }
357

    
358

    
359
    } catch (e) {
360
        console.log("error at line:" + e.lineNumber);
361
        console.log("error:" + e);
362
        console.log("error at message:" + message);
363
    }
364

    
365
},        
366
        parseHeartbeat: function(eyeTrackingData) {
367
                try {
368
                        
369
                } catch (e) {
370
                        console.log("error at line:" + e.lineNumber);
371
                        console.log("error:" + e);
372
                        console.log("error at message:" + message);
373
                }
374

    
375
        },
376
        sendMessageToTracker: function(message) {
377
        //console.log("eyeTribe.js :: "+"sendMessageToTracker()" +", message:" + message );
378
                self.port.emit("sendToTracker", message);
379
                waitingForResponse = true;
380
        },
381
        startCalibration: function() {
382

    
383

    
384
                if (window.mozInnerScreenX < 5 && window.mozInnerScreenY < 5) {
385
                        //console.log("fullscreeen");
386
                        eyeTribe["setCalibrationParameters"]();
387
                        $("#calibration_blackout").css("display", "block");
388
                        //move settings to back
389
                        //$("#settings").css("zIndex", 0);
390
                        //console.log("Starting calibration");
391
                        overflowXBeforeCalibration = $('body').css("overflowX");
392
                        overflowYBeforeCalibration = $('body').css("overflowY");
393
                        window.scroll(0,0);
394
                        $('body').css("overflow","hidden");
395
                        //console.log("overflowXBeforeCalibrationw: "+overflowXBeforeCalibration);
396
                        //console.log("overflowYBeforeCalibrationw: "+overflowYBeforeCalibration);
397
                        $("#calibrationImage").css("display", "block");
398
                        if (!calibrationRequestSent) {
399
                                if (showFollowMeMessageAtCalibration) {
400
                                        $("#calibrationImage").notify("Follow Me!");
401
                                        showFollowMeMessageAtCalibration = false;
402
                                }
403
                                
404
                                    setTimeout(function() { 
405
                                        eyeTribe["sendCalibrationRequest"](9); 
406
                                },4000);
407

    
408
                                calibrationRequestSent = true;
409
                                
410
                                
411
                        }
412
                        setTimeout(function() { 
413
                                $.notify("3");
414
                                setTimeout(function() { 
415
                                $.notify("2");
416
                                setTimeout(function() { 
417
                                $.notify("1");
418
                        }, 3000);
419
                        }, 2000);
420
                        }, 1000);
421
                } else {                
422
                        if (showFullscreenMessageForCalibration){
423
                                $.notify("The Eyetracker is not calibrated.", {autoHide: true, className: 'error'});
424
                                $.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'});
425

    
426
                                showFullscreenMessageForCalibration = false;
427
                        }        
428

    
429
                }
430

    
431

    
432

    
433
        },
434
        sendCalibrationRequest: function(points) {
435
                console.log("send calibration request to tracker");
436
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"start\",\"values\":{\"pointcount\": " + points + "}}");
437
        },
438
        sendCalibrationPoint: function(x, y) {
439
                $("#calibrationImage").css("display", "block");
440
                $("#calibrationImage").animate({
441
                        left: "+" + (x - calibrationIconSizeHalf),
442
                        top: "+" + (y - calibrationIconSizeHalf)
443
                }, 750);
444
                console.log("message:" + "{'category':'calibration','request':'pointstart','values':{'x': " + x + ",'y':" + y + "}}");
445
                setTimeout(function() {
446
                        eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"pointstart\",\"values\":{\"x\": " + x + ",\"y\":" + y + "}}");
447
                }, 700);
448
        },
449
        sendCalibrationPointend:function() {
450
                console.log("Sending Calibration Pointend.");
451
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"pointend\"}");
452
        },
453
        startCalibrationPointTimer:function() {
454
                console.log("Started PointCounter.");
455
                calibrationTimer = setTimeout(function() {
456
                        eyeTribe["sendCalibrationPointend"]();
457
                }, 3000);
458
        },        
459
        clearCurrentCalibration:function() {
460
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"clear\"}");
461
        },
462
        abortRunningCalibration:function() {
463
                eyeTribe["sendMessageToTracker"]("{\"category\":\"calibration\",\"request\":\"abort\"}");
464
        },
465
        getTrackerStatus:function() {
466
                var preferences =
467
                        '{"category": "tracker",' + '"request": "get",' + '"values": [' + '"push",' + '"heartbeatinterval",' + '"version",' + '"trackerstate",' + '"framerate",' + '"iscalibrated",' + '"iscalibrating",' + '"calibresult",' + '"frame",' + '"screenindex",' + '"screenresw",' + '"screenresh",' + '"screenpsyw",' + '"screenpsyh"]' + '}'
468
                eyeTribe["sendMessageToTracker"](preferences);
469
        },
470
        setTrackerSettings:function() {
471
                var preferences =
472
                        '{"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'] + '}' + '}'
473
                console.log(preferences);
474
                eyeTribe["sendMessageToTracker"](preferences);
475
        },
476
        initiateCalibration:function(){                
477
                
478
                if (eyeTrackerIsCalibrating) {
479
                        eyeTribe["abortRunningCalibration"]();
480
                }
481
                if (eyeTrackerIsCalibrated) {
482
                        eyeTribe["clearCurrentCalibration"]();
483
                }
484
                if (firstRun == false && eyeTrackerIsCalibrated == false && eyeTrackerIsCalibrating == false) {
485
                        //document.getElementById('calibrate').checked = false;
486
                        eyeTribe["startCalibration"]();
487
                }                
488
        }        
489
}