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.
This brings up a dialog box to make your font selection.
Locate the Monospaced.bold font type then change the font size selection to 12, when done press the OK button.
(c) 2009 – Vince Thompson
Tags: Arduino, Joystick, Labyrinth, Simulation


June 18, 2009 at 5:09 am |
[...] 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 [...]