Package eas.users.lukas.schleimpilze

Source Code of eas.users.lukas.schleimpilze.Schleim

/*
* Datei:            Schleim.java
* Autor(en):        Lukas König
* Java-Version:     6.0
* Erstellt:         08.03.2010
*
* (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.lukas.schleimpilze;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import eas.math.geometry.Vector2D;
import eas.miscellaneous.StaticMethods;
import eas.plugins.PluginProperties;
import eas.plugins.standard.eaPlugin.StandardPluginForEA;
import eas.plugins.standard.eaPlugin.xmlRecording.XMLAufnSpeichern;
import eas.plugins.standard.eaPlugin.xmlRecording.XMLAufnahmePlugin;
import eas.plugins.standard.visualization.AllroundVideoPlugin;
import eas.simulation.Wink;
import eas.simulation.agent.GenericSensor;
import eas.simulation.event.EASEvent;
import eas.simulation.spatial.sim2D.marbSimulation.EnvironmentEA;
import eas.simulation.spatial.sim2D.marbSimulation.RobEA;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.startSetup.parameterDatatypes.Datatypes;

/**
* @author Lukas König
*/
@PluginProperties(pluginIsHidden = false)
public class Schleim extends StandardPluginForEA {

    private static final long serialVersionUID = -7744221558554091285L;

    /**
     * Schleimattribut.
     */
    private static final String SLIME_PROZ_P_ATT = "slimeProzP";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_SA_ATT = "slimeSA";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_SW_ATT = "slimeSW";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_SO_ATT = "slimeSO";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_SS_ATT = "slimeSS";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_DEP_T_ATT = "slimeDepT";

    /**
     * Schleimattribut.
     */
    private static final String SLIME_RA_ATT = "slimeRA";

    /**
     * Standardwert aus Paper in Prozent der Bildgröße.
     */
    private static final double SLIME_PROZ_P = 5;

    /**
     * Standardwert aus Paper in Grad.
     */
    private static final double SLIME_SA = 15;

    /**
     * Standardwert aus Paper in Pixel.
     */
    private static final double SLIME_SW = 1;

    /**
     * Standardwert aus Paper in Pixel.
     */
    private static final double SLIME_SO = 15;

    /**
     * Geratener Wert.
     */
    private static final double SLIME_SS = 1;

    /**
     * Standardwert aus Paper (konstant).
     */
    private static final double SLIME_DEP_T = 5;

    /**
     * Standardwert aus Paper in Grad.
     */
    private static final double SLIME_RA = 45;

    /**
     * Spuren der Roboter.
     */
    private double[][] trailFeld;

    /**
     * Der Parametersatz.
     */
    private ParCollection pars;

    /**
     * Der Zufallsgenerator.
     */
    private Random rand;

    /**
     * Ausgleich der Partikelgröße, da ein Roboter mehr als ein Pixel einnimmt.
     */
    final private double partikelGrAusgl = 0.5;

    /**
     * Vor Gesamt-Simulation.
     *
     * @param env
     *            Die Umgebung.
     * @param params
     *            der Parametersatz.
     */
    @Override
    public void runBeforeSimulation(final EnvironmentEA env, final ParCollection params) {
        EnvironmentEA umg = env;

        this.pars = params;
        this.rand = new Random(params.getSeed());
        this.trailFeld = new double[umg.getFeld().length]
                                   [umg.getFeld()[0].length];
        this.paramKorrigieren();

        ArrayList<RobEA> zuloeschen = new ArrayList<RobEA>(umg.getRobAgents()
                .size());
        int schleimanz;

        // Roboter löschen.
        zuloeschen.addAll(umg.getRobAgents());
        for (RobEA r : zuloeschen) {
            umg.removeAgent(r);
        }

        // Schleim hinzufügen.
        schleimanz = (int) (umg.getFeld().length
                * umg.getFeld()[0].length
                * (Double) this.pars
                        .getParValue(Schleim.SLIME_PROZ_P_ATT) / 100);

        for (int i = 0; i < schleimanz; i++) {
            RobEA r = new RobEA(i, umg, this.pars, this.rand);
            umg.hinzuRobotRand(r);
        }

        XMLAufnahmePlugin aufnahmePlug = (XMLAufnahmePlugin) umg
                .getPluginObject(new XMLAufnahmePlugin().id());

        if (aufnahmePlug != null) {
            aufnahmePlug.setAufnahme(
                    new XMLAufnSpeichern(this.pars, schleimanz, umg),
                    this.pars);
        }

        StaticMethods.log(StaticMethods.LOG_INFO,
                "Schleimplugin - Geladene Roboter durch Schleim ersetzt.",
                this.pars);
        StaticMethods.log(StaticMethods.LOG_INFO,
                "Schleimplugin - Schleimpartikel in Simulation: " + schleimanz,
                this.pars);
    }

    /**
     * Vor Umschalten.
     *
     * @param env
     *            Die Umgebung.
     * @param simZyk
     *            Der aktuelle Simulationszyklus.
     * @param params
     *            der Parametersatz.
     */
    @Override
    public void runDuringSimulation(
            final EnvironmentEA env,
            final Wink simZyk,
            final ParCollection params) {
        EnvironmentEA umg = env;

        // Aktuatorik:
        for (RobEA r : umg.getRobAgents()) {
            if (this.vorwaerts(r)) {
                this.depositTrail(r.getPosition());
            } else {
                r.setAngle(this.rand.nextDouble() * 360);
            }
        }

        // Sensorik:
        for (RobEA r : umg.getRobAgents()) {
            double sensF = this.sensWert(r, "F");
            double sensFL = this.sensWert(r, "FL");
            double sensFR = this.sensWert(r, "FR");

            if (sensF > sensFL && sensF > sensFR) {

            } else if (sensF < sensFL && sensF < sensFR) {
                boolean left = this.rand.nextBoolean();
                if (left) {
                    r.setAngle(r.getAngle()
                            + (Double) this.pars
                                    .getParValue(Schleim.SLIME_RA_ATT));
                } else {
                    r.setAngle(r.getAngle()
                            - (Double) this.pars
                                    .getParValue(Schleim.SLIME_RA_ATT));
                }
            } else if (sensFL < sensFR) {
                r.setAngle(r.getAngle()
                        - (Double) this.pars
                                .getParValue(Schleim.SLIME_RA_ATT));
            } else if (sensFL > sensFR) {
                r.setAngle(r.getAngle()
                        + (Double) this.pars
                                .getParValue(Schleim.SLIME_RA_ATT));
            }
        }

        // Diffuse trail / store picture:
        this.diffuseTrail();
       
        AllroundVideoPlugin video
            = (AllroundVideoPlugin) umg.getPluginObject(new AllroundVideoPlugin().id());
        if (video != null) {
            video.setDarBild(this.erzeugeFeldBild());
        }
    }

    /**
     * Umstellen der Parameter auf Schleim-Parameter.
     */
    @SuppressWarnings("all")
    private void paramKorrigieren() {
        this.pars.setParValue(eas.statistics.ConstantsStatistics.VERZERR_ATTR, this.partikelGrAusgl
                / eas.simulation.ConstantsSimulation.ROB_AUSDEHNUNG_X);
        if (eas.simulation.ConstantsSimulation.ROB_AUSDEHNUNG_X
                != eas.simulation.ConstantsSimulation.ROB_AUSDEHNUNG_Y) {
            throw new RuntimeException("Roboter müssen quadratisch sein.");
        }
        this.pars.setParValue(AllroundVideoPlugin.ZUSATZ_BILD_PAR, "extern");
    }

    /**
     * Bewegt einen Roboter um SS vorw�rts, falls dies möglich ist.
     *
     * @param r
     *            Der zu bewegende Roboter.
     *
     * @return On der Roboter bewegt wurde.
     */
    private boolean vorwaerts(final RobEA r) {
        boolean versetzt;

        versetzt = r.setPos(r.getPosition().x
                + (Double) this.pars.getParValue(Schleim.SLIME_SS_ATT)
                * r.getBlickrichtung().x / this.partikelGrAusgl, r
                .getPosition().y
                + (Double) this.pars.getParValue(Schleim.SLIME_SS_ATT)
                * r.getBlickrichtung().y / this.partikelGrAusgl, false);

        return versetzt;
    }

    /**
     * @param x
     *            Koordinate.
     * @param y
     *            Koordinate.
     *
     * @return Der Trailwert an dieser Koordinate, 0, falls die Koordinate
     *         au�erhalb derGültigkeit ist.
     */
    private double getTrailSoft(final int x, final int y) {
        if (x >= 0 && this.trailFeld.length > x && y >= 0
                && this.trailFeld[0].length > y) {
            return this.trailFeld[x][y];
        } else {
            return 0;
        }
    }

    /**
     * @param x
     *            Koordinate.
     * @param y
     *            Koordinate.
     * @param wert
     *            Der Wert, auf den das Feld gesetzt werden soll.
     *
     * @return Ob etwas verändert wurde.
     */
    private boolean setTrailSoft(final int x, final int y, final double wert) {
        if (x >= 0 && this.trailFeld.length > x && y >= 0
                && this.trailFeld[0].length > y) {
            this.trailFeld[x][y] = wert;
            return true;
        }

        return false;
    }

    /**
     * Verteilt die Schleimspur.
     */
    private void diffuseTrail() {
        double wert;

        for (int x = 0; x < this.trailFeld.length; x++) {
            for (int y = 0; y < this.trailFeld[0].length; y++) {
                wert = this.getTrailSoft(x, y);
                wert += this.getTrailSoft(x - 1, y);
                wert += this.getTrailSoft(x + 1, y);
                wert += this.getTrailSoft(x, y);
                wert += this.getTrailSoft(x - 1, y - 1);
                wert += this.getTrailSoft(x + 1, y - 1);
                wert += this.getTrailSoft(x, y);
                wert += this.getTrailSoft(x - 1, y + 1);
                wert += this.getTrailSoft(x + 1, y + 1);
                this.setTrailSoft(x, y, wert / 9.1);
            }
        }
    }

    /**
     * Gibt den Wert des angegebenen Sensors des betreffenden Roboters zurück.
     * Sensorennamen: "FL", "F", "FR".
     *
     * @param schleim
     *            Der Roboter, dessen Sensor zur�chgegeben werden soll.
     *
     * @param sensor
     *            Der gew�nschte Sensorname des Roboters.
     *
     * @return Der Wert des entsprechenden Sensors, -1, falls nicht berechenbar.
     */
    private double sensWert(final RobEA schleim, final String sensor) {
        Vector2D schleimVek = new Vector2D(schleim.getPosition());
        Vector2D sensRicht = new Vector2D(schleim.getBlickrichtung());

        if (sensor.equalsIgnoreCase("F")) {
            sensRicht.setLength((Double) this.pars
                    .getParValue(Schleim.SLIME_SO_ATT));
            schleimVek.translate(sensRicht);
            return this.getTrailSoft((int) schleimVek.x, (int) schleimVek.y);
        } else if (sensor.equalsIgnoreCase("FR")) {
            sensRicht.rotate(Vector2D.NULL_VECTOR, -(Double) this.pars
                    .getParValue(Schleim.SLIME_RA_ATT)
                    / 180 * Math.PI);
            sensRicht.setLength((Double) this.pars
                    .getParValue(Schleim.SLIME_SO_ATT));
            schleimVek.translate(sensRicht);
            return this.getTrailSoft((int) schleimVek.x, (int) schleimVek.y);
        } else if (sensor.equalsIgnoreCase("FR")) {
            sensRicht.rotate(Vector2D.NULL_VECTOR, (Double) this.pars
                    .getParValue(Schleim.SLIME_RA_ATT)
                    / 180 * Math.PI);
            sensRicht.setLength((Double) this.pars
                    .getParValue(Schleim.SLIME_SO_ATT));
            schleimVek.translate(sensRicht);
            return this.getTrailSoft((int) schleimVek.x, (int) schleimVek.y);
        }

        return -1;
    }

    /**
     * @param position
     *            Die Position, auf der die Spur hinterlegt werden soll.
     */
    private void depositTrail(final Vector2D position) {
        this.trailFeld[(int) position.x][(int) position.y] = (Double) this.pars
                .getParValue(Schleim.SLIME_DEP_T_ATT);
    }

