Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dsm/dsm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

static constexpr uint8_t DSM_VERSION_MAJOR = 2;
static constexpr uint8_t DSM_VERSION_MINOR = 5;
static constexpr uint8_t DSM_VERSION_PATCH = 11;
static constexpr uint8_t DSM_VERSION_PATCH = 12;

static auto const DSM_VERSION =
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH);
Expand Down
8 changes: 4 additions & 4 deletions src/dsm/headers/Edge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace dsm {
Id m_id;
std::pair<Id, Id> m_nodePair;
int m_capacity;
int m_transportCapacity;
double m_transportCapacity;
double m_angle;

void m_setAngle(std::pair<double, double> srcNodeCoordinates,
Expand All @@ -29,11 +29,11 @@ namespace dsm {
Edge(Id id,
std::pair<Id, Id> nodePair,
int capacity = 1,
int transportCapacity = 1,
double transportCapacity = 1.,
std::vector<std::pair<double, double>> geometry = {});

void setCapacity(int capacity);
void setTransportCapacity(int capacity);
void setTransportCapacity(double capacity);
void setGeometry(std::vector<std::pair<double, double>> geometry);

/// @brief Get the edge's id
Expand All @@ -56,7 +56,7 @@ namespace dsm {
int capacity() const;
/// @brief Get the edge's transport capacity, in number of agents
/// @return int The edge's transport capacity, in number of agents
int transportCapacity() const;
double transportCapacity() const;
/// @brief Get the edge's angle, in radians, between the source and target nodes
/// @return double The edge's angle, in radians
double angle() const;
Expand Down
2 changes: 1 addition & 1 deletion src/dsm/headers/Road.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace dsm {
std::string name = std::string(),
std::vector<std::pair<double, double>> geometry = {},
std::optional<int> capacity = std::nullopt,
int transportCapacity = 1);
double transportCapacity = 1.);
/// @brief Set the mean vehicle length, in meters (default is 5)
/// @param meanVehicleLength The mean vehicle length
/// @throws std::invalid_argument If the mean vehicle length is less or equal to 0
Expand Down
149 changes: 79 additions & 70 deletions src/dsm/headers/RoadDynamics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,87 +550,98 @@
requires(is_numeric_v<delay_t>)
void RoadDynamics<delay_t>::m_evolveStreet(const std::unique_ptr<Street>& pStreet,
bool reinsert_agents) {
auto const nLanes = pStreet->nLanes();
std::uniform_real_distribution<double> uniformDist{0., 1.};
bool bCanPass{true};
if (pStreet->isStochastic() &&
(uniformDist(this->m_generator) >
dynamic_cast<StochasticStreet&>(*pStreet).flowRate())) {
bCanPass = false;
}
for (auto queueIndex = 0; queueIndex < nLanes; ++queueIndex) {
if (pStreet->queue(queueIndex).empty()) {
continue;
}
const auto agentId{pStreet->queue(queueIndex).front()};
auto const& pAgent{this->agents().at(agentId)};
if (pAgent->freeTime() > this->time()) {
continue;
auto const& transportCapacity{pStreet->transportCapacity()};
for (auto i = 0; i < std::ceil(transportCapacity); ++i) {
auto const nLanes = pStreet->nLanes();
std::uniform_real_distribution<double> uniformDist{0., 1.};
bool bCanPass{true};
if (pStreet->isStochastic() &&
(uniformDist(this->m_generator) >
dynamic_cast<StochasticStreet&>(*pStreet).flowRate())) {
bCanPass = false;
}

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
pAgent->setSpeed(0.);
const auto& destinationNode{this->graph().node(pStreet->target())};
if (destinationNode->isFull()) {
continue;
if (i == std::ceil(transportCapacity) - 1) {
double integral;
double fractional = std::modf(transportCapacity, &integral);
if (fractional != 0. && uniformDist(this->m_generator) > fractional) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
bCanPass = false;

Check notice

Code scanning / Cppcheck (reported by Codacy)

time is Y2038-unsafe Note

time is Y2038-unsafe
}
}
if (destinationNode->isTrafficLight()) {
auto& tl = dynamic_cast<TrafficLight&>(*destinationNode);
auto const direction{pStreet->laneMapping().at(queueIndex)};
if (!tl.isGreen(pStreet->id(), direction)) {
for (auto queueIndex = 0; queueIndex < nLanes; ++queueIndex) {
if (pStreet->queue(queueIndex).empty()) {
continue;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
}
}
bCanPass = bCanPass &&
(uniformDist(this->m_generator) < m_passageProbability.value_or(1.1));
bool bArrived{false};
if (!bCanPass) {
if (pAgent->isRandom()) {
bArrived = true;
} else {
const auto agentId{pStreet->queue(queueIndex).front()};
auto const& pAgent{this->agents().at(agentId)};

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
if (pAgent->freeTime() > this->time()) {
continue;
}
}
if (!pAgent->isRandom()) {
if (destinationNode->id() ==
this->itineraries().at(pAgent->itineraryId())->destination()) {
bArrived = true;
pAgent->setSpeed(0.);
const auto& destinationNode{this->graph().node(pStreet->target())};
if (destinationNode->isFull()) {
continue;
}
if (destinationNode->isTrafficLight()) {
auto& tl = dynamic_cast<TrafficLight&>(*destinationNode);
auto const direction{pStreet->laneMapping().at(queueIndex)};

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
if (!tl.isGreen(pStreet->id(), direction)) {
continue;
}
}
bCanPass = bCanPass &&
(uniformDist(this->m_generator) < m_passageProbability.value_or(1.1));
bool bArrived{false};
if (!bCanPass) {
if (pAgent->isRandom()) {
bArrived = true;
} else {
continue;
}
}
if (!pAgent->isRandom()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

time is Y2038-unsafe Note

time is Y2038-unsafe
if (destinationNode->id() ==

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
this->itineraries().at(pAgent->itineraryId())->destination()) {
bArrived = true;

Check notice

Code scanning / Cppcheck (reported by Codacy)

time is Y2038-unsafe Note

time is Y2038-unsafe
}
}
if (bArrived) {
pStreet->dequeue(queueIndex);
m_travelDTs.push_back(
{pAgent->distance(),
static_cast<double>(this->time() - pAgent->spawnTime())});
if (reinsert_agents) {
// reset Agent's values
pAgent->reset(this->time());
} else {
m_agentsToRemove.push_back(agentId);
// this->removeAgent(agentId);
}
continue;
}
auto const& nextStreet{

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
this->graph().edge(this->agents().at(agentId)->nextStreetId().value())};
if (nextStreet->isFull()) {
continue;

Check warning on line 624 in src/dsm/headers/RoadDynamics.hpp

View check run for this annotation

Codecov / codecov/patch

src/dsm/headers/RoadDynamics.hpp#L624

Added line #L624 was not covered by tests
}
}
if (bArrived) {
pStreet->dequeue(queueIndex);

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
m_travelDTs.push_back({pAgent->distance(),
static_cast<double>(this->time() - pAgent->spawnTime())});
if (reinsert_agents) {
// reset Agent's values
pAgent->reset(this->time());
} else {
m_agentsToRemove.push_back(agentId);
// this->removeAgent(agentId);
if (destinationNode->id() != nextStreet->source()) {
Logger::error(std::format("Agent {} is going to the wrong street", agentId));

Check warning on line 628 in src/dsm/headers/RoadDynamics.hpp

View check run for this annotation

Codecov / codecov/patch

src/dsm/headers/RoadDynamics.hpp#L628

Added line #L628 was not covered by tests
}
assert(destinationNode->id() == nextStreet->source());
if (destinationNode->isIntersection()) {
auto& intersection = dynamic_cast<Intersection&>(*destinationNode);
auto const delta{nextStreet->deltaAngle(pStreet->angle())};
// m_increaseTurnCounts(pStreet->id(), delta);
intersection.addAgent(delta, agentId);
} else if (destinationNode->isRoundabout()) {
auto& roundabout = dynamic_cast<Roundabout&>(*destinationNode);
roundabout.enqueue(agentId);
}
continue;
}
auto const& nextStreet{
this->graph().edge(this->agents().at(agentId)->nextStreetId().value())};
if (nextStreet->isFull()) {
continue;
}
pStreet->dequeue(queueIndex);
if (destinationNode->id() != nextStreet->source()) {
Logger::error(std::format("Agent {} is going to the wrong street", agentId));
}
assert(destinationNode->id() == nextStreet->source());
if (destinationNode->isIntersection()) {
auto& intersection = dynamic_cast<Intersection&>(*destinationNode);
auto const delta{nextStreet->deltaAngle(pStreet->angle())};
// m_increaseTurnCounts(pStreet->id(), delta);
intersection.addAgent(delta, agentId);
} else if (destinationNode->isRoundabout()) {
auto& roundabout = dynamic_cast<Roundabout&>(*destinationNode);
roundabout.enqueue(agentId);
}
}
}

template <typename delay_t>

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
requires(is_numeric_v<delay_t>)
bool RoadDynamics<delay_t>::m_evolveNode(const std::unique_ptr<Node>& pNode) {
if (pNode->isIntersection()) {
Expand Down Expand Up @@ -700,7 +711,7 @@
const auto& street{this->graph().edge(*pAgent->streetId())};
auto const nLanes = street->nLanes();
bool bArrived{false};
if (!pAgent->isRandom()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
if (this->itineraries().at(pAgent->itineraryId())->destination() ==
street->target()) {
pAgent->updateItinerary();
Expand Down Expand Up @@ -1111,9 +1122,7 @@
if (bUpdateData) {
m_streetTails[streetId] += pStreet->nExitingAgents();
}
for (auto i = 0; i < pStreet->transportCapacity(); ++i) {
m_evolveStreet(pStreet, reinsert_agents);
}
m_evolveStreet(pStreet, reinsert_agents);
}
});
std::for_each(this->m_agentsToRemove.cbegin(),
Expand Down
4 changes: 2 additions & 2 deletions src/dsm/headers/Street.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace dsm {
std::string name = std::string(),
std::vector<std::pair<double, double>> geometry = {},
std::optional<int> capacity = std::nullopt,
int transportCapacity = 1);
double transportCapacity = 1.);
virtual ~Street() = default;

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

void setFlowRate(double const flowRate);
double flowRate() const;
Expand Down
16 changes: 5 additions & 11 deletions src/dsm/sources/Edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace dsm {
Edge::Edge(Id id,
std::pair<Id, Id> nodePair,
int capacity,
int transportCapacity,
double transportCapacity,
std::vector<std::pair<double, double>> geometry)
: m_geometry{std::move(geometry)},
m_id(id),
Expand All @@ -21,10 +21,7 @@ namespace dsm {
if (capacity < 1) {
Logger::error(std::format("Edge capacity ({}) must be greater than 0.", capacity));
}
if (transportCapacity < 1) {
Logger::error(std::format("Edge transport capacity ({}) must be greater than 0.",
transportCapacity));
}
assert(transportCapacity > 0.);
if (m_geometry.size() > 1) {
m_setAngle(m_geometry[m_geometry.size() - 2], m_geometry.back());
} else {
Expand All @@ -50,11 +47,8 @@ namespace dsm {
}
m_capacity = capacity;
}
void Edge::setTransportCapacity(int capacity) {
if (capacity < 1) {
Logger::error(
std::format("Edge transport capacity ({}) must be greater than 0.", capacity));
}
void Edge::setTransportCapacity(double capacity) {
assert(capacity > 0.);
m_transportCapacity = capacity;
}

Expand All @@ -72,7 +66,7 @@ namespace dsm {
Id Edge::target() const { return m_nodePair.second; }
std::pair<Id, Id> const& Edge::nodePair() const { return m_nodePair; }
int Edge::capacity() const { return m_capacity; }
int Edge::transportCapacity() const { return m_transportCapacity; }
double Edge::transportCapacity() const { return m_transportCapacity; }
double Edge::angle() const { return m_angle; }
std::vector<std::pair<double, double>> const& Edge::geometry() const {
return m_geometry;
Expand Down
2 changes: 1 addition & 1 deletion src/dsm/sources/Road.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace dsm {
std::string name,
std::vector<std::pair<double, double>> geometry,
std::optional<int> capacity,
int transportCapacity)
double transportCapacity)
: Edge(id,
std::move(nodePair),
capacity.value_or(std::ceil((length * nLanes) / m_meanVehicleLength)),
Expand Down
4 changes: 2 additions & 2 deletions src/dsm/sources/Street.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
std::string name,
std::vector<std::pair<double, double>> geometry,
std::optional<int> capacity,
int transportCapacity)
double transportCapacity)
: Road(id,
std::move(nodePair),
length,
Expand Down Expand Up @@ -140,7 +140,7 @@
std::vector<std::pair<double, double>> geometry,
double flowRate,
std::optional<int> capacity,
int transportCapacity)
double transportCapacity)

Check warning on line 143 in src/dsm/sources/Street.cpp

View check run for this annotation

Codecov / codecov/patch

src/dsm/sources/Street.cpp#L143

Added line #L143 was not covered by tests
: Street(id,
std::move(nodePair),
length,
Expand Down
37 changes: 33 additions & 4 deletions test/Test_dynamics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@
dynamics.addAgents(n);
THEN("The number of agents is correct") { CHECK_EQ(dynamics.nAgents(), 100); }
THEN("If we evolve the dynamics agent disappear gradually") {
// for (auto i{0}; i < 40; ++i) {
// dynamics.evolve(false);
// }
// CHECK(dynamics.nAgents() < n);
for (auto i{0}; i < 40; ++i) {
dynamics.evolve(false);
}
CHECK(dynamics.nAgents() < n);
}
}
}
Expand Down Expand Up @@ -512,7 +512,7 @@
dynamics.evolve(false);
dynamics.evolve(false);
THEN("The agent evolves") {
CHECK_EQ(dynamics.time() - dynamics.agents().at(0)->spawnTime(), 2);

Check notice

Code scanning / Cppcheck (reported by Codacy)

time is Y2038-unsafe Note test

time is Y2038-unsafe
CHECK_EQ(dynamics.agents().at(0)->freeTime(), dynamics.time());
CHECK_EQ(dynamics.agents().at(0)->streetId().value(), 1);
CHECK_EQ(dynamics.agents().at(0)->speed(), 13.8888888889);
Expand All @@ -522,6 +522,35 @@
THEN("The agent reaches the destination") { CHECK(dynamics.agents().empty()); }
}
}
GIVEN("A dynamics object, an itinerary and an agent") {
Street s1{0, std::make_pair(0, 1), 13.8888888889};

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note test

MISRA 12.3 rule
Street s2{1, std::make_pair(1, 0), 13.8888888889};

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note test

MISRA 12.3 rule
s1.setTransportCapacity(0.3);
RoadNetwork graph2;
graph2.addStreets(s1, s2);
graph2.buildAdj();
Dynamics dynamics{graph2, false, 69, 0., dsm::weight_functions::streetLength, 1.};
dynamics.addItinerary(std::unique_ptr<Itinerary>(new Itinerary(0, 1)));
dynamics.updatePaths();
dynamics.addAgent(0, 0, 0);
WHEN("We evolve the dynamics") {
dynamics.evolve(false);
dynamics.evolve(false);
THEN("The agent evolves") {
CHECK_EQ(dynamics.time() - dynamics.agents().at(0)->spawnTime(), 2);
CHECK_EQ(dynamics.agents().at(0)->freeTime(), dynamics.time());
CHECK_EQ(dynamics.agents().at(0)->streetId().value(), 1);
CHECK_EQ(dynamics.agents().at(0)->speed(), 13.8888888889);
CHECK_EQ(dynamics.agents().at(0)->distance(), 13.8888888889);
}
auto i{0};
while (dynamics.nAgents() > 0) {
dynamics.evolve(false);
++i;
}
THEN("The agent reaches the destination") { CHECK(i > 0); }
}
}
GIVEN("A dynamics object, an itinerary and an agent") {
Street s1{0, std::make_pair(0, 1), 13.8888888889};
Street s2{1, std::make_pair(1, 0), 13.8888888889};
Expand Down Expand Up @@ -883,7 +912,7 @@
"A dynamics with one stochastic street and one normal street network and an "
"agent") {
Street s1{0, std::make_pair(0, 1), 3.};
Street s2{1, std::make_pair(1, 2), 1.};

Check notice

Code scanning / Cppcheck (reported by Codacy)

time is Y2038-unsafe Note test

time is Y2038-unsafe
RoadNetwork graph2;
graph2.addStreets(s1, s2);
graph2.buildAdj();
Expand Down
Loading