{"id":1118,"date":"2017-06-25T14:56:35","date_gmt":"2017-06-25T13:56:35","guid":{"rendered":"http:\/\/ofalcao.pt\/blog\/?p=1118"},"modified":"2017-06-25T14:57:49","modified_gmt":"2017-06-25T13:57:49","slug":"triplex-gamepad-control","status":"publish","type":"post","link":"https:\/\/ofalcao.pt\/blog\/2017\/triplex-gamepad-control","title":{"rendered":"Triplex &#8211; gamepad control"},"content":{"rendered":"<div class=\"seriesmeta\">This post is part 3 of 3 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/triplex\" class=\"series-303\" title=\"Triplex\">Triplex<\/a><\/div><p>Alexandre from PLUG asked for a way to control Triplex with a gamepad.<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Triplex v0.4 - gamepad control\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/y3y2Yt7QhUg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>There is a already a <a href=\"http:\/\/www.ev3dev.org\/docs\/tutorials\/using-ps3-sixaxis\/\">good tutorial at ev3dev site<\/a> made by Anton Vanhoucke so I just post the particular settings for my gamepad, a &#8220;Terios T3&#8221;-like Bluetooth gamepad.<\/p>\n<p>To pair it to EV3 (running ev3dev) we need to turn Bluetooth ON in the Display Menus (&#8216;brickman&#8217;).<\/p>\n<p>We put it in pairable mode by pressing &#8220;Home&#8221; and &#8220;X&#8221; until it starts blinking. Then from command line we run bluetoothctl and:<\/p>\n<pre>agent on\r\ndefault-agent\r\nscan on\r\n...\r\npair 58:00:8E:83:1B:8C\r\ntrust 58:00:8E:83:1B:8C\r\nconnect 58:00:8E:83:1B:8C\r\n...\r\nConnection successful\r\nexit<\/pre>\n<p>The gamepad LEDs should stop blinking and one of the LEDs should stay ON. To change between gamepad mode and keyboard+mouse mode we press HOME+X or HOME+A\/B\/Y.<\/p>\n<p>After a successful connection, we see something like this in dmesg:<\/p>\n<pre>[ 520.522776] Bluetooth: HIDP (Human Interface Emulation) ver 1.2\r\n[ 520.522905] Bluetooth: HIDP socket layer initialized\r\n[ 522.148994] hid-generic 0005:1949:0402.0001: unknown main item tag 0x0\r\n[ 522.181426] input: Bluetooth Gamepad as \/devices\/platform\/serial8250.2\/tty\/ttyS2\/hci0\/hci0:1\/0005:1949:0402.0001\/input\/input2\r\n[ 522.205296] hid-generic 0005:1949:0402.0001: input,hidraw0: BLUETOOTH HID v1.1b Keyboard [Bluetooth Gamepad] on 00:17:ec:02:91:b7<\/pre>\n<p>The name (&#8216;Bluetooth Gamepad&#8217;) is important for our python script.<\/p>\n<p>This is the script I use &#8211; a small but important part of it is still based on\u00a0Anton Vanhoucke&#8217; script.<br \/>\nNOTE: the script lost indents when I copy&amp;pasted it to WordPress. Sorry.<\/p>\n<pre>#!\/usr\/bin\/env python3\r\nfrom math import cos,sin,atan2,pi,sqrt\r\nfrom time import sleep\r\nimport ev3dev.ev3 as ev3\r\nimport evdev\r\nimport threading\r\nfrom select import select\r\n\r\nM11 = 0.666\r\nM12 = 0\r\nM13 = 0.333\r\nM21 = -0.333\r\nM22 = -0.574\r\nM23 = 0.333 \r\nM31 = -0.333\r\nM32 = 0.574\r\nM33 = 0.333\r\n\r\nSPEED = 1560 # \/sys\/class\/tacho-motor\/motorx\/max_speed\r\nTIME = 50\r\n\r\n# before start make sure gamepad is paired\r\n\r\n## Initializing ##\r\nprint(\"Finding gamepad...\")\r\ndevices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]\r\nfor device in devices:\r\n if device.name == 'Bluetooth Gamepad':\r\n gamepad = evdev.InputDevice(device.fn)\r\n print(\"Gamepad found\")\r\n\r\nx = 0\r\ny = 0\r\nang = 0\r\nray = 0\r\ns1 = 0\r\ns2 = 0\r\ns3 = 0\r\n\r\nrotate_left=False\r\nrotate_right=False\r\n\r\nrunning = True\r\n\r\nclass MotorThread(threading.Thread):\r\n def __init__(self):\r\n self.m1 = ev3.MediumMotor('outA')\r\n self.m2 = ev3.MediumMotor('outB')\r\n self.m3 = ev3.MediumMotor('outC')\r\n\r\n# coast seems to help\r\n self.m1.stop_action='coast'\r\n self.m2.stop_action='coast'\r\n self.m3.stop_action='coast'\r\n\r\nthreading.Thread.__init__(self)\r\n print(\"Ready\")\r\n\r\ndef run(self):\r\n while running:\r\n if (rotate_left or rotate_right):\r\n if rotate_left:\r\n self.m1.run_timed(time_sp=TIME\/4, speed_sp=SPEED)\r\n self.m2.run_timed(time_sp=TIME\/4, speed_sp=SPEED)\r\n self.m3.run_timed(time_sp=TIME\/4, speed_sp=SPEED)\r\n sleep(TIME\/4\/1000)\r\n else:\r\n self.m1.run_timed(time_sp=TIME, speed_sp=-SPEED)\r\n self.m2.run_timed(time_sp=TIME, speed_sp=-SPEED)\r\n self.m3.run_timed(time_sp=TIME, speed_sp=-SPEED)\r\n sleep(TIME\/1000)\r\n else:\r\n self.m1.run_timed(time_sp=TIME, speed_sp=s1)\r\n self.m2.run_timed(time_sp=TIME, speed_sp=s2)\r\n self.m3.run_timed(time_sp=TIME, speed_sp=s3)\r\n sleep(TIME\/1000)\r\n\r\nmotor_thread = MotorThread()\r\nmotor_thread.setDaemon(True)\r\nmotor_thread.start()\r\n\r\nwhile True:\r\n select([gamepad], [], [])\r\n for event in gamepad.read():\r\n if event.type == 3:\r\n # joystick or pag\r\n\r\nif event.code == 0:\r\n # left.joystick - X\r\n if event.value &gt; 128:\r\n rotate_right=True\r\n rotate_left=False\r\n else:\r\n if event.value &lt; 128:\r\n rotate_left=True\r\n rotate_right=False\r\n else:\r\n rotate_right=False\r\n rotate_left=False\r\n\r\nif (event.code ==5) or (event.code == 2):\r\n\r\nif event.code == 5:\r\n # right joystick - Y\r\n y=(128-event.value)\/(128\/100)\r\n if event.code == 2:\r\n # rigt joystick - X\r\n x=(-128+event.value)\/(128\/100)\r\n\r\n ray = sqrt(x*x+y*y)\r\n\r\nif x!=0:\r\n ang=atan2(y,x)\r\n else:\r\n if y==0:\r\n ang=0\r\n else:\r\n if y&gt;0:\r\n ang=pi\/2\r\n else:\r\n ang=-pi\/2\r\n\r\nif ray&gt;5:\r\n ax = cos(ang)\r\n ay = sin(ang)\r\n\r\nf1 = M11 * ax + M12 * ay\r\n f2 = M21 * ax + M22 * ay\r\n f3 = M31 * ax + M32 * ay\r\n\r\ns1 = f1 * SPEED\r\n s2 = f2 * SPEED\r\n s3 = f3 * SPEED\r\n\r\nelse:\r\n s1 = 0\r\n s2 = 0\r\n s3 = 0<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This post is part 3  of 3 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/triplex\" class=\"series-303\" title=\"Triplex\">Triplex<\/a><\/div><p>Alexandre from PLUG asked for a way to control Triplex with a gamepad. There is a already a good tutorial at ev3dev site made by Anton Vanhoucke so I just post the particular settings for my gamepad, a &#8220;Terios T3&#8221;-like Bluetooth gamepad. To pair it to EV3 (running ev3dev) we need to turn Bluetooth ON &hellip; <a href=\"https:\/\/ofalcao.pt\/blog\/2017\/triplex-gamepad-control\" class=\"more-link\">Continuar a ler<span class=\"screen-reader-text\"> &#8220;Triplex &#8211; gamepad control&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[],"series":[303],"class_list":["post-1118","post","type-post","status-publish","format-standard","hentry","category-sem-categoria","series-triplex"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2Mhyv-i2","_links":{"self":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/comments?post=1118"}],"version-history":[{"count":0,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1118\/revisions"}],"wp:attachment":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/media?parent=1118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/categories?post=1118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/tags?post=1118"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/series?post=1118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}