    /**
     * Erzeugt eine Bild-Darstellung des Trail-Feldes.
     *
     * @return Eine Bild-Darstellung des Trail-Feldes.
     */
    private BufferedImage erzeugeFeldBild() {
        BufferedImage buffImgFeld = new BufferedImage(this.trailFeld.length,
                this.trailFeld[0].length, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImgFeld.createGraphics();

        // Feld zeichnen.
        for (int i = 0; i < this.trailFeld.length; i++) {
            for (int j = 0; j < this.trailFeld[0].length; j++) {
                g.setColor(new Color(255, 255, Math.max(0,
                        255 - 50 * (int) this.trailFeld[i][j])));
                g.drawLine(i, j, i, j);
            }
        }

        return buffImgFeld;
    }

    /**
     * @return Identifikation des Plugins.
     */
    @Override
    public String id() {
        return "schleimplugin_v1";
    }

    /**
     * Nach Gesamt-Simulation.
     *
     * @param umg
     *            Die Umgebung.
     * @param params
     *            der Parametersatz.
     */
    @Override
    public void runAfterSimulation(final EnvironmentEA umg, final ParCollection params) {

    }

    /**
     * über diese Methode können neue Parameter definiert werden, die nur in
     * diesem PluginGültigkeit haben. Wichtig ist zu gewährleisten, dass keine
     * gleichnamigen Parameter in verschiedenen Plugins existieren.
     *
     * @return Die Liste von Parametern.
     */
    @Override
    public List<SingleParameter> getParameters() {
        ArrayList<SingleParameter> arr = new ArrayList<SingleParameter>(7);

        arr.add(new SingleParameter(Schleim.SLIME_PROZ_P_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_PROZ_P,
                "Schleimparameter: Prozentualer Anteil der Population an "
                        + "der Größe des Feldes.", "SCHLEIM"));
        arr.add(new SingleParameter(Schleim.SLIME_SA_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_SA,
                "Schleimparameter: Sensorenwinkel in Blickrichtung. ",
                "SCHLEIM"));
        arr.add(new SingleParameter(Schleim.SLIME_SW_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_SW, "Schleimparameter: Sensorenbreite (Width).",
                "SCHLEIM"));
        arr
                .add(new SingleParameter(Schleim.SLIME_SO_ATT, Datatypes.DOUBLE,
                        Schleim.SLIME_SO, "Schleimparameter: Sensor-Offset.",
                        "SCHLEIM"));
        arr.add(new SingleParameter(Schleim.SLIME_SS_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_SS, "Schleimparameter: Schrittweite (Step size)."
                        + "der Größe des Feldes.", "SCHLEIM"));
        arr.add(new SingleParameter(Schleim.SLIME_DEP_T_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_DEP_T, "Schleimparameter: Depositionsrate.",
                "SCHLEIM"));
        arr.add(new SingleParameter(Schleim.SLIME_RA_ATT, Datatypes.DOUBLE,
                Schleim.SLIME_RA,
                "Schleimparameter: Agenten-Rotationswinkel (Rotation angle).",
                "SCHLEIM"));

        return arr;
    }

    /**
     * über diese Methode können generische Sensoren definiert werden,
     * die als Liste von Sensoren zurückgegeben werden müssen. Die Liste kann
     * <code>null</code> sein.
     *
     * @return  Die Liste generischer Sensoren.
     */
    @Override
    public List<GenericSensor<?, ?, ?>> getGenericSensors() {
        return null;
    }
   
    /**
     * über diese Methode können abhängigkeiten zwischen Plugins definiert
     * werden. Die hier zurückgegebene Liste sollte die IDs aller Plugins
     * enthalten, die von diesem Plugin benötigt werden und ohne die kein
     * Start der Simulation möglich sein soll.
     *
     * @return Die Liste benötigter Plugins. Diese Liste kann <code>null</code>
     *         sein, wenn keine abhängigkeiten definiert werden sollen.
     */
    @Override
    public List<String> getRequiredPlugins() {
        return null;
    }

    @Override
    public void handleEvent(
            final EASEvent e,
            final EnvironmentEA env,
            final Wink lastTick,
            final ParCollection params) {
       
    }
}
TOP

Related Classes of eas.users.lukas.schleimpilze.Schleim

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.