Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Eye-Tracking Classroom
/
gaze-server.cs
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
1
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
241680ff
authored
Oct 10, 2019
by
Stefan Schreistetter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored. Timer task memory leaks are to be fixed.
parent
b55d8fdf
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
89 additions
and
84 deletions
+89
-84
GazeWebSocketServer/Program.cs
+9
-8
TrackerBridge/DSP/GazeDecimator.cs
+12
-3
TrackerBridge/DSP/IGazeFilter.cs
+1
-0
TrackerBridge/FakeTracker.cs
+28
-19
TrackerBridge/GazeDataProcessor.cs
+4
-14
TrackerBridge/IBridgeTracker.cs
+6
-4
TrackerBridge/TobiiEyeTracker.cs
+29
-36
No files found.
GazeWebSocketServer/Program.cs
View file @
241680ff
...
@@ -16,18 +16,17 @@ namespace GazeWebSocketServer
...
@@ -16,18 +16,17 @@ namespace GazeWebSocketServer
if
(
args
.
Length
>
0
&&
args
[
0
]
==
"-d"
)
if
(
args
.
Length
>
0
&&
args
[
0
]
==
"-d"
)
{
{
tracker
=
new
FakeTracker
(
600
);
tracker
=
new
FakeTracker
(
600
);
tracker
.
GazeDataAvailable
+=
OnGazeDataAvailable
;
//TODO: Extend interface usage
//tracker.GazeDataProcessor.OutputFrequency = config.OutputFrequency;
}
}
else
else
{
{
TobiiEyeTracker
tobiiEyeTracker
=
new
TobiiEyeTracker
(
config
.
TrackerSerialNumber
);
tracker
=
new
TobiiEyeTracker
(
config
.
TrackerSerialNumber
);
tobiiEyeTracker
.
ConnectionEvent
+=
OnConnectionEstablished
;
tobiiEyeTracker
.
ConnectionTimeout
+=
OnConnectionTimeout
;
tobiiEyeTracker
.
GazeDataAvailable
+=
OnGazeDataAvailable
;
tobiiEyeTracker
.
Connect
();
}
}
tracker
.
ConnectionEvent
+=
OnConnectionEstablished
;
tracker
.
ConnectionTimeout
+=
OnConnectionTimeout
;
tracker
.
GazeDataAvailable
+=
OnGazeDataAvailable
;
tracker
.
Connect
();
gazeServer
=
new
GazeServer
(
config
.
WebSocketPort
,
config
.
WebSocketEndpoint
);
gazeServer
=
new
GazeServer
(
config
.
WebSocketPort
,
config
.
WebSocketEndpoint
);
gazeServer
.
Start
();
gazeServer
.
Start
();
Console
.
ReadLine
();
Console
.
ReadLine
();
...
@@ -52,7 +51,8 @@ namespace GazeWebSocketServer
...
@@ -52,7 +51,8 @@ namespace GazeWebSocketServer
{
{
Console
.
WriteLine
(
$"Tracker
{
sender
.
SerialNumber
}
connected."
);
Console
.
WriteLine
(
$"Tracker
{
sender
.
SerialNumber
}
connected."
);
ConfigurationData
config
=
ConfigurationData
.
ParseToObject
();
ConfigurationData
config
=
ConfigurationData
.
ParseToObject
();
sender
.
SetTrackingFrequency
(
config
.
TrackerFrequency
);
sender
.
TrackingFrequency
=
config
.
TrackerFrequency
;
sender
.
OutputFrequency
=
config
.
OutputFrequency
;
}
}
}
}
}
}
\ No newline at end of file
TrackerBridge/DSP/GazeDecimator.cs
View file @
241680ff
...
@@ -16,6 +16,7 @@ namespace TrackerBridge.DSP
...
@@ -16,6 +16,7 @@ namespace TrackerBridge.DSP
private
readonly
Object
outputLock
=
new
Object
();
private
readonly
Object
outputLock
=
new
Object
();
private
readonly
Object
valueCountLock
=
new
Object
();
private
readonly
Object
valueCountLock
=
new
Object
();
private
Int64
valueCount
;
private
Int64
valueCount
;
private
Task
timerTask
;
private
Int64
ValueCount
{
private
Int64
ValueCount
{
get
{
get
{
...
@@ -47,10 +48,10 @@ namespace TrackerBridge.DSP
...
@@ -47,10 +48,10 @@ namespace TrackerBridge.DSP
}
}
}
}
public
GazeDecimator
(
Single
outputFrequency
)
public
GazeDecimator
(
GazeDataProcessor
dataProcessor
)
{
{
this
.
outputFrequency
=
o
utputFrequency
;
outputFrequency
=
dataProcessor
.
O
utputFrequency
;
Task
.
Run
(()
=>
TriggerOutput
(
outputFrequency
));
Task
timerTask
=
Task
.
Run
(()
=>
TriggerOutput
(
outputFrequency
));
}
}
public
void
Input
(
GazeData
input
,
Object
sender
=
null
)
public
void
Input
(
GazeData
input
,
Object
sender
=
null
)
{
{
...
@@ -89,5 +90,13 @@ namespace TrackerBridge.DSP
...
@@ -89,5 +90,13 @@ namespace TrackerBridge.DSP
timer
.
AutoReset
=
true
;
timer
.
AutoReset
=
true
;
timer
.
Start
();
timer
.
Start
();
}
}
public
void
Update
(
GazeDataProcessor
dataProcessor
)
{
outputFrequency
=
dataProcessor
.
OutputFrequency
;
//timerTask.Dispose(); //TODO: Implement proper cancellation
//TODO: Fix memory leak
timerTask
=
Task
.
Run
(()
=>
TriggerOutput
(
outputFrequency
));
}
}
}
}
}
TrackerBridge/DSP/IGazeFilter.cs
View file @
241680ff
...
@@ -11,5 +11,6 @@ namespace TrackerBridge.DSP
...
@@ -11,5 +11,6 @@ namespace TrackerBridge.DSP
event
GazeDataHandler
OutputAvailable
;
event
GazeDataHandler
OutputAvailable
;
void
Input
(
GazeData
input
,
Object
sender
=
null
);
void
Input
(
GazeData
input
,
Object
sender
=
null
);
void
Reset
();
void
Reset
();
void
Update
(
GazeDataProcessor
dataProcessor
);
}
}
}
}
TrackerBridge/FakeTracker.cs
View file @
241680ff
...
@@ -8,30 +8,48 @@ namespace TrackerBridge
...
@@ -8,30 +8,48 @@ namespace TrackerBridge
{
{
public
class
FakeTracker
:
IBridgeTracker
public
class
FakeTracker
:
IBridgeTracker
{
{
public
event
ConnectionEventHandler
ConnectionEvent
;
public
event
ConnectionEventHandler
ConnectionTimeout
;
public
event
GazeDataHandler
GazeDataAvailable
{
public
event
GazeDataHandler
GazeDataAvailable
{
add
{
add
{
G
azeDataProcessor
.
GazeDataProcessed
+=
value
;
g
azeDataProcessor
.
GazeDataProcessed
+=
value
;
}
}
remove
{
remove
{
G
azeDataProcessor
.
GazeDataProcessed
-=
value
;
g
azeDataProcessor
.
GazeDataProcessed
-=
value
;
}
}
}
}
public
event
EventHandler
<
Single
>
TrackingFrequencyChanged
;
private
readonly
GazeDataProcessor
gazeDataProcessor
;
private
Task
timerTask
;
private
Single
trackerFrequency
;
private
Single
trackerFrequency
;
public
String
SerialNumber
=>
throw
new
NotImplementedException
();
public
GazeDataProcessor
GazeDataProcessor
{
get
;
}
public
Single
OutputFrequency
{
get
=>
gazeDataProcessor
.
OutputFrequency
;
set
=>
gazeDataProcessor
.
OutputFrequency
=
value
;
}
public
String
SerialNumber
=>
"Fake"
;
public
Single
TrackingFrequency
{
get
{
return
trackerFrequency
;
}
set
{
//timerTask.Dispose(); //TODO: Proper cancellation
//TODO: Fix memory leak
timerTask
=
Task
.
Run
(()
=>
SimulateGazeDataHz
(
value
));
}
}
public
FakeTracker
(
Single
frequency
)
public
FakeTracker
(
Single
frequency
)
{
{
trackerFrequency
=
frequency
;
trackerFrequency
=
frequency
;
GazeDataProcessor
=
new
GazeDataProcessor
(
this
);
gazeDataProcessor
=
new
GazeDataProcessor
();
//GazeDataProcessor.OutputFrequency = 1;
Task
.
Run
(()
=>
SimulateGazeDataHz
(
frequency
));
}
}
public
void
Connect
()
{
timerTask
=
Task
.
Run
(()
=>
SimulateGazeDataHz
(
trackerFrequency
));
ConnectionEvent
?.
Invoke
(
this
);
}
private
void
SimulateGazeDataHz
(
Single
frequency
)
private
void
SimulateGazeDataHz
(
Single
frequency
)
{
{
System
.
Timers
.
Timer
timer
=
new
System
.
Timers
.
Timer
(
1000.0
/
frequency
);
//TODO: Implement Dispose
System
.
Timers
.
Timer
timer
=
new
System
.
Timers
.
Timer
(
1000.0
/
frequency
);
//TODO: Implement Dispose
...
@@ -39,19 +57,10 @@ namespace TrackerBridge
...
@@ -39,19 +57,10 @@ namespace TrackerBridge
{
{
Point
mousePosition
=
Control
.
MousePosition
;
Point
mousePosition
=
Control
.
MousePosition
;
GazeData
data
=
new
GazeData
(
mousePosition
.
X
,
mousePosition
.
Y
,
mousePosition
.
X
,
mousePosition
.
Y
,
0
,
0
);
GazeData
data
=
new
GazeData
(
mousePosition
.
X
,
mousePosition
.
Y
,
mousePosition
.
X
,
mousePosition
.
Y
,
0
,
0
);
G
azeDataProcessor
.
Process
(
this
,
data
);
g
azeDataProcessor
.
Process
(
this
,
data
);
};
};
timer
.
AutoReset
=
true
;
timer
.
AutoReset
=
true
;
timer
.
Start
();
timer
.
Start
();
}
}
public
Single
GetTrackingFrequency
()
{
return
trackerFrequency
;
}
public
void
SetTrackingFrequency
(
Single
value
)
{
throw
new
NotImplementedException
();
}
}
}
}
}
TrackerBridge/GazeDataProcessor.cs
View file @
241680ff
...
@@ -33,13 +33,13 @@ namespace TrackerBridge
...
@@ -33,13 +33,13 @@ namespace TrackerBridge
}
}
}
}
public
GazeDataProcessor
(
IBridgeTracker
tracker
)
public
GazeDataProcessor
()
{
{
tracker
.
TrackingFrequencyChanged
+=
OnTrackingFrequencyChanged
;
outputFrequency
=
60
;
//Default
screenHeight
=
Convert
.
ToSingle
(
SystemParameters
.
PrimaryScreenHeight
);
screenHeight
=
Convert
.
ToSingle
(
SystemParameters
.
PrimaryScreenHeight
);
screenWidth
=
Convert
.
ToSingle
(
SystemParameters
.
PrimaryScreenWidth
);
screenWidth
=
Convert
.
ToSingle
(
SystemParameters
.
PrimaryScreenWidth
);
gazeFilters
=
new
IGazeFilter
[
1
];
gazeFilters
=
new
IGazeFilter
[
1
];
gazeFilters
[
0
]
=
new
GazeDecimator
(
60
);
//TODO: Refactor frequency passthrough
gazeFilters
[
0
]
=
new
GazeDecimator
(
this
);
//TODO: Refactor frequency passthrough
//Chain filters
//Chain filters
for
(
Int32
index
=
0
;
index
<
gazeFilters
.
Length
-
1
;
index
++)
for
(
Int32
index
=
0
;
index
<
gazeFilters
.
Length
-
1
;
index
++)
...
@@ -52,6 +52,7 @@ namespace TrackerBridge
...
@@ -52,6 +52,7 @@ namespace TrackerBridge
{
{
foreach
(
IGazeFilter
filter
in
gazeFilters
)
foreach
(
IGazeFilter
filter
in
gazeFilters
)
{
{
filter
.
Update
(
this
);
filter
.
Reset
();
filter
.
Reset
();
}
}
}
}
...
@@ -71,16 +72,5 @@ namespace TrackerBridge
...
@@ -71,16 +72,5 @@ namespace TrackerBridge
{
{
gazeFilters
[
0
].
Input
(
input
);
gazeFilters
[
0
].
Input
(
input
);
}
}
private
void
OnTrackingFrequencyChanged
(
Object
sender
,
Single
frequency
)
{
foreach
(
IGazeFilter
filter
in
gazeFilters
)
{
if
(
filter
.
GetType
()
==
typeof
(
GazeDecimator
))
{
GazeDecimator
decimator
=
(
GazeDecimator
)
filter
;
throw
new
NotImplementedException
();
}
}
}
}
}
}
}
TrackerBridge/IBridgeTracker.cs
View file @
241680ff
...
@@ -11,12 +11,14 @@ namespace TrackerBridge
...
@@ -11,12 +11,14 @@ namespace TrackerBridge
public
interface
IBridgeTracker
public
interface
IBridgeTracker
{
{
event
ConnectionEventHandler
ConnectionEvent
;
event
ConnectionEventHandler
ConnectionTimeout
;
event
GazeDataHandler
GazeDataAvailable
;
event
GazeDataHandler
GazeDataAvailable
;
event
EventHandler
<
Single
>
TrackingFrequencyChanged
;
GazeDataProcessor
GazeDataProcessor
{
get
;
}
Single
OutputFrequency
{
get
;
set
;
}
String
SerialNumber
{
get
;
}
String
SerialNumber
{
get
;
}
Single
TrackingFrequency
{
get
;
set
;
}
Single
GetTrackingFrequency
();
void
Connect
();
void
SetTrackingFrequency
(
Single
value
);
}
}
}
}
TrackerBridge/TobiiEyeTracker.cs
View file @
241680ff
...
@@ -13,55 +13,55 @@ namespace TrackerBridge
...
@@ -13,55 +13,55 @@ namespace TrackerBridge
public
event
ConnectionEventHandler
ConnectionTimeout
;
public
event
ConnectionEventHandler
ConnectionTimeout
;
public
event
GazeDataHandler
GazeDataAvailable
{
public
event
GazeDataHandler
GazeDataAvailable
{
add
{
add
{
G
azeDataProcessor
.
GazeDataProcessed
+=
value
;
g
azeDataProcessor
.
GazeDataProcessed
+=
value
;
}
}
remove
{
remove
{
G
azeDataProcessor
.
GazeDataProcessed
-=
value
;
g
azeDataProcessor
.
GazeDataProcessed
-=
value
;
}
}
}
}
public
event
EventHandler
<
Single
>
TrackingFrequencyChanged
;
private
readonly
GazeDataProcessor
gazeDataProcessor
;
private
IEyeTracker
eyeTracker
=
null
;
private
IEyeTracker
eyeTracker
=
null
;
public
GazeDataProcessor
GazeDataProcessor
{
get
;
}
public
Boolean
IsConnected
{
get
;
private
set
;
}
=
false
;
public
Boolean
IsConnected
{
get
;
private
set
;
}
=
false
;
public
Single
OutputFrequency
{
get
=>
gazeDataProcessor
.
OutputFrequency
;
set
=>
gazeDataProcessor
.
OutputFrequency
=
value
;
}
public
String
SerialNumber
{
get
;
private
set
;
}
=
null
;
public
String
SerialNumber
{
get
;
private
set
;
}
=
null
;
public
Single
TrackingFrequency
{
get
{
if
(
eyeTracker
!=
null
)
{
return
eyeTracker
.
GetGazeOutputFrequency
();
}
else
{
return
0f
;
}
}
set
{
if
(
eyeTracker
!=
null
&&
eyeTracker
.
GetAllGazeOutputFrequencies
().
Contains
(
value
))
{
eyeTracker
.
SetGazeOutputFrequency
(
value
);
}
}
}
public
TobiiEyeTracker
()
public
TobiiEyeTracker
()
{
{
GazeDataProcessor
=
new
GazeDataProcessor
(
this
);
gazeDataProcessor
=
new
GazeDataProcessor
(
);
}
}
public
TobiiEyeTracker
(
String
serialNumber
)
:
this
()
public
TobiiEyeTracker
(
String
serialNumber
)
:
this
()
{
{
SerialNumber
=
serialNumber
;
SerialNumber
=
serialNumber
;
}
}
public
void
Connect
()
public
void
Connect
()
{
{
Task
task
=
new
Task
(()
=>
InitiateConnection
());
Task
task
=
new
Task
(()
=>
InitiateConnection
());
task
.
Start
();
task
.
Start
();
}
}
public
Single
GetTrackingFrequency
()
{
if
(
eyeTracker
!=
null
)
{
return
eyeTracker
.
GetGazeOutputFrequency
();
}
else
{
throw
new
NullReferenceException
();
}
}
public
void
SetTrackingFrequency
(
float
value
)
{
if
(
eyeTracker
!=
null
&&
eyeTracker
.
GetAllGazeOutputFrequencies
().
Contains
(
value
))
{
eyeTracker
.
SetGazeOutputFrequency
(
value
);
}
}
private
void
InitiateConnection
()
private
void
InitiateConnection
()
{
{
DateTime
time
=
DateTime
.
Now
;
DateTime
time
=
DateTime
.
Now
;
...
@@ -98,16 +98,10 @@ namespace TrackerBridge
...
@@ -98,16 +98,10 @@ namespace TrackerBridge
ConnectionTimeout
?.
Invoke
(
this
);
ConnectionTimeout
?.
Invoke
(
this
);
}
}
}
}
eyeTracker
.
GazeDataReceived
+=
GazeDataProcessor
.
Process
;
eyeTracker
.
GazeDataReceived
+=
gazeDataProcessor
.
Process
;
eyeTracker
.
GazeOutputFrequencyChanged
+=
OnGazeOutputFrequencyChanged
;
SerialNumber
=
eyeTracker
.
SerialNumber
;
SerialNumber
=
eyeTracker
.
SerialNumber
;
SetTrackingFrequency
(
600f
)
;
TrackingFrequency
=
600f
;
ConnectionEvent
?.
Invoke
(
this
);
ConnectionEvent
?.
Invoke
(
this
);
}
}
private
void
OnGazeOutputFrequencyChanged
(
Object
sender
,
GazeOutputFrequencyEventArgs
e
)
{
TrackingFrequencyChanged
?.
Invoke
(
this
,
e
.
GazeOutputFrequency
);
}
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment