From 83a9323e0481abce2f4a447670197efc24e2bcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Benito=20Lamata?= Date: Sat, 7 Dec 2024 13:23:16 +0100 Subject: [PATCH] Implement TIU via JSON --- EVC/OR_interface/interface.cpp | 10 +- EVC/STM/stm.cpp | 2 +- EVC/TrackConditions/track_condition.h | 18 +++- EVC/TrackConditions/track_conditions.cpp | 120 ++++++++++++--------- EVC/TrainSubsystems/train_interface.cpp | 131 +++++++++++++++++++---- EVC/TrainSubsystems/train_interface.h | 22 +--- 6 files changed, 201 insertions(+), 102 deletions(-) diff --git a/EVC/OR_interface/interface.cpp b/EVC/OR_interface/interface.cpp index 578143d4..884e3a4c 100644 --- a/EVC/OR_interface/interface.cpp +++ b/EVC/OR_interface/interface.cpp @@ -183,15 +183,9 @@ void SetParameters() }; manager.AddParameter(p); - p = new ORserver::Parameter("etcs::neutral_section"); + p = new ORserver::Parameter("etcs::obu_tr"); p->GetValue = []() { - return (neutral_section_info.start ? std::to_string(*neutral_section_info.start) : "")+";"+(neutral_section_info.end ? std::to_string(*neutral_section_info.end) : ""); - }; - manager.AddParameter(p); - - p = new ORserver::Parameter("etcs::lower_pantographs"); - p->GetValue = []() { - return (lower_pantograph_info.start ? std::to_string(*lower_pantograph_info.start) : "")+";"+(lower_pantograph_info.end ? std::to_string(*lower_pantograph_info.end) : ""); + return obu_tr_status; }; manager.AddParameter(p); diff --git a/EVC/STM/stm.cpp b/EVC/STM/stm.cpp index d2c85120..bb88e5e9 100644 --- a/EVC/STM/stm.cpp +++ b/EVC/STM/stm.cpp @@ -766,7 +766,7 @@ void handle_stm_message(stm_message &msg) tiu.close_air_intake = true; if (ti.M_TIMS_CMD == M_TIMS_CMD_t::MainSwitchOpen) tiu.open_circuit_breaker = true; - else if (ti.M_TIMS_CMD == M_TIMS_CMD_t::MainSwitchOpen) + else if (ti.M_TIMS_CMD == M_TIMS_CMD_t::MainSwitchClose) tiu.open_circuit_breaker = false; if (ti.M_TITR_CMD == M_TITR_CMD_t::TCO) tiu.TCO = true; diff --git a/EVC/TrackConditions/track_condition.h b/EVC/TrackConditions/track_condition.h index 347c3cd4..4eac2a50 100644 --- a/EVC/TrackConditions/track_condition.h +++ b/EVC/TrackConditions/track_condition.h @@ -86,6 +86,11 @@ struct PlanningTrackCondition TractionSystem = tractionSystem; } }; +struct track_condition_profile_external +{ + optional start; + optional end; +}; struct track_condition { TrackConditions condition; @@ -104,12 +109,14 @@ struct track_condition bool end_displayed; int64_t end_time; std::vector> targets; + optional external; track_condition() : start_symbol(TrackConditionType_DMI::None, false), end_symbol(TrackConditionType_DMI::None, false) { active_symbol = announcement_symbol = end_active_symbol = -1; announce = order = display_end = end_displayed = false; announce_distance = std::numeric_limits::max(); } + virtual ~track_condition() = default; virtual double get_distance_to_train() { if (condition == TrackConditions::BigMetalMasses) @@ -140,7 +147,16 @@ struct track_condition_platforms : track_condition bool left_side; bool right_side; }; -extern std::list> track_conditions; +struct track_condition_traction_change : track_condition +{ + int m_voltage; + int nid_ctraction; +}; +struct track_condition_current_consumption : track_condition +{ + double max_current; +}; +extern std::set> track_conditions; extern optional restore_initial_states_various; void update_track_conditions(); void update_brake_contributions(); diff --git a/EVC/TrackConditions/track_conditions.cpp b/EVC/TrackConditions/track_conditions.cpp index 08888d7e..56914acd 100644 --- a/EVC/TrackConditions/track_conditions.cpp +++ b/EVC/TrackConditions/track_conditions.cpp @@ -12,9 +12,8 @@ #include "../TrainSubsystems/power.h" #include "../TrainSubsystems/train_interface.h" #include "../Supervision/conversion_model.h" -std::list> track_conditions; +std::set> track_conditions; std::set brake_change; -//std::map>> track_condition_targets; void add_condition(); void update_brake_contributions() { @@ -60,9 +59,6 @@ void update_brake_contributions() } void update_track_conditions() { - neutral_section_info = {{},{}}; - lower_pantograph_info = {{},{}}; - air_tightness_info = {{},{}}; for (auto it = track_conditions.begin(); it != track_conditions.end();) { track_condition *c = it->get(); double end = c->get_end_distance_to_train(); @@ -110,13 +106,14 @@ void update_track_conditions() dist_base min = d_minsafefront(c->start); distance &pointD = c->start; distance &pointE = c->end; - if (pointC.max-max < 0) { - track_condition_profile_external info = {{},{}}; + if (pointC.max-max < 0 && pointE.min-min > -L_TRAIN) { + track_condition_profile_external ext; if (pointD.max-max > -L_TRAIN) - info.start = pointD.max-max; - if (pointE.min-min > -L_TRAIN) - info.end = pointE.min-min; - if (!neutral_section_info.start && !neutral_section_info.end) neutral_section_info = info; + ext.start = pointD.max-max; + ext.end = pointE.min-min; + c->external = ext; + } else { + c->external = {}; } c->announce_distance = pointC.max-max; if (min > c->end.min) { @@ -135,13 +132,14 @@ void update_track_conditions() dist_base min = d_minsafefront(c->start); distance &pointD = c->start; distance &pointE = c->end; - if (pointC.max-max < 0) { - track_condition_profile_external info = {{},{}}; + if (pointC.max-max < 0 && pointE.min-min > -L_TRAIN) { + track_condition_profile_external ext; if (pointD.max-max > -L_TRAIN) - info.start = pointD.max-max; - if (pointE.min-min > -L_TRAIN) - info.end = pointE.min-min; - if (!lower_pantograph_info.start && !lower_pantograph_info.end) lower_pantograph_info = info; + ext.start = pointD.max-max; + ext.end = pointE.min-min; + c->external = ext; + } else { + c->external = {}; } c->announce_distance = pointC.max-max; if (min > c->end.min) { @@ -165,13 +163,14 @@ void update_track_conditions() dist_base min = d_minsafefront(c->start); distance &pointD = c->start; distance &pointE = c->end; - if (pointC.max-max < 0) { - track_condition_profile_external info = {{},{}}; + if (pointC.max-max < 0 && pointE.min-min > -L_TRAIN) { + track_condition_profile_external ext; if (pointD.max-max > 0) - info.start = pointD.max-max; - if (pointE.min-min > -L_TRAIN) - info.end = pointE.min-min; - if (!air_tightness_info.start && !air_tightness_info.end) air_tightness_info = info; + ext.start = pointD.max-max; + ext.end = pointE.min-min; + c->external = ext; + } else { + c->external = {}; } c->announce_distance = pointC.max-max; if (min - L_TRAIN > c->end.min) { @@ -187,7 +186,16 @@ void update_track_conditions() } else if (c->condition == TrackConditions::ChangeOfTractionSystem) { distance pointC = c->start - V_est * 20; dist_base max = d_maxsafefront(c->start); + dist_base min = d_minsafefront(c->start) - L_TRAIN; distance &pointF = c->start; + if (pointC.max-max < 0 && pointF.min-min > 0) { + track_condition_profile_external ext; + if (pointF.min-min > 0) + ext.start = pointF.max-max; + c->external = ext; + } else { + c->external = {}; + } c->announce_distance = pointC.max-max; if (c->end_displayed) { c->announce = false; @@ -204,8 +212,13 @@ void update_track_conditions() dist_base max = d_maxsafefront(c->start); dist_base min = d_minsafefront(c->start) - L_TRAIN; distance &pointF = c->start; - if (min < pointF.min) { - + if (pointC.max-max < 0 && pointF.min-min > 0) { + track_condition_profile_external ext; + if (pointF.min-min > 0) + ext.start = pointF.max-max; + c->external = ext; + } else { + c->external = {}; } } else if (c->condition == TrackConditions::RadioHole) { distance &pointD = c->start; @@ -223,28 +236,14 @@ void update_track_conditions() dist_base min = d_minsafefront(c->start) - L_TRAIN; distance &pointD = c->start; distance &pointE = c->end; - if (pointC.max-max < 0) { - track_condition_profile_external info = {{},{}}; - if (pointD.max-max > -L_TRAIN) - info.start = pointD.max-max; - if (pointE.min-min > -L_TRAIN) - info.end = pointE.min-min; - track_condition_profile_external *info2 = nullptr; - switch (c->condition) { - case TrackConditions::SwitchOffEddyCurrentEmergencyBrake: - info2 = &eddy_eb_inhibition; - break; - case TrackConditions::SwitchOffEddyCurrentServiceBrake: - info2 = &eddy_sb_inhibition; - break; - case TrackConditions::SwitchOffMagneticShoe: - info2 = &magnetic_inhibition; - break; - case TrackConditions::SwitchOffRegenerativeBrake: - info2 = ®enerative_inhibition; - break; - } - if (info2 != nullptr && !info2->start && !info2->end) *info2 = info; + if (pointC.max-max < 0 && pointE.min-min > 0) { + track_condition_profile_external ext; + if (pointD.max-max > 0) + ext.start = pointD.max-max; + ext.end = pointE.min-min; + c->external = ext; + } else { + c->external = {}; } c->announce_distance = pointC.max-max; if (min > c->end.min) { @@ -257,6 +256,21 @@ void update_track_conditions() c->announce = true; c->order = false; } + } else if (c->condition == TrackConditions::StationPlatform) { + distance pointC = c->start - V_est * 20; + dist_base max = d_maxsafefront(c->start); + dist_base min = d_minsafefront(c->start) - L_TRAIN; + distance &pointD = c->start; + distance &pointE = c->end; + if (pointC.max-max < 0 && pointE.min-min > 0) { + track_condition_profile_external ext; + if (pointD.max-max > 0) + ext.start = pointD.max-max; + ext.end = pointE.min-min; + c->external = ext; + } else { + c->external = {}; + } } ++it; } @@ -269,10 +283,12 @@ void load_track_condition_traction(TrackConditionChangeTractionSystem cond, dist else ++it; } - track_condition *tc = new track_condition(); + track_condition_traction_change *tc = new track_condition_traction_change(); tc->start = ref + cond.D_TRACTION.get_value(cond.Q_SCALE); tc->condition = TrackConditions::ChangeOfTractionSystem; tc->profile = false; + tc->m_voltage = cond.M_VOLTAGE; + tc->nid_ctraction = cond.NID_CTRACTION; TractionSystem_DMI traction; switch (cond.M_VOLTAGE.rawdata) { case M_VOLTAGE_t::NonFitted: traction = TractionSystem_DMI::NonFitted; break; @@ -286,7 +302,7 @@ void load_track_condition_traction(TrackConditionChangeTractionSystem cond, dist tc->announcement_symbol = 25 + cond.M_VOLTAGE.rawdata*2 + (automatic_traction_system_change ? 0 : 1); tc->active_symbol = 23 + cond.M_VOLTAGE.rawdata*2 + (automatic_traction_system_change ? 0 : 1); tc->end_active_symbol = tc->active_symbol; - track_conditions.push_back(std::shared_ptr(tc)); + track_conditions.insert(std::shared_ptr(tc)); } void load_track_condition_bigmetal(TrackConditionBigMetalMasses cond, distance ref) { @@ -313,7 +329,7 @@ void load_track_condition_bigmetal(TrackConditionBigMetalMasses cond, distance r tc->end = tc->start + it->L_TRACKCOND.get_value(cond.Q_SCALE); tc->profile = true; tc->condition = TrackConditions::BigMetalMasses; - track_conditions.push_back(std::shared_ptr(tc)); + track_conditions.insert(std::shared_ptr(tc)); } } void load_track_condition_various(TrackCondition cond, distance ref, bool special) @@ -462,7 +478,7 @@ void load_track_condition_various(TrackCondition cond, distance ref, bool specia if (exists) delete tc; else - track_conditions.push_back(std::shared_ptr(tc)); + track_conditions.insert(std::shared_ptr(tc)); } update_brake_contributions(); @@ -509,6 +525,6 @@ void load_track_condition_platforms(TrackConditionStationPlatforms cond, distanc tc->right_side = it->Q_PLATFORM != Q_PLATFORM_t::LeftSide; tc->left_side = it->Q_PLATFORM != Q_PLATFORM_t::RightSide; tc->condition = TrackConditions::StationPlatform; - track_conditions.push_back(std::shared_ptr(tc)); + track_conditions.insert(std::shared_ptr(tc)); } } \ No newline at end of file diff --git a/EVC/TrainSubsystems/train_interface.cpp b/EVC/TrainSubsystems/train_interface.cpp index a4422768..8ee8e188 100644 --- a/EVC/TrainSubsystems/train_interface.cpp +++ b/EVC/TrainSubsystems/train_interface.cpp @@ -10,6 +10,8 @@ #include "../TrackConditions/track_condition.h" #include "train_interface.h" #include "../STM/stm.h" +#include +using json = nlohmann::json; bool cab_active[2] = {true, false}; bool sl_signal; bool ps_signal; @@ -20,20 +22,6 @@ bool SB_command; bool EB_command; double brake_pressure; int reverser_direction; -track_condition_profile_external regenerative_inhibition; -track_condition_profile_external magnetic_inhibition; -track_condition_profile_external eddy_eb_inhibition; -track_condition_profile_external eddy_sb_inhibition; -track_condition_profile_external neutral_section_info; -track_condition_profile_external lower_pantograph_info; -track_condition_profile_external air_tightness_info; -bool regenerative_inhibition_stm; -bool magnetic_inhibition_stm; -bool eddy_eb_inhibition_stm; -bool eddy_sb_inhibition_stm; -bool neutral_section_stm; -bool lower_pantograph_stm; -bool air_tightness_stm; bool traction_cutoff_active; bool ep_brake_available=true; bool eddy_brake_available=true; @@ -46,22 +34,123 @@ bool automatic_eddy_inhibition; bool automatic_magnetic_inhibition; bool automatic_regenerative_inhibition; extern bool TCO; +std::set used_external_condition_ids; +std::map, int> external_conditions; +std::string obu_tr_status; void update_train_interface() { + for (auto it = external_conditions.begin(); it != external_conditions.end(); ) { + if (track_conditions.find(it->first) == track_conditions.end()) { + used_external_condition_ids.erase(it->second); + it = external_conditions.erase(it); + } else { + ++it; + } + } + json obu_json; + json platform_conditions; + json traction_change_condition; + json allowed_current_consumption_condition; + for (auto &tc : track_conditions) { + if (tc->external && external_conditions.find(tc) == external_conditions.end()) { + if (tc->condition == TrackConditions::StationPlatform) { + auto *platform = (track_condition_platforms*)tc.get(); + json cond; + if (tc->external->start) + cond["StartDistanceToTrainM"] = *(tc->external->start); + if (tc->external->end) + cond["EndDistanceToTrainM"] = *(tc->external->end); + cond["LeftSide"] = platform->left_side; + cond["RightSide"] = platform->right_side; + cond["HeightM"] = platform->platform_height; + platform_conditions.push_back(cond); + } else if (tc->condition == TrackConditions::ChangeOfTractionSystem) { + auto *traction = (track_condition_traction_change*)tc.get(); + if (tc->external->start) + traction_change_condition["DistanceToTrainM"] = *(tc->external->start); + traction_change_condition["M_VOLTAGE"] = traction->m_voltage; + traction_change_condition["NID_CTRACTION"] = traction->nid_ctraction; + } else if (tc->condition == TrackConditions::ChangeOfAllowedCurrentConsumption) { + auto *current = (track_condition_current_consumption*)tc.get(); + if (tc->external->start) + allowed_current_consumption_condition["DistanceToTrainM"] = *(tc->external->start); + allowed_current_consumption_condition["MaxCurrentA"] = current->max_current; + } else { + for (int i=0; i<256; i++) { + if (used_external_condition_ids.find(i) == used_external_condition_ids.end()) { + used_external_condition_ids.insert(i); + external_conditions[tc] = i; + break; + } + } + } + } + } + json profile_conditions; + for (auto &kvp : external_conditions) { + if (kvp.first->external) { + json cond; + cond["Id"] = kvp.second; + int type = 0; + switch (kvp.first->condition) + { + case TrackConditions::SwitchOffRegenerativeBrake: + type = 0; + break; + case TrackConditions::SwitchOffMagneticShoe: + type = 1; + break; + case TrackConditions::SwitchOffEddyCurrentServiceBrake: + type = 2; + break; + case TrackConditions::SwitchOffEddyCurrentEmergencyBrake: + type = 3; + break; + case TrackConditions::AirTightness: + type = 4; + break; + case TrackConditions::PowerLessSectionLowerPantograph: + type = 5; + break; + case TrackConditions::PowerLessSectionSwitchMainPowerSwitch: + type = 6; + break; + } + cond["Type"] = type; + if (kvp.first->external->start) + cond["StartDistanceToTrainM"] = *(kvp.first->external->start); + if (kvp.first->external->end) + cond["EndDistanceToTrainM"] = *(kvp.first->external->end); + profile_conditions.push_back(cond); + } + } + if (!traction_change_condition.empty()) + obu_json["TractionSystemChange"] = traction_change_condition; + if (!allowed_current_consumption_condition.empty()) + obu_json["AllowedCurrentConsumptionChange"] = allowed_current_consumption_condition; + if (!profile_conditions.empty()) + obu_json["TrackConditions"] = profile_conditions; + traction_cutoff_active = TCO; if (mode == Mode::SL || mode == Mode::NL || mode == Mode::SN) { for (auto kvp : installed_stms) { auto *stm = kvp.second; if (stm->active()) { traction_cutoff_active |= stm->tiu_function.TCO; - neutral_section_stm = stm->tiu_function.open_circuit_breaker; - lower_pantograph_stm = stm->tiu_function.lower_pantograph; - air_tightness_stm = stm->tiu_function.close_air_intake; - regenerative_inhibition_stm = stm->tiu_function.regenerative_brake_inhibition; - magnetic_inhibition_stm = stm->tiu_function.magnetic_shoe_inhibition; - eddy_eb_inhibition_stm = stm->tiu_function.eddy_emergency_brake_inhibition; - eddy_sb_inhibition_stm = stm->tiu_function.eddy_service_brake_inhibition; + obu_json["OBU_TR_MPS_Cmd"] = !stm->tiu_function.open_circuit_breaker; + obu_json["OBU_TR_PG_Cmd"] = stm->tiu_function.lower_pantograph; + obu_json["OBU_TR_AT_Cmd"] = stm->tiu_function.close_air_intake; + obu_json["OBU_TR_RBInhibit_Cmd"] = stm->tiu_function.regenerative_brake_inhibition; + obu_json["OBU_TR_MGInhibit_Cmd"] = stm->tiu_function.magnetic_shoe_inhibition; + obu_json["OBU_TR_ECEInhibit_Cmd"] = stm->tiu_function.eddy_emergency_brake_inhibition; + obu_json["OBU_TR_ECSInhibit_Cmd"] = stm->tiu_function.eddy_service_brake_inhibition; } } } + + obu_json["OBU_TR_TCO_Cmd"] = traction_cutoff_active; + obu_json["OBU_TR_EB3_Cmd"] = !EB_command; + obu_json["OBU_TR_ServiceBrake"] = SB_command; + + obu_tr_status = obu_json.dump(); } \ No newline at end of file diff --git a/EVC/TrainSubsystems/train_interface.h b/EVC/TrainSubsystems/train_interface.h index fa04d124..c4bcdea8 100644 --- a/EVC/TrainSubsystems/train_interface.h +++ b/EVC/TrainSubsystems/train_interface.h @@ -8,6 +8,8 @@ */ #pragma once #include "../optional.h" +#include +#include extern bool sl_signal; extern bool ps_signal; extern bool nl_signal; @@ -16,28 +18,10 @@ extern bool failed; extern bool SB_command; extern double brake_pressure; extern bool EB_command; -struct track_condition_profile_external -{ - optional start; - optional end; -}; -extern track_condition_profile_external regenerative_inhibition; -extern track_condition_profile_external magnetic_inhibition; -extern track_condition_profile_external eddy_eb_inhibition; -extern track_condition_profile_external eddy_sb_inhibition; -extern track_condition_profile_external neutral_section_info; -extern track_condition_profile_external lower_pantograph_info; -extern track_condition_profile_external air_tightness_info; -extern bool regenerative_inhibition_stm; -extern bool magnetic_inhibition_stm; -extern bool eddy_eb_inhibition_stm; -extern bool eddy_sb_inhibition_stm; -extern bool neutral_section_stm; -extern bool lower_pantograph_stm; -extern bool air_tightness_stm; extern bool traction_cutoff_active; extern bool cab_active[2]; extern int reverser_direction; +extern std::string obu_tr_status; extern optional set_speed; extern bool ep_brake_available; extern bool eddy_brake_available;