36 from bluetooth
import *
45 L2CAP_PSM_HIDP_CTRL = 17
46 L2CAP_PSM_HIDP_INTR = 19
57 for name
in [
"/dev/input/uinput",
"/dev/misc/uinput",
"/dev/uinput"]:
59 return os.open(name, os.O_WRONLY)
66 def __init__(self, buttons, axes, axmin, axmax, axfuzz, axflat):
69 print >> sys.stderr,
"Trying to modprobe uinput." 70 os.system(
"modprobe uinput > /dev/null 2>&1")
74 print >> sys.stderr,
"Can't open uinput device. Is it accessible by this user? Did you mean to run as root?" 85 UI_SET_EVBIT = 0x40045564
86 UI_SET_KEYBIT = 0x40045565
87 UI_SET_RELBIT = 0x40045566
88 UI_DEV_CREATE = 0x5501
89 UI_SET_RELBIT = 0x40045566
90 UI_SET_ABSBIT = 0x40045567
91 uinput_user_dev =
"80sHHHHi" + (uinput.ABS_MAX+1)*4*
'i' 93 if len(axes) != len(axmin)
or len(axes) != len(axmax):
94 raise Exception(
"uinputjoy.__init__: axes, axmin and axmax should have same length")
95 absmin = [0] * (uinput.ABS_MAX+1)
96 absmax = [0] * (uinput.ABS_MAX+1)
97 absfuzz = [2] * (uinput.ABS_MAX+1)
98 absflat = [4] * (uinput.ABS_MAX+1)
99 for i
in range(0, len(axes)):
100 absmin[axes[i]] = axmin[i]
101 absmax[axes[i]] = axmax[i]
102 absfuzz[axes[i]] = axfuzz[i]
103 absflat[axes[i]] = axflat[i]
105 os.write(self.
file, struct.pack(uinput_user_dev,
"Sony Playstation SixAxis/DS3",
106 uinput.BUS_USB, 0x054C, 0x0268, 0, 0, *(absmax + absmin + absfuzz + absflat)))
108 fcntl.ioctl(self.
file, UI_SET_EVBIT, uinput.EV_KEY)
111 fcntl.ioctl(self.
file, UI_SET_KEYBIT, b)
114 fcntl.ioctl(self.
file, UI_SET_EVBIT, uinput.EV_ABS)
115 fcntl.ioctl(self.
file, UI_SET_ABSBIT, a)
117 fcntl.ioctl(self.
file, UI_DEV_CREATE)
119 self.
value = [
None] * (len(buttons) + len(axes))
120 self.
type = [uinput.EV_KEY] * len(buttons) + [uinput.EV_ABS] * len(axes)
124 input_event =
"LLHHi" 127 tl = int((t - th) * 1000000)
128 if len(value) != len(self.
value):
129 print >> sys.stderr,
"Unexpected length for value in update (%i instead of %i). This is a bug."%(len(value), len(self.
value))
130 for i
in range(0, len(value)):
131 if value[i] != self.
value[i]:
132 os.write(self.
file, struct.pack(input_event, th, tl, self.
type[i], self.
code[i], value[i]))
133 self.
value = list(value)
137 Exception.__init__(self,
"Unsupported joystick.")
140 def __init__(self, inactivity_timeout = float(1e3000), continuous_motion_output =
False):
152 buttons = range(0x100,0x111)
158 for i
in range(-4,0):
162 if continuous_motion_output:
165 for i
in range(4,len(axmin)-4):
168 self.
axmid = [sum(pair)/2
for pair
in zip(axmin, axmax)]
178 if len(rawdata) == 50:
179 joy_coding =
"!1B2x3B1x4B4x12B15x4H" 180 data = list(struct.unpack(joy_coding, rawdata))
183 print >> sys.stderr,
"Unexpected prefix (%i). Is this a PS3 Dual Shock or Six Axis?"%prefix
187 curbyte = data.pop(0)
189 out.append(int((curbyte & (1 << k)) != 0))
192 axis_motion = [abs(out[17:][i] - self.
axmid[i]) > 20
for i
in range(0,len(out)-17-4)]
194 if any(out[0:17])
or any(axis_motion):
197 elif len(rawdata) == 13:
199 print >> sys.stderr,
"Your bluetooth adapter is not supported. Does it support Bluetooth 2.0? Please report its model to blaise@willowgarage.com" 202 print >> sys.stderr,
"Unexpected packet length (%i). Is this a PS3 Dual Shock or Six Axis?"%len(rawdata)
206 self.joy.update([0] * 17 + self.
axmid)
208 def run(self, intr, ctrl):
212 lastactivitytime = lastvalidtime = time.time()
214 (rd, wr, err) = select.select([intr], [], [], 0.1)
215 curtime = time.time()
216 if len(rd) + len(wr) + len(err) == 0:
218 ctrl.send(
"\x53\xf4\x42\x03\x00\x00")
222 print "Connection activated" 225 rawdata = intr.recv(128)
226 except BluetoothError, s:
227 print "Got Bluetooth error %s. Disconnecting."%s
229 if len(rawdata) == 0:
230 print "Joystick shut down the connection, battery may be discharged." 232 stepout = self.
step(rawdata)
234 lastvalidtime = curtime
236 lastactivitytime = curtime
238 print "Joystick inactive for %.0f seconds. Disconnecting to save battery."%self.
inactivity_timeout 240 if curtime - lastvalidtime >= 0.1:
242 if curtime - lastvalidtime >= 5:
243 print "No valid data for 5 seconds. Disconnecting. This should not happen, please report it." 251 Exception.__init__(self)
256 proc = subprocess.Popen([
'hciconfig'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
257 (out, err) = proc.communicate()
258 if out.find(
'UP') == -1:
259 os.system(
"hciconfig hci0 up > /dev/null 2>&1")
260 if out.find(
'PSCAN') == -1:
261 os.system(
"hciconfig hci0 pscan > /dev/null 2>&1")
269 sock = BluetoothSocket(L2CAP)
273 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
280 sock.bind((
"", port))
284 print >> sys.stderr,
"Error binding to socket, will retry every 5 seconds. Do you have another ps3joy.py running? This error occurs on some distributions (such as Ubuntu Karmic). Please read http://www.ros.org/wiki/ps3joy/Troubleshooting for solutions." 294 self.
listen(intr_sock, ctrl_sock)
299 self.
listen(intr_sock, ctrl_sock)
304 print "Waiting for connection. Disconnect your PS3 joystick from USB and press the pairing button." 306 intr_sock.settimeout(5)
307 ctrl_sock.settimeout(1)
310 (intr, (idev, iport)) = intr_sock.accept();
313 if str(e) ==
'timed out':
320 (ctrl, (cdev, cport)) = ctrl_sock.accept();
322 print >> sys.stderr,
"Got interrupt connection without control connection. Giving up on it." 326 self.decoder.run(intr, ctrl)
327 print "Connection terminated." 329 print >> sys.stderr,
"Simultaneous connection from two different devices. Ignoring both." 334 except BadJoystickException:
336 except KeyboardInterrupt:
337 print "CTRL+C detected. Exiting." 340 traceback.print_exc()
341 print >> sys.stderr,
"Caught exception: %s"%str(e)
345 inactivity_timout_string =
"--inactivity-timeout" 346 no_disable_bluetoothd_string =
"--no-disable-bluetoothd" 347 redirect_output_string =
"--redirect-output" 348 continuous_motion_output_string =
"--continuous-output" 351 print "usage: ps3joy.py ["+inactivity_timout_string+
"=<n>] ["+no_disable_bluetoothd_string+
"] ["+redirect_output_string+
"] ["+continuous_motion_output_string+
"]=<f>" 352 print "<n>: inactivity timeout in seconds (saves battery life)." 353 print "<f>: file name to redirect output to." 354 print "Unless "+no_disable_bluetoothd_string+
" is specified, bluetoothd will be stopped." 358 if not arg.startswith(prefix):
360 if not arg.startswith(prefix+
"="):
361 print "Expected '=' after "+prefix
366 if __name__ ==
"__main__":
372 args = [
'sudo', sys.executable] + sys.argv + [os.environ]
373 os.execlpe(
'sudo', *args)
375 raise SystemExit(
"Root Privlages Required.")
378 inactivity_timeout = float(1e3000)
379 disable_bluetoothd =
True 380 continuous_output =
False 381 for arg
in sys.argv[1:]:
385 str_value = arg[len(inactivity_timout_string)+1:]
387 inactivity_timeout = float(str_value)
388 if inactivity_timeout < 0:
389 print "Inactivity timeout must be positive." 393 print "Error parsing inactivity timeout: "+str_value
396 elif arg == no_disable_bluetoothd_string:
397 disable_bluetoothd =
False 398 elif arg == continuous_motion_output_string:
399 continuous_output =
True 401 str_value = arg[len(redirect_output_string)+1:]
403 print "Redirecting output to:", str_value
404 sys.stdout = open(str_value,
"a", 1)
406 print "Error opening file to redirect output:", str_value
408 sys.stderr = sys.stdout
410 print "Ignoring parameter: '%s'"%arg
412 if disable_bluetoothd:
413 os.system(
"/etc/init.d/bluetooth stop > /dev/null 2>&1")
416 while os.system(
"hciconfig hci0 > /dev/null 2>&1") != 0:
417 print >> sys.stderr,
"No bluetooth dongle found or bluez rosdep not installed. Will retry in 5 seconds." 419 if inactivity_timeout == float(1e3000):
420 print "No inactivity timeout was set. (Run with --help for details.)" 422 print "Inactivity timeout set to %.0f seconds."%inactivity_timeout
424 cm.listen_bluetooth()
426 if disable_bluetoothd:
427 os.system(
"/etc/init.d/bluetooth start > /dev/null 2>&1")
429 errorcode = e.errorcode
430 except KeyboardInterrupt:
431 print "CTRL+C detected. Exiting." def listen_bluetooth(self)
def is_arg_with_param(arg, prefix)
def prepare_socket(self, sock, port)
def __init__(self, decoder)
def __init__(self, errorcode)
def prepare_net_socket(self, port)
def prepare_bluetooth_socket(self, port)
def listen(self, intr_sock, ctrl_sock)
def __init__(self, inactivity_timeout=float(1e3000), continuous_motion_output=False)
def listen_net(self, intr_port, ctrl_port)
def run(self, intr, ctrl)