Collision detection between 2 objects with an ultrasonic sensor (Arduino)

edited April 2018 in Arduino

So I'm working from the code in Step 6 (I will attach below) of this tutorial: http://www.instructables.com/id/How-to-control-a-simple-Processing-game-with-Ardui/

I am using an HR-SR04 ultrasonic sensor to control the plane, moving it up and down via hand movements.

What I am trying to do is implement an obstacle feature to the game, by having the score decrease by 1 when the plane hits a cloud. However I can't get the collision detection working for when the plane hits a cloud. The original author has managed to get this working perfectly for when the plane hits the bird but I'm not sure how to get it working between the plane and clouds, I've tried everything I can think of but I'm stuck.

Any help would be appreciated.

Below is the code that I'm working from:

`//Ultrasound plane, a game with a plane and an ultrsound sensor (but

//by Yoruk for Instructables

//send commments or questions to Yoruk16_72 AT yahoo DOT fr


//19 07 14 : initial code
//20 07 14 : it works with arduino !!
//07 07 15 : picture for the plane and for the grass
//06 12 15 : score system with the bird


int i, j; 

int Score ;
float DistancePlaneBird;


float Hauteur; //en Y
float Angle;
int DistanceUltra;
int IncomingDistance;
//float Pas; //pour deplacements X

float BirdX;
float BirdY;

float GrassX ;  //for X position




String DataIn; //incoming data on the serial port

//5 a 32 cm


float [] CloudX = new float[6];
float [] CloudY = new float[6];

//vitesse constante hein


PImage Cloud;
PImage Bird;
PImage Plane;
PImage Grass;



// serial port config
import processing.serial.*; 
Serial myPort;    



//preparation
void setup() 
{

    myPort = new Serial(this, "/dev/cu.usbmodem1411", 9600); 

    myPort.bufferUntil(10);   //end the reception as it detects a carriage return

    frameRate(30); 

    size(800, 600);
    rectMode(CORNERS) ; //we give the corners coordinates 
    noCursor(); //why not ?
    textSize(16);

    Hauteur = 300; //initial plane value


    Cloud = loadImage("cloud.png");  //load a picture
    Bird = loadImage("bird.png");  
    Plane = loadImage("plane.png");  //the new plane picture

        Grass = loadImage("grass.png");  //some grass


    //int clouds position
    for  (int i = 1; i <= 5; i = i+1) {
        CloudX[i]=random(1000);
        CloudY[i]=random(400);
    }


    Score = 0;
}


//incoming data event on the serial port


void serialEvent(Serial p) { 
    DataIn = p.readString(); 
    // println(DataIn);

    IncomingDistance = int(trim(DataIn)); //conversion from string to integer

    println(IncomingDistance); //checks....

    if (IncomingDistance>1  && IncomingDistance<100 ) {
        DistanceUltra = IncomingDistance; //save the value only if its in the range 1 to 100     }
    }
}


//main drawing loop
void draw() 
{
    background(0, 0, 0);
    Ciel(); //draw the sky
    fill(5, 72, 0);



    //rect(0, 580, 800, 600); //some grass

    //new grass : 

    for  (int i = -2; i <= 4; i = i+1) {  //a loop to display the grass picture 6 times

        image(Grass, 224*i  + GrassX, 550, 224, 58);  // 224 58 : picture size
    }

    //calculates the X grass translation. Same formulae than the bird
    GrassX = GrassX  -  cos(radians(Angle))*10;

    if (GrassX < -224) {  //why 224 ? to have a perfect loop
        GrassX=224;
    }


    text(Angle, 10, 30); //debug things...
    text(Hauteur, 10, 60); 


    //new part : check the distance between the plane and bird and increase the score
    DistancePlaneBird = sqrt(pow((400-BirdX), 2) + pow((Hauteur-BirdY), 2)) ;

    if (DistancePlaneBird < 40) {
        //we hit the bird   
        Score = Score+ 1;

        //reset the bird position
        BirdX = 900;
        BirdY = random(600);
    }

    //here we draw the score
    text("Score :", 200, 30); 
    text( Score, 260, 30); 



    //Angle = mouseY-300; //uncomment this line and comment the next one if you want to play with the mouse
    Angle = (18- DistanceUltra)*4;  // you can increase the 4 value...



    Hauteur = Hauteur + sin(radians(Angle))*10; //calculates the vertical position of the plane

    //check the height range to keep the plane on the screen 
    if (Hauteur < 0) {
        Hauteur=0;
    }

    if (Hauteur > 600) {
        Hauteur=600;
    }

    TraceAvion(Hauteur, Angle);

    BirdX = BirdX - cos(radians(Angle))*10;

    if (BirdX < -30) {
        BirdX=900;
        BirdY = random(600);
    }

    //draw and move the clouds
    for  (int i = 1; i <= 5; i = i+1) {
        CloudX[i] = CloudX[i] - cos(radians(Angle))*(10+2*i);

        image(Cloud, CloudX[i], CloudY[i], 300, 200);

        if (CloudX[i] < -300) {
            CloudX[i]=1000;
            CloudY[i] = random(400);
        }
    }

    image(Bird, BirdX, BirdY, 59, 38); //displays the useless bird. 59 and 38 are the size in pixels of the picture
}


void Ciel() {
    //draw the sky

    noStroke();
    rectMode(CORNERS);

    for  (int i = 1; i < 600; i = i+10) {
        fill( 49    +i*0.165, 118   +i*0.118, 181  + i*0.075   );
        rect(0, i, 800, i+10);
    }
}


void TraceAvion(float Y, float AngleInclinaison) {
    //draw the plane at given position and angle

    noStroke();
    pushMatrix();
    translate(400, Y);
    rotate(radians(AngleInclinaison)); //in degres  ! 


    /*
    Drawing concept :  ;-)

     |\___o__
     ________>     

     */

    scale(0.5);  //0.2 pas mal

    //unless drawing the plane "by hands", just display the stored picture instead. Note that the parameters 2 and 3 are half the picture size, to make sure that the plane rotates in his center.
    image(Plane, -111, -55, 223, 110); // 223 110 : picture size



    popMatrix(); //end of the rotation matrix
}

//file end`

