Joystick Simulation with Processing

If you’re building a control system for a robot, a new game or even controls in your house you probably need a way to interact with your program. The joystick is a common user input device to work with, however, the variety of types and device drivers can raise a few issues when working with multiple operating system.

In order to introduce joystick interaction for the Windows, Linux, and Mac operating systems we need a cross platform programming environment. The Processing Language gives us a way to simulate the joystick for each computing system.

After working with the Arduino and its programming environment, creating a program with the Processing Language has a familar look and feel.

Create a new Sketch in Processing called: JoystickSimulation

import processing.opengl.*;

/*---->>>
 Program: Joystick

 This program simulates using a joystick by using a mouse and
 the graphics features of Processing.

 Author: Vince Thompson
 http://www.twitter.com/SomeoneKnows

<<<----*/

int displayWidth = 640;
int displayHeight = 480;
int joyOutputRange = 90;  //Maximum value for full horiz or vert position where centered is 0.
int textHorizPos, textVertPos;  //Display positions for text feedback values.
int fontSpace = 12;

float curJoyDisplayWidth;
float curJoyDisplayHeight;

float maxJoyRange=200;     //Maximum joystick range
float curJoyAngle;     //Current joystick angle
float curJoyRange;     //Current joystick range
float joyDisplayCenterX;  //Joystick displayed Center X
float joyDisplayCenterY;  //Joystick displayed Center Y

float surfDisplayCenterX;
float surfDisplayCenterY;

float rSize;

boolean isMouseTracking=false;
color color1;
color color2;

void setup() {
  PFont font;
  size(displayWidth, displayHeight, OPENGL);
  joyDisplayCenterX = displayWidth/2;
  joyDisplayCenterY = 25 + maxJoyRange/2;
  curJoyDisplayWidth = maxJoyRange * .85;
  curJoyDisplayHeight = curJoyDisplayWidth;
  maxJoyRange = curJoyDisplayWidth / 2;

  surfDisplayCenterX=displayWidth/2;
  surfDisplayCenterY=displayHeight* .65;

  smooth();
  strokeWeight(10.0);
  stroke(0, 100);
  color1=color(0);  //Color = Black
  color2=color(150);  

  rSize = displayWidth/2;

  font = loadFont("Monospaced.bold-12.vlw");
  textFont(font);
}

void draw()
{
  float joyHorizontalText, joyVerticalText;

  background(226);

  float dx = mouseX - joyDisplayCenterX;
  float dy = mouseY - joyDisplayCenterY;

  if(mousePressed && (mouseButton == LEFT))
    isMouseTracking = true;

  if(mousePressed && (mouseButton == RIGHT))
    isMouseTracking = false;

  if (isMouseTracking)
  {
    curJoyAngle = atan2(dy, dx);
    curJoyRange = dist(mouseX, mouseY, joyDisplayCenterX, joyDisplayCenterY);
  }
  else
  {
    curJoyRange = 0;
  }

  fill(200);
  noStroke();
  ellipse(joyDisplayCenterX, joyDisplayCenterY, curJoyDisplayHeight, curJoyDisplayWidth);

  stroke(0,100);
  segment(joyDisplayCenterX, joyDisplayCenterY, curJoyAngle);
  ellipse(joyDisplayCenterX, joyDisplayCenterY, 20, 20);

  fill(160,0,0);
  textHorizPos = 50;
  textVertPos = (int)(joyDisplayCenterY - 50);
  text("Horiz:", textHorizPos, textVertPos);
  textHorizPos += (4*fontSpace);
  joyHorizontalText = (joyOutputRange*(cos(curJoyAngle) * curJoyRange)/ maxJoyRange);
  text(nf(joyHorizontalText, 2, 1), textHorizPos, textVertPos);

  textHorizPos = 50;
  textVertPos += 12;  

  text("Vert:", textHorizPos, textVertPos);
  textHorizPos += (4*fontSpace);
  joyVerticalText = (joyOutputRange*(-(sin(curJoyAngle) * curJoyRange)/maxJoyRange));
  text(nf(joyVerticalText, 2, 1), textHorizPos, textVertPos);

  labySurface(joyHorizontalText, joyVerticalText);
}

void segment(float x, float y, float a)
{
  pushMatrix();
  translate(x, y);
  rotate(a);
  if (curJoyRange > maxJoyRange)
    curJoyRange = maxJoyRange;

  line(0, 0, curJoyRange, 0);
  popMatrix();
}

void labySurface(float angleHoriz, float angleVert)
{
  float radHoriz;
  float radVert;

  radHoriz = radians(angleHoriz) * .15;
  radVert = radians(angleVert-60) * .15;
  noFill();
  stroke(200);
  pushMatrix();
  translate(surfDisplayCenterX, surfDisplayCenterY, 0);
  rotateX(HALF_PI+ (radians(-60) * .15));
  box(rSize+5, rSize+5, 1);
  popMatrix();

  pushMatrix();
  stroke(0);
  translate(surfDisplayCenterX, surfDisplayCenterY, 0);
  rotateX(HALF_PI+radVert);
  rotateY(radHoriz);
  fill(0,20,240);
  box(rSize, rSize, 8);
  popMatrix();

}

Line 58 Error

Chances are you tried running the sketch and get the following error message:

java.lang.NullPointerException
at java.io.DataInputStream.readInt(DataInputStream.java:370)
at processing.core.PFont.<init>(PFont.java:128)
at processing.core.PApplet.loadFont(PApplet.java:3517)
at Joystick.setup(Joystick.java:77)
at processing.core.PApplet.handleDraw(PApplet.java:1400)
at processing.core.PApplet.run(PApplet.java:1328)
at java.lang.Thread.run(Thread.java:619)
Exception in thread “Animation Thread” java.lang.RuntimeException: Could not load font Monospaced.bold-12.vlw. Make sure that the font has been copied to the data folder of your sketch.
at processing.core.PApplet.die(PApplet.java:2186)
at processing.core.PApplet.die(PApplet.java:2195)
at processing.core.PApplet.loadFont(PApplet.java:3520)
at Joystick.setup(Joystick.java:77)
at processing.core.PApplet.handleDraw(PApplet.java:1400)
at processing.core.PApplet.run(PApplet.java:1328)
at java.lang.Thread.run(Thread.java:619)

If this happens, the compiler is complaining because it doesn’t find the specified font. When you create a new Processing sketch it places it in a new folder. The font needs to be added to the data folder.

Creating the font file is accomplished by selecting Tools -> Create Font … from the Processing Menu.

Processings Tools-Create Font... selection

Processing's Tools->Create Font... selection

This brings up a dialog box to make your font selection.

Selecting the Monospaced.bold font

Selecting the Monospaced.bold font

Locate the Monospaced.bold font type then change the font size selection to 12, when done press the OK button.

(c) 2009 – Vince Thompson
Advertisements

Tags: , , ,

3 Responses to “Joystick Simulation with Processing”

  1. Notes About Developing Arduino Workshops « Someoneknows Says:

    […] video was captured for the DIY Robotics Lab article “Joystick Simulation with Processing” where this virtual joystick will be operating the robotic labyrinth through an […]

  2. Hello to the UK’s Robot Brighton « DIY Robotics Lab Says:

    […] interested in robotics. An article on this site illustrates using Processing to interact with a simulated joystick. Since publishing that article I’ve added xBox 360 controller support through Processing to […]

  3. William Shipley Says:

    do you know of a way processing can act like a joystick for windows, as in give out joystick input and a game could use it. I would use the robot library but it only has room for two axises with the mouse.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: