Package eas.users.ocScenarios.traffic

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

/*
* File name:        CarsEnvironment.java (package eas.users.ocScenario.cars)
* Author(s):        Lukas König
* Java version:     7.0
* Generation date:  09.05.2014 (14:54:07)
*
* (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.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.plugins.standard.liveInteraction.MethodRunnableProperties;
import eas.plugins.standard.visualization.AllroundVideoPlugin;
import eas.simulation.Wink;
import eas.simulation.spatial.sim2D.gridSimulation.standardEnvironments.AbstractGridEnvironment;
import eas.simulation.spatial.sim2D.gridSimulation.standardGridObjects.GridObject;
import eas.simulation.spatial.sim2D.standardAgents.AbstractAgent2D;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.users.ocScenarios.traffic.lights.LightsPlugin;
import eas.users.ocScenarios.traffic.strategies.StrategyFactory;

/**
* @author Lukas König
*/
public class TrafficEnvironment extends AbstractGridEnvironment<AbstractAgent2D<?>> {
   
    /**
     * All serializable classes must have this.
     */
    private static final long serialVersionUID = 5640257554252878857L;
   
    /**
     * A globally used (within cars scenario) random number generator.
     */
    public Random RAND;

    /**
     * Standard constructor.
     *
     * @param id      The environments id (pretty much arbitrary).
     * @param params  The program parameters.
     */
    public TrafficEnvironment(int id, ParCollection params) {
        super(id, params, params.getParValueInt("GridFields"), params.getParValueInt("GridFields"), true);
        RAND = new Random(params.getSeed());
    }
   
    @Override
    @MethodRunnableProperties(ignoreMethod=true)
    public List<SingleParameter> getParameters() {
        List<SingleParameter> parsList = super.getParameters();
        parsList.addAll(TrafficParameters.getParameter());
        return parsList;
    }

    /**
     * Performs areset procedure including a newly triggered positioning of
     * streets, cars etc.
     */
    @MethodRunnableProperties(ignoreMethod=true)
    private void reset() {
        this.removeAllAgents();
        this.removeAllGridObjects();
       
        try {
            this.positionStreets(TrafficParameters.numStreets, TrafficParameters.proportionOfRoundabouts / 100.0);
            this.positionCars(TrafficParameters.numCars);
            AllroundVideoPlugin vid = (AllroundVideoPlugin) this.getSimTime().getPluginObject(new AllroundVideoPlugin().id());
            vid.showTooltipps(false);
            vid.setFollowAgent(true);
        } catch (Exception e) {}
    }

    /**
     * Positions the specified number of cars randomly on the streets, if
     * possible. If not, as many cars are positioned as possible.
     *
     * @param numAgents  The desired number of cars to position.
     */
    public void positionCars(int numAgents) {
        ArrayList<AbstractAgent2D<?>> list = new ArrayList<>(numAgents);
        for (int i = 0; i < numAgents; i++) {
            CarAgent ca = new CarAgent(
                    i + 1000,
                    this,
                    this.getParCollection(),
                    StrategyFactory.getDrivingStrategy(TrafficParameters.drivingStrategy),
                    StrategyFactory.getCollisionStrategy(TrafficParameters.collisionStrategy));
            list.add(ca);
        }
        this.distributeAgentsOverEmptyFields(list, l -> l.size() == 1);
    }

