我正在尝试制作一个神经进化计划,以制造可以避开其他汽车并停放自己的汽车。我已经能够实现神经网络,并且需要数学来支持它。每辆车都有一个神经网络,可以接收输入(来自传感器)并产生输出(转向和油门)。一辆汽车从其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