Package org.movsim.simulator.roadnetwork

Source Code of org.movsim.simulator.roadnetwork.SimpleRamp

/*
* Copyright (C) 2010, 2011, 2012 by Arne Kesting, Martin Treiber, Ralph Germ, Martin Budden
* <movsim.org@gmail.com>
* -----------------------------------------------------------------------------------------
*
* This file is part of
*
* MovSim - the multi-model open-source vehicular-traffic simulator.
*
* MovSim is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MovSim is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MovSim. If not, see <http://www.gnu.org/licenses/>
* or <http://www.movsim.org>.
*
* -----------------------------------------------------------------------------------------
*/
package org.movsim.simulator.roadnetwork;

import java.util.SortedSet;
import java.util.TreeSet;

import org.movsim.simulator.MovsimConstants;
import org.movsim.simulator.vehicles.TestVehicle;
import org.movsim.simulator.vehicles.TrafficCompositionGenerator;
import org.movsim.simulator.vehicles.Vehicle;
import org.movsim.utilities.Units;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* simple onramp model which drops vehicles in the largest gap on the {@link RoadSegment}.
*
* Ignores the initial speed settings from input.
*
*/
public class SimpleRamp extends AbstractTrafficSource {

    private static final Logger LOG = LoggerFactory.getLogger(SimpleRamp.class);

    private static final double MINIMUM_GAP_BOUNDARY = 3;

    private final double relativeGapToLeader;

    private final double relativeSpeedToLeader;

    private final InflowTimeSeries inflowTimeSeries;

    public SimpleRamp(TrafficCompositionGenerator vehGenerator, RoadSegment roadSegment,
            org.movsim.autogen.SimpleRamp simpleRampData,
            InflowTimeSeries inflowTimeSeries) {
        super(vehGenerator, roadSegment);
        this.inflowTimeSeries = inflowTimeSeries;
        this.relativeSpeedToLeader = simpleRampData.getRelativeSpeed();
        this.relativeGapToLeader = simpleRampData.getRelativeGap();

    }

    @Override
    public void timeStep(double dt, double simulationTime, long iterationCount) {
        if (LOG.isDebugEnabled()) {
            LOG.debug(String.format("simple ramp timestep=%.2f, current inflow=%d, waiting vehicles=%d",
                    simulationTime, +(int) (getTotalInflow(simulationTime) * Units.INVS_TO_INVH), getQueueLength()));
        }

        final double totalInflow = getTotalInflow(simulationTime);
        nWait += totalInflow * dt;

        calcApproximateInflow(dt);

        if (nWait >= 1.0) {
            // try to insert vehicle
            final TestVehicle testVehicle = vehGenerator.getTestVehicle();
            SortedSet<GapCandidate> gapCandidates = findLargestPossibleGap(testVehicle); // only one insert per timestep

            if (!gapCandidates.isEmpty()) {
                GapCandidate gap = gapCandidates.first();
                addVehicle(roadSegment.laneSegment(gap.laneIndex), testVehicle, gap.enterPosition, gap.enterSpeed);
                // TODO testwise adding, check for accidents
                nWait--;
                incrementInflowCount(1);
                recordData(simulationTime, totalInflow);
            }
        }
    }

