Commit dd2d937a authored by Kučera Petr RNDr. Ph.D.'s avatar Kučera Petr RNDr. Ph.D.
Browse files

Initial activity times

parent deb570d0
......@@ -145,7 +145,8 @@ main([[maybe_unused]] int argc, char *argv[])
sg->PrintSubgraph(f, subg_kopanky_petrov, "subg_kopanky_petrov");
}
Loco::TrainRoutes routes(input_data, sg);
routes.UpdateActivities(input_data.mTrainList);
routes.UpdateActivities(input_data.mTrainList,
Loco::global_cfg.model.current_time.Seconds());
{
std::ofstream f(Loco::global_cfg.output.model_data);
routes.PrintModelData(f, "");
......
......@@ -41,4 +41,5 @@ default-directory = data
max-duration-addition = 300
min-stop-duration = 60
allowed-delay = 60
transition-time=10
transition-time = 10
current-time = 7:00
......@@ -146,5 +146,6 @@ Loco::CfgModel::Parse(const INISection &sect)
allowed_delay = sect.UnsignedValue("allowed-delay").value_or(allowed_delay);
transition_time =
sect.UnsignedValue("transition-time").value_or(transition_time);
current_time = sect.TimeSpecValue("current-time");
return true;
}
......@@ -72,6 +72,7 @@ namespace Loco
activity_time_type min_stop_duration{60};
activity_time_type allowed_delay{60};
activity_time_type transition_time{10};
TimeSpec current_time{0, 0};
bool Parse(const INISection &sect);
};
......
......@@ -63,14 +63,19 @@ Loco::GlobalIdent::IdentStringWithHint(const std::string &region_hint) const
Loco::TimeSpec
Loco::parse_time_spec(const std::string &ts)
{
return TimeSpec(ts);
}
Loco::TimeSpec::TimeSpec(const std::string &ts)
{
auto colon = ts.find(':');
if (colon == std::string::npos)
{
throw SyntaxErrorException("parse_time_spec", "no semicolon");
}
return TimeSpec{static_cast<unsigned>(std::stoul(ts)),
static_cast<unsigned>(std::stoul(ts.substr(colon + 1)))};
hour = static_cast<unsigned>(std::stoul(ts));
minute = std::stoul(ts.substr(colon + 1));
}
std::ostream &
......@@ -79,3 +84,9 @@ Loco::TimeSpec::Print(std::ostream &os) const
return os << std::setw(2) << std::setfill('0') << hour << ":" << std::setw(2)
<< std::setfill('0') << minute;
}
auto
Loco::TimeSpec::Seconds() const -> activity_time_type
{
return (hour * 60 + minute) * 60;
}
......@@ -51,9 +51,12 @@ namespace Loco
TimeSpec() = default;
TimeSpec(unsigned h, unsigned m) : hour(h), minute(m) {}
TimeSpec(const std::string &ts);
bool Valid() const;
std::ostream &Print(std::ostream &os) const;
activity_time_type Seconds() const;
};
TimeSpec parse_time_spec(const std::string &ts);
......
......@@ -87,8 +87,6 @@ void
Loco::TrainRouteGraph::AddEnterActivity()
{
mActList.emplace_back(mTrain->Ident() + "Enter", mEnterPlace, false);
mActList.back().mMinDuration = kTrainActivityMinDuration;
mActList.back().mMaxDuration = kTrainActivityMaxDuration;
mActList.back().mTransitionTime = global_cfg.model.transition_time;
}
......@@ -96,8 +94,6 @@ void
Loco::TrainRouteGraph::AddLeaveActivity()
{
mActList.emplace_back(mTrain->Ident() + "Leave", mLeavePlace, true);
mActList.back().mMinDuration = kTrainActivityMinDuration;
mActList.back().mMaxDuration = kTrainActivityMaxDuration;
mActList.back().mTransitionTime = global_cfg.model.transition_time;
}
......@@ -132,18 +128,30 @@ Loco::TrainRouteGraph::AddElementActivities(unsigned element_id)
element.mPlaceActivities[place] = mActList.size();
element.mSectActivities[sect] = mActList.size();
mActList.emplace_back(name, place, false);
auto &act = mActList.back();
if (node_info.mNodeType == SGSubgraph::NODE_TYPE::INNER)
{
mActList.back().mMinDuration = place->MinDuration();
mActList.back().mMaxDuration = place->MaxDuration();
act.mMinDuration = place->MinDuration();
act.mMaxDuration = place->MaxDuration();
act.mScheduledMinDuration = act.mMinDuration;
}
else
{
mActList.back().mMinDuration = global_cfg.model.min_stop_duration;
auto stop_index = mElements[element_id].mStartStop;
if (node_info.mNodeType == SGSubgraph::NODE_TYPE::LEAF)
{
++stop_index;
}
const auto &stop = mTrain->StopAt(stop_index);
act.mMinDuration = global_cfg.model.min_stop_duration;
// TODO: Should be computed from the stop schedule
mActList.back().mMaxDuration = kMaxStopDuration;
act.mMaxDuration = kMaxStopDuration;
act.mScheduled = true;
act.mScheduledStart = stop.ScheduledStart();
act.mScheduledEnd = stop.ScheduledEnd();
act.mScheduledMinDuration = stop.ScheduledMinDuration();
}
mActList.back().mTransitionTime = global_cfg.model.transition_time;
act.mTransitionTime = global_cfg.model.transition_time;
}
}
......@@ -370,29 +378,11 @@ Loco::TrainRouteGraph::ConnectElementActivities(unsigned element_id)
}
void
Loco::TrainRouteGraph::UpdateActivities(const SectionCPtr &initial_section)
Loco::TrainRouteGraph::UpdateActivities(const SectionCPtr &initial_section,
activity_time_type current_time)
{
ClearActivities(false);
/*if (!initial_section)
{
mActList.front().mForced = true;
mActList.front().mUse = true;
}
else
{
unsigned sect_id = mSectionGraph->SectionId(initial_section);
unsigned elem_id = ElementWithSection(sect_id);
if (elem_id == mElements.size())
{
std::cerr
<< "[TrainRouteGraph::UpdateWithInitialSection] Train is not "
"on the route"
<< std::endl;
return;
}
UpdateInitialActivity(elem_id, sect_id);
}*/
for (unsigned elem_id = UpdateInitialActivity(initial_section);
for (unsigned elem_id = UpdateInitialActivity(initial_section, current_time);
elem_id < mElements.size(); ++elem_id)
{
UpdateElement(mElements[elem_id]);
......@@ -401,12 +391,18 @@ Loco::TrainRouteGraph::UpdateActivities(const SectionCPtr &initial_section)
}
unsigned
Loco::TrainRouteGraph::UpdateInitialActivity(const SectionCPtr &initial_section)
Loco::TrainRouteGraph::UpdateInitialActivity(const SectionCPtr &initial_section,
activity_time_type current_time)
{
if (!initial_section)
{
mActList.front().mForced = true;
mActList.front().mUse = true;
auto &act = mActList.front();
act.mForced = true;
act.mUse = true;
act.mMinDuration = kTrainActivityMinDuration;
act.mMaxDuration = kTrainActivityMaxDuration;
act.mMinStart = current_time;
act.mMaxEnd = current_time + act.mMaxDuration;
return 0;
}
unsigned sect_id = mSectionGraph->SectionId(initial_section);
......@@ -414,16 +410,19 @@ Loco::TrainRouteGraph::UpdateInitialActivity(const SectionCPtr &initial_section)
if (elem_id == mElements.size())
{
std::cerr << "[TrainRouteGraph::UpdateWithInitialSection] Train is not "
"on the route, assume it is before the route start"
"on the route, it shall be not part of the schedule"
<< std::endl;
mActList.front().mForced = true;
mActList.front().mUse = true;
return 0;
mActList.front().mForced = false;
mActList.front().mUse = false;
return mElements.size();
}
const auto act_id = mElements[elem_id].mSectActivities[sect_id];
auto &act = mActList[act_id];
act.mUse = true;
act.mForced = true;
act.mMinStart = current_time;
act.mMaxEnd =
std::max(current_time + act.mScheduledMinDuration, act.mScheduledEnd);
return elem_id;
}
......@@ -459,11 +458,12 @@ Loco::TrainRouteGraph::ElementWithSection(unsigned sect_id) const
}
void
Loco::TrainRoutes::UpdateActivities(const TrainList &train_list)
Loco::TrainRoutes::UpdateActivities(const TrainList &train_list,
activity_time_type current_time)
{
for (const auto &[train, sect] : train_list.TrainSections())
{
mRouteGraphs.at(train).UpdateActivities(sect);
mRouteGraphs.at(train).UpdateActivities(sect, current_time);
}
}
......
......@@ -32,6 +32,11 @@ namespace Loco
std::vector<unsigned> mSucc{};
activity_time_type mTransitionTime{kDefaultTransitionTime};
bool mScheduled{false};
activity_time_type mScheduledStart{0};
activity_time_type mScheduledEnd{0};
activity_time_type mScheduledMinDuration{0};
bool mUse{false};
Activity(std::string name, Place place, bool forced)
......@@ -108,7 +113,8 @@ namespace Loco
unsigned ElementWithSection(unsigned sect_id) const;
void UpdateElement(const Element &el);
void UpdateSubgraphNode(const Element &el, unsigned node);
unsigned UpdateInitialActivity(const SectionCPtr &initial_section);
unsigned UpdateInitialActivity(const SectionCPtr &initial_section,
activity_time_type current_time);
void UpdateLastActivity();
public:
......@@ -118,7 +124,8 @@ namespace Loco
std::ostream &PrintActivities(std::ostream &os, const std::string &prefix,
bool only_used) const;
void UpdateActivities(const SectionCPtr &initial_section);
void UpdateActivities(const SectionCPtr &initial_section,
activity_time_type current_time);
bool HasUsableActivity() const;
void CollectPlaces(UsedPlaces &used_places, bool only_used) const;
};
......@@ -148,7 +155,8 @@ namespace Loco
std::ostream &PrintModelData(std::ostream &os,
const std::string &prefix) const;
void UpdateActivities(const TrainList &train_list);
void UpdateActivities(const TrainList &train_list,
activity_time_type current_time);
};
} // namespace Loco
......
......@@ -9,6 +9,7 @@
*/
#include "trains_desc.h"
#include "cfgfile.h"
std::ostream &
Loco::TrafficPoint::PrintData(std::ostream &os, const std::string &prefix,
......@@ -74,6 +75,57 @@ Loco::TrainStop::Print(std::ostream &os, const std::string &prefix) const
return mSpec.Print(os, pfix);
}
auto
Loco::TrainStop::ScheduledStart() const -> activity_time_type
{
switch (mSpec.mStop)
{
case StopKind::UNKNOWN:
case StopKind::MANDATORY:
case StopKind::ON_DEMAND:
return mSpec.mArrival.Seconds();
case StopKind::PASS:
return mSpec.mPassAfter.Seconds();
default:
throw InternalErrorException("TrainStop::ScheduledStart",
"Unknown stop kind");
}
}
auto
Loco::TrainStop::ScheduledEnd() const -> activity_time_type
{
switch (mSpec.mStop)
{
case StopKind::UNKNOWN:
case StopKind::MANDATORY:
case StopKind::ON_DEMAND:
return mSpec.mDeparture.Seconds() + global_cfg.model.allowed_delay;
case StopKind::PASS:
return mSpec.mPassBefore.Seconds() + global_cfg.model.allowed_delay;
default:
throw InternalErrorException("TrainStop::ScheduledStart",
"Unknown stop kind");
}
}
auto
Loco::TrainStop::ScheduledMinDuration() const -> activity_time_type
{
switch (mSpec.mStop)
{
case StopKind::UNKNOWN:
case StopKind::MANDATORY:
case StopKind::ON_DEMAND:
return global_cfg.model.min_stop_duration;
case StopKind::PASS:
return 0;
default:
throw InternalErrorException("TrainStop::ScheduledStart",
"Unknown stop kind");
}
}
std::ostream &
Loco::TrainStopSpec::Print(std::ostream &os, const std::string &prefix) const
{
......
......@@ -116,6 +116,10 @@ namespace Loco
{
return mTrafficPoint->Empty();
}
activity_time_type ScheduledStart() const;
activity_time_type ScheduledEnd() const;
activity_time_type ScheduledMinDuration() const;
};
enum class TrainType
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment