From d3a1b76c1316d4e691b88dc199a89b6ffa7eb37b Mon Sep 17 00:00:00 2001 From: Arne Graf <ar.graf.cst@gmail.com> Date: Mon, 17 Jul 2017 13:37:59 +0200 Subject: [PATCH] getCost../getDirection.. added --- routing/ff_router/UnivFFviaFM.cpp | 215 +++++++++++++++++++++++++++--- routing/ff_router/UnivFFviaFM.h | 21 +-- routing/ff_router/ffRouter.cpp | 6 +- 3 files changed, 215 insertions(+), 27 deletions(-) diff --git a/routing/ff_router/UnivFFviaFM.cpp b/routing/ff_router/UnivFFviaFM.cpp index 94537574..b540dc4f 100644 --- a/routing/ff_router/UnivFFviaFM.cpp +++ b/routing/ff_router/UnivFFviaFM.cpp @@ -30,6 +30,7 @@ UnivFFviaFM::UnivFFviaFM(Room* roomArg, Configuration* const confArg, double hx, _configuration = confArg; _scope = FF_ROOM_SCALE; + _room = roomArg->GetID(); std::vector<Line> lines; std::map<int, Line> tmpDoors; @@ -68,7 +69,6 @@ UnivFFviaFM::UnivFFviaFM(Room* roomArg, Configuration* const confArg, double hx, //create(lines, tmpDoors, wantedDoors, FF_HOMO_SPEED, hx, wallAvoid, useWallAvoid); create(lines, tmpDoors, wantedDoors, FF_WALL_AVOID, hx, wallAvoid, useWallAvoid); - //writeFF("UnivFFRoom.vtk", this->getKnownDoorUIDs()); } UnivFFviaFM::UnivFFviaFM(SubRoom* sr, Configuration* const conf, double hx, double wallAvoid, bool useWallAvoid) @@ -80,6 +80,7 @@ UnivFFviaFM::UnivFFviaFM(SubRoom* subRoomArg, Configuration* const confArg, doub //then call other constructor including the mode _configuration = confArg; _scope = FF_SUBROOM_SCALE; + _room = subRoomArg->GetRoomID(); std::vector<Line> lines; std::map<int, Line> tmpDoors; @@ -110,7 +111,6 @@ UnivFFviaFM::UnivFFviaFM(SubRoom* subRoomArg, Configuration* const confArg, doub } create(lines, tmpDoors, wantedDoors, FF_HOMO_SPEED, hx, wallAvoid, useWallAvoid); - writeFF("UnivFFSubroom.vtk", this->getKnownDoorUIDs()); } void UnivFFviaFM::create(std::vector<Line>& walls, std::map<int, Line>& doors, std::vector<int> targetUIDs, int mode, @@ -573,6 +573,9 @@ void UnivFFviaFM::calcCost(const long int key, double* cost, Point* dir, const d if (col == DBL_MAX) { //one sided update with row cost[key] = onesidedCalc(row, _grid->Gethx()/speed[key]); //flag[key] = FM_SINGLE; + if (!dir) { + return; + } if (pointsRight) { dir[key]._x = (-(cost[key+1]-cost[key])/_grid->Gethx()); dir[key]._y = (0.); @@ -587,6 +590,9 @@ void UnivFFviaFM::calcCost(const long int key, double* cost, Point* dir, const d if (row == DBL_MAX) { //one sided update with col cost[key] = onesidedCalc(col, _grid->Gethy()/speed[key]); //flag[key] = FM_SINGLE; + if (!dir) { + return; + } if (pointsUp) { dir[key]._x = (0.); dir[key]._y = (-(cost[key+(_grid->GetiMax())]-cost[key])/_grid->Gethy()); @@ -603,6 +609,9 @@ void UnivFFviaFM::calcCost(const long int key, double* cost, Point* dir, const d if (precheck >= 0) { cost[key] = precheck; //flag[key] = FM_DOUBLE; + if (!dir) { + return; + } if (pointsUp && pointsRight) { dir[key]._x = (-(cost[key+1]-cost[key])/_grid->Gethx()); dir[key]._y = (-(cost[key+(_grid->GetiMax())]-cost[key])/_grid->Gethy()); @@ -756,6 +765,9 @@ void UnivFFviaFM::calcDist(const long int key, double* cost, Point* dir, const d if (col == DBL_MAX) { //one sided update with row cost[key] = onesidedCalc(row, _grid->Gethx()/speed[key]); //flag[key] = FM_SINGLE; + if (!dir) { + return; + } if (pointsRight) { dir[key]._x = (-(cost[key+1]-cost[key])/_grid->Gethx()); dir[key]._y = (0.); @@ -770,6 +782,9 @@ void UnivFFviaFM::calcDist(const long int key, double* cost, Point* dir, const d if (row == DBL_MAX) { //one sided update with col cost[key] = onesidedCalc(col, _grid->Gethy()/speed[key]); //flag[key] = FM_SINGLE; + if (!dir) { + return; + } if (pointsUp) { dir[key]._x = (0.); dir[key]._y = (-(cost[key+(_grid->GetiMax())]-cost[key])/_grid->Gethy()); @@ -786,6 +801,9 @@ void UnivFFviaFM::calcDist(const long int key, double* cost, Point* dir, const d if (precheck >= 0) { cost[key] = precheck; //flag[key] = FM_DOUBLE; + if (!dir) { + return; + } if (pointsUp && pointsRight) { dir[key]._x = (-(cost[key+1]-cost[key])/_grid->Gethx()); dir[key]._y = (-(cost[key+(_grid->GetiMax())]-cost[key])/_grid->Gethy()); @@ -824,18 +842,22 @@ inline double UnivFFviaFM::twosidedCalc(double x, double y, double hDivF) { //on return -2.; //this line should never execute } //twosidedCalc -void UnivFFviaFM::addTarget(const int uid) { +void UnivFFviaFM::addTarget(const int uid, double* costarrayDBL, Point* gradarrayPt) { + if (_doors.count(uid) == 0) { + Log->Write("ERROR: \tCould not find door with uid %d in Room %d", uid, _room); + return; + } Line tempTargetLine = Line(_doors[uid]); Point tempCenterPoint = Point(tempTargetLine.GetCentre()); //this allocation must be on shared heap! to be accessible by any thread later (should be shared in openmp) - double* newArrayDBL = new double[_nPoints]; + double* newArrayDBL = (costarrayDBL)? costarrayDBL : new double[_nPoints]; Point* newArrayPt = nullptr; if (_user == DISTANCE_AND_DIRECTIONS_USED) { - newArrayPt = new Point[_nPoints]; + newArrayPt = (gradarrayPt)? gradarrayPt : new Point[_nPoints]; } - if (_costFieldWithKey[uid]) + if (_costFieldWithKey[uid] && !costarrayDBL) delete[] _costFieldWithKey[uid]; _costFieldWithKey[uid] = newArrayDBL; @@ -848,7 +870,7 @@ void UnivFFviaFM::addTarget(const int uid) { } } - if (_directionFieldWithKey[uid]) + if (_directionFieldWithKey[uid] && !gradarrayPt) delete[] _directionFieldWithKey[uid]; if (newArrayPt) _directionFieldWithKey[uid] = newArrayPt; @@ -869,16 +891,65 @@ void UnivFFviaFM::addTarget(const int uid) { _uids.emplace_back(uid); } +void UnivFFviaFM::addTarget(const int uid, Line* door, double* costarray, Point* gradarray){ + if (_doors.count(uid) == 0) { + _doors.emplace(std::make_pair(uid, *door)); + } + addTarget(uid, costarray, gradarray); +} + void UnivFFviaFM::addAllTargets() { for (auto uidmap : _doors) { addTarget(uidmap.first); } } +void UnivFFviaFM::addAllTargetsParallel() { + //free old memory + for (auto memoryDBL : _costFieldWithKey) { + if (memoryDBL.first == 0) continue; //do not free distancemap + if (memoryDBL.second) delete[](memoryDBL.second); + } + for (auto memoryPt : _directionFieldWithKey) { + if (memoryPt.first == 0) continue; //do not free walldirectionmap + if (memoryPt.second) delete[](memoryPt.second); + } + //allocate new memory + for (auto uidmap : _doors) { + _costFieldWithKey[uidmap.first] = new double[_nPoints]; + if (_user == DISTANCE_MEASUREMENTS_ONLY) { + _directionFieldWithKey[uidmap.first] = nullptr; + } + if (_user == DISTANCE_AND_DIRECTIONS_USED) { + _directionFieldWithKey[uidmap.first] = new Point[_nPoints]; + } + } + + //parallel region +#pragma omp parallel + { +#pragma omp for + for (unsigned int i = 0; i < _doors.size(); ++i) { + auto doorPair = _doors.begin(); + std::advance(doorPair, i); + addTarget(doorPair->first, _costFieldWithKey[doorPair->first], _directionFieldWithKey[doorPair->first]); + } + }; +} + std::vector<int> UnivFFviaFM::getKnownDoorUIDs(){ return _uids; } +void UnivFFviaFM::setUser(int userArg) { + _user=userArg; +} + +void UnivFFviaFM::setMode(int modeArg) { + _mode=modeArg; +} + + void UnivFFviaFM::writeFF(const std::string& filename, std::vector<int> targetID) { Log->Write("INFO: \tWrite Floorfield to file"); Log->Write(filename); @@ -939,6 +1010,26 @@ void UnivFFviaFM::writeFF(const std::string& filename, std::vector<int> targetID if (!targetID.empty()) { for (unsigned int iTarget = 0; iTarget < targetID.size(); ++iTarget) { Log->Write("%s: target number %d: UID %d", filename.c_str(), iTarget, targetID[iTarget]); + + if (_costFieldWithKey.count(targetID[iTarget]) == 0) { + continue; + } + double *costarray = _costFieldWithKey[targetID[iTarget]]; + + std::string name = _building->GetTransOrCrossByUID(targetID[iTarget])->GetCaption() + "-" + + std::to_string(targetID[iTarget]); + std::replace(name.begin(), name.end(), ' ', '_'); + + if (!costarray) { + continue; + } + + file << "SCALARS CostTarget" << name << " float 1" << std::endl; + file << "LOOKUP_TABLE default" << std::endl; + for (long int i = 0; i < _grid->GetnPoints(); ++i) { + file << costarray[i] << std::endl; + } + if (_directionFieldWithKey.count(targetID[iTarget]) == 0) { continue; } @@ -948,21 +1039,111 @@ void UnivFFviaFM::writeFF(const std::string& filename, std::vector<int> targetID continue; } - std::string name = _building->GetTransOrCrossByUID(targetID[iTarget])->GetCaption() + "-" + - std::to_string(targetID[iTarget]); - std::replace(name.begin(), name.end(), ' ', '_'); + file << "VECTORS GradientTarget" << name << " float" << std::endl; for (int i = 0; i < _grid->GetnPoints(); ++i) { file << gradarray[i]._x << " " << gradarray[i]._y << " 0.0" << std::endl; } - double *costarray = _costFieldWithKey[targetID[iTarget]]; - file << "SCALARS CostTarget" << name << " float 1" << std::endl; - file << "LOOKUP_TABLE default" << std::endl; - for (long int i = 0; i < _grid->GetnPoints(); ++i) { - file << costarray[i] << std::endl; - } + } } file.close(); -} \ No newline at end of file +} + +//@todo: @ar.graf: mode is argument, which should not be needed, the info is stored in members like speedmode, ... +double UnivFFviaFM::getCostToDestination(const int destID, const Point& position, int mode) { + assert(_grid->includesPoint(position)); + if (_costFieldWithKey.count(destID)==1 && _costFieldWithKey[destID]) { + return _costFieldWithKey[destID][_grid->getKeyAtPoint(position)]; + } else if (_directCalculation && _doors.count(destID) > 0) { + _costFieldWithKey[destID] = new double[_nPoints]; + if (_user == DISTANCE_AND_DIRECTIONS_USED) { + _directionFieldWithKey[destID] = new Point[_nPoints]; + } else { + _directionFieldWithKey[destID] = nullptr; + } + + addTarget(destID, _costFieldWithKey[destID], _directionFieldWithKey[destID]); + getCostToDestination(destID, position, mode); + } + return 0.; +} + +double UnivFFviaFM::getCostToDestination(const int destID, const Point& position) { + assert(_grid->includesPoint(position)); + if (_costFieldWithKey.count(destID)==1 && _costFieldWithKey[destID]) { + return _costFieldWithKey[destID][_grid->getKeyAtPoint(position)]; + } else if (_directCalculation && _doors.count(destID) > 0) { + _costFieldWithKey[destID] = new double[_nPoints]; + if (_user == DISTANCE_AND_DIRECTIONS_USED) { + _directionFieldWithKey[destID] = new Point[_nPoints]; + } else { + _directionFieldWithKey[destID] = nullptr; + } + + addTarget(destID, _costFieldWithKey[destID], _directionFieldWithKey[destID]); + getCostToDestination(destID, position); + } + return 0.; +} + +RectGrid* UnivFFviaFM::getGrid(){ + return _grid; +} + +void UnivFFviaFM::getDirectionToUID(int destID, const long int key, Point& direction, int mode){ + assert(key > 0 && key < _nPoints); + if (_directionFieldWithKey.count(destID)==1 && _directionFieldWithKey[destID]) { + direction = _directionFieldWithKey[destID][key]; + } else if (_directCalculation && _doors.count(destID) > 0) { + //free memory if needed + if (_costFieldWithKey.count(destID) == 1 && _costFieldWithKey[destID]) { + delete[] _costFieldWithKey[destID]; + } + //allocate memory + _costFieldWithKey[destID] = new double[_nPoints]; + if (_user == DISTANCE_AND_DIRECTIONS_USED) { + _directionFieldWithKey[destID] = new Point[_nPoints]; + } else { + _directionFieldWithKey[destID] = nullptr; + } + + //calculate destID's fields and call function + addTarget(destID, _costFieldWithKey[destID], _directionFieldWithKey[destID]); + getDirectionToUID(destID, key, direction, mode); + } + return; +} + +void UnivFFviaFM::getDirectionToUID(int destID, const long int key, Point& direction){ + assert(key > 0 && key < _nPoints); + if (_directionFieldWithKey.count(destID)==1 && _directionFieldWithKey[destID]) { + direction = _directionFieldWithKey[destID][key]; + } else if (_directCalculation && _doors.count(destID) > 0) { + //free memory if needed + if (_costFieldWithKey.count(destID) == 1 && _costFieldWithKey[destID]) { + delete[] _costFieldWithKey[destID]; + } + //allocate memory + _costFieldWithKey[destID] = new double[_nPoints]; + if (_user == DISTANCE_AND_DIRECTIONS_USED) { + _directionFieldWithKey[destID] = new Point[_nPoints]; + } else { + _directionFieldWithKey[destID] = nullptr; + } + + //calculate destID's fields and call function + addTarget(destID, _costFieldWithKey[destID], _directionFieldWithKey[destID]); + getDirectionToUID(destID, key, direction); + } + return; +} + +/* Log: + * todo: + * - implement error treatment: extend fctns to throw errors and handle them + * - error treatment will be advantageous, if calculation of FFs can be postponed + * to be done in Simulation::RunBody, where + * all cores are available + * - (WIP) fill subroom* array with correct values \ No newline at end of file diff --git a/routing/ff_router/UnivFFviaFM.h b/routing/ff_router/UnivFFviaFM.h index 8844e5f1..cdfdb4c6 100644 --- a/routing/ff_router/UnivFFviaFM.h +++ b/routing/ff_router/UnivFFviaFM.h @@ -91,16 +91,19 @@ public: UnivFFviaFM(UnivFFviaFM&){}; ~UnivFFviaFM(){}; - void addTarget(const int uid, Line* door); - void addTarget(const int uid); + void addTarget(const int uid, Line* door, double* costarray = nullptr, Point* gradarray = nullptr); + void addTarget(const int uid, double* costarray = nullptr, Point* gradarray = nullptr); void addAllTargets(); + void addAllTargetsParallel(); std::vector<int> getKnownDoorUIDs(); - - double getCostToDestination(const int destID, const Point& position, int mode) {return 0.;}; - double getCostToDestination(const int destID, const Point& position) {return 0.;}; - RectGrid* getGrid(){return nullptr;}; - virtual void getDirectionToUID(int destID, const long int key, Point& direction, int mode){}; - void getDirectionToUID(int destID, const long int key, Point& direction){}; + void setUser(int userArg); + void setMode(int modeArg); + + double getCostToDestination(const int destID, const Point& position, int mode); + double getCostToDestination(const int destID, const Point& position); + RectGrid* getGrid(); + virtual void getDirectionToUID(int destID, const long int key, Point& direction, int mode); + void getDirectionToUID(int destID, const long int key, Point& direction); void writeFF(const std::string&, std::vector<int> targetID); void createRectGrid(std::vector<Line>& walls, std::map<int, Line>& doors, double spacing); @@ -128,10 +131,12 @@ public: private: Building* _building = nullptr; Configuration* _configuration = nullptr; + int _room = -1; //not set int _mode = LINESEGMENT; //default int _user = DISTANCE_AND_DIRECTIONS_USED; //default int _speedmode = FF_HOMO_SPEED; //default int _scope = 0; //not set / unknown + bool _directCalculation = true; RectGrid* _grid = nullptr; long int _nPoints = 0; std::vector<double*> _speedFieldSelector; diff --git a/routing/ff_router/ffRouter.cpp b/routing/ff_router/ffRouter.cpp index b29cc0e0..93ea1a87 100644 --- a/routing/ff_router/ffRouter.cpp +++ b/routing/ff_router/ffRouter.cpp @@ -187,13 +187,15 @@ bool FFRouter::Init(Building* building) // } else { // locffptr = new LocalFloorfieldViaFM(pairRoomIt->second.get(), building, 0.125, 0.125, 0.0, false); // } - locffptr->addAllTargets(); + locffptr->setUser(DISTANCE_MEASUREMENTS_ONLY); + locffptr->setMode(CENTERPOINT); + locffptr->addAllTargetsParallel(); locffptr->writeFF("UnivFF.vtk", locffptr->getKnownDoorUIDs()); Log->Write("INFO: \tAdding distances in Room %d to matrix", (*pairRoomIt).first); //#pragma omp critical(_locffviafm) _locffviafm.insert(std::make_pair((*pairRoomIt).first, locffptr)); } - return true; //@todo: ar.graf: remove this!! + // nowait, because the parallel region ends directly afterwards //#pragma omp for nowait -- GitLab