Pong game for ELEC1620 board.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Joystick.cpp Source File

Joystick.cpp

00001 #include "Joystick.h"
00002 
00003 Joystick::Joystick(PinName vertPin,PinName horizPin)
00004 {
00005     vert = new AnalogIn(vertPin);
00006     horiz = new AnalogIn(horizPin);
00007 }
00008 
00009 void Joystick::init()
00010 {
00011     // read centred values of joystick
00012     _x0 = horiz->read();
00013     _y0 = vert->read();
00014 
00015     // this assumes that the joystick is centred when the init function is called
00016     // if perfectly centred, the pots should read 0.5, but this may
00017     // not be the case and x0 and y0 will be used to calibrate readings
00018 }
00019 
00020 Direction Joystick::get_direction()
00021 {
00022     float angle = get_angle();  // 0 to 360, -1 for centred
00023 
00024     Direction d;
00025     // partition 360 into segments and check which segment the angle is in
00026     if (angle < 0.0f) {
00027         d = CENTRE;   // check for -1.0 angle
00028     } else if (angle < 22.5f) {  // then keep going in 45 degree increments
00029         d = N;
00030     } else if (angle < 67.5f) {
00031         d = NE;
00032     } else if (angle < 112.5f) {
00033         d = E;
00034     } else if (angle < 157.5f) {
00035         d = SE;
00036     } else if (angle < 202.5f) {
00037         d = S;
00038     } else if (angle < 247.5f) {
00039         d = SW;
00040     } else if (angle < 292.5f) {
00041         d = W;
00042     } else if (angle < 337.5f) {
00043         d = NW;
00044     } else {
00045         d = N;
00046     }
00047 
00048     return d;
00049 }
00050 
00051 // this method gets the magnitude of the joystick movement
00052 float Joystick::get_mag() {
00053     Polar p = get_polar();
00054     return p.mag;
00055 }
00056 
00057 // this method gets the angle of joystick movement (0 to 360, 0 North)
00058 float Joystick::get_angle()
00059 {
00060     Polar p = get_polar();
00061     return p.angle;
00062 }
00063 
00064 // get raw joystick coordinate in range -1 to 1
00065 // Direction (x,y)
00066 // North     (0,1)
00067 // East      (1,0)
00068 // South     (0,-1)
00069 // West      (-1,0)
00070 Vector2D Joystick::get_coord()
00071 {
00072     // read() returns value in range 0.0 to 1.0 so is scaled and centre value
00073     // substracted to get values in the range -1.0 to 1.0
00074     float x = 2.0f*( horiz->read() - _x0 );
00075     float y = 2.0f*( vert->read() - _y0 );
00076 
00077     // Note: the values are negated so positive is up and right.
00078     Vector2D coord = {-x,y};
00079     return coord;
00080 }
00081 
00082 // This maps the raw x,y coord onto a circular grid.
00083 // See:  http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
00084 Vector2D Joystick::get_mapped_coord()
00085 {
00086     Vector2D coord = get_coord();
00087 
00088     // do the transformation
00089     float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
00090     float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
00091 
00092     Vector2D mapped_coord = {x,y};
00093     return mapped_coord;
00094 }
00095 
00096 // this function converts the mapped coordinates into polar form
00097 Polar Joystick::get_polar()
00098 {
00099     // get the mapped coordinate
00100     Vector2D coord = get_mapped_coord();
00101 
00102     // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
00103     // We want 0 degrees to correspond to North and increase clockwise to 359
00104     // like a compass heading, so we need to swap the axis and invert y
00105     float x = coord.y;
00106     float y = coord.x;
00107 
00108     float mag = sqrt(x*x+y*y);  // pythagoras
00109     float angle = RAD2DEG*atan2(y,x);
00110     // angle will be in range -180 to 180, so add 360 to negative angles to
00111     // move to 0 to 360 range
00112     if (angle < 0.0f) {
00113         angle+=360.0f;
00114     }
00115 
00116     // the noise on the ADC causes the values of x and y to fluctuate slightly
00117     // around the centred values. This causes the random angle values to get
00118     // calculated when the joystick is centred and untouched. This is also when
00119     // the magnitude is very small, so we can check for a small magnitude and then
00120     // set the angle to -1. This will inform us when the angle is invalid and the
00121     // joystick is centred
00122 
00123     if (mag < TOL) {
00124         mag = 0.0f;
00125         angle = -1.0f;
00126     }
00127 
00128     Polar p = {mag,angle};
00129     return p;
00130 }