Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
JPScore
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
92
Issues
92
List
Boards
Labels
Service Desk
Milestones
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
JuPedSim
JPScore
Commits
e8efcb45
Commit
e8efcb45
authored
Jul 26, 2015
by
Ulrich Kemloh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New information are now accepted with a probability in events
parent
0a05650f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
360 additions
and
97 deletions
+360
-97
IO/IODispatcher.cpp
IO/IODispatcher.cpp
+0
-1
Simulation.cpp
Simulation.cpp
+18
-17
events/EventManager.cpp
events/EventManager.cpp
+193
-61
events/EventManager.h
events/EventManager.h
+4
-0
geometry/Building.cpp
geometry/Building.cpp
+5
-2
pedestrian/Knowledge.cpp
pedestrian/Knowledge.cpp
+47
-5
pedestrian/Knowledge.h
pedestrian/Knowledge.h
+69
-3
pedestrian/Pedestrian.cpp
pedestrian/Pedestrian.cpp
+11
-4
pedestrian/Pedestrian.h
pedestrian/Pedestrian.h
+13
-4
No files found.
IO/IODispatcher.cpp
View file @
e8efcb45
...
...
@@ -557,7 +557,6 @@ void TrajectoriesJPSV06::WriteFrame(int frameNr, Building* building)
char
tmp1
[
CLENGTH
]
=
""
;
int
color
=
ped
->
GetColor
();
double
a
=
ped
->
GetLargerAxis
();
double
b
=
ped
->
GetSmallerAxis
();
...
...
Simulation.cpp
View file @
e8efcb45
...
...
@@ -498,29 +498,29 @@ int Simulation::RunBody(double maxSimTime)
while
(
(
_nPeds
||
!
_agentSrcManager
.
IsCompleted
()
)
&&
t
<
maxSimTime
)
{
t
=
0
+
(
frameNr
-
1
)
*
_deltaT
;
//process the queue for incoming pedestrians
ProcessAgentsQueue
();
if
(
t
>
Pedestrian
::
GetMinPremovementTime
())
{
//update the linked cells
_building
->
UpdateGrid
();
//update the linked cells
_building
->
UpdateGrid
();
// update the positions
_operationalModel
->
ComputeNextTimeStep
(
t
,
_deltaT
,
_building
.
get
());
// update the positions
_operationalModel
->
ComputeNextTimeStep
(
t
,
_deltaT
,
_building
.
get
());
//update the routes and location
s
UpdateRoutesAndLocations
();
//update the event
s
_em
->
ProcessEvent
();
//update the events
//_em->Update_Events(t);
_em
->
ProcessEvent
();
//update the routes and locations
UpdateRoutesAndLocations
();
//other updates
//someone might have left the building
_nPeds
=
_building
->
GetAllPedestrians
().
size
();
}
//other updates
//someone might have left the building
_nPeds
=
_building
->
GetAllPedestrians
().
size
();
}
// update the global time
Pedestrian
::
SetGlobalTime
(
t
);
...
...
@@ -528,7 +528,8 @@ int Simulation::RunBody(double maxSimTime)
if
(
0
==
frameNr
%
writeInterval
)
{
_iod
->
WriteFrame
(
frameNr
/
writeInterval
,
_building
.
get
());
}
Log
->
ProgressBar
(
initialnPeds
,
initialnPeds
-
_building
->
GetAllPedestrians
().
size
()
,
t
);
Log
->
ProgressBar
(
initialnPeds
,
initialnPeds
-
_nPeds
,
t
);
// needed to control the execution time PART 2
// time(&endtime);
// double timeToWait=t-difftime(endtime, starttime);
...
...
@@ -571,5 +572,5 @@ AgentsSourcesManager& Simulation::GetAgentSrcManager()
Building
*
Simulation
::
GetBuilding
()
{
return
_building
.
get
();
return
_building
.
get
();
}
events/EventManager.cpp
View file @
e8efcb45
...
...
@@ -82,11 +82,16 @@ EventManager::EventManager(Building *_b)
//generate random number between 0 and 1 uniformly distributed
_rdDistribution
=
std
::
uniform_real_distribution
<
double
>
(
0
,
1
);
std
::
random_device
rd
;
_rdGenerator
=
std
::
mt19937
(
rd
());
//std::random_device rd;
//_rdGenerator=std::mt19937(rd());
_rdGenerator
=
std
::
mt19937
(
23
);
//save the first graph
CreateRoutingEngine
(
_b
,
true
);
//create and
CreateSomeEngine
();
}
EventManager
::~
EventManager
()
...
...
@@ -202,9 +207,9 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
//actualize the information about the newly closed door
if
(
door
.
second
->
IsOpen
()
==
false
)
{
ped
->
AddKnownClosedDoor
(
door
.
first
,
Pedestrian
::
GetGlobalTime
());
//1.0 because the information is sure
ped
->
AddKnownClosedDoor
(
door
.
first
,
Pedestrian
::
GetGlobalTime
(),
!
door
.
second
->
IsOpen
(),
_updateFrequency
,
1.0
);
ped
->
SetNewEventFlag
(
true
);
}
}
}
...
...
@@ -214,8 +219,14 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
vector
<
Pedestrian
*>
informant
;
for
(
auto
&&
ped
:
_b
->
GetAllPedestrians
())
{
if
(
ped
->
GetNewEventFlag
())
//
if (ped->GetNewEventFlag())
informant
.
push_back
(
ped
);
for
(
auto
&&
info
:
ped
->
GetKnownledge
())
{
info
.
second
.
DecreaseLatency
(
_updateFrequency
);
}
}
...
...
@@ -231,7 +242,8 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
vector
<
SubRoom
*>
empty
;
if
(
_b
->
IsVisible
(
ped1
->
GetPos
(),
ped2
->
GetPos
(),
empty
))
{
//SynchronizeKnowledge(ped1, ped2); //ped1->SetSpotlight(true);
//if(SynchronizeKnowledge(ped1, ped2)) //ped1->SetSpotlight(true);
//if(MergeKnowledgeUsingProbability(ped1, ped2))
if
(
MergeKnowledge
(
ped1
,
ped2
))
{
//p2 is now an informant
...
...
@@ -246,6 +258,7 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
if
(
informant
.
size
()
==
_b
->
GetAllPedestrians
().
size
())
{
//Log->Write("INFO:\t all pedestrians are now propagating information");
for
(
auto
&&
ped
:
_b
->
GetAllPedestrians
())
ped
->
SetNewEventFlag
(
false
);
}
...
...
@@ -275,7 +288,8 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
//Clear the memory and attempt to reroute
//this can happen if all doors are known to be closed
ped
->
ClearKnowledge
();
//Log->Write("ERROR: \t clearing ped knowledge");
Log
->
Write
(
"ERROR:
\t
clearing ped knowledge"
);
//ped->Dump(ped->GetID());
if
(
UpdateRoute
(
ped
)
==
false
)
{
Log
->
Write
(
"ERROR:
\t
cannot reroute the pedestrian. unknown problem"
);
...
...
@@ -353,63 +367,139 @@ bool EventManager::SynchronizeKnowledge(Pedestrian* p1, Pedestrian* p2)
p2
->
ClearKnowledge
();
for
(
auto
&&
info
:
merge_info
)
{
p1
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
());
p2
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
());
p1
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
(),
info
.
second
.
GetState
(),
info
.
second
.
GetQuality
(),
_updateFrequency
);
p2
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
(),
info
.
second
.
GetState
(),
info
.
second
.
GetQuality
(),
_updateFrequency
);
}
return
true
;
}
bool
EventManager
::
MergeKnowledgeUsingProbability
(
Pedestrian
*
p1
,
Pedestrian
*
p2
)
{
auto
const
&
old_info1
=
p1
->
GetKnownledge
();
auto
const
&
old_info2
=
p2
->
GetKnownledge
();
map
<
int
,
Knowledge
>
merge_info
;
//collect the most recent knowledge
//only the knowledge that has been accepted
for
(
auto
&&
info1
:
old_info1
)
{
merge_info
[
info1
.
first
]
=
info1
.
second
;
}
for
(
auto
&&
info2
:
old_info2
)
{
//update infos according to a newest time
if
(
merge_info
.
count
(
info2
.
first
)
>
0
)
{
if
(
info2
.
second
.
GetTime
()
>
merge_info
[
info2
.
first
].
GetTime
())
// and the quality
// only if I never refused that information
{
merge_info
[
info2
.
first
]
=
info2
.
second
;
}
}
else
//the info was not present, just add
{
merge_info
[
info2
.
first
]
=
info2
.
second
;
}
}
//synchronize the knowledge
//accept the information with a certain probability
if
(
_rdDistribution
(
_rdGenerator
)
<
(
1
-
p1
->
GetRiskTolerance
()))
{
//p1->ClearKnowledge();
p2
->
ClearKnowledge
();
for
(
auto
&&
info
:
merge_info
)
{
p2
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
(),
info
.
second
.
GetState
(),
_updateFrequency
,
1.0
);
}
//p2->SetSpotlight(false);
return
true
;
}
else
{
cout
<<
"refusing the information:"
<<
p2
->
GetID
()
<<
endl
;
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
//p2->SetSpotlight(true);
//exit(0);
return
false
;
}
}
bool
EventManager
::
MergeKnowledge
(
Pedestrian
*
p1
,
Pedestrian
*
p2
)
{
auto
const
&
old_info1
=
p1
->
GetKnownledge
();
auto
const
&
old_info2
=
p2
->
GetKnownledge
();
map
<
int
,
Knowledge
>
merge_info
;
//collect the most recent knowledge
for
(
auto
&&
info1
:
old_info1
)
{
merge_info
[
info1
.
first
]
=
info1
.
second
;
}
for
(
auto
&&
info2
:
old_info2
)
{
//update infos according to a newest time
if
(
merge_info
.
count
(
info2
.
first
)
>
0
)
{
if
(
info2
.
second
.
GetTime
()
>
merge_info
[
info2
.
first
].
GetTime
())
{
merge_info
[
info2
.
first
]
=
info2
.
second
;
}
}
else
//the info was not present, just add
{
merge_info
[
info2
.
first
]
=
info2
.
second
;
}
}
//synchronize the knowledge
//accept the information with a certain probability
//cout<<_rdDistribution(_rdGenerator)<<endl;
if
(
_rdDistribution
(
_rdGenerator
)
<
(
1
-
p1
->
GetRiskTolerance
()))
{
//p1->ClearKnowledge();
p2
->
ClearKnowledge
();
for
(
auto
&&
info
:
merge_info
)
{
//p1->AddKnownClosedDoor(info.first, info.second.GetTime());
p2
->
AddKnownClosedDoor
(
info
.
first
,
info
.
second
.
GetTime
());
}
//p2->SetSpotlight(false);
return
true
;
}
else
{
cout
<<
"refusing the information:"
<<
p2
->
GetID
()
<<
endl
;
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
//p2->SetSpotlight(true);
//exit(0);
return
false
;
}
auto
&
old_info2
=
p2
->
GetKnownledge
();
//accept the new information
if
(
_rdDistribution
(
_rdGenerator
)
<
(
1
-
p1
->
GetRiskTolerance
()))
{
for
(
const
auto
&
info1
:
old_info1
)
{
//I dont forward information that I refused already
if
(
info1
.
second
.
HasBeenRefused
())
continue
;
// Is the latency ok ?
if
(
!
info1
.
second
.
CanBeForwarded
())
continue
;
//do I already have that information ?
if
(
old_info2
.
count
(
info1
.
first
)
>
0
)
{
//only accept if it is newer
if
(
info1
.
second
.
GetTime
()
>
old_info2
[
info1
.
first
].
GetTime
())
{
//maybe I already refused that information earlier. Keep refusing
if
(
old_info2
[
info1
.
first
].
HasBeenRefused
()
==
false
)
{
old_info2
[
info1
.
first
]
=
info1
.
second
;
//alter the quality of the info
old_info2
[
info1
.
first
].
SetQuality
(
0.5
);
old_info2
[
info1
.
first
].
SetLatency
(
_updateFrequency
);
}
}
}
else
{
//new piece of information
old_info2
[
info1
.
first
]
=
info1
.
second
;
//alter the quality of the info
old_info2
[
info1
.
first
].
SetQuality
(
0.5
);
old_info2
[
info1
.
first
].
SetLatency
(
_updateFrequency
);
}
}
return
true
;
}
//refuse the new information
else
{
for
(
const
auto
&
info1
:
old_info1
)
{
if
(
old_info2
.
count
(
info1
.
first
)
>
0
)
{
old_info2
[
info1
.
first
].
Refuse
(
true
);
old_info2
[
info1
.
first
].
SetLatency
(
_updateFrequency
);
//cout<<"refusing present: "<<p2->GetID()<<endl;
}
else
{
//refuse the information and set a bad quality
old_info2
[
info1
.
first
]
=
info1
.
second
;
//alter the quality of the info
old_info2
[
info1
.
first
].
SetQuality
(
0.0
);
old_info2
[
info1
.
first
].
Refuse
(
true
);
old_info2
[
info1
.
first
].
SetLatency
(
_updateFrequency
);
//cout<<"refusing: "<<p2->GetID()<<endl;
}
}
//p2->SetSpotlight(true);
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
cout
<<
"refusing..."
<<
p2
->
GetID
()
<<
endl
;
return
false
;
}
}
void
EventManager
::
ProcessEvent
()
...
...
@@ -426,7 +516,7 @@ void EventManager::ProcessEvent()
UpdateAgentKnowledge
(
_building
);
//actualize based on the new knowledge
_lastUpdateTime
=
current_time
;
//cout<<"updat
ing..."<<current_time<<endl
<<endl;
//cout<<"updat
e: "<<current_time
<<endl;
}
//update the building state
...
...
@@ -561,9 +651,6 @@ bool EventManager::CreateRoutingEngine(Building* _b, int first_engine)
// create a new one with the actual configuration
if
(
_eventEngineStorage
.
count
(
key
)
==
0
)
{
//std::shared_ptr<RoutingEngine> engine = std::shared_ptr<RoutingEngine>(new RoutingEngine());
//engine.get()->Init(_b);
//_eventEngineStorage[key]=engine.get();
//populate the engine with the routers defined in the ini file
//and initialize
...
...
@@ -631,4 +718,49 @@ Router * EventManager::CreateRouter(const RoutingStrategy& strategy)
return
rout
;
}
void
EventManager
::
CreateSomeEngine
()
{
Log
->
Write
(
"INFO:
\t
populating routers"
);
std
::
map
<
int
,
bool
>
doors_states
;
//save the doors states
for
(
auto
&&
t
:
_building
->
GetAllTransitions
())
{
doors_states
[
t
.
second
->
GetID
()]
=
t
.
second
->
IsOpen
();
}
//open all doors
for
(
auto
&&
t
:
_building
->
GetAllTransitions
())
{
t
.
second
->
Open
();
}
//close the doors one by one and create engines
for
(
auto
&&
t1
:
_building
->
GetAllTransitions
())
{
for
(
auto
&&
t2
:
_building
->
GetAllTransitions
())
{
t2
.
second
->
Open
();
}
t1
.
second
->
Close
();
//create the engine;
CreateRoutingEngine
(
_building
,
false
);
}
//restore the door states
for
(
auto
&&
t
:
_building
->
GetAllTransitions
())
{
if
(
doors_states
[
t
.
second
->
GetID
()])
{
t
.
second
->
Open
();
}
else
{
t
.
second
->
Close
();
}
}
Log
->
Write
(
"INFO:
\t
done"
);
}
events/EventManager.h
View file @
e8efcb45
...
...
@@ -120,6 +120,9 @@ private:
*/
bool
MergeKnowledge
(
Pedestrian
*
p1
,
Pedestrian
*
p2
);
bool
MergeKnowledgeUsingProbability
(
Pedestrian
*
p1
,
Pedestrian
*
p2
);
/**
* Update the pedestrian route based on the new information
* @param p1
...
...
@@ -127,6 +130,7 @@ private:
*/
bool
UpdateRoute
(
Pedestrian
*
p1
);
void
CreateSomeEngine
();
private:
...
...
geometry/Building.cpp
View file @
e8efcb45
...
...
@@ -1257,16 +1257,19 @@ void Building::DeletePedestrian(Pedestrian* &ped)
}
}
_allPedestians
.
erase
(
it
);
}
//update the stats before deleting
Transition
*
trans
=
GetTransitionByUID
(
ped
->
GetExitIndex
());
if
(
trans
)
{
trans
->
IncreaseDoorUsage
(
1
,
ped
->
GetGlobalTime
());
//this can happen if the pedesrians is pushed too hard
// or cant stop due to high velocity
// he will remain in the simulation in that case
if
(
trans
->
IsOpen
()
==
false
)
return
;
}
_allPedestians
.
erase
(
it
);
delete
ped
;
//ped=nullptr;
}
const
vector
<
Pedestrian
*>&
Building
::
GetAllPedestrians
()
const
...
...
pedestrian/Knowledge.cpp
View file @
e8efcb45
...
...
@@ -27,8 +27,6 @@
#include "Knowledge.h"
#include "../IO/OutputHandler.h"
extern
OutputHandler
*
Log
;
Knowledge
::
Knowledge
()
{
...
...
@@ -36,22 +34,29 @@ Knowledge::Knowledge()
_time
=
0
;
_quality
=
1
;
_id
=-
1
;
_hasBeenRefusedOnce
=
false
;
_latency
=
0.0
;
}
Knowledge
::~
Knowledge
()
{
}
void
Knowledge
::
Dump
()
std
::
string
Knowledge
::
Dump
()
{
Log
->
Write
(
"INFO:
\t
door [%d] state [%d] since [%f]
\n
"
,
_id
,
_isClosed
,
_time
);
char
tmp
[
2048
];
sprintf
(
tmp
,
"door [%d] state [%d] since [%.2f] sec. Refused= %d, Quality=%.2f, latency=%.2f"
,
_id
,
_isClosed
,
_time
,
_hasBeenRefusedOnce
,
_quality
,
_latency
);
return
std
::
string
(
tmp
);
}
void
Knowledge
::
SetState
(
int
id
,
bool
is_closed
,
double
time
)
void
Knowledge
::
SetState
(
int
id
,
bool
is_closed
,
double
time
,
double
quality
,
double
latency
,
bool
refuse
)
{
_isClosed
=
is_closed
;
_time
=
time
;
_id
=
id
;
_quality
=
quality
;
_hasBeenRefusedOnce
=
refuse
;
_latency
=
latency
;
}
bool
Knowledge
::
GetState
()
const
...
...
@@ -64,7 +69,44 @@ double Knowledge::GetQuality() const
return
_quality
;
}
void
Knowledge
::
SetQuality
(
double
quality
)
{
_quality
=
quality
;
}
double
Knowledge
::
GetTime
()
const
{
return
_time
;
}
bool
Knowledge
::
HasBeenRefused
()
const
{
return
_hasBeenRefusedOnce
;
}
void
Knowledge
::
Refuse
(
bool
state
)
{
_hasBeenRefusedOnce
=
state
;
}
bool
Knowledge
::
CanBeForwarded
()
const
{
return
(
_latency
<=
0
);
}
void
Knowledge
::
SetLatency
(
double
latency
)
{
_latency
=
latency
;
}
double
Knowledge
::
GetLatency
()
const
{
return
_latency
;
}
void
Knowledge
::
DecreaseLatency
(
double
minus
)
{
_latency
=
_latency
-
minus
;
if
(
_latency
<=
0
)
_latency
=
0.0
;
}
pedestrian/Knowledge.h
View file @
e8efcb45
...
...
@@ -43,12 +43,76 @@ public:
*/
~
Knowledge
();
void
Dump
();
void
SetState
(
int
id
,
bool
is_closed
,
double
time
);
/**
* Initialize the knowledge
* @param id
* @param is_closed
* @param time
* @param quality
* @param refuse
*/
void
SetState
(
int
id
,
bool
is_closed
,
double
time
,
double
quality
,
double
latency
,
bool
refuse
=
false
);
/**
* @return the state of the object. close or open
*/
bool
GetState
()
const
;
/**
* transmitted knowledge have a lower quality than those gathered by oneself.
* @return the quality of the knowledge
*/
double
GetQuality
()
const
;
/**
* transmitted knowledge have a lower quality than those gathered by oneself.
* @return the quality of the knowledge
*/
void
SetQuality
(
double
quality
);
/**
* When was the event recorded
*/
double
GetTime
()
const
;
/**
* @return whether this knowledge has been refused before
*/
bool
HasBeenRefused
()
const
;
/**
* store but refuse the knowledge.
* @param state
*/
void
Refuse
(
bool
state
);
/**
* print the content of the knowledge as string
*/
std
::
string
Dump
();
/**
* @return true, if the information can be forwarded
*/
bool
CanBeForwarded
()
const
;
/**
* Set/Get the latency time before forwarding the information
*/
void
SetLatency
(
double
latency
);
/**
* Set/Get the latency time before forwarding the information
*/
double
GetLatency
()
const
;
/**
* Update the latency by reducing the specified time.
* The latency will eventually be 0 and the information will be forwarded.
* @param minus
*/
void
DecreaseLatency
(
double
minus
);
private:
/// information quality in [0..1]. 1 is very reliable information
double
_quality
;
//
...
...
@@ -59,7 +123,9 @@ private:
/// id of the door
int
_id
;
/// whether I already accepted or refused that information
bool
_refusedOnce
;
bool
_hasBeenRefusedOnce
;
/// time to retain this information before forwarding
double
_latency
;
};
#endif
/* KNOWLEDGE_H_ */
...
...
pedestrian/Pedestrian.cpp
View file @
e8efcb45
...
...
@@ -329,10 +329,10 @@ void Pedestrian::ClearMentalMap()
_exitIndex
=
-
1
;
}
void
Pedestrian
::
AddKnownClosedDoor
(
int
door
,
double
t
ime
)
void
Pedestrian
::
AddKnownClosedDoor
(
int
door
,
double
t
time
,
bool
state
,
double
quality
,
double
latency
)
{
if
(
t
ime
==
0
)
time
=
_globalTime
;
_knownDoors
[
door
].
SetState
(
door
,
true
,
time
);
if
(
t
time
==
0
)
t
time
=
_globalTime
;
_knownDoors
[
door
].
SetState
(
door
,
state
,
ttime
,
quality
,
latency
);
}
void
Pedestrian
::
ClearKnowledge
()
...
...
@@ -340,7 +340,7 @@ void Pedestrian::ClearKnowledge()
_knownDoors
.
clear
();
}
const
map
<
int
,
Knowledge
>&
Pedestrian
::
GetKnownledge
()
const
map
<
int
,
Knowledge
>&
Pedestrian
::
GetKnownledge
()
{
return
_knownDoors
;
}
...
...
@@ -350,6 +350,9 @@ const std::string Pedestrian::GetKnowledgeAsString() const
string
key
=
""
;
for
(
auto
&&
knowledge
:
_knownDoors
)
{
//skip low quality information
if
(
knowledge
.
second
.
GetQuality
()
<
0.2
)
continue
;
int
door
=
knowledge
.
first
;
if
(
key
.
empty
())
key
.
append
(
std
::
to_string
(
door
));
...
...
@@ -765,6 +768,10 @@ void Pedestrian::Dump(int ID, int pa)
printf
(
">> mental map"
);