    @MethodRunnableProperties(ignoreMethod=true)
    private boolean isInCircleArea(int val, int size) {
        if (TrafficParameters.roundaboutRadius * 2 >= size) {
            return false;
        }
        return val % size - size / 2 > 0 && val % size - size / 2 <= TrafficParameters.roundaboutRadius
                || val % size - size / 2 - 1 < 0 && val % size - size / 2 - 1 >= -TrafficParameters.roundaboutRadius;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    private boolean isOnCircle(int val, int size) {
        if (TrafficParameters.roundaboutRadius * 2 >= size) {
            return false;
        }
        return val % size - size / 2 == TrafficParameters.roundaboutRadius || val % size - size / 2 - 1 == -TrafficParameters.roundaboutRadius;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    private boolean isInCircleArea(int x, int y, int size) {
        return isInCircleArea(x, size) && isInCircleArea(y, size);
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    private boolean isOnCircle(int x, int y, int size) {
        return isOnCircle(x, size) && isInCircleArea(y, size)
                || isOnCircle(y, size) && isInCircleArea(x, size);
    }
   
    private HashMap<Vector2D, Boolean> circles = new HashMap<>();
   
    @MethodRunnableProperties(ignoreMethod=true)
    public HashMap<Vector2D, Boolean> getCirclesDist() {
        return this.circles;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public void positionStreets(int noCrossings, double circleProb) {
        int dir = this.getWidth() / (noCrossings) + 1;
        int size = dir - 1;
       
        int crossingsX = 0;
        int crossingsY = 0;
       
        circles = new HashMap<>();
        Boolean nextIsCircle = false;
       
        for (int i = 0; i < this.getWidth(); i++) {
            if (i % size == 0) {
                crossingsX++;
            }
            crossingsY = 0;
            for (int j = 0; j < this.getHeight(); j++) {
                if (j % size == 0) {
                    crossingsY++;
                }
               
                Vector2D vec = new Vector2D(crossingsX, crossingsY);
                nextIsCircle = circles.get(vec);
                if (nextIsCircle == null) {
                    circles.put(vec, RAND.nextDouble() < circleProb);
                    nextIsCircle = circles.get(vec);
                }
               
               
                if (isOnCircle(i, j, size) && nextIsCircle) {
                    StreetObject agent = new StreetObject();

                    agent.setOnCircle(true);
                   
                    if (i % size <= size / 2) {
                        agent.setRightLaneNtoS(true);
                    }
                   
                    if (j % size <= size / 2) {
                        agent.setRightLaneWtoE(true);
                    }

                    if (i % size >= size / 2 + 1) {
                        agent.setLeftLaneNtoS(true);
                    }
                   
                    if (j % size >= size / 2 + 1) {
                        agent.setLeftLaneWtoE(true);
                    }

                    this.addGridObject(agent, i, j);
                } else if (!nextIsCircle || !isInCircleArea(i, j, size)) {
                    if (i % size == size / 2 || j % size == size / 2
                            || (TrafficParameters.twoLanes && (i % size == size / 2 + 1 || j % size == size / 2 + 1))) {
                        StreetObject agent = new StreetObject();
                       
                        if (i % size == size / 2) {
                            agent.setRightLaneNtoS(true);
                        }
                       
                        if (j % size == size / 2) {
                            agent.setRightLaneWtoE(true);
                        }
   
                        if (TrafficParameters.twoLanes) {
                            if (i % size == size / 2 + 1) {
                                agent.setLeftLaneNtoS(true);
                            }
                           
                            if (j % size == size / 2 + 1) {
                                agent.setLeftLaneWtoE(true);
                            }
                        }
   
                        this.addGridObject(agent, i, j);
                    }
                }
            }
        }
    }
   
    private int waitingTime;
   
    public int getNumOfWaitingCars() {
        return waitingTime;
    }
   
    public void setWaitingTime(int waitingTime) {
        this.waitingTime = waitingTime;
    }

    public int getNumOfStoredTracePoints() {
        return TrafficParameters.numOfStoredTracePoints;
    }
   
    @Override
    public void step(Wink simTime) {
        super.step(simTime);
       
        if (TrafficParameters.resetRequested) {
            this.reset();

            try {
                LightsPlugin plug = (LightsPlugin) this.getSimTime().getPluginObject(new LightsPlugin().id());
                plug.reset(this, this.getParCollection());
            } catch (Exception e) {}

//            ChartEvent e2 = new ChartEvent("Cars", "Avg. speed", 0);
//            e2.setChartFramePos(new Vector2D(0, 300));
//            this.getSimTime().broadcastEvent(e2);
            TrafficParameters.resetRequested = false;
        } else {
//            ChartEvent e1 = new ChartEvent("Cars", "Waiting time", (this.getWaitingTime()));
//            ChartEvent e2 = new ChartEvent("Cars", "Avg. speed", this.getAverageSpeed() * 100);
//            e1.setyAxisLabel("Waiting cars per tick");
//            this.getSimTime().broadcastEvent(e1);
//            this.getSimTime().broadcastEvent(e2);
        }
       
        this.waitingTime = 0;
    }

    public double getAverageSpeed() {
        float speed = 0;
       
        List<CarAgent> carList = this.getAllCars();
       
        for (AbstractAgent2D<?> c : carList) {
            speed += ((CarAgent) c).getSpeedD();
        }
       
        return speed / carList.size();
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public ArrayList<CarAgent> getAllCars() {
        ArrayList<CarAgent> cars = new ArrayList<>(this.getAgents().size());
       
        for (AbstractAgent2D<?> a : this.getAgents()) {
            if (a.getClass().equals(CarAgent.class)) {
                cars.add((CarAgent) a);
            }
        }
       
        return cars;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public HashMap<Vector2D, StreetObject> getAllStreetAgents() {
        HashMap<Vector2D, StreetObject> streetAgents = new HashMap<Vector2D, StreetObject>();
       
        for (int i = 0; i < this.getGridWidth(); i++) {
            for (int j = 0; j < this.getGridHeight(); j++) {
                for (GridObject a : this.getFieldPosition(new Vector2D(i, j))) {
                    if (a.getClass().equals(StreetObject.class)) {
                        streetAgents.put(new Vector2D(i, j), (StreetObject) a);
                    }
                }
            }
        }
       
        return streetAgents;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isRightLaneNtoS(int column, int row) {
        List<GridObject> field = this.getFieldPosition(column, row);
        for (GridObject g : field) {
            if (g.getClass().equals(StreetObject.class)) {
                return ((StreetObject) g).isRightLaneNtoS();
            }
        }
       
        return false;
    }

    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isLeftLaneNtoS(int column, int row) {
        List<GridObject> field = this.getFieldPosition(column, row);
        for (GridObject g : field) {
            if (g.getClass().equals(StreetObject.class)) {
                return ((StreetObject) g).isLeftLaneNtoS();
            }
        }
       
        return false;
    }

    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isLeftLaneWtoE(int column, int row) {
        List<GridObject> field = this.getFieldPosition(column, row);
        for (GridObject g : field) {
            if (g.getClass().equals(StreetObject.class)) {
                return ((StreetObject) g).isRightLaneWtoE();
            }
        }
       
        return false;
    }

    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isRightLaneWtoE(int column, int row) {
        List<GridObject> field = this.getFieldPosition(column, row);
        for (GridObject g : field) {
            if (g.getClass().equals(StreetObject.class)) {
                return ((StreetObject) g).isLeftLaneWtoE();
            }
        }
       
        return false;
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isCrossing(int column, int row) {
        List<GridObject> field = this.getFieldPosition(column, row);
        for (GridObject g : field) {
            if (g.getClass().equals(StreetObject.class)) {
                StreetObject sa = (StreetObject) g;
                return sa.isCrossing();
            }
        }
       
        return false;
    }
   
    @Override
    @MethodRunnableProperties(ignoreMethod=true)
    public synchronized BufferedImage getOutsideView() {
        BufferedImage img = super.getOutsideView();
       
        try {
            AllroundVideoPlugin vid = (AllroundVideoPlugin) this.getSimTime().getPluginObject(new AllroundVideoPlugin().id());
            CarAgent c = (CarAgent) this.getAgent(vid.getMarkedAgentId());
            Graphics2D g = img.createGraphics();
            g.setColor(Color.blue);
           
            Polygon2D pol = new Polygon2D();
            pol.add(new Vector2D(c.getTargetLocation()).add(new Vector2D(0.5, 0.5)));
            pol.add(new Vector2D(c.getTargetLocation()).add(new Vector2D(-0.5, 0.5)));
            pol.add(new Vector2D(c.getTargetLocation()).add(new Vector2D(-0.5, -0.5)));
            pol.add(new Vector2D(c.getTargetLocation()).add(new Vector2D(0.5, -0.5)));
            g.setStroke(new BasicStroke(5));
           
            g.drawPolygon(this.getPolygonInVisualization(pol).toPol());
           
            g.setStroke(new BasicStroke(2));
            g.setColor(Color.red);
            c.getTrace().forEach(v ->
                {Vector2D a = this.getPointInVisualization(v);
                g.drawOval((int) a.x - 3, (int) a.y - 3, 6, 6);});
        } catch (Exception e) {}
       
        return img;
    }
   
    public double getTargetsReachedPerTickPerCar() {
        double sum = 0;
       
        ArrayList<CarAgent> cars = this.getAllCars();
       
        for (CarAgent c : cars) {
            sum += c.getTargetCount();
        }
       
        return sum / this.getSimTime().getCurrentTime().getLastTick() / cars.size();
    }
   
    @MethodRunnableProperties(ignoreMethod=true)
    public boolean isOnStreet(double x, double y) {
        return this.getFieldPosition(new Vector2D(x, y)).size() > 0;
    }
   
    public double getAvgDistanceToTarget() {
        double targetDist = 0;
       
        ArrayList<CarAgent> cars = this.getAllCars();
       
        for (CarAgent c : cars) {
            targetDist += c.distanceToTarget();
        }
       
        return targetDist / cars.size();
    }
}
TOP

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

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.