/*
* File name: DomPhysAgent.java (package eas.simulation.users.Dominik.rocket)
* Author(s): Dominik
* Java version: 6.0
* Generation date: 12.04.2011 (12:24:29)
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.users.students.dominikColling.rocket;
import java.awt.Color;
import java.util.List;
import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.simulation.Wink;
import eas.simulation.agent.Evolvable;
import eas.simulation.brain.BrainControlled;
import eas.simulation.spatial.sim2D.physicalSimulation.physicsEngine.net.phys2d.math.ROVector2f;
import eas.simulation.spatial.sim2D.physicalSimulation.physicsEngine.net.phys2d.math.Vector2f;
import eas.simulation.spatial.sim2D.physicalSimulation.standardAgents.PhysicsAgent2D;
import eas.simulation.spatial.sim2D.physicalSimulation.standardEnvironments.PhysicsEnvironment2D;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.startSetup.parameterDatatypes.Datatypes;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysAntrieb;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysDrehung;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysSensorImpSeite;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysSensorImpVorne;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysSensorKraftSeite;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysSensorKraftVorne;
import eas.users.students.dominikColling.rocket.SensAct.DomPhysSensorRot;
import eas.users.students.dominikColling.rocket.brain.DomPhysNeuroBrain;
/**
* @author Dominik Colling
*
*/
public class DomPhysAgent extends PhysicsAgent2D<PhysicsEnvironment2D<?>>
implements BrainControlled<DomPhysNeuroBrain>, Evolvable<PhysicsAgent2D<?>> {
/**
*
*/
private static final long serialVersionUID = -5398475994837366596L;
private DomPhysNeuroBrain hirn;
private Polygon2D shape;
Color farbe = Color.yellow;
private double[] maxSensorWerte;
private double[] maxActuatorWerte;
private double[] sensorWerte;
private double[] actuatorWerte;
/** Maximal erreichter Abstand zum Mond */
private double maxAbstand;
/** Minimal erreichter Abstand zum Mond */
private double minAbstand;
/** Fitnesswert des Agenten */
private int fitness;
/** Tick, in dem der Agent geboren wurde */
private int geburt;
/** Mindestanzahl an Ticks, die der Agent ueberlebt */
private int mindLebenszeit;
/** wahr, wenn der Agent nicht gestorben ist */
private boolean lebend;
/* gibt Groesse an: 0 klein 1 normal 2 groß
public int groesse;*/
/** Maximal erlaubter Abstand zum Mond */
public static double MAX_ORBIT_ABSTAND = 200;
/** Maximal erlaubte Rotationsgeschwindigkeit */
public static double MAX_ROTATION_SPEED = 10;
/**
* @param id
* @param environment
* @param name
* @param masse
* @param geboren
*/
public DomPhysAgent(int id, PhysicsEnvironment2D<?> environment, String name, float masse, ParCollection params, int geburt) {
super(id, environment, name, masse, params);
this.geburt = geburt;
this.lebend = true;
maxAbstand = Double.MIN_VALUE;
minAbstand = Double.MAX_VALUE;
this.addSensor(new DomPhysSensorImpVorne());
this.addSensor(new DomPhysSensorImpSeite());
this.addSensor(new DomPhysSensorRot());
this.addSensor(new DomPhysSensorKraftVorne());
this.addSensor(new DomPhysSensorKraftSeite());
this.addActuator(new DomPhysAntrieb());
this.addActuator(new DomPhysDrehung());
this.sensorWerte = new double[this.getSensors().size()];
//this.maxSensorWerte = new double[this.getSensors().size()];
this.actuatorWerte= new double[this.getActuators().size()];
this.maxActuatorWerte = new double[this.getActuators().size()];
this.maxActuatorWerte[0] = params.getParValueDouble("maxAntrieb");
this.maxActuatorWerte[1] = params.getParValueDouble("maxDrehung");
this.mindLebenszeit = params.getParValueInt("mindLebenszeit");
//this.groesse = params.getParWertInt("groesse");
}
/* Form des Körpers */
@Override
public synchronized Polygon2D getAgentShape() {
if (shape == null) {
/*shape = new Polygon2D();
shape.add(new Vector2D(-2.5, -2.5));
shape.add(new Vector2D(2.5, -2.5));
shape.add(new Vector2D(0, 5));
//normalerweise
/*shape = new Polygon2D();
shape.add(new Vector2D(-0.00001, -0.00001));
shape.add(new Vector2D(0.00001, -0.00001));
shape.add(new Vector2D(0, 0.00001)); */
shape = new Polygon2D();
shape.add(new Vector2D(-0.25, -0.25));
shape.add(new Vector2D(0.25, -0.25));
shape.add(new Vector2D(0, 0.5));
/*if(groesse == 2){
shape = new Polygon2D();
shape.add(new Vector2D(-2.5, -2.5));
shape.add(new Vector2D(2.5, -2.5));
shape.add(new Vector2D(0, 5));
}
/*shape.add(new Vector2D(-1, -1));
shape.add(new Vector2D(-1, 0.5));
shape.add(new Vector2D(-0.5, 1));;
shape.add(new Vector2D(0.5, 1));
shape.add(new Vector2D(1, 0.5));
shape.add(new Vector2D(1, -1)); */
}
return shape;
}
public void setAgentShapeBIG() {
shape = new Polygon2D();
shape.add(new Vector2D(-2.5, -2.5));
shape.add(new Vector2D(2.5, -2.5));
shape.add(new Vector2D(0, 5));
}
/* Ausgabe der Farbe des Körpers */
@Override
public Color getAgentColor() {
return farbe;
}
@Override
public void implantBrain(DomPhysNeuroBrain setBrain) {
hirn = setBrain;
}
@Override
public DomPhysNeuroBrain getBrain() {
return hirn;
}
public void setMaxSensorWerte(double[] maxSensorWerte) {
this.maxSensorWerte = maxSensorWerte;
}
public double[] getMaxSensorWerte() {
return maxSensorWerte;
}
public void setSensorWerte(double[] sensorWerte) {
this.sensorWerte = sensorWerte;
}
public double[] getSensorWerte() {
return sensorWerte;
}
public void setActuatorWerte(double[] actuatorWerte) {
this.actuatorWerte = actuatorWerte;
}
public double[] getActuatorWerte() {
return actuatorWerte;
}
public void setMaxActuatorWerte(double[] maxActuatorWerte) {
this.maxActuatorWerte = maxActuatorWerte;
}
public double[] getMaxActuatorWerte() {
return maxActuatorWerte;
}
public int getMindLebenszeit() {
return mindLebenszeit;
}
@Override
public List<SingleParameter> getParameters() {
List<SingleParameter> list = super.getParameters();
//list.add(new SingleParameter("maxAntrieb", Datatypes.DOUBLE, 80.0, "maximale Antriebsstärke", ""+ this.id()));
list.add(new SingleParameter("maxAntrieb", Datatypes.DOUBLE, 80.0, "maximale Antriebsstärke", "AGENT"));
list.add(new SingleParameter("maxDrehung", Datatypes.DOUBLE, 0.3, "maximale Drehbeschleunigung", "AGENT"));
list.add(new SingleParameter("mindLebenszeit", Datatypes.INTEGER, 20, "Lebenszeit bevor Evaluation beginnt", "AGENT"));
list.add(new SingleParameter("groesse", Datatypes.INTEGER, 0, "Groesse 0 klein 1 normal 2 gross", "AGENT"));
return list;
}
public double getMinAbstand() {
return this.minAbstand;
}
public double getMaxAbstand() {
return this.maxAbstand;
}
@Override
public double getEvaluation() {
return fitness;
}
public int getEvaluationInt() {
return fitness;
}
@Override
public Evolvable<PhysicsAgent2D<?>> createMutatedOffspring() {
//this.getBrain().mutate(null);
return this;
}
@Override
public List<Evolvable<PhysicsAgent2D<?>>> createMutatedManyOffspring() {
return null;
}
@Override
public Evolvable<PhysicsAgent2D<?>> createOffspring(
List<Evolvable<PhysicsAgent2D<?>>> mates) {
return null;
}
@Override
public List<Evolvable<PhysicsAgent2D<?>>> createManyOffspring(
List<Evolvable<PhysicsAgent2D<?>>> mates) {
return null;
}
@Override
public PhysicsAgent2D<?> getThisEvolvableAgent() {
return null;
}
public void evaluate (Wink simZyk) {
this.fitness = 0;
int lebenszeit = (int) (simZyk.getCurrentTime() - this.geburt);
if (lebenszeit > mindLebenszeit ) {
DomPhysMond mond = (DomPhysMond) this.getEnvironment().getAgent(0);
double radius = mond.getRadius();
Vector2D posMond = this.getEnvironment().getAgentPosition(0);
Vector2D pos = this.getEnvironment().getAgentPosition(this.getID());
//float rot = this.getEnvironment().getAgent(this.getID()).getRotation();
/* Berechnung des Abstands zwischen Körper und Mond */
double xAbstand = posMond.x- pos.x;
double yAbstand = posMond.y- pos.y;
double abstand = java.lang.Math.sqrt(xAbstand*xAbstand + yAbstand*yAbstand) - radius;
if (abstand > maxAbstand) {
maxAbstand = abstand;
}
if (abstand < minAbstand) {
minAbstand = abstand;
}
/* wenn abgestürzt oder nach mindLebenszeit Runden noch nicht gestartet dann tot */
if (minAbstand < 2) {
lebend = false;
//System.out.println ("ZU NAH: " + abstand);
this.farbe = Color.red;
return;
//System.out.println("ID: " + this.getID() + " ABSTAND: " + abstand + )
}
/* wenn äußeren Ring passiert dann tot */
if (maxAbstand > MAX_ORBIT_ABSTAND) {
//System.out.println ("ZU WEIT: " + abstand);
lebend = false;
return;
}
/* wenn Rotation zu schnell */
if (Math.abs((Double) this.sense(2)) > MAX_ROTATION_SPEED) {
//System.out.println (" - ZU SCHNELL: " + rot);
lebend = false;
return;
}
// normalerweise
this.fitness = lebenszeit;
// für Versuch 110707
/*
double geschwindigkeit = Math.sqrt(this.getVelocity().getX()*this.getVelocity().getX()+this.getVelocity().getY()*this.getVelocity().getY());
double perfFlughoehe = (100 - Math.abs(100 - abstand)) / 100;
this.fitness = this.fitness + Math.round((float)(geschwindigkeit * perfFlughoehe));
*/
}
}
public boolean getAmLeben() {
return this.lebend;
}
public void setAmLeben(boolean lebend) {
this.lebend = lebend;
}
public int getGeburt() {
return this.geburt;
}
public void setGeburt(int currentTime) {
this.geburt= currentTime;
}
public void reset(int runde) {
this.lebend = true;
this.farbe = Color.yellow;
this.actuatorWerte[0] = 0;
this.actuatorWerte[1] = 0;
this.maxAbstand = Double.MIN_VALUE;
this.minAbstand = Double.MAX_VALUE;
this.fitness = 0;
this.geburt = runde;
ROVector2f kraft = this.getForce();
float x = kraft.getX() * -1;
float y = kraft.getY() * -1;
this.addForce(new Vector2f(x,y));
ROVector2f geschwindigkeit = this.getVelocity();
float x2 = geschwindigkeit.getX() * -1;
float y2 = geschwindigkeit.getY() * -1;
this.adjustVelocity(new Vector2f(x2,y2));
float winkelgeschw = this.getAngularVelocity();
this.adjustAngularVelocity(-1 * winkelgeschw);
//this.setRotation(-1 * this.getRotation());
this.setRotation(0);
}
}