This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
elfin8er's profile picture

"Driving" Turtles With Xbox Controller!

Started by elfin8er, 11 July 2013 - 12:47 AM
elfin8er #1
Posted 11 July 2013 - 02:47 AM
Before I start, I just wanted to say that I'm not sure whether or not this is the correct place to post this. I didn't post it in the program section, because the program itself doesn't really do anything. I didn't put it in the tutorial section because it was meant to be more of a showcase then a tutorial. However, please move to a different place if you see it fitting better somewhere else.

This is a little thing I've been working on for the past few days. I know it's not very efficient, but hey, it works. I'll go ahead and show the code for everything hear. After a bit of optimization, I may make an API for this. Not sure yet though. Depends if anybody would want to use it. Anyways, here's sort of how it works.

I have a wired Xbox controller plugged into my Windows computer. I don't remember for sure, but I think it installed the drivers automatically. Then, I used Python with the Pygame module to get the input from the controller (I actually just modified some code from the Pygame website). Then, I used a module called Requests to send HTTP requests to my web server. It sends the state of the button (whether the button is up, or down), and which button was pressed (A number between 0 and 9 I think). The HTTP requests are then received from my web server. The web server then saves what it receives from Python, to a file stored on the web server. A turtle then reads the file on the web server, and makes a file matching the file on the web server. Then, the turtle reads the information from the file, and moves accordingly.

Currently, the controls are a bit odd. This was simply just cause I didn't want to take time figuring out the joystick, or joypad. The turtle can move forward, rotate left and right, place blocks, destroy blocks, and move up and down. I'll definitely try to work get those working though. Also, the turtle sometimes moves several steps more than intended. Trying to work this out as well. Of course, there's also a bit of lag between when the button is pressed, and when the turtle is moved, but it's not too extreme.

So here's the Python code (Note: 90% of the code is from the Pygame website. I don't really use Python, so some stuff may be able to be removed. Please let me know if there's something I should remove):

import requests
import pygame
from pygame.locals import *

def main():
		baseurl = "http://yourwebsite.com/php/scripts/index.php"
		pygame.init()
		joysticks = []
		for i in range(0, pygame.joystick.get_count()):
				joysticks.append(pygame.joystick.Joystick(i))
				joysticks[-1].init()
				print ("Detected joystick '",joysticks[-1].get_name(),"'")
		while 1:
				for event in pygame.event.get():
						if event.type == JOYBUTTONDOWN:
							payload= {'button' : str(event.button),
									  'position' : 'down'}
							r = requests.get(baseurl, params=payload)
							print(str(event.button) + " down")
							  
						elif event.type == JOYBUTTONUP:
							payload= {'button' : str(event.button),
									  'position' : 'up'}
							r = requests.get(baseurl, params=payload)
							print(str(event.button) + " up")
						elif event.type == JOYHATMOTION:
							print(joysticks[event.joy].get_hat(event.hat))
					  
						  

if __name__ == "__main__":
		main()

Here's the turtle script:

url = "http://yourwebsite.com/php/scripts"

while true do
  data = http.get(url .. "data.txt").readAll()
  file = fs.open("data", "w")
  file.write(data)
  file.close()

  file = fs.open("data", "r")
  position = file.readLine()
  button = file.readLine()
  file.close()
  term.clear()
  term.setCursorPos(1,1)

  if (position == "down") then
	if (button == "3") then
	  print("Moving Forward")
	  turtle.forward()
	end
	if (button == "0") then
	  print("A Pressed")
	end
	if (button == "1") then
	  print("Turning Right")
	  turtle.turnRight()
	  sleep(0.5)
	end
	if (button == "2") then
	  print("Moving Left")
	  turtle.turnLeft()
	  sleep(0.5)
	end
	if (button == "4") then
	  print("Moving Down")
	  turtle.down()
	end
	if (button == "5") then
	  print("Moving Up")
	  turtle.up()
	end
	if (button == "6") then
	  print("Destroying Block")
	  turtle.dig()
	end
	if (button == "7") then
	  print("Placing Block")
	  turtle.place(1)
	end
  end
end

and the PHP script:

<?php
$position = $_GET['position'];
$button = $_GET['button'];
$fh = fopen("data.txt", 'w') or die("can't open file");
fwrite($fh, $position . "\n");
fwrite($fh, $button);
fclose($fh);
?>

Currently, I'm working on a way to make the controller vibrate. This would be used when the turtle performs an invalid move (Such as not being able to move forward, or not be able to destroy a certain block).

Lastly, I would make a video of this, but I have a really bad cough. Hopefully in a few days I'll be able to make something. Hope you guys enjoy this! Let me know what you think about it, and whether or not I should try to make an API for it.
Zudo #2
Posted 11 July 2013 - 02:55 AM
Why did you need to save the file?

data = http.get(url .. "data.txt").readAll()
file = fs.open("data", "w")
file.write(data)
file.close()

file = fs.open("data", "r")
position = file.readLine()
button = file.readLine()
file.close()

I know why you want to, but it is possible to not have to save the file.
elfin8er #3
Posted 11 July 2013 - 03:02 AM
Why did you need to save the file?

data = http.get(url .. "data.txt").readAll()
file = fs.open("data", "w")
file.write(data)
file.close()

file = fs.open("data", "r")
position = file.readLine()
button = file.readLine()
file.close()

I know why you want to, but it is possible to not have to save the file.
I couldn't figure out how to read multiple lines from the HTTP request. xD
H4X0RZ #4
Posted 11 July 2013 - 03:16 AM
Uhm… *Cough*

local link = "http://www.test.com"
local connection = http.get(link)

local firstLine = connection.readLine()
local secondLine = connection.readLine()
--Just an example
elfin8er #5
Posted 11 July 2013 - 12:53 PM
Uhm… *Cough*

local link = "http://www.test.com"
local connection = http.get(link)

local firstLine = connection.readLine()
local secondLine = connection.readLine()
--Just an example
Oh, ok. Didn't know you could do that. Thanks :)/>
Yevano #6
Posted 11 July 2013 - 01:13 PM
That's a somewhat complicated structure, hehe. Going from your controller, to Python, to a web server, to PHP, to a Minecraft server, and finally to Lua. +1 for creativity. :D/>
elfin8er #7
Posted 11 July 2013 - 01:32 PM
That's a somewhat complicated structure, hehe. Going from your controller, to Python, to a web server, to PHP, to a Minecraft server, and finally to Lua. +1 for creativity. :D/>
Heh, thanks!
Lyqyd #8
Posted 11 July 2013 - 01:36 PM
Wouldn't it be easier to just use something like JoyToKey and build the turtle program to respond to key events?
elfin8er #9
Posted 11 July 2013 - 01:38 PM
Wouldn't it be easier to just use something like JoyToKey and build the turtle program to respond to key events?
From my understanding, JoyToKey emulates keypresses. I would need the turtle gui to be open to send the keypresses to. Plus, it's a lot more fun doing it this way xD
Alice #10
Posted 11 July 2013 - 04:46 PM
So is there a possible way for me to upload this on my server when it's done so I could use it, with your permission?
elfin8er #11
Posted 11 July 2013 - 05:09 PM
So is there a possible way for me to upload this on my server when it's done so I could use it, with your permission?
Yea. I can put it on pastebin in just a few minutes. If you're using it for anything public, credit would be nice, though not needed.
elfin8er #12
Posted 12 July 2013 - 07:15 PM
Sorry for the wait for the pastebin code. I sorta ran into a couple of other things, and forgot to do it. HERE's a link to the pastebin. The pastebin code is z1Vf6AMw
Zambonie #13
Posted 12 July 2013 - 07:20 PM
Seems cool. I really want to try it but I dont have the right equipment for connecting my controller to my computer ;)/>
elfin8er #14
Posted 12 July 2013 - 07:46 PM
Seems cool. I really want to try it but I dont have the right equipment for connecting my controller to my computer ;)/>
All you need is a wired controller.