From 72f46a6abd93ae5597743034fccb91364962120c Mon Sep 17 00:00:00 2001 From: hiwis <hiwis@irmb.tu-bs.de> Date: Wed, 20 Mar 2019 19:59:27 +0100 Subject: [PATCH] refactored TrafficMovement and Junction (method names and parameters), added TrafficMovementFactoryTest --- src/Traffic/Junction/Junction.h | 6 +- src/Traffic/Junction/JunctionRandom.cpp | 28 ++++--- src/Traffic/Junction/JunctionRandom.h | 16 ++-- src/Traffic/Output/CarDisplay.cpp | 2 + src/Traffic/TrafficMovement.cpp | 56 ++++++------- src/Traffic/TrafficMovement.h | 4 +- src/Traffic/TrafficMovementFactoryImpl.cpp | 3 +- src/Traffic/TrafficMovementFactoryImpl.h | 3 +- src/Traffic/TrafficMovementFactoryTest.h | 21 +++++ .../TrafficMovementFactoryTestFehler.cpp | 81 +++++++++++++++++++ targets/apps/LBM/TrafficTest/TrafficTest.cpp | 34 +++++--- 11 files changed, 184 insertions(+), 70 deletions(-) create mode 100644 src/Traffic/TrafficMovementFactoryTest.h create mode 100644 src/Traffic/TrafficMovementFactoryTestFehler.cpp diff --git a/src/Traffic/Junction/Junction.h b/src/Traffic/Junction/Junction.h index cefc1f5ba..8af481aef 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 b3bfdd4e0..f5c427f89 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 5f9142194..531eb210f 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 6543a9ca1..e54709fbb 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 270b57191..b4ff8b056 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 96821e99c..ccd7c8c74 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 5867255fd..a01625ef0 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 1ebca424a..f50143f83 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 000000000..77df69e16 --- /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 000000000..1ab651c49 --- /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 6dc51dfbe..f6dbc40b7 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; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- GitLab