From 4ff0873ec98340fc4d5ebbbc85cac42482bd75a1 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Mon, 26 Feb 2024 13:02:30 -0700 Subject: [PATCH 1/3] constructs `TimedLinkPath` using `run_dispatch` rather than loading from file --- .../demos/speed_limit_train_sim_demo.py | 11 +- .../resources/demo_data/timed_path.yaml | 181 ------------------ 2 files changed, 10 insertions(+), 182 deletions(-) delete mode 100644 python/altrios/resources/demo_data/timed_path.yaml diff --git a/python/altrios/demos/speed_limit_train_sim_demo.py b/python/altrios/demos/speed_limit_train_sim_demo.py index 2d3abdf4..052ad02e 100644 --- a/python/altrios/demos/speed_limit_train_sim_demo.py +++ b/python/altrios/demos/speed_limit_train_sim_demo.py @@ -71,7 +71,16 @@ ) train_sim.set_save_interval(SAVE_INTERVAL) -timed_link_path = alt.TimedLinkPath.from_file(alt.resources_root() / "demo_data/timed_path.yaml") +est_time_net, _consist = alt.make_est_times(train_sim, network) + +timed_link_path = alt.run_dispatch( + network.tolist(), + alt.SpeedLimitTrainSimVec([train_sim]), + [est_time_net], + + False, + False, +)[0] t0 = time.perf_counter() train_sim.walk_timed_path( diff --git a/python/altrios/resources/demo_data/timed_path.yaml b/python/altrios/resources/demo_data/timed_path.yaml deleted file mode 100644 index 14061c9d..00000000 --- a/python/altrios/resources/demo_data/timed_path.yaml +++ /dev/null @@ -1,181 +0,0 @@ ---- -- link_idx: 539 - time: 0.0 -- link_idx: 976 - time: 471.3276588001754 -- link_idx: 537 - time: 664.2435651995474 -- link_idx: 1069 - time: 669.8052468260285 -- link_idx: 1070 - time: 675.2123202818912 -- link_idx: 1067 - time: 680.4670713404194 -- link_idx: 1068 - time: 685.7322631789139 -- link_idx: 1065 - time: 750.0316982633667 -- link_idx: 1066 - time: 821.4127159677446 -- link_idx: 1022 - time: 928.0988061151002 -- link_idx: 1019 - time: 931.6031144821318 -- link_idx: 1023 - time: 934.5714404191822 -- link_idx: 1024 - time: 1022.1753590186127 -- link_idx: 1021 - time: 1029.32380989159 -- link_idx: 1061 - time: 1060.4010425481247 -- link_idx: 1059 - time: 1138.3998740506358 -- link_idx: 1062 - time: 1213.435914629954 -- link_idx: 1060 - time: 1338.1200933839427 -- link_idx: 1057 - time: 1338.8247849526815 -- link_idx: 593 - time: 1340.0388422721298 -- link_idx: 515 - time: 1344.096186902956 -- link_idx: 514 - time: 1345.7193353374023 -- link_idx: 468 - time: 1353.8271795401815 -- link_idx: 1039 - time: 1370.7675995221362 -- link_idx: 1040 - time: 1381.7529600837734 -- link_idx: 1037 - time: 1484.4329189859563 -- link_idx: 1038 - time: 1665.5708991733845 -- link_idx: 1035 - time: 1910.0359617118957 -- link_idx: 1036 - time: 2273.0498999668052 -- link_idx: 1041 - time: 2273.7480271435343 -- link_idx: 1044 - time: 2311.361982530798 -- link_idx: 932 - time: 2312.8393268537475 -- link_idx: 931 - time: 2367.1951595458668 -- link_idx: 926 - time: 2377.0759622056503 -- link_idx: 933 - time: 2397.547131925705 -- link_idx: 934 - time: 2447.1303134907503 -- link_idx: 775 - time: 2561.4285364458337 -- link_idx: 774 - time: 2562.8134816425154 -- link_idx: 772 - time: 2695.2194482851774 -- link_idx: 600 - time: 2705.8261823984794 -- link_idx: 769 - time: 2976.6453246219316 -- link_idx: 766 - time: 3079.5111658269307 -- link_idx: 601 - time: 3080.2344946393277 -- link_idx: 585 - time: 3114.8937512086704 -- link_idx: 892 - time: 3118.6621074102586 -- link_idx: 889 - time: 3126.6707542985678 -- link_idx: 890 - time: 3464.2805280138273 -- link_idx: 887 - time: 3516.6127216195455 -- link_idx: 353 - time: 3618.642811043421 -- link_idx: 208 - time: 3737.2148368529743 -- link_idx: 205 - time: 3737.8809652498458 -- link_idx: 746 - time: 3806.333944134647 -- link_idx: 747 - time: 4132.527137253666 -- link_idx: 744 - time: 4251.626173636178 -- link_idx: 748 - time: 4574.802535830531 -- link_idx: 321 - time: 4613.835624188301 -- link_idx: 207 - time: 4928.87497606338 -- link_idx: 218 - time: 4932.057368429145 -- link_idx: 217 - time: 5051.822968246881 -- link_idx: 565 - time: 12633.254462061683 -- link_idx: 859 - time: 12634.763615332544 -- link_idx: 639 - time: 12901.865753482562 -- link_idx: 638 - time: 12928.501647096127 -- link_idx: 642 - time: 12951.677391398116 -- link_idx: 643 - time: 14986.036379710538 -- link_idx: 640 - time: 15329.709621474962 -- link_idx: 641 - time: 16286.82667385717 -- link_idx: 649 - time: 16289.873164817458 -- link_idx: 647 - time: 16818.635888182092 -- link_idx: 646 - time: 16822.120298361406 -- link_idx: 644 - time: 17496.738409583457 -- link_idx: 655 - time: 17507.287701691035 -- link_idx: 652 - time: 18072.975756174652 -- link_idx: 653 - time: 18419.480703838984 -- link_idx: 648 - time: 19842.854069320252 -- link_idx: 657 - time: 19860.89528137748 -- link_idx: 650 - time: 20964.075617994415 -- link_idx: 654 - time: 20968.215443957248 -- link_idx: 651 - time: 21446.132353170193 -- link_idx: 667 - time: 21451.496097373194 -- link_idx: 664 - time: 23628.958056258503 -- link_idx: 665 - time: 23711.437780065346 -- link_idx: 689 - time: 23864.113440633402 -- link_idx: 686 - time: 23947.17114713986 -- link_idx: 687 - time: 23951.273165991064 -- link_idx: 684 - time: 23965.42821224453 -- link_idx: 685 - time: 24013.5577931531 -- link_idx: 682 - time: 24097.14818814106 -- link_idx: 681 - time: 24599.696372821112 -- link_idx: 683 - time: 24616.313873915584 From b6aae33f9989d71b3bb9e53b2a71dd49b8100d3b Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Mon, 26 Feb 2024 13:04:19 -0700 Subject: [PATCH 2/3] added missing function in pyi, plot formatting, and more generic API --- python/altrios/altrios_pyo3.pyi | 9 ++++++- .../altrios/demos/set_speed_train_sim_demo.py | 16 ++++++------ .../demos/speed_limit_train_sim_demo.py | 16 ++++++------ .../consist/locomotive/locomotive_model.rs | 14 ++++++----- .../src/meet_pass/est_times/mod.rs | 25 +++++++++++++------ .../src/train/set_speed_train_sim.rs | 4 +-- 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/python/altrios/altrios_pyo3.pyi b/python/altrios/altrios_pyo3.pyi index 6b662f48..11b9f543 100644 --- a/python/altrios/altrios_pyo3.pyi +++ b/python/altrios/altrios_pyo3.pyi @@ -1,7 +1,7 @@ from typing import Any, Dict, List, Optional import polars as pl from typing_extensions import Self -from typing import Union +from typing import Union, Tuple from dataclasses import dataclass @@ -904,6 +904,13 @@ def run_dispatch( ) -> List[TimedLinkPath]: ... +def make_est_times( + speed_limit_train_sim: SpeedLimitTrainSim, + network: List[Link], +) -> Tuple[EstTimeNet, Consist]: + ... + + @dataclass class TimedLinkPath(SerdeAPI): @classmethod diff --git a/python/altrios/demos/set_speed_train_sim_demo.py b/python/altrios/demos/set_speed_train_sim_demo.py index a15ae84f..3676b222 100644 --- a/python/altrios/demos/set_speed_train_sim_demo.py +++ b/python/altrios/demos/set_speed_train_sim_demo.py @@ -95,38 +95,38 @@ fig, ax = plt.subplots(3, 1, sharex=True) ax[0].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.pwr_whl_out_watts, + np.array(train_sim.history.pwr_whl_out_watts) / 1e6, label="tract pwr", ) -ax[0].set_ylabel('Power') +ax[0].set_ylabel('Power [MW]') ax[0].legend() ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_aero_newtons, + np.array(train_sim.history.res_aero_newtons) / 1e3, label='aero', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_rolling_newtons, + np.array(train_sim.history.res_rolling_newtons) / 1e3, label='rolling', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_curve_newtons, + np.array(train_sim.history.res_curve_newtons) / 1e3, label='curve', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_bearing_newtons, + np.array(train_sim.history.res_bearing_newtons) / 1e3, label='bearing', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_grade_newtons, + np.array(train_sim.history.res_grade_newtons) / 1e3, label='grade', ) -ax[1].set_ylabel('Force [N]') +ax[1].set_ylabel('Force [MN]') ax[1].legend() ax[-1].plot( diff --git a/python/altrios/demos/speed_limit_train_sim_demo.py b/python/altrios/demos/speed_limit_train_sim_demo.py index 052ad02e..aa679117 100644 --- a/python/altrios/demos/speed_limit_train_sim_demo.py +++ b/python/altrios/demos/speed_limit_train_sim_demo.py @@ -94,38 +94,38 @@ fig, ax = plt.subplots(3, 1, sharex=True) ax[0].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.pwr_whl_out_watts, + np.array(train_sim.history.pwr_whl_out_watts) / 1e6, label="tract pwr", ) -ax[0].set_ylabel('Power') +ax[0].set_ylabel('Power [MW]') ax[0].legend() ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_aero_newtons, + np.array(train_sim.history.res_aero_newtons) / 1e3, label='aero', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_rolling_newtons, + np.array(train_sim.history.res_rolling_newtons) / 1e3, label='rolling', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_curve_newtons, + np.array(train_sim.history.res_curve_newtons) / 1e3, label='curve', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_bearing_newtons, + np.array(train_sim.history.res_bearing_newtons) / 1e3, label='bearing', ) ax[1].plot( np.array(train_sim.history.time_seconds) / 3_600, - train_sim.history.res_grade_newtons, + np.array(train_sim.history.res_grade_newtons) / 1e3, label='grade', ) -ax[1].set_ylabel('Force [N]') +ax[1].set_ylabel('Force [MN]') ax[1].legend() ax[-1].plot( diff --git a/rust/altrios-core/src/consist/locomotive/locomotive_model.rs b/rust/altrios-core/src/consist/locomotive/locomotive_model.rs index e85cc490..002aa50c 100644 --- a/rust/altrios-core/src/consist/locomotive/locomotive_model.rs +++ b/rust/altrios-core/src/consist/locomotive/locomotive_model.rs @@ -596,17 +596,19 @@ impl Locomotive { pub fn default_battery_electric_loco() -> Self { // TODO: add `pwr_aux_offset` and `pwr_aux_traction_coeff` based on calibration let bel_type = PowertrainType::BatteryElectricLoco(BatteryElectricLoco::default()); - let mut bel = Locomotive::default(); - bel.loco_type = bel_type; - bel + Locomotive { + loco_type: bel_type, + ..Default::default() + } } pub fn default_hybrid_electric_loco() -> Self { // TODO: add `pwr_aux_offset` and `pwr_aux_traction_coeff` based on calibration let hel_type = PowertrainType::HybridLoco(Box::default()); - let mut hel = Locomotive::default(); - hel.loco_type = hel_type; - hel + Locomotive { + loco_type: hel_type, + ..Default::default() + } } pub fn get_pwr_rated(&self) -> si::Power { diff --git a/rust/altrios-core/src/meet_pass/est_times/mod.rs b/rust/altrios-core/src/meet_pass/est_times/mod.rs index d6e4bf10..6fccfd86 100644 --- a/rust/altrios-core/src/meet_pass/est_times/mod.rs +++ b/rust/altrios-core/src/meet_pass/est_times/mod.rs @@ -1,5 +1,6 @@ use super::disp_imports::*; use crate::consist::Consist; +use crate::track::Network; use uc::SPEED_DIFF_JOIN; use uc::TIME_NAN; @@ -82,7 +83,7 @@ pub fn check_od_pair_valid( network: Vec, ) -> anyhow::Result<()> { if let Err(error) = get_link_idx_options(&origs, &dests, &network) { - Err(error.into()) + Err(error) } else { Ok(()) } @@ -470,10 +471,11 @@ fn add_new_join_paths( } } -pub fn make_est_times( +pub fn make_est_times>( speed_limit_train_sim: &SpeedLimitTrainSim, - network: &[Link], + network: N, ) -> anyhow::Result<(EstTimeNet, Consist)> { + let network = network.as_ref(); let dests = &speed_limit_train_sim.dests; let (link_idx_options, origs) = get_link_idx_options(&speed_limit_train_sim.origs, dests, network)?; @@ -573,8 +575,7 @@ pub fn make_est_times( let mut est_idxs_end = Vec::::with_capacity(8); // Iterate and process all saved sims - while !saved_sims.is_empty() { - let mut sim = saved_sims.pop().unwrap(); + while let Some(mut sim) = saved_sims.pop() { let mut has_split = false; ensure!( sim.train_sim.link_idx_last().unwrap().is_real(), @@ -737,7 +738,17 @@ pub fn make_est_times( #[pyfunction(name = "make_est_times")] pub fn make_est_times_py( speed_limit_train_sim: SpeedLimitTrainSim, - network: Vec, + network: &PyAny, ) -> anyhow::Result<(EstTimeNet, Consist)> { - Ok(make_est_times(&speed_limit_train_sim, &network)?) + let network = match network.extract::() { + Ok(n) => n, + Err(_) => { + let n = network + .extract::>() + .map_err(|_| anyhow!("{}", format_dbg!()))?; + Network(n) + } + }; + + make_est_times(&speed_limit_train_sim, network) } diff --git a/rust/altrios-core/src/train/set_speed_train_sim.rs b/rust/altrios-core/src/train/set_speed_train_sim.rs index 9543d59b..05fa4d06 100644 --- a/rust/altrios-core/src/train/set_speed_train_sim.rs +++ b/rust/altrios-core/src/train/set_speed_train_sim.rs @@ -159,11 +159,11 @@ pub struct SpeedTraceElement { save_interval: Option, ) -> Self { let path_tpc = match path_tpc_file { - Some(file) => PathTpc::from_file(&file).unwrap(), + Some(file) => PathTpc::from_file(file).unwrap(), None => PathTpc::valid() }; let train_res = match train_res_file { - Some(file) => TrainRes::from_file(&file).unwrap(), + Some(file) => TrainRes::from_file(file).unwrap(), None => TrainRes::valid() }; From c2225aa0e61067a6bee347ced3effdf59b1c7c14 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Mon, 26 Feb 2024 14:49:16 -0700 Subject: [PATCH 3/3] possibly fixed test --- .github/workflows/py-tests.yaml | 8 ++++---- .github/workflows/rust-tests.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/py-tests.yaml b/.github/workflows/py-tests.yaml index b78cfe02..ab29bbd6 100644 --- a/.github/workflows/py-tests.yaml +++ b/.github/workflows/py-tests.yaml @@ -2,10 +2,10 @@ name: py-tests on: push: - branches: [ main ] - paths: - - "python/**" - - "rust/**" + branches: [ main ] + paths: + - "python/**" + - "rust/**" pull_request: paths: - "python/**" diff --git a/.github/workflows/rust-tests.yaml b/.github/workflows/rust-tests.yaml index d80fa5af..65d1052f 100644 --- a/.github/workflows/rust-tests.yaml +++ b/.github/workflows/rust-tests.yaml @@ -6,7 +6,7 @@ on: paths: - "rust/**" - "!python/**" - pull_request: + pull_request: paths: - "rust/**" - "!python/**"