Answers

  • I realise the code pasted horribly into that post, I'm new here sorry

  • Edit your post above with the gear icon, highlight code, and Ctrl-o to indent 4 spaces.

  • First: Do you understand the basics of collision detection? What type is your plane / cloud collision?

  • I do know the basics yes, I've made my own processing game for an assignment in the past which included multiple object collisions, however the main object was controlled by mouseX and mouseY instead of an ultrasonic sensor.

    Sorry I don't understand what you mean by 'what type is the plane/cloud collision?'

  • I meant, notice how Thompson classifies collision detections -- point/rect, rect/rect, circle/rect, circle/circle etc. Which type of collision are you trying to implement for plane/cloud?

  • Ah okay, I see what you mean. In the code I'm working from, the objects are images rather than shapes drawn in processing, although I guess it would be rect/rect I am trying to implement.

  • Great! So given that you know the origin (x,y) and width/height of each image rectangles, collision would be defined (in Java example code) like this:

    Where should you check for collision?

  • That's the thing...I don't know the origin (x,y) of either image, as the plane is controlled by the data input from the arduino sensor (incoming distance between my hand and the sensor) and the clouds are in an array and programmed to be randomly placed within the sketch. I do however know the width/height of both images, I just don't know the origin (x, y) for either.

  • edited April 2018

    The original author however has somehow made collision detection work between plane/bird in this section of code, which I would also assume would be a rect/rect collision:

    `//new part : check the distance between the plane and bird and increase the score
        DistancePlaneBird = sqrt(pow((400-BirdX), 2) + pow((Hauteur-BirdY), 2)) ;
    
        if (DistancePlaneBird < 40) {
            //we hit the bird   
            Score = Score+ 1;
    
            //reset the bird position
            BirdX = 900;
            BirdY = random(600);
        }`
    
  • edited April 2018

    No, that is point-circle collision detection.

    You can tell it is point-point by the pythagorean theorem -- a square root (sqrt()) of two squares (pow(n, 2)).

    The bird is treated as a point, the plane another point, and the < 40 treats the plane point as a 40px radius circle.

    See the example, which has a triangle illustration to explain how the calculation of collision distance is working:

Sign In or Register to comment.