传感器与jBox2D中其他对象之间的不可靠碰撞检测(处理)

时间:2017-09-19 17:43:14

标签: neural-network processing collision-detection box2d jbox2d

我正在尝试制作一个神经进化计划,以制造可以避开其他汽车并停放自己的汽车。我已经能够实现神经网络,并且需要数学来支持它。每辆车都有一个神经网络,可以接收输入(来自传感器)并产生输出(转向和油门)。一辆汽车从其12个传感器接收到这个输入:8个碰撞反转传感器告诉汽车它是否即将与某些东西碰撞,另外4个感官告诉它它离停车位有多远。 8碰撞厌恶(C.A.)传感器具有fd.isSensor = true。 我考虑到传感器与自己的汽车碰撞(因为它们来自它的中心)。 问题在于,有时碰撞监听器 beginContact / endContact 在与边界重叠时不会触发,只会在汽车与汽车中心发生碰撞时触发响应汽车。有时,传感器碰撞在汽车碰撞之前不会记录。这会破坏传感器的目的。如果有人熟悉Box2D中的碰撞听,我真的很感谢你的帮助,所以我可以开始有趣的部分 - 遗传算法。谢谢!

这是我的碰撞监听器:

/*
  Evolving Neural Network
 Author: Aniekan Umoren
 Created: Sun Sep, 10 2017
 */

// Imports
import controlP5.*;
import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
import org.jbox2d.callbacks.ContactImpulse;
import org.jbox2d.callbacks.ContactListener;
import org.jbox2d.collision.Manifold;
import org.jbox2d.dynamics.contacts.Contact;



Box2DProcessing box2d;
ControlP5 control;
int populationSize, CURR_CAR;
ArrayList <Car> Population;
ArrayList<Boundary> boundaries;


void setup() {
  size(1000, 600);
  box2d = new Box2DProcessing(this);

  // Initializing a BOX2D world
  box2d.createWorld();
  box2d.setGravity(0, 0);
  box2d.listenForCollisions();


  // Creating World Boundaries
  boundaries = new ArrayList<Boundary>();
  boundaries.add(new Boundary(width/2, 0, width, 5));
  boundaries.add(new Boundary(0, height/2, 5, height));
  boundaries.add(new Boundary(width/2, height, width, 5));
  boundaries.add(new Boundary(width, height/2, 5, height));

  // Creating Initial Population
  populationSize = 10;
  Population = new ArrayList<Car>();
  for (int i = 0; i < populationSize; i++){
    Population.add(new Car(new float[0]));
  }

  // Creating User Control Interface
  control = new ControlP5(this);
  Slider currCar_slider = control.addSlider("CURR_CAR",  0, populationSize-1, 0, width/2 - 250, 25, 500, 10); 
  currCar_slider.setColorBackground(color(255, 255, 255));

  CURR_CAR = 0;
}

void draw() {
  background(0);
  fill(255);

  // Draw the Parking Spaces
  rectMode(CENTER);
  rect(width/2-300, height/2, 10, 300);
  rect(width/2, height/2, 10, 300);
  rect(width/2+300, height/2, 10, 300);
  for (int j = 0; j < 4; j++){
    rect(width/2, height/2 + 50*j, 200, 10);
    rect(width/2, height/2 + -50*j, 200, 10);
    rect(width/2-300, height/2 + 50*j, 200, 10);
    rect(width/2-300, height/2 + -50*j, 200, 10);
    rect(width/2+300, height/2 + 50*j, 200, 10);
    rect(width/2+300, height/2 + -50*j, 200, 10);
  }

  box2d.step();

  for (Boundary b : boundaries){
    b.render();
  }

  for (Car c : Population){
    if (Population.indexOf(c) == CURR_CAR){
      c.displayNN(true);
    } else{
      c.displayNN(false);
    }
    c.update();
    c.render();
  }
}


// ---------------------------- PROBLEMATIC AREA --------------------------------

void preSolve(Contact cp, Manifold oldManifold) {
    Fixture f1 = cp.getFixtureA();
    Fixture f2 = cp.getFixtureB();

    Body b1 = f1.getBody();
    Body b2 = f2.getBody();

    Object o1 = b1.getUserData();
    Object o2 = b2.getUserData();

    /*print("PRE SOLVE:\n");
     print(o1.getClass());
     print("\n");
     print(o2.getClass());
     print("\n");*/

    if (o1.getClass() == Boundary.class && o2.getClass() == Boundary.class) { // Stop boundaries from colliding since it's unecessary
      cp.setEnabled(false);
      //print("stop\n\n");
    } else if (o1.getClass() == Sensor.class && o2.getClass() == Sensor.class) {
      cp.setEnabled(false);
    }
  }

  void beginContact(Contact cp) {
    //print("collided\n");
    Fixture f1 = cp.getFixtureA();
    Fixture f2 = cp.getFixtureB();

    Body b1 = f1.getBody();
    Body b2 = f2.getBody();

    Object o1 = b1.getUserData();
    Object o2 = b2.getUserData();

    print("BEGIN CONTACT:\n");
    print(o1.getClass());
    print("\n");
    print(o2.getClass());
    print("\n");

    if (o1.getClass() == Sensor.class ^ o2.getClass() == Sensor.class) {

      print("Collision b/w Sensor and non-Sensor\n");

      if (o1.getClass() == Sensor.class) {
        Sensor s = (Sensor) o1;
        if (o2.getClass() == Car.class) {
          Car c = (Car) o2;
          boolean flag = true;
          print("SENSOR ID: " + str(s.id) + " CAR ID: " + str(c.id) + "\n");
          if (s.id == c.id) {
            flag = false;
            cp.setEnabled(false);
          }
          s.changeState(flag);
        } else { // It is a boundary
          s.changeState(true);
        }
      } else if (o2.getClass() == Sensor.class) {
        Sensor s = (Sensor) o2;
        if (o1.getClass() == Car.class) {
          Car c = (Car) o1;
          boolean flag = true;
          print("SENSOR ID: " + str(s.id) + " CAR ID: " + str(c.id) + "\n");
          if (s.id == c.id) {
            flag = false;
            cp.setEnabled(false);
          }
          s.changeState(flag);
        } else { // It is a boundary
          s.changeState(true);
        }
      }
    }
  }

  void endContact(Contact cp) {
    //print("no collision\n");
    Fixture f1 = cp.getFixtureA();
    Fixture f2 = cp.getFixtureB();

    Body b1 = f1.getBody();
    Body b2 = f2.getBody();

    Object o1 = b1.getUserData();
    Object o2 = b2.getUserData();

    print("END CONTACT: \n");
    print(o1.getClass());
    print("\n");
    print(o2.getClass());
    print("\n");

    if (o1.getClass() == Sensor.class || o2.getClass() == Sensor.class ) {
      print("Collision b/w Sensor and Object ended\n");
      if (o1.getClass() == Sensor.class) {
        Sensor s = (Sensor) o1;
        s.changeState(false);
        print("state changed\n");
      } else if (o2.getClass() == Sensor.class) {
        Sensor s = (Sensor) o2;
        s.changeState(false);
        print("state changed\n");
      }
    }
  }

