diff --git a/src/Traffic/Junction/Junction.h b/src/Traffic/Junction/Junction.h index cefc1f5ba666b6a159ba1f954529d8a3055d84bb..8af481aefef0f007d463b27d8f1b2190784d2fe4 100644 --- a/src/Traffic/Junction/Junction.h +++ b/src/Traffic/Junction/Junction.h @@ -10,17 +10,17 @@ class TrafficMovement; class VF_PUBLIC Junction { public: - virtual void checkOutCellIndices(uint roadLength) = 0; + virtual void checkOutCellIndices(const uint roadLength) const = 0; virtual void setCellIndexForNoUTurn(std::vector<int> carCanNotEnterThisOutCell) = 0; virtual bool acceptsCar(uint cellIndex) = 0; //determines if a car can enter the junction virtual void registerCar(uint cellIndex, uint numberOfCellsAlreadyMoved, uint speed, uint oldSpeed) = 0; //registers all cars entering the junction - virtual void calculateTimeStep(TrafficMovement& road) = 0; + virtual void calculateTimeStep(TrafficMovement &road) = 0; virtual void updateJunction() = 0; virtual const std::vector<uint>& getInCellIndices() const = 0; - virtual void dispJunction(const uint index, uint roadLength) const = 0; + virtual void dispJunction(const uint index, const uint roadLength) const = 0; virtual const uint getNumCarsOnJunction() const = 0; }; \ No newline at end of file diff --git a/src/Traffic/Junction/JunctionRandom.cpp b/src/Traffic/Junction/JunctionRandom.cpp index b3bfdd4e0ead2a78223eafb9d425404abc104ef2..f5c427f8915ceb5f3de31a8e2f7835007c14914c 100644 --- a/src/Traffic/Junction/JunctionRandom.cpp +++ b/src/Traffic/Junction/JunctionRandom.cpp @@ -52,15 +52,15 @@ bool JunctionRandom::acceptsCar(uint cellIndex) } -void JunctionRandom::registerCar(uint cellIndex, uint numberOfCellsAlreadyMoved, uint speed, uint oldSpeed) +void JunctionRandom::registerCar(uint cellIndex, uint alreadyMoved, uint speed, uint oldSpeed) { uint index = getInCellsVectorIndex(cellIndex); - //data.carsOnJunction[index] = speed - 1; //all cars, which enter the junction have to slow down by one increment - data.carsOnJunction[index] = 0; //all cars, which enter the junction go really slow + data.carsOnJunction[index] = speed - 1; //all cars, which enter the junction have to slow down by one increment + //data.carsOnJunction[index] = 0; //all cars, which enter the junction have to stop data.oldSpeeds[index] = oldSpeed; data.carCanEnter[index] = false; - data.alreadyMoved[index] = numberOfCellsAlreadyMoved; + data.alreadyMoved[index] = alreadyMoved; } @@ -95,8 +95,6 @@ void JunctionRandom::calculateTimeStep(TrafficMovement& road) uint index = 0; for (int carSpeed : data.carsOnJunction) { if (carSpeed >= 0) { //check if there is a car on the junction - if (carSpeed == 0) - carSpeed += 1; applyRules(carSpeed, index, road); data.alreadyMoved[index] = 0; } @@ -106,13 +104,16 @@ void JunctionRandom::calculateTimeStep(TrafficMovement& road) } -void JunctionRandom::applyRules(int & carSpeed, const int & index, TrafficMovement& road) +void JunctionRandom::applyRules(int & carSpeed, int index, TrafficMovement& road) { + if (carSpeed == 0 && data.alreadyMoved[index] == 0) + carSpeed += 1; + int remainingDistance = static_cast<uint>(carSpeed) - data.alreadyMoved[index]; if (remainingDistance > 0) { int outCell = chooseOutCell(index); if (outCell >= 0) { - breakCar(outCell, carSpeed, remainingDistance, index, road); + brakeCar(outCell, carSpeed, remainingDistance, road); if (remainingDistance > 0) { moveCar(outCell, carSpeed, index, remainingDistance, road); return; @@ -124,17 +125,18 @@ void JunctionRandom::applyRules(int & carSpeed, const int & index, TrafficMoveme } -void JunctionRandom::breakCar(uint outCellIndex, int &speed, int &remainingDistance, const int & index, TrafficMovement& road) +void JunctionRandom::brakeCar(uint outCellIndex, int &speed, int &remainingDistance, TrafficMovement& road) { int gap = road.getGapAfterOutCell(outCellIndex, remainingDistance); if (gap < remainingDistance) { + if (gap > speed) gap = speed; speed = speed - remainingDistance + gap; remainingDistance = gap; } } -void JunctionRandom::moveCar(uint outCell, int & carSpeed, const int & index, int remainingDistance, TrafficMovement& road) +void JunctionRandom::moveCar(uint outCell, int carSpeed, int index, int remainingDistance, TrafficMovement& road) { road.moveJunctionCar(outCell, remainingDistance, carSpeed, data.oldSpeeds[index]); data.carsOnJunction[index] = -1; @@ -142,7 +144,7 @@ void JunctionRandom::moveCar(uint outCell, int & carSpeed, const int & index, in } -int JunctionRandom::chooseOutCell(const int & index) +int JunctionRandom::chooseOutCell(int index) { std::vector<uint> outCellsTemp; @@ -209,7 +211,7 @@ const std::vector<uint>& JunctionRandom::getInCellIndices() const return data.inCellIndices; } -void JunctionRandom::dispJunction(const uint index, uint roadLength) const +void JunctionRandom::dispJunction(const uint index, const uint roadLength) const { if (find(data.inCellIndices.begin(), data.inCellIndices.end(), (roadLength - index - 1)) != data.inCellIndices.end()) { std::cout << std::setw(4) << "in"; @@ -233,7 +235,7 @@ const uint JunctionRandom::getNumCarsOnJunction() const } -void JunctionRandom::checkOutCellIndices(uint roadLength) +void JunctionRandom::checkOutCellIndices(const uint roadLength) const { try { for (uint cell : data.outCellIndices) diff --git a/src/Traffic/Junction/JunctionRandom.h b/src/Traffic/Junction/JunctionRandom.h index 5f9142194c994be068510f1b02865118e62f0e30..531eb210f93112eac60660efb5527a7eaf12844a 100644 --- a/src/Traffic/Junction/JunctionRandom.h +++ b/src/Traffic/Junction/JunctionRandom.h @@ -24,26 +24,26 @@ public: virtual bool acceptsCar(uint cellIndex); //determines if a car can enter the junction virtual void registerCar(uint cellIndex, uint numberOfCellsAlreadyMoved, uint speed, uint oldSpeed); //registers all cars entering the junction - virtual void calculateTimeStep(TrafficMovement& road); + virtual void calculateTimeStep(TrafficMovement &road); virtual void updateJunction(); virtual const std::vector<uint>& getInCellIndices() const; - virtual void dispJunction(const uint index, uint roadLength) const; + virtual void dispJunction(const uint index, const uint roadLength) const; virtual const uint getNumCarsOnJunction() const; - virtual void checkOutCellIndices(uint roadLength); + virtual void checkOutCellIndices(const uint roadLength) const; private: uint getInCellsVectorIndex(uint cellIndex); - void applyRules(int &carSpeed,const int &index, TrafficMovement& road); - void breakCar(uint outCellIndex, int &speed, int &remainingDistance, const int & index, TrafficMovement& road); - void moveCar(uint outCell, int & carSpeed, const int & index, int remainingDistance, TrafficMovement& road); - int chooseOutCell(const int & index); + void applyRules(int &carSpeed,int index, TrafficMovement &road); + void brakeCar(uint outCellIndex, int &speed, int &remainingDistance, TrafficMovement &road); + void moveCar(uint outCell, int carSpeed, int index, int remainingDistance, TrafficMovement &road); + int chooseOutCell(int index); int generateRandomOutCellIndex(uint outCellsTempSize); - void writeConcentrations(TrafficMovement& road); + void writeConcentrations(TrafficMovement &road); }; diff --git a/src/Traffic/Output/CarDisplay.cpp b/src/Traffic/Output/CarDisplay.cpp index 6543a9ca18897b6ca39f14e8434466c423c65297..e54709fbbd03ed788446442e7ffa2691b66f2015 100644 --- a/src/Traffic/Output/CarDisplay.cpp +++ b/src/Traffic/Output/CarDisplay.cpp @@ -85,6 +85,8 @@ void CarDisplay::dispCurrentRoad() const void CarDisplay::dispResults(const std::vector<int> * neighbors, const std::vector<std::shared_ptr<Sink> > & sinks, const std::vector<std::shared_ptr<Junction> > & junctions, const std::vector<std::shared_ptr<Source> > & sources) { + writeResultsToFile(); + visualizeSafetyDistanceForConsole(neighbors); reverse(results.begin(), results.end()); diff --git a/src/Traffic/TrafficMovement.cpp b/src/Traffic/TrafficMovement.cpp index 270b571918e9fc1bbd64ea6a4c9004f17c98c5c1..b4ff8b0569c990bf9c929868e69f34a1b5a75773 100644 --- a/src/Traffic/TrafficMovement.cpp +++ b/src/Traffic/TrafficMovement.cpp @@ -123,7 +123,7 @@ void TrafficMovement::loopTroughTimesteps(uint timeSteps) for (uint step = 1; step < timeSteps + 1; step++) { calculateTimestep(step); } - if (display != nullptr) display->dispResults(&road->neighbors, road->sinks, road->junctions, road->sources); + dispResults(); } @@ -188,7 +188,7 @@ void TrafficMovement::applyRules(uint carIndex) { uint speed = (*pcurrent)[carIndex]; accelerateCar(speed); - breakCar(carIndex, speed); + brakeCar(carIndex, speed); dawdleCar(carIndex, speed); moveCar(carIndex, speed); } @@ -200,7 +200,7 @@ void TrafficMovement::accelerateCar(uint & speed) } } -void TrafficMovement::breakCar(uint carIndex, uint &speed) +void TrafficMovement::brakeCar(uint carIndex, uint &speed) { int neighbor = road->neighbors[carIndex]; gap = getGapAfterCar(carIndex, speed, neighbor); @@ -214,7 +214,7 @@ void TrafficMovement::dawdleCar(uint carIndex, uint & speed) randomNumber = distFloat(engine); //Barlovic / SlowToStart - if ((*pcurrent)[carIndex] == 0 && useSlowToStart == true) { + if (useSlowToStart == true && (*pcurrent)[carIndex] == 0) { if (randomNumber < slowStartPossibility) { speed = 0; } @@ -264,16 +264,24 @@ void TrafficMovement::moveJunctionCar(uint outCellIndex, uint remainingDistance, } int neighbor = outCellIndex; - uint currentCell = outCellIndex; - uint numberOfCellsMoved = iterateNeighborsInMove(currentCell, remainingDistance, neighbor); + uint numberOfCellsMoved = iterateNeighborsInMove(outCellIndex, remainingDistance, neighbor); + try{ + if (neighbor <= -1000 && neighbor > -2000) { + throw std::runtime_error("car entered two junctions in one timestep"); + } + } + catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + std::cin.get(); + exit(EXIT_FAILURE); + } if (neighbor >= 0) { (*pnext)[neighbor] = speed; writeConcentration(neighbor, oldSpeed); } - } @@ -284,8 +292,8 @@ uint TrafficMovement::iterateNeighborsInMove(uint & currentCell, uint speed, int for (uint i = 2; i <= speed; i++) { if (neighbor >= 0) { currentCell = neighbor; - numberOfCellsMoved += 1; neighbor = road->neighbors[neighbor]; + ++numberOfCellsMoved; } else break; @@ -311,21 +319,19 @@ std::shared_ptr<Sink>& TrafficMovement::getSinkFromNeighbor(int neighbor) uint TrafficMovement::getGapAfterCar(uint carIndex, uint speed, int neighbor) { - uint currentCell = carIndex; - for (uint i = 0; i < (speed + road->safetyDistance); i++) { if (neighbor <= -2000) return getGapToSink(neighbor, i, speed); if (neighbor <= -1000) - return getGapToJunction(neighbor, i, speed, currentCell); + return getGapToJunction(neighbor, i, speed, carIndex); //car in Cell if ((*pcurrent)[neighbor] > -1) return adjustGapToSafetyDist(i); //empty cell -> get next neighbor, update currentCell - currentCell = neighbor; + carIndex = neighbor; neighbor = road->neighbors[neighbor]; } return speed; @@ -336,9 +342,7 @@ uint TrafficMovement::getGapAfterOutCell(uint outCellIndex, uint speed) { if ((*pcurrent)[outCellIndex] > -1) return 0; - - - uint currentCell = outCellIndex; + int neighbor = outCellIndex; for (uint i = 0; i < (speed + road->safetyDistance); i++) { @@ -352,22 +356,18 @@ uint TrafficMovement::getGapAfterOutCell(uint outCellIndex, uint speed) if ((*pcurrent)[neighbor] > -1) return adjustGapToSafetyDist(i); - //empty cell -> get next neighbor, update currentCell - currentCell = neighbor; + //empty cell -> get next neighbor neighbor = road->neighbors[neighbor]; } return speed; - - //return getGapAfterCar(outCellIndex, speed, outCellIndex); - } uint TrafficMovement::getGapToSink(int neighbor, uint i, uint speed) { - if (getSinkFromNeighbor(neighbor)->carCanEnter()) + if (getSinkFromNeighbor(neighbor)->carCanEnter() && i <= speed) return speed; - return adjustGapToSafetyDist(i); + return i; } @@ -379,12 +379,12 @@ uint TrafficMovement::getGapToJunction(int neighbor, uint i, uint speed, uint cu } -uint TrafficMovement::adjustGapToSafetyDist(uint speed) +uint TrafficMovement::adjustGapToSafetyDist(uint gap) { - if (speed <= road->safetyDistance) + if (gap <= road->safetyDistance) return 0; else - return speed - road->safetyDistance; + return gap - road->safetyDistance; } void TrafficMovement::writeConcentration(uint index, uint oldSpeed) @@ -451,14 +451,14 @@ void TrafficMovement::visualizeVehicleLengthForVTK() int neighbor = road->neighbors[i]; for (uint j = 1; j <= road->safetyDistance; j++) { - + if (neighbor <= -1000) break; if ((*pcurrent)[neighbor] > -1) { std::cerr << "safetyDistance was violated: timestep: " << currentStep << "\t carIndex: " << i << std::endl; break; } - else + else (road->currentWithLongVehicles)[neighbor] = (*pcurrent)[i]; neighbor = road->neighbors[neighbor]; } @@ -470,7 +470,7 @@ void TrafficMovement::visualizeVehicleLengthForVTK() void TrafficMovement::checkSpeed(uint speed) { - if (speed > road->maxVelocity){ + if (speed > road->maxVelocity) { std::cerr << "Speed is greater than allowed maxSpeed" << std::endl; } } \ No newline at end of file diff --git a/src/Traffic/TrafficMovement.h b/src/Traffic/TrafficMovement.h index 96821e99ca1ffa60e3cfcdd7e11965ca5d2f4fdb..ccd7c8c74ca3e92100c9ae1b14d866d685545789 100644 --- a/src/Traffic/TrafficMovement.h +++ b/src/Traffic/TrafficMovement.h @@ -62,7 +62,7 @@ private: uint getGapAfterCar(uint carIndex, uint speed, int neighbor); uint getGapToSink(int neighbor, uint i, uint speed); uint getGapToJunction(int neighbor, uint i, uint speed, uint currentCell); - uint adjustGapToSafetyDist(uint speed); + uint adjustGapToSafetyDist(uint gap); //getVectorIndex std::shared_ptr<Junction>& getJunctionFromNeighbor(int neighbor); @@ -71,7 +71,7 @@ private: //apply rules void applyRules(uint carIndex); void accelerateCar(uint &speed); - void breakCar(uint carIndex, uint &speed); + void brakeCar(uint carIndex, uint &speed); void dawdleCar(uint carIndex, uint &speed); void moveCar(const uint carIndex, uint speed); uint iterateNeighborsInMove(uint ¤tCell, uint speed, int &neighbor); diff --git a/src/Traffic/TrafficMovementFactoryImpl.cpp b/src/Traffic/TrafficMovementFactoryImpl.cpp index 5867255fdd0edd4926332d8eddbd078a1df1c263..a01625ef00cfa25ab7f53f39f90a6decaf81ad3e 100644 --- a/src/Traffic/TrafficMovementFactoryImpl.cpp +++ b/src/Traffic/TrafficMovementFactoryImpl.cpp @@ -112,4 +112,5 @@ void TrafficMovementFactoryImpl::calculateTimestep(uint step, uint stepForVTK) simulator->calculateTimestep(step); simulator->visualizeVehicleLengthForVTK(); finder.writeVTK(outputPath + outputFilename + "_" + std::to_string(stepForVTK) + ".vtk", *cars); -} \ No newline at end of file +} + diff --git a/src/Traffic/TrafficMovementFactoryImpl.h b/src/Traffic/TrafficMovementFactoryImpl.h index 1ebca424a4d4d74928ba0cb9d586c2ef8dd9643d..f50143f83cceb42657dfacd80a608e788c0483bb 100644 --- a/src/Traffic/TrafficMovementFactoryImpl.h +++ b/src/Traffic/TrafficMovementFactoryImpl.h @@ -19,8 +19,7 @@ public: virtual void initTrafficMovement(real * pconcArrayStart = nullptr); virtual void calculateTimestep(uint step, uint stepForVTK); - -private: +protected: StreetPointFinder finder; std::shared_ptr<TrafficMovement> simulator; std::string outputPath; diff --git a/src/Traffic/TrafficMovementFactoryTest.h b/src/Traffic/TrafficMovementFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..77df69e166e86fb4899f36bcb73eb072352acf0a --- /dev/null +++ b/src/Traffic/TrafficMovementFactoryTest.h @@ -0,0 +1,21 @@ +# pragma once + +//#include <VirtualFluidsDefinitions.h> +#include "TrafficMovementFactoryImpl.h" + +#include <vector> +#include <memory> + +#include "Core/DataTypes.h" +#include "GridGenerator/StreetPointFinder/StreetPointFinder.h" + + +class VF_PUBLIC TrafficMovementFactoryTest: +public TrafficMovementFactoryImpl{ +public: + TrafficMovementFactoryTest() {}; + ~TrafficMovementFactoryTest() {}; + virtual void initTrafficMovement(real * pconcArrayStart = nullptr); + virtual void calculateTimestep(uint step, uint stepForVTK); + void loopThroughTimesteps(uint timeSteps); +}; \ No newline at end of file diff --git a/src/Traffic/TrafficMovementFactoryTestFehler.cpp b/src/Traffic/TrafficMovementFactoryTestFehler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ab651c49124bcef89cb6197388ad254b0bda4cd --- /dev/null +++ b/src/Traffic/TrafficMovementFactoryTestFehler.cpp @@ -0,0 +1,81 @@ +#include "TrafficMovementFactoryTest.h" + +#include <iostream> + +#include "GridGenerator/StreetPointFinder/JunctionReader.h" +#include "GridGenerator/StreetPointFinder/SourceReader.h" +#include "GridGenerator/StreetPointFinder/SinkReader.h" + +#include "RoadNetwork/RoadMaker.h" +#include "TrafficMovement.h" +#include "Source/SourceRandom.h" +#include "Junction/JunctionRandom.h" +#include "Sink/SinkRandom.h" +#include "Output/ConcentrationByPosition.h" +#include "Output/ConcBySpeedAndAcceleration.h" +#include "Utilities/safe_casting.h" + + +void TrafficMovementFactoryTest::initTrafficMovement(real * pconcArrayStart) +{ + //Variables + + real vehicleDensity = 0.1f; + + const uint maxVelocity = 14; + real dawdlePossibility = (real) 0.2; //typical value: 0.2 + real slowToStartPossibility = (real) 0.4; + + uint vehicleLength = 7; + + getRoadLength = 10; + + + //make RoadNetwork + auto roadNetwork = std::make_unique<RoadMaker>(roadLength, maxVelocity, vehicleLength, vehicleDensity); + + + //Sources + unique_ptr<Source> s = make_unique <SourceRandom>(SourceRandom(9, 0.5f)) + roadNetwork->addSource(source); + + + //Sinks + unique_ptr<Sink> s = make_unique <SinkRandom>(SinkRandom(9, 0.5f)); + / roadNetwork->addSink(move(s)); + + + //init TrafficMovement + this->simulator = std::make_shared<TrafficMovement>(move(roadNetwork), dawdlePossibility); + simulator->setSlowToStart(slowToStartPossibility); + simulator->setMaxAcceleration(2); + simulator->se + + + //init ConcentrationOutwriter + std::unique_ptr<ConcentrationOutwriter> writer = std::make_unique<ConcBySpeedAndAcceleration>(ConcBySpeedAndAcceleration(simulator->getRoadLength(), pconcArrayStart)); + simulator->setConcentrationOutwriter(move(writer)); + + //prepare writing to vtk + //this->outputPath = "M:/Basel2019/results/"; + this->outputPath = "C:/Users/hiwi/BaselDokumente/Basel_Ergebnisse/"; + this->outputFilename = "ExampleStreets"; + this->cars = &(simulator->getVehiclesForVTK()); + + //write initial Timestep + simulator->visualizeVehicleLengthForVTK(); + finder.writeVTK(outputPath + outputFilename + "_" + std::to_string(0) + ".vtk", *cars); +} + +void TrafficMovementFactoryTest::calculateTimestep(uint step, uint stepForVTK) +{ + simulator->calculateTimestep(step); + simulator->visualizeVehicleLengthForVTK(); + finder.writeVTK(outputPath + outputFilename + "_" + std::to_string(stepForVTK) + ".vtk", *cars); +} + +void TrafficMovementFactoryTest::loopThroughTimesteps(uint timeSteps) +{ + simulator->setSaveResultsTrue(timeSteps); + calculateTimeStep; +} diff --git a/targets/apps/LBM/TrafficTest/TrafficTest.cpp b/targets/apps/LBM/TrafficTest/TrafficTest.cpp index 6dc51dfbe2c0c393c067467e1641e335f49d5a80..f6dbc40b7f03c2a2d5cbae5b7c9115386727b9a2 100644 --- a/targets/apps/LBM/TrafficTest/TrafficTest.cpp +++ b/targets/apps/LBM/TrafficTest/TrafficTest.cpp @@ -7,32 +7,40 @@ #include "Traffic/TrafficMovementFactoryImpl.h" +#include "TrafficMovementFactoryTest.h" int main() { - uint numberOfTimesteps = 5; + //{uint numberOfTimesteps = 30; - //Logger - logging::Logger::addStream(&std::cout); - logging::Logger::setDebugLevel(logging::Logger::Level::INFO_LOW); - logging::Logger::timeStamp(logging::Logger::ENABLE); - logging::Logger::enablePrintedRankNumbers(logging::Logger::ENABLE); + ////Logger + //logging::Logger::addStream(&std::cout); + //logging::Logger::setDebugLevel(logging::Logger::Level::INFO_LOW); + //logging::Logger::timeStamp(logging::Logger::ENABLE); + //logging::Logger::enablePrintedRankNumbers(logging::Logger::ENABLE); - TrafficMovementFactory * factory = new TrafficMovementFactoryImpl(); - factory->initTrafficMovement(); + //TrafficMovementFactory * factory = new TrafficMovementFactoryImpl(); + //factory->initTrafficMovement(); + + //for (uint step = 1; step <= numberOfTimesteps; step++) { + // factory->calculateTimestep(step,step); + //} - for (uint step = 1; step <= numberOfTimesteps; step++) { - factory->calculateTimestep(step,step); - } + //std::cout << std::endl << std::endl;} - std::cout << std::endl << std::endl; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + {uint numberOfTimesteps = 20; - + TrafficMovementFactoryTest * factory = new TrafficMovementFactoryTest(); + factory->initTrafficMovement(); + factory->loopThroughTimesteps(numberOfTimesteps); + + std::cout << std::endl << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////