Package eas.users.ocScenarios.traffic

Source Code of eas.users.ocScenarios.traffic.CarAgent

/*
* File name:        CarAgent.java (package eas.users.ocScenario.cars)
* Author(s):        Lukas König
* Java version:     7.0
* Generation date:  09.05.2014 (14:54:18)
*
* (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.ocScenarios.traffic;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.LinkedList;

import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.miscellaneous.StaticMethods;
import eas.plugins.standard.liveInteraction.MethodRunnableProperties;
import eas.plugins.standard.visualization.AllroundVideoPlugin;
import eas.simulation.Wink;
import eas.simulation.agent.GenericSensor;
import eas.simulation.spatial.sim2D.standardAgents.AbstractAgent2D;
import eas.startSetup.ParCollection;
import eas.users.ocScenarios.traffic.strategies.CollisionStrategy;
import eas.users.ocScenarios.traffic.strategies.DrivingStrategy;

/**
* Implementation of a car as an agent in the CarsEnvironment used in the OC
* scenario.
*
* @author Lukas König
*/
public class CarAgent extends AbstractAgent2D<TrafficEnvironment> {

    /**
     * All serializable classes must have this.
     */
    private static final long serialVersionUID = -5355637887498848830L;
   
    /**
     * The driving strategy of this CarAgent, telling which way to turn at a
     * specific time step.
     */
    private DrivingStrategy drivingStrat;
   
    /**
     * The collision strategy of this CarAgent, telling at a specific time step
     * if the agent can occupy fields in its neighborhood as well as what to do
     * if a collision occurrs.
     */
    private CollisionStrategy collStrat;

    /**
     * A list of trace points storing the agent's path.
     */
    private LinkedList<Vector2D> trace = new LinkedList<>();
   
    /**
     * An image of the CarAgent.
     */
    public static final transient BufferedImage CAR_IMG = StaticMethods.loadImage("./sharedDirectory/AgentImages/car.png");
   
    /**
     * Standard constructor.
     *
     * @param id            An arbitrary id for the agent.
     * @param env           The environment of the agent.
     * @param params        The program parameters.
     * @param drivingStrat  The agent's driving strategy.
     * @param collStrat     The agent's collision strategy.
     */
    public CarAgent(
            int id,
            TrafficEnvironment env,
            ParCollection params,
            DrivingStrategy drivingStrat,
            CollisionStrategy collStrat) {
        super(id, env, params);
       
        this.drivingStrat = drivingStrat;
        this.collStrat = collStrat;
       
        /*
         * The following "sensors" are visualized during the simulation to show
         * some information about the street an agent is on. They are not used
         * as actual sensors otherwise in this implementation.
         */
        this.addSensor(new GenericSensor<Float, TrafficEnvironment, CarAgent>() {

            private static final long serialVersionUID = 1554927077206871098L;

            @Override
            public Float sense(TrafficEnvironment env, CarAgent agent) {
                return CarAgent.this.speedMax;
            }

            @Override
            public String id() {
                return "Speed";
            }
        });
       
        this.addSensor(new GenericSensor<Boolean, TrafficEnvironment, CarAgent>() {

            private static final long serialVersionUID = 1567658595447840894L;

            @Override
            public Boolean sense(TrafficEnvironment env, CarAgent agent) {
                return agent.collStrat.canDriveForward(agent);
            }

            @Override
            public String id() {
                return "CanDrv";
            }
        });
       
        this.addSensor(new GenericSensor<Boolean, TrafficEnvironment, CarAgent>() {

            private static final long serialVersionUID = -437857495301670559L;

            @Override
            public Boolean sense(TrafficEnvironment env, CarAgent agent) {
                return agent.isFacingInTrafficFlowDirection();
            }

            @Override
            public String id() {
                return "InFlow";
            }
        });

        this.addSensor(new GenericSensor<String, TrafficEnvironment, CarAgent>() {

            private static final long serialVersionUID = -6425480377355224417L;

            @Override
            public String sense(TrafficEnvironment env, CarAgent agent) {
                Vector2D pos = agent.getAgentPosition();
                int x = (int) pos.x;
                int y = (int) pos.y;
               
                String s = "";
               
                if (env.isLeftLaneNtoS(x, y)) {s += "N";}
                if (env.isRightLaneNtoS(x, y)) {s += "S";}
                if (env.isRightLaneWtoE(x, y)) {s += "E";}
                if (env.isLeftLaneWtoE(x, y)) {s += "W";}
               
                return s;
            }

            @Override
            public String id() {
                return "Street";
            }
        });

        this.randomizeTarget();
    }

    public void turnRight() {
        this.setAgentAngle(this.getAgentAngle() + 90);
    }
   
    public void turnLeft() {
        this.setAgentAngle(this.getAgentAngle() - 90);
    }
   
    /* **********************************************************************
     * The following methods concern the visual appearance of the agent such as
     * its "physical" body shape.
     ************************************************************************/
   
    /**
     * Generates an image of the internal state of an agent.
     * The "MethodRunnableProperties(ignoreMethod=true)" annotation ensures
     * that this method is not shown by the Observer/Controller plugin.
     */
    @Override
    @MethodRunnableProperties(ignoreMethod=true)
    public BufferedImage getInsideView() {
        BufferedImage img = super.getInsideView();
        BufferedImage newImg = new BufferedImage(
                Math.max(img.getWidth() + 100, CAR_IMG.getWidth() + 100),
                img.getHeight() + CAR_IMG.getHeight() + 100, img.getType());
        Graphics2D g = newImg.createGraphics();
       
        g.setColor(Color.white);
        g.fillRect(0, 0, newImg.getWidth(), newImg.getHeight());
        g.drawImage(img, 0, 0, null);
        g.drawImage(CAR_IMG, (img.getWidth() - CAR_IMG.getWidth()) / 2, img.getHeight() + 30, null);
       
        return newImg;
    }
   
    private Polygon2D pol;
    private boolean resetRequested = true;
   
    @Override
    @MethodRunnableProperties(ignoreMethod=true)
    public Color getAgentColor() {
        if (this.isWaiting) {
            return Color.orange;
        }
        return Color.blue;
    }
   
    public boolean isWaiting = false;
   
    private void setAgentSize(double diameter) {
        this.pol = new Polygon2D();
        pol.add(new Vector2D(+0, +diameter - 0.2));
        pol.add(new Vector2D(+diameter / 2, -diameter / 2));
        pol.add(new Vector2D(-diameter / 2, -diameter / 2));
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    @Override
    public synchronized Polygon2D getAgentShape() {
        if (pol == null) {
            this.setAgentSize(0.5);
        }
       
        return pol;
    }
   
    /**
     * The step method of the agent. This method is invoked any time a time
     * step notification is sent by the simulation engine. The standard
     * master scheduler implementation propagates every tick from
     * the master scheduler to the environment step method and the agents' step
     * method's. Using the "requestNotification..." methods of AbstractEnvironment
     * other time steps can be requested.
     *
     * @param simTime  The current time of the notification.
     */
    @Override
    public void step(Wink simTime) {
        super.step(simTime);
       
        if (this.targetLocation.distance(this.getAgentPosition()) < 2) {
            this.randomizeTarget();
            targetCount++;
        }
       
        if (this.resetRequested) {
            this.targetCount = 0;
            this.resetRequested = false;
            this.drivingStrat.reset(this);
           
            this.trace.clear();
            for (int i = 0; i < this.getEnvironment().getNumOfStoredTracePoints(); i++) {
                this.trace.add(new Vector2D(this.getAgentPosition()));
            }
        }

        if (this.drivingStrat.drive(this, simTime)) {
            this.isWaiting = false;
        } else {
            if (TrafficParameters.activateCollStrat || !this.collStrat.onCollision(this)) {
                this.getEnvironment().setWaitingTime(this.getEnvironment().getNumOfWaitingCars() + 1);
                this.isWaiting = true;
            }
        }

        if (trace.size() > 0 && !trace.getLast().equals(this.getAgentPosition())) {
            this.trace.removeFirst();
            this.trace.add(this.getAgentPosition());
        }
    }
   
    /* **********************************************************************
     * The following methods provide some useful tools to inspect the agents
     * state in the environment as well as to affect this state, for example,
     * by randomizing the position of the target to find.
     ************************************************************************/
   
    public float speedMax = 1f;
   
    @MethodRunnableProperties(ignoreMethod=true)
    public CollisionStrategy getCollStrat() {
        return this.collStrat;
    }
   
    public void driveForward() {
        this.setAgentPosition(new Vector2D(this.getAgentPosition()).add(this.getNormalizedLOV()));
    }

    public double distanceToTarget() {
        return this.getAgentPosition().distance(getTargetLocation());
    }
   
    public boolean isMarked() {
        AllroundVideoPlugin v = (AllroundVideoPlugin) this.getEnvironment().getSimTime().getPluginObject(new AllroundVideoPlugin().id());
        return v.getMarkedAgentId() == this.id();
    }

    public float getSpeedD() {
        if (this.isWaiting) {
            return 0;
        }
        return this.speedMax;
    }
   
    private Vector2D targetLocation = new Vector2D(3, 4);
   
    public void randomizeTarget() {
        Vector2D v = new Vector2D(this.getEnvironment().RAND.nextInt(this.getEnvironment().getGridWidth()),
                this.getEnvironment().RAND.nextInt(this.getEnvironment().getGridHeight()));
       
        while (!this.getEnvironment().isOnStreet(v.x, v.y)) {
            v = new Vector2D(this.getEnvironment().RAND.nextInt(this.getEnvironment().getGridWidth()),
                    this.getEnvironment().RAND.nextInt(this.getEnvironment().getGridHeight()));
        }
       
        this.targetLocation = v;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public Vector2D getTargetLocation() {
        return this.targetLocation;
    }
   
    /**
     * @return  Only if truly on the left side, not on the same lane!
     */
    public boolean isTargetOnLeftSide() {
        if (isTargetOnSameLane()) {
            return false;
        }
       
        Vector2D dirToTarget = new Vector2D(this.targetLocation);
        dirToTarget.sub(this.getAgentPosition());
        return !this.getNormalizedLOV().drehrichtung(dirToTarget);
    }

    public boolean isTargetOnSameLane() {
        int posX = (int) this.getAgentPosition().x;
        int posY = (int) this.getAgentPosition().y;
        int targetX = (int) this.targetLocation.x;
        int targetY = (int) this.targetLocation.y;
       
        if (posX == targetX || posY == targetY) {
            return true;
        } else {
            return false;
        }
    }
   
    /**
     * @return  Only if truly on the right side, not on the same lane!
     */
    public boolean isTargetOnRightSide() {
        if (isTargetOnSameLane()) {
            return true;
        }

        Vector2D dirToTarget = new Vector2D(this.targetLocation);
        dirToTarget.sub(this.getAgentPosition());
        return this.getNormalizedLOV().drehrichtung(dirToTarget);
    }

    public boolean isTargetAhead() {
        return new Vector2D(this.getAgentPosition()).add(this.getNormalizedLOV()).distance(this.targetLocation) <
            this.getAgentPosition().distance(this.targetLocation);
    }
   
    public Integer isOnCrossing() {
        int col = (int) this.getAgentPosition().x;
        int row = (int) this.getAgentPosition().y;
        Vector2D inFront = new Vector2D(col, row).add(this.getNormalizedLOV());
        int inFrontCol = (int) inFront.x;
        int inFrontRow = (int) inFront.y;

        if (this.getEnvironment().isCrossing(inFrontCol, inFrontRow)
                && this.getEnvironment().isCrossing(col, row)) {
            return 1;
        }
       
        if (!this.getEnvironment().isCrossing(inFrontCol, inFrontRow)
                && this.getEnvironment().isCrossing(col, row)) {
            return 2;
        }
       
        return null;
    }
   
    public String facingInDirection() {
        Vector2D vec = this.getNormalizedLOV();
       
        if ((int) vec.x == 1) {
            return "E";
        }
        if ((int) vec.y == 1) {
            return "S";
        }
        if ((int) vec.x == -1) {
            return "W";
        }
        if ((int) vec.y == -1) {
            return "N";
        }
       
        return "FALSE";
    }
   
    public boolean isFacingInTrafficFlowDirection() {
        String facing = this.facingInDirection();
        int agentPosX = (int) this.getAgentPosition().x;
        int agentPosY = (int) this.getAgentPosition().y;
        return facing.equals("N") && this.getEnvironment().isLeftLaneNtoS(agentPosX, agentPosY)
                || facing.equals("E") && this.getEnvironment().isRightLaneWtoE(agentPosX, agentPosY)
                || facing.equals("S") && this.getEnvironment().isRightLaneNtoS(agentPosX, agentPosY)
                || facing.equals("W") && this.getEnvironment().isLeftLaneWtoE(agentPosX, agentPosY);
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public LinkedList<Vector2D> getTrace() {
        return this.trace;
    }
   
    private int targetCount = 0;
   
    public int getTargetCount() {
        return this.targetCount;
    }

    public void setResetRequested() {
        this.resetRequested = true;
    }
}
TOP

Related Classes of eas.users.ocScenarios.traffic.CarAgent

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.