    private SortedSet<GapCandidate> findLargestPossibleGap(TestVehicle testVehicle) {
        SortedSet<GapCandidate> gapCandidates = new TreeSet<>();

        for (LaneSegment laneSegment : roadSegment.laneSegments()) {
            for (Vehicle vehicle : laneSegment) {
                evaluateVehicle(vehicle, laneSegment, testVehicle, gapCandidates);
            }

            // check also rear vehicles of next downstream segment
            Vehicle rearVehicleNextLaneSegment = laneSegment.sinkLaneSegment().rearVehicle();
            if (rearVehicleNextLaneSegment != null) {
                evaluateVehicle(rearVehicleNextLaneSegment, laneSegment, testVehicle, gapCandidates);
            }
            if (rearVehicleNextLaneSegment == null && laneSegment.vehicleCountWithoutObstacles() == 0) {
                gapCandidates.add(new GapCandidate(MovsimConstants.GAP_INFINITY, laneSegment.lane(), 0.5
                        * roadSegment.roadLength() - testVehicle.length(), testVehicle.getRelativeRandomizationV0()));
            }
        }

        // if (false) {
        // int counter = 0;
        // System.out.println("gap candidated size=" + gapCandidates.size());
        // for (GapCandidate gap : gapCandidates) {
        // ++counter;
        // System.out.println("candidate " + counter + ":" + gap.toString());
        // }
        // }

        return gapCandidates;

    }

    private void evaluateVehicle(Vehicle vehicle, LaneSegment laneSegment, TestVehicle testVehicle,
            SortedSet<GapCandidate> gapCandidates) {
        if (vehicle.getRearPosition() < testVehicle.length() + MINIMUM_GAP_BOUNDARY) {
            // available upstream road segment too small
            LOG.debug("no sufficient upstream gap: rearPosition={}", vehicle.getRearPosition());
            return;
        }
        Vehicle rearVehicle = laneSegment.rearVehicle(vehicle.getRearPosition() - 1); // TODO finds not rear vehicle but
                                                                                      // itself !!!
                                                                                      // if (rearVehicle == vehicle) {
        // System.out.println("!!! rear vehicle is identical to vehicle!");
        // }
        final double gap = vehicle.getNetDistanceToRearVehicle(rearVehicle);
        if (gap < testVehicle.length() + 2 * MINIMUM_GAP_BOUNDARY) {
            // gap too small
            // System.out.println("gap too small, gap=" + gap + ", vehicle=" + vehicle.toString() + ", rearVehicle="
            // + rearVehicle.toString());
            return;
        }

        double enterFrontPosition = Math.max(testVehicle.length(), vehicle.getRearPosition() - relativeGapToLeader * gap
                + 0.5 * testVehicle.length());
        final double gapToLeader = vehicle.getRearPosition() - enterFrontPosition;
        double speed = relativeSpeedToLeader * vehicle.getSpeed();
        gapCandidates.add(new GapCandidate(gapToLeader, laneSegment.lane(), enterFrontPosition, speed));
    }

    @Override
    public double getTotalInflow(double time) {
        return inflowTimeSeries.getFlowPerLane(time) * roadSegment.laneCount();
    }

    final class GapCandidate implements Comparable<GapCandidate> {

        final int laneIndex;
        final double gapToLeader;
        final double enterPosition;
        final double enterSpeed;

        public GapCandidate(double gapToLeader, int laneIndex, double enterPosition, double enterSpeed) {
            this.gapToLeader = gapToLeader;
            this.laneIndex = laneIndex;
            this.enterPosition = enterPosition;
            this.enterSpeed = enterSpeed;
        }

        @Override
        public int compareTo(GapCandidate o) {
            // BEFORE = -1, EQUAL = 0, AFTER = 1

            // same instance
            if (this == o) {
                return 0;
            }

            // compare gaps
            if (this.gapToLeader > o.gapToLeader) {
                return -1;
            } else if (this.gapToLeader < o.gapToLeader) {
                return 1;
            }

            // gaps identical, compare lanes, prefer small laneIndex index (i.e. laneIndex to the right)
            if (this.laneIndex < o.laneIndex) {
                return -1;
            } else if (this.laneIndex > o.laneIndex) {
                return 1;
            }

            return 0;
        }

        @Override
        public String toString() {
            return "GapCandidate [laneIndex=" + laneIndex + ", gapToLeader=" + gapToLeader + ", enterPosition="
                    + enterPosition + ", enterSpeed=" + enterSpeed + "]";
        }

    }

}
TOP

Related Classes of org.movsim.simulator.roadnetwork.SimpleRamp

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.