Skip to content

Commit 59144c2

Browse files
committed
Make street transport capacity a double value
1 parent f031e28 commit 59144c2

File tree

9 files changed

+128
-96
lines changed

9 files changed

+128
-96
lines changed

src/dsm/dsm.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
static constexpr uint8_t DSM_VERSION_MAJOR = 2;
88
static constexpr uint8_t DSM_VERSION_MINOR = 5;
9-
static constexpr uint8_t DSM_VERSION_PATCH = 11;
9+
static constexpr uint8_t DSM_VERSION_PATCH = 12;
1010

1111
static auto const DSM_VERSION =
1212
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH);

src/dsm/headers/Edge.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace dsm {
1111
Id m_id;
1212
std::pair<Id, Id> m_nodePair;
1313
int m_capacity;
14-
int m_transportCapacity;
14+
double m_transportCapacity;
1515
double m_angle;
1616

1717
void m_setAngle(std::pair<double, double> srcNodeCoordinates,
@@ -29,11 +29,11 @@ namespace dsm {
2929
Edge(Id id,
3030
std::pair<Id, Id> nodePair,
3131
int capacity = 1,
32-
int transportCapacity = 1,
32+
double transportCapacity = 1.,
3333
std::vector<std::pair<double, double>> geometry = {});
3434

3535
void setCapacity(int capacity);
36-
void setTransportCapacity(int capacity);
36+
void setTransportCapacity(double capacity);
3737
void setGeometry(std::vector<std::pair<double, double>> geometry);
3838

3939
/// @brief Get the edge's id
@@ -56,7 +56,7 @@ namespace dsm {
5656
int capacity() const;
5757
/// @brief Get the edge's transport capacity, in number of agents
5858
/// @return int The edge's transport capacity, in number of agents
59-
int transportCapacity() const;
59+
double transportCapacity() const;
6060
/// @brief Get the edge's angle, in radians, between the source and target nodes
6161
/// @return double The edge's angle, in radians
6262
double angle() const;

src/dsm/headers/Road.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace dsm {
3838
std::string name = std::string(),
3939
std::vector<std::pair<double, double>> geometry = {},
4040
std::optional<int> capacity = std::nullopt,
41-
int transportCapacity = 1);
41+
double transportCapacity = 1.);
4242
/// @brief Set the mean vehicle length, in meters (default is 5)
4343
/// @param meanVehicleLength The mean vehicle length
4444
/// @throws std::invalid_argument If the mean vehicle length is less or equal to 0

src/dsm/headers/RoadDynamics.hpp

Lines changed: 79 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -550,82 +550,93 @@ namespace dsm {
550550
requires(is_numeric_v<delay_t>)
551551
void RoadDynamics<delay_t>::m_evolveStreet(const std::unique_ptr<Street>& pStreet,
552552
bool reinsert_agents) {
553-
auto const nLanes = pStreet->nLanes();
554-
std::uniform_real_distribution<double> uniformDist{0., 1.};
555-
bool bCanPass{true};
556-
if (pStreet->isStochastic() &&
557-
(uniformDist(this->m_generator) >
558-
dynamic_cast<StochasticStreet&>(*pStreet).flowRate())) {
559-
bCanPass = false;
560-
}
561-
for (auto queueIndex = 0; queueIndex < nLanes; ++queueIndex) {
562-
if (pStreet->queue(queueIndex).empty()) {
563-
continue;
564-
}
565-
const auto agentId{pStreet->queue(queueIndex).front()};
566-
auto const& pAgent{this->agents().at(agentId)};
567-
if (pAgent->freeTime() > this->time()) {
568-
continue;
553+
auto const& transportCapacity{pStreet->transportCapacity()};
554+
for (auto i = 0; i < std::ceil(transportCapacity); ++i) {
555+
auto const nLanes = pStreet->nLanes();
556+
std::uniform_real_distribution<double> uniformDist{0., 1.};
557+
bool bCanPass{true};
558+
if (pStreet->isStochastic() &&
559+
(uniformDist(this->m_generator) >
560+
dynamic_cast<StochasticStreet&>(*pStreet).flowRate())) {
561+
bCanPass = false;
569562
}
570-
pAgent->setSpeed(0.);
571-
const auto& destinationNode{this->graph().node(pStreet->target())};
572-
if (destinationNode->isFull()) {
573-
continue;
563+
if (i == std::ceil(transportCapacity) - 1) {
564+
double integral;
565+
double fractional = std::modf(transportCapacity, &integral);
566+
if (fractional != 0. && uniformDist(this->m_generator) > fractional) {
567+
bCanPass = false;
568+
}
574569
}
575-
if (destinationNode->isTrafficLight()) {
576-
auto& tl = dynamic_cast<TrafficLight&>(*destinationNode);
577-
auto const direction{pStreet->laneMapping().at(queueIndex)};
578-
if (!tl.isGreen(pStreet->id(), direction)) {
570+
for (auto queueIndex = 0; queueIndex < nLanes; ++queueIndex) {
571+
if (pStreet->queue(queueIndex).empty()) {
579572
continue;
580573
}
581-
}
582-
bCanPass = bCanPass &&
583-
(uniformDist(this->m_generator) < m_passageProbability.value_or(1.1));
584-
bool bArrived{false};
585-
if (!bCanPass) {
586-
if (pAgent->isRandom()) {
587-
bArrived = true;
588-
} else {
574+
const auto agentId{pStreet->queue(queueIndex).front()};
575+
auto const& pAgent{this->agents().at(agentId)};
576+
if (pAgent->freeTime() > this->time()) {
589577
continue;
590578
}
591-
}
592-
if (!pAgent->isRandom()) {
593-
if (destinationNode->id() ==
594-
this->itineraries().at(pAgent->itineraryId())->destination()) {
595-
bArrived = true;
579+
pAgent->setSpeed(0.);
580+
const auto& destinationNode{this->graph().node(pStreet->target())};
581+
if (destinationNode->isFull()) {
582+
continue;
583+
}
584+
if (destinationNode->isTrafficLight()) {
585+
auto& tl = dynamic_cast<TrafficLight&>(*destinationNode);
586+
auto const direction{pStreet->laneMapping().at(queueIndex)};
587+
if (!tl.isGreen(pStreet->id(), direction)) {
588+
continue;
589+
}
590+
}
591+
bCanPass = bCanPass &&
592+
(uniformDist(this->m_generator) < m_passageProbability.value_or(1.1));
593+
bool bArrived{false};
594+
if (!bCanPass) {
595+
if (pAgent->isRandom()) {
596+
bArrived = true;
597+
} else {
598+
continue;
599+
}
600+
}
601+
if (!pAgent->isRandom()) {
602+
if (destinationNode->id() ==
603+
this->itineraries().at(pAgent->itineraryId())->destination()) {
604+
bArrived = true;
605+
}
606+
}
607+
if (bArrived) {
608+
pStreet->dequeue(queueIndex);
609+
m_travelDTs.push_back(
610+
{pAgent->distance(),
611+
static_cast<double>(this->time() - pAgent->spawnTime())});
612+
if (reinsert_agents) {
613+
// reset Agent's values
614+
pAgent->reset(this->time());
615+
} else {
616+
m_agentsToRemove.push_back(agentId);
617+
// this->removeAgent(agentId);
618+
}
619+
continue;
620+
}
621+
auto const& nextStreet{
622+
this->graph().edge(this->agents().at(agentId)->nextStreetId().value())};
623+
if (nextStreet->isFull()) {
624+
continue;
596625
}
597-
}
598-
if (bArrived) {
599626
pStreet->dequeue(queueIndex);
600-
m_travelDTs.push_back({pAgent->distance(),
601-
static_cast<double>(this->time() - pAgent->spawnTime())});
602-
if (reinsert_agents) {
603-
// reset Agent's values
604-
pAgent->reset(this->time());
605-
} else {
606-
m_agentsToRemove.push_back(agentId);
607-
// this->removeAgent(agentId);
627+
if (destinationNode->id() != nextStreet->source()) {
628+
Logger::error(std::format("Agent {} is going to the wrong street", agentId));
629+
}
630+
assert(destinationNode->id() == nextStreet->source());
631+
if (destinationNode->isIntersection()) {
632+
auto& intersection = dynamic_cast<Intersection&>(*destinationNode);
633+
auto const delta{nextStreet->deltaAngle(pStreet->angle())};
634+
// m_increaseTurnCounts(pStreet->id(), delta);
635+
intersection.addAgent(delta, agentId);
636+
} else if (destinationNode->isRoundabout()) {
637+
auto& roundabout = dynamic_cast<Roundabout&>(*destinationNode);
638+
roundabout.enqueue(agentId);
608639
}
609-
continue;
610-
}
611-
auto const& nextStreet{
612-
this->graph().edge(this->agents().at(agentId)->nextStreetId().value())};
613-
if (nextStreet->isFull()) {
614-
continue;
615-
}
616-
pStreet->dequeue(queueIndex);
617-
if (destinationNode->id() != nextStreet->source()) {
618-
Logger::error(std::format("Agent {} is going to the wrong street", agentId));
619-
}
620-
assert(destinationNode->id() == nextStreet->source());
621-
if (destinationNode->isIntersection()) {
622-
auto& intersection = dynamic_cast<Intersection&>(*destinationNode);
623-
auto const delta{nextStreet->deltaAngle(pStreet->angle())};
624-
// m_increaseTurnCounts(pStreet->id(), delta);
625-
intersection.addAgent(delta, agentId);
626-
} else if (destinationNode->isRoundabout()) {
627-
auto& roundabout = dynamic_cast<Roundabout&>(*destinationNode);
628-
roundabout.enqueue(agentId);
629640
}
630641
}
631642
}
@@ -1111,9 +1122,7 @@ namespace dsm {
11111122
if (bUpdateData) {
11121123
m_streetTails[streetId] += pStreet->nExitingAgents();
11131124
}
1114-
for (auto i = 0; i < pStreet->transportCapacity(); ++i) {
1115-
m_evolveStreet(pStreet, reinsert_agents);
1116-
}
1125+
m_evolveStreet(pStreet, reinsert_agents);
11171126
}
11181127
});
11191128
std::for_each(this->m_agentsToRemove.cbegin(),

src/dsm/headers/Street.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ namespace dsm {
6161
std::string name = std::string(),
6262
std::vector<std::pair<double, double>> geometry = {},
6363
std::optional<int> capacity = std::nullopt,
64-
int transportCapacity = 1);
64+
double transportCapacity = 1.);
6565
virtual ~Street() = default;
6666

6767
/// @brief Set the street's queue
@@ -135,7 +135,7 @@ namespace dsm {
135135
std::vector<std::pair<double, double>> geometry = {},
136136
double flowRate = 1.,
137137
std::optional<int> capacity = std::nullopt,
138-
int transportCapacity = 1);
138+
double transportCapacity = 1.);
139139

140140
void setFlowRate(double const flowRate);
141141
double flowRate() const;

src/dsm/sources/Edge.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace dsm {
1111
Edge::Edge(Id id,
1212
std::pair<Id, Id> nodePair,
1313
int capacity,
14-
int transportCapacity,
14+
double transportCapacity,
1515
std::vector<std::pair<double, double>> geometry)
1616
: m_geometry{std::move(geometry)},
1717
m_id(id),
@@ -21,10 +21,7 @@ namespace dsm {
2121
if (capacity < 1) {
2222
Logger::error(std::format("Edge capacity ({}) must be greater than 0.", capacity));
2323
}
24-
if (transportCapacity < 1) {
25-
Logger::error(std::format("Edge transport capacity ({}) must be greater than 0.",
26-
transportCapacity));
27-
}
24+
assert(transportCapacity > 0.);
2825
if (m_geometry.size() > 1) {
2926
m_setAngle(m_geometry[m_geometry.size() - 2], m_geometry.back());
3027
} else {
@@ -50,11 +47,8 @@ namespace dsm {
5047
}
5148
m_capacity = capacity;
5249
}
53-
void Edge::setTransportCapacity(int capacity) {
54-
if (capacity < 1) {
55-
Logger::error(
56-
std::format("Edge transport capacity ({}) must be greater than 0.", capacity));
57-
}
50+
void Edge::setTransportCapacity(double capacity) {
51+
assert(capacity > 0.);
5852
m_transportCapacity = capacity;
5953
}
6054

@@ -72,7 +66,7 @@ namespace dsm {
7266
Id Edge::target() const { return m_nodePair.second; }
7367
std::pair<Id, Id> const& Edge::nodePair() const { return m_nodePair; }
7468
int Edge::capacity() const { return m_capacity; }
75-
int Edge::transportCapacity() const { return m_transportCapacity; }
69+
double Edge::transportCapacity() const { return m_transportCapacity; }
7670
double Edge::angle() const { return m_angle; }
7771
std::vector<std::pair<double, double>> const& Edge::geometry() const {
7872
return m_geometry;

src/dsm/sources/Road.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace dsm {
2727
std::string name,
2828
std::vector<std::pair<double, double>> geometry,
2929
std::optional<int> capacity,
30-
int transportCapacity)
30+
double transportCapacity)
3131
: Edge(id,
3232
std::move(nodePair),
3333
capacity.value_or(std::ceil((length * nLanes) / m_meanVehicleLength)),

src/dsm/sources/Street.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace dsm {
2929
std::string name,
3030
std::vector<std::pair<double, double>> geometry,
3131
std::optional<int> capacity,
32-
int transportCapacity)
32+
double transportCapacity)
3333
: Road(id,
3434
std::move(nodePair),
3535
length,
@@ -140,7 +140,7 @@ namespace dsm {
140140
std::vector<std::pair<double, double>> geometry,
141141
double flowRate,
142142
std::optional<int> capacity,
143-
int transportCapacity)
143+
double transportCapacity)
144144
: Street(id,
145145
std::move(nodePair),
146146
length,

test/Test_dynamics.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,10 @@ TEST_CASE("Dynamics") {
260260
dynamics.addAgents(n);
261261
THEN("The number of agents is correct") { CHECK_EQ(dynamics.nAgents(), 100); }
262262
THEN("If we evolve the dynamics agent disappear gradually") {
263-
// for (auto i{0}; i < 40; ++i) {
264-
// dynamics.evolve(false);
265-
// }
266-
// CHECK(dynamics.nAgents() < n);
263+
for (auto i{0}; i < 40; ++i) {
264+
dynamics.evolve(false);
265+
}
266+
CHECK(dynamics.nAgents() < n);
267267
}
268268
}
269269
}
@@ -522,6 +522,35 @@ TEST_CASE("Dynamics") {
522522
THEN("The agent reaches the destination") { CHECK(dynamics.agents().empty()); }
523523
}
524524
}
525+
GIVEN("A dynamics object, an itinerary and an agent") {
526+
Street s1{0, std::make_pair(0, 1), 13.8888888889};
527+
Street s2{1, std::make_pair(1, 0), 13.8888888889};
528+
s1.setTransportCapacity(0.3);
529+
RoadNetwork graph2;
530+
graph2.addStreets(s1, s2);
531+
graph2.buildAdj();
532+
Dynamics dynamics{graph2, false, 69, 0., dsm::weight_functions::streetLength, 1.};
533+
dynamics.addItinerary(std::unique_ptr<Itinerary>(new Itinerary(0, 1)));
534+
dynamics.updatePaths();
535+
dynamics.addAgent(0, 0, 0);
536+
WHEN("We evolve the dynamics") {
537+
dynamics.evolve(false);
538+
dynamics.evolve(false);
539+
THEN("The agent evolves") {
540+
CHECK_EQ(dynamics.time() - dynamics.agents().at(0)->spawnTime(), 2);
541+
CHECK_EQ(dynamics.agents().at(0)->freeTime(), dynamics.time());
542+
CHECK_EQ(dynamics.agents().at(0)->streetId().value(), 1);
543+
CHECK_EQ(dynamics.agents().at(0)->speed(), 13.8888888889);
544+
CHECK_EQ(dynamics.agents().at(0)->distance(), 13.8888888889);
545+
}
546+
auto i{0};
547+
while (dynamics.nAgents() > 0) {
548+
dynamics.evolve(false);
549+
++i;
550+
}
551+
THEN("The agent reaches the destination") { CHECK(i > 0); }
552+
}
553+
}
525554
GIVEN("A dynamics object, an itinerary and an agent") {
526555
Street s1{0, std::make_pair(0, 1), 13.8888888889};
527556
Street s2{1, std::make_pair(1, 0), 13.8888888889};

0 commit comments

Comments
 (0)