这是我的传感器类:

class Sensor {

  // Variables to keep track of
  Body body;
  int state;
  float id; 
  float x, y, w, h, angle_offset;

  Sensor(float x_, float y_, float w_, float h_, float a_, float id_) {
    /*
      Sensor(float x_, y_, w_, h_, a_, id_) - Sensor constructor
      float x, y - position of Sensor (and corresponding Car)
      float w, h - dimensions of the Sensor
      float a - angle relative to the car
      float id - ID# shared with its corresponding car
    */
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    state = 0;
    id = id_;
    angle_offset = a_;
    makeBody();
  }

  void makeBody() {
    /*
      void makeBody() - define and create body
    */

    BodyDef bd = new BodyDef();
    bd.position.set(box2d.coordPixelsToWorld(x, y));
    bd.type = BodyType.DYNAMIC;
    bd.setAngle(angle_offset);


    body = box2d.createBody(bd);

    PolygonShape rect = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w/2);
    float box2dH = box2d.scalarPixelsToWorld(h/2);
    Vec2 origin = new Vec2(0, -box2dH/2);
    rect.setAsBox(box2dW, box2dH, origin, 0);

    FixtureDef fd = new FixtureDef();
    fd.isSensor = true;
    fd.shape = rect;
    fd.friction = 0;
    fd.restitution = 0;
    body.createFixture(fd);
    body.setUserData(this);
  }

  void changeState(boolean flag){
    /*
      void changeState(boolean flag) - switches the Sensor on/off when contact has begun/ended
      boolean flag - on/off
    */

    if (flag){
      //print("collided\n");
      state = 1;
    } else{
      //print("no collision\n");
      state = 0;
    }
  }

  void update(Vec2 carPixelPos_, float angle){
    /*
      void update(Vec2 carPizelPos, float angle) - update the position of Sensor
      Vec2 carPixelPos - position of Car on the screen in pixels
      float angle - angle of the Car (in Processing CW direction is positive)
    */

    Vec2 pos = box2d.coordPixelsToWorld(carPixelPos_);
    body.setTransform(pos, angle + angle_offset);
  }

  void render() {
    /*
      void render() - display the Sensor
    */

    stroke(255, 255, 255, 50);
    Vec2 pos = box2d.getBodyPixelCoord(body);
    float angle = body.getAngle();
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(-angle +PI/2); //front facing Sensor should be first
    rectMode(CORNER);
    rect(0, 0, w, h);
    popMatrix();
  }
}

这是我的Car类:

class Boundary{
  // Variables to keep track of
  Body body;
  float x, y, w, h;

  Boundary(float x_, float y_, float w_, float h_){
    /*
      Boundary(float x_, y_, w_, h_) - Boundary Constructor
      float x_, y_ - position in pixel coord
      float w_, y_ - width and height
    */
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    makeBody();
  }

  void makeBody(){
    /*
      void makeBody() - define and create body
    */

    BodyDef bd = new BodyDef();
    bd.position.set(box2d.coordPixelsToWorld(x,y));
    bd.type = BodyType.DYNAMIC; // It should be STATIC but then the sensors wouldn't collide with it

    body = box2d.createBody(bd);

    PolygonShape rect = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w/2);
    float box2dH = box2d.scalarPixelsToWorld(h/2);
    rect.setAsBox(box2dW, box2dH);

    FixtureDef fd = new FixtureDef();
    fd.shape = rect;
    fd.friction = 0;
    fd.restitution = 0;
    fd.density = 1000000000000.0; // High mass to make it approx STATIC
    body.createFixture(fd);
    body.setUserData(this);
  }

  void render(){
    /*
      void render() - display the Boundary
    */
    Vec2 pos = box2d.getBodyPixelCoord(body);
    fill(255);
    stroke(255);
    pushMatrix();
    translate(pos.x, pos.y);
    rectMode(CENTER);
    rect(0,0,w,h);
    popMatrix();
  }


}

我没有包含我的神经网络类和矩阵类,因为我认为没有必要。 The Car isn't colliding with anything but the Sensors are still active. I think endContact() isn't activating

0 个答案:

没有答案