2
2
import logging
3
3
from time import time , ctime
4
4
from dataclasses import dataclass
5
+ from collections import deque # for storing x, y time series
6
+ import numpy as np # for smoothing moving average
5
7
import ctypes # for windows mouse
6
8
import socket # udp networking
7
9
import struct # binary unpacking
10
+ # Done: Windows
11
+ # TODO: Mac, Linux
8
12
9
13
print ("\n \n CLIENT: Starting PhilNav\n " )
10
14
24
28
"-p" , "--port" , type = int , default = 4245 , help = "bind to port, default 4245"
25
29
)
26
30
parser .add_argument (
27
- "-s" , "--speed" , type = int , default = 30 , help = "mouse speed, default 30"
31
+ "-s" , "--speed" , type = int , default = 25 , help = "mouse speed, default 25"
32
+ )
33
+ parser .add_argument (
34
+ "-S" , "--smooth" , type = int , default = 3 , help = "averages mouse movements to smooth out jittering, default 3"
28
35
)
29
36
args = parser .parse_args ()
37
+ if args .smooth < 1 :
38
+ args .smooth = 1
39
+
30
40
31
41
if args .verbose :
32
42
logging .getLogger ().setLevel (logging .DEBUG )
@@ -73,6 +83,16 @@ class PhilNav:
73
83
msg_time_start = time ()
74
84
msg_time_total = 0
75
85
msg_num = 0
86
+ x_q = deque ([], args .smooth )
87
+ y_q = deque ([], args .smooth )
88
+ x_q_long = deque ([], args .smooth * 3 )
89
+ y_q_long = deque ([], args .smooth * 3 )
90
+
91
+
92
+ def smooth (q ):
93
+ sum = np .sum (q )
94
+ avg = sum / len (q )
95
+ return avg
76
96
77
97
78
98
# Main event loop:
@@ -101,6 +121,21 @@ class PhilNav:
101
121
# x_diff, y_diff, n/a, n/a, n/a, camera capture time
102
122
x , y , z , pitch , yaw , roll = struct .unpack ("dddddd" , data )
103
123
124
+ # Simple moving average to smooth out jitters
125
+ PhilNav .x_q .append (x )
126
+ PhilNav .y_q .append (y )
127
+ PhilNav .x_q_long .append (x )
128
+ PhilNav .y_q_long .append (y )
129
+ if x ** 2 + y ** 2 < 0.2 :
130
+ x_smooth = smooth (PhilNav .x_q_long )
131
+ y_smooth = smooth (PhilNav .y_q_long )
132
+ elif x ** 2 + y ** 2 < 0.5 :
133
+ x_smooth = smooth (PhilNav .x_q )
134
+ y_smooth = smooth (PhilNav .y_q )
135
+ else :
136
+ x_smooth = x
137
+ y_smooth = y
138
+
104
139
# The Magic Happens Now! eg. move mouse cursor =P
105
140
pt = POINT ()
106
141
ctypes .windll .user32 .GetCursorPos (
@@ -109,8 +144,8 @@ class PhilNav:
109
144
# I'm moving the Y axis slightly faster because looking left and right
110
145
# is easier than nodding up and down. Also, monitors are wider than they
111
146
# are tall.
112
- x_new = round (pt .x + x * args .speed )
113
- y_new = round (pt .y + y * args .speed * 1.33 )
147
+ x_new = round (pt .x + x_smooth * args .speed )
148
+ y_new = round (pt .y + y_smooth * args .speed * 1.25 )
114
149
ctypes .windll .user32 .SetCursorPos (x_new , y_new ) # move mouse cursor
115
150
116
151
# I'm trying to measure the total time from capturing the frame on the
0 commit comments