We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, i'm working on the next phase of my project (https://forum.processing.org/two/discussion/23539/genetic-algorithm-driven-ecosystem), i've managed to implement a neural network for the creatures (as soon as i finish commenting it i'll share the whole code) and now i'm trying to improve the creatures perception of the environment. right now they just perceive the environment by triangulating the distance of the closest food source (distance from body, distance from antenna sx and antenna dx).
i've made a simple code to explain what i'd like to achieve:
you can move the ship with WASD, the ship has 5 eyes represented by lines, length of the lines represent how far it can sees. there are random obstacles of random dimension and random color.
i've made a function (collision) to calculate the minimum distance from an obstacle (ship radius/2 + obstacle radius/2) and to check if we are exceeding those values (the ship turns red if we touch something).
now, first of all i'd like the ship to be unable to update its position if that means exceeding the minimum distance from something (ie. ship gets stuck even if slightly touching something diagonally).
and the most important thing: the lines representing the eyes should modify their length if they touch something, that way i can calculate objects distance and position by simply looking at the various lines sizes. Optional the line should be able to get the rgb color of the object they are "seeing".
I know i'm asking a lot, but bare with me and i'll present you a fully functional, easy to use (sort of), Neural Network to play with :D
Ship myShip;
float obsNum;
ArrayList<Obstacle> obstacles;
boolean [] keys = new boolean[128];
void setup() {
size(600, 600);
smooth();
myShip = new Ship();
obsNum = 5;
obstacles = new ArrayList<Obstacle>();
for (int i = 0; i < obsNum; i++){
obstacles.add(new Obstacle(random(width), random(height)));
}
}
void draw() {
background(255);
myShip.run();
for (int i = 0; i < obstacles.size(); i++){
Obstacle o = obstacles.get(i);
o.display();
}
}
void keyPressed() { //allows to move while rotate
keys[key] = true;
}
void keyReleased() {
keys[key] = false;
}
class Ship {
PVector pos, vel; // position and velocity
int speed; // constant speed
float theta; // angle of rotation
float rotS; // rotation speed
float sight; //sight distance
float sightSpread; //distance between eyes
float radius; //radius of the ship
float col; //color of the ship
Ship() {
speed = 5;
rotS = 5;
theta = 0; // must be initialized at 0°
sight = 200;
sightSpread = 30;
radius = 50;
col = 0;
pos = new PVector(width/2, height/2);
vel = new PVector();
}
void run() { //generic function container
move();
collision();
display();
}
void move() {
vel.x = speed*cos(theta); //this modify vel.x and vel.y
vel.y = speed*sin(theta); //based ont the actual angle
if (keys['w']) //move forward
pos.add(vel);
if (keys['s']) //move backward half speed
pos.sub(vel.div(2));
if (keys['d']) //rotate right
theta += radians(rotS);
if (keys['a']) //rotate left
theta -= radians(rotS);
}
void collision() {
int touchedObs = 0;
for (int i=0; i < obstacles.size(); i++) { //check obstacles array
float minDist = (radius/2) + (obstacles.get(i).radius/2); //calculate minimumdistance based on ship radius and obstacle radius
PVector obsPos = obstacles.get(i).position.copy();
float d = PVector.dist(pos, obsPos);
if (d < minDist) {
touchedObs ++;
}
}
if (touchedObs > 0) col = 255;
else col = 0;
}
void display() {
pos.x=constrain(pos.x, 25, width-25); // limit position vector to screen size
pos.y=constrain(pos.y, 25, height-25);
pushMatrix();
translate(pos.x, pos.y); //translate origin to allow rotation
rotate(theta);
stroke(0); //lines of sight, Player MUST face east if theta=0
line(0, 0, sight, -sightSpread*2); //leftmost eye
line(0, 0, sight, -sightSpread); //left eye
line(0, 0, sight, 0); //central eye
line(0, 0, sight, sightSpread); //right eye
line(0, 0, sight, sightSpread*2); //rightmost eye
fill(col, 0, 0);
ellipseMode(CENTER);
ellipse(0, 0, radius, radius); //player body
popMatrix();
}
}
class Obstacle{
PVector position;
float radius;
color col;
Obstacle(float x,float y){
radius = random(20, 50);
position= new PVector(x,y);
col = color(random(255), random(255), random(255));
}
void display(){
stroke(0);
fill(col);
ellipseMode(CENTER);
ellipse(position.x,position.y,radius,radius);
}
}
Answers
I think I understand.
Are you sure that you want the eyes to be represented by lines -- not by an arc wedge?
In any case, what are obstacles -- are they circles, rectangles, polygons, or something else? Your demo shows them as ellipses -- is that all they will be?
@jeremydouglass that's a good question, how would you approach the problem with arc wedge?
the problem is related to the architecture of the project. i'll try to explain: every neuron of the neural net can take a single input each frame, so if i use a "cone of view" i have no idea about how to feed informations to the net about "what's inside the cone". with the line method i will get 5 separate distance (thus the net can understand both distance AND direction) by adding color detection the plan is: detect color of the touched objects, sum up the rgb components of their colors, feed the 3 summed components as inputs to understand "what am i seeing" (3 rgb neurons for the left eye and 3 for the right one).
that was my plan, but if any of you guys have a different approach or idea, you're welcome.
about the "will there be just ellipses colliding?" question: i don't know, but right now it's not that important, i can easily use ellipse only if that will make things easier
i solved the body collision issue in a pretty simple way: just added a "stucked" boolean, and a nexPosition vector to forecast what my next position will be. check if my next position will exceed minimum distance from obstacles, if not, allow movement, otherwise, deny it.
here's an updated ship class, if the ship is red at the beginning of the simulation please restart it (you spawned inside an obstacle so no movement is allowed, but it's irrelevant right now so i don't need to fix it)
now... onto the eye problem
for those of you interested in the solution, here's the final code, i solved it myself: move the ship with WAD (forward and rotation) obstacle collision (the ship will turn red if next move will collide with an obstacle) if you spawn inside an obstacle, movement that will increase distance will be allowed (so you can exit the obstacle but you cannot get inside). the ship has 6 lines of sight, all of them perceive both distance of the closest object and its color (lines change color based on detection), the 2 eyes just make a sum of the perceived colors and returns a summed color.