HTML - UCSD-E4E/Wolf-Tracker-2014 GitHub Wiki

Contents

Styling

Bootstrap was used to help format the webpage for looks and style and is available here.

Gamepad

Code

var hasGP = false;
var repGP;

$(document).ready(function() {
	function canGame(){
		return "getGamepads" in navigator;
	}

	function sendGamepadData(){
		var gp = navigator.getGamepads()[0];
		//console.log(gp.axes[1] + " " + gp.axes[3]);

		var sendData = JSON.stringify({leftStick: gp.axes[1], rightStick: gp.axes[3]});

		//for debug
		console.log(sendData);

		$.ajax({
			url: '/node_eats',
			data: sendData,
			type: 'POST',
			dataType: 'json',
			success: function(data){
				//for debug
				console.log("success!");
			}
		}).done(function(){
			console.log("Done!");
		})
	}

	if(canGame()) {
		//Do this when gamepade is connected
		$(window).on("gamepadconnected", function() {
			hasGP = true;
			console.log("gamepad connected!");
			repGP = window.setInterval(sendGamepadData,100);
		});

		//show when gamepad disconnects
		$(window).on("gamepaddisconnected", function() {
			console.log("disconnection event");
			window.clearInterval(repGP);
		});

		//setup an interval for Chrome
		var checkGP = window.setInterval(function() {
			console.log('checkGP');
			if(navigator.getGamepads()[0]) {
				if(!hasGP) $(window).trigger("gamepadconnected");
				window.clearInterval(checkGP);
			}
		}, 500);
	}		
});

*** How it works

HTML5 uses allows gamepad usage with the navigator.getGamepads()[0]. For further info on how this works look at the HTML 5 Gamepad documentation.

function sendGamepadData(){
	var gp = navigator.getGamepads()[0];
	//console.log(gp.axes[1] + " " + gp.axes[3]);

	var sendData = JSON.stringify({leftStick: gp.axes[1], rightStick: gp.axes[3]});

	//for debug
	console.log(sendData);

	$.ajax({
		url: '/node_eats',
		data: sendData,
		type: 'POST',
		dataType: 'json',
		success: function(data){
			//for debug
			console.log("success!");
		}
	}).done(function(){
		console.log("Done!");
	})
}

sendGamePadData() is called, after a controller is connected and sends the gamepad data over an AJAX POST request. If we wanted to add buttons add gp.buttons[#] into the sendData variable and would look something like:

var sendData = JSON.stringify({leftStick: gp.axes[1], rightStick: gp.axes[3], xButton: gp.buttons[0]});

This means that you have to edit the server code parsing on the Beagle Bone. The line to edit is stringData

//in serverWSerial.js
req.on('end',function(){
  var OBJ = JSON.parse(body);
  var stringData =  "L:" + OBJ.leftStick.toFixed(2) + "|" +
                    "R:" + OBJ.rightStick.toFixed(2) + ";";
  sendToArduino(stringData);

});

Continuing with our example, the code on the server would change to:

var stringData =  "L:" + OBJ.leftStick.toFixed(2) + "|" +
                  "R:" + OBJ.rightStick.toFixed(2) + "|" + 
                  "X:" + OBJ.xButton + ";"; //should come out to "X:true" or "X:false"

and the code on the arduino would change from:

void parseData(String data){
  String leftMotorString = "";
  String rightMotorString = "";
  int state = 0;
  for(int i = 0; i < data.length(); i++){
    char c = data.charAt(i);
    if(c == 'L'){
      state = 0;
      continue;
    }
    if(c == 'R'){
      state = 1;
      continue;
    }
    if(c == ':' || c =='|' || c == ';'){
      continue;
    }
    
    switch(state) {
      case 0:
        // parsing leftMotorString data
        leftMotorString.concat(data.charAt(i));
        break;
      case 1:
        //parsing rightMotorString data
        rightMotorString.concat(data.charAt(i));        
        break;
      default:
        //don't do anything
        break;
    }
  } //end of for loop
  updateMotors(leftMotorString, rightMotorString);
}

To:

void parseData(String data){
  String leftMotorString = "";
  String rightMotorString = "";
  String buttonString = "";
  int state = 0;
  for(int i = 0; i < data.length(); i++){
    char c = data.charAt(i);
    if(c == 'L'){
      state = 0;
      continue;
    }
    if(c == 'R'){
      state = 1;
      continue;
    }
    if(c == 'X'){
      state = 2;
      continue;
	}
    if(c == ':' || c =='|' || c == ';'){
      continue;
    }
    
    switch(state) {
      case 0:
        // parsing leftMotorString data
        leftMotorString.concat(data.charAt(i));
        break;
      case 1:
        //parsing rightMotorString data
        rightMotorString.concat(data.charAt(i));        
        break;
      case 2:
        //parsing buttonString data
        buttonString.concat(data.charAt(i));
        break;
      default:
        //don't do anything
        break;
    }
  } //end of for loop
  updateMotors(leftMotorString, rightMotorString);

  buttonFunction(buttonString);
}

function buttonFunction(data){
  if(data == "true"){    //button was pressed
    ...
    //code to do something when button is pressed
    ...
  } else {
    ...
    //code to do something when button is not pressed
    ...	
  }
}