Skip to content

Commit 852257f

Browse files
committed
stdcm: towed rolling stock parameter
Signed-off-by: Egor Berezovskiy <[email protected]>
1 parent 02e76f0 commit 852257f

File tree

19 files changed

+513
-29
lines changed

19 files changed

+513
-29
lines changed

editoast/editoast_schemas/src/rolling_stock/gamma.rs

+6
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ pub struct Gamma {
1616
#[derivative(Hash(hash_with = "editoast_common::hash_float::<3,_>"))]
1717
value: f64,
1818
}
19+
20+
impl Gamma {
21+
pub fn new(gamma_type: String, value: f64) -> Self {
22+
Self { gamma_type, value }
23+
}
24+
}

editoast/editoast_schemas/src/rolling_stock/rolling_resistance.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,22 @@ editoast_common::schemas! {
1313
#[allow(non_snake_case)]
1414
pub struct RollingResistance {
1515
#[serde(rename = "type")]
16-
rolling_resistance_type: String,
16+
pub rolling_resistance_type: String,
1717
#[derivative(Hash(hash_with = "editoast_common::hash_float::<5,_>"))]
18-
A: f64,
18+
pub A: f64,
1919
#[derivative(Hash(hash_with = "editoast_common::hash_float::<5,_>"))]
20-
B: f64,
20+
pub B: f64,
2121
#[derivative(Hash(hash_with = "editoast_common::hash_float::<5,_>"))]
22-
C: f64,
22+
pub C: f64,
23+
}
24+
25+
impl RollingResistance {
26+
pub fn new(rolling_resistance_type: String, a: f64, b: f64, c: f64) -> Self {
27+
Self {
28+
rolling_resistance_type,
29+
A: a,
30+
B: b,
31+
C: c,
32+
}
33+
}
2334
}

editoast/editoast_schemas/src/rolling_stock/towed_rolling_stock.rs

+2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ pub struct TowedRollingStock {
66
pub name: String,
77
pub railjson_version: String,
88

9+
/// In kg
910
pub mass: f64,
11+
/// In m
1012
pub length: f64,
1113
pub comfort_acceleration: f64,
1214
pub startup_acceleration: f64,

editoast/openapi.yaml

+53
Original file line numberDiff line numberDiff line change
@@ -2581,6 +2581,10 @@ paths:
25812581
format: double
25822582
description: Total mass of the consist in kg
25832583
nullable: true
2584+
towed_rolling_stock_id:
2585+
type: integer
2586+
format: int64
2587+
nullable: true
25842588
work_schedule_group_id:
25852589
type: integer
25862590
format: int64
@@ -4212,10 +4216,12 @@ components:
42124216
- $ref: '#/components/schemas/EditoastRollingStockErrorKeyNotFound'
42134217
- $ref: '#/components/schemas/EditoastRollingStockErrorLiveryMultipartError'
42144218
- $ref: '#/components/schemas/EditoastRollingStockErrorNameAlreadyUsed'
4219+
- $ref: '#/components/schemas/EditoastSTDCMErrorConsistEntryInvalid'
42154220
- $ref: '#/components/schemas/EditoastSTDCMErrorInfraNotFound'
42164221
- $ref: '#/components/schemas/EditoastSTDCMErrorInvalidPathItems'
42174222
- $ref: '#/components/schemas/EditoastSTDCMErrorRollingStockNotFound'
42184223
- $ref: '#/components/schemas/EditoastSTDCMErrorTimetableNotFound'
4224+
- $ref: '#/components/schemas/EditoastSTDCMErrorTowedRollingStockNotFound'
42194225
- $ref: '#/components/schemas/EditoastScenarioErrorInfraNotFound'
42204226
- $ref: '#/components/schemas/EditoastScenarioErrorNotFound'
42214227
- $ref: '#/components/schemas/EditoastScenarioErrorTimetableNotFound'
@@ -5111,6 +5117,25 @@ components:
51115117
type: string
51125118
enum:
51135119
- editoast:rollingstocks:NameAlreadyUsed
5120+
EditoastSTDCMErrorConsistEntryInvalid:
5121+
type: object
5122+
required:
5123+
- type
5124+
- status
5125+
- message
5126+
properties:
5127+
context:
5128+
type: object
5129+
message:
5130+
type: string
5131+
status:
5132+
type: integer
5133+
enum:
5134+
- 400
5135+
type:
5136+
type: string
5137+
enum:
5138+
- editoast:stdcm_v2:ConsistEntryInvalid
51145139
EditoastSTDCMErrorInfraNotFound:
51155140
type: object
51165141
required:
@@ -5207,6 +5232,30 @@ components:
52075232
type: string
52085233
enum:
52095234
- editoast:stdcm_v2:TimetableNotFound
5235+
EditoastSTDCMErrorTowedRollingStockNotFound:
5236+
type: object
5237+
required:
5238+
- type
5239+
- status
5240+
- message
5241+
properties:
5242+
context:
5243+
type: object
5244+
required:
5245+
- towed_rolling_stock_id
5246+
properties:
5247+
towed_rolling_stock_id:
5248+
type: integer
5249+
message:
5250+
type: string
5251+
status:
5252+
type: integer
5253+
enum:
5254+
- 400
5255+
type:
5256+
type: string
5257+
enum:
5258+
- editoast:stdcm_v2:TowedRollingStockNotFound
52105259
EditoastScenarioErrorInfraNotFound:
52115260
type: object
52125261
required:
@@ -8728,6 +8777,10 @@ components:
87288777
format: double
87298778
description: Total mass of the consist in kg
87308779
nullable: true
8780+
towed_rolling_stock_id:
8781+
type: integer
8782+
format: int64
8783+
nullable: true
87318784
work_schedule_group_id:
87328785
type: integer
87338786
format: int64

editoast/src/core/simulation.rs

+95-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use editoast_schemas::rolling_stock::EffortCurves;
55
use editoast_schemas::rolling_stock::Gamma;
66
use editoast_schemas::rolling_stock::RollingResistance;
77
use editoast_schemas::rolling_stock::RollingStock;
8+
use editoast_schemas::rolling_stock::TowedRollingStock;
89
use editoast_schemas::train_schedule::Comfort;
910
use editoast_schemas::train_schedule::Distribution;
1011
use editoast_schemas::train_schedule::MarginValue;
@@ -68,40 +69,63 @@ pub struct PhysicsRollingStock {
6869

6970
#[derive(Debug, Default)]
7071
pub struct SimulationParameters {
72+
/// In kg
7173
pub total_mass: Option<f64>,
7274
pub total_length: Option<f64>,
7375
pub max_speed: Option<f64>,
7476
}
7577

7678
impl PhysicsRollingStock {
77-
pub fn new(traction_engine: RollingStock, params: SimulationParameters) -> Self {
79+
pub fn new(
80+
traction_engine: RollingStock,
81+
towed_rolling_stock: Option<TowedRollingStock>,
82+
params: SimulationParameters,
83+
) -> Self {
7884
let traction_engine_length = traction_engine.length * 1000.0;
85+
86+
let towed_rolling_stock_length = towed_rolling_stock
87+
.as_ref()
88+
.map(|trs| trs.length)
89+
.unwrap_or(0.0); // TODO check the unit
7990
let length = params
8091
.total_length
8192
.map(|tl| tl * 1000.0)
82-
.unwrap_or(traction_engine_length)
93+
.unwrap_or_else(|| traction_engine_length + towed_rolling_stock_length)
8394
.round() as u64;
8495

8596
let traction_engine_mass = traction_engine.mass;
86-
let mass = params.total_mass.unwrap_or(traction_engine_mass).round() as u64;
97+
let towed_rolling_stock_mass = towed_rolling_stock.as_ref().map(|trs| trs.mass);
98+
let mass = params
99+
.total_mass
100+
.unwrap_or_else(|| traction_engine_mass + towed_rolling_stock_mass.unwrap_or(0.0))
101+
.round() as u64;
87102

88103
let max_speed = f64::min(
89104
traction_engine.max_speed,
90105
params.max_speed.unwrap_or(traction_engine.max_speed),
91106
);
92107

108+
let comfort_acceleration =
109+
compute_comfort_acceleration(&traction_engine, &towed_rolling_stock);
110+
let startup_acceleration =
111+
compute_startup_acceleration(&traction_engine, &towed_rolling_stock);
112+
let inertia_coefficient =
113+
compute_inertia_coefficient(&traction_engine, &towed_rolling_stock, params.total_mass);
114+
let rolling_resistance =
115+
compute_rolling_resistance(&traction_engine, &towed_rolling_stock, params.total_mass);
116+
93117
Self {
94118
effort_curves: traction_engine.effort_curves,
95119
base_power_class: traction_engine.base_power_class,
96120
length,
97121
mass,
98122
max_speed,
99123
startup_time: (traction_engine.startup_time * 1000.0).round() as u64,
100-
startup_acceleration: traction_engine.startup_acceleration,
101-
comfort_acceleration: traction_engine.comfort_acceleration,
124+
startup_acceleration,
125+
comfort_acceleration,
102126
gamma: traction_engine.gamma,
103-
inertia_coefficient: traction_engine.inertia_coefficient,
104-
rolling_resistance: traction_engine.rolling_resistance,
127+
inertia_coefficient,
128+
rolling_resistance,
105129
power_restrictions: traction_engine.power_restrictions.into_iter().collect(),
106130
electrical_power_startup_time: traction_engine
107131
.electrical_power_startup_time
@@ -113,6 +137,70 @@ impl PhysicsRollingStock {
113137
}
114138
}
115139

140+
fn compute_rolling_resistance(
141+
traction_engine: &RollingStock,
142+
towed_rolling_stock: &Option<TowedRollingStock>,
143+
total_mass: Option<f64>,
144+
) -> RollingResistance {
145+
if let (Some(towed_rolling_stock), Some(total_mass)) = (towed_rolling_stock, total_mass) {
146+
let traction_engine_rr = &traction_engine.rolling_resistance;
147+
let towed_rs_rr = &towed_rolling_stock.rolling_resistance;
148+
let traction_engine_mass = traction_engine.mass;
149+
150+
let a = traction_engine_rr.A * traction_engine_mass
151+
+ towed_rs_rr.A * (total_mass - traction_engine_mass);
152+
let b = traction_engine_rr.B * traction_engine_mass
153+
+ towed_rs_rr.B * (total_mass - traction_engine_mass);
154+
let c = traction_engine_rr.C * traction_engine_mass
155+
+ towed_rs_rr.C * (total_mass - traction_engine_mass);
156+
157+
RollingResistance::new(traction_engine_rr.rolling_resistance_type.clone(), a, b, c)
158+
} else {
159+
traction_engine.rolling_resistance.clone()
160+
}
161+
}
162+
163+
fn compute_inertia_coefficient(
164+
traction_engine: &RollingStock,
165+
towed_rolling_stock: &Option<TowedRollingStock>,
166+
total_mass: Option<f64>,
167+
) -> f64 {
168+
if let (Some(towed_rolling_stock), Some(total_mass)) = (towed_rolling_stock, total_mass) {
169+
(traction_engine.mass * traction_engine.inertia_coefficient)
170+
+ ((total_mass - towed_rolling_stock.mass) * towed_rolling_stock.inertia_coefficient)
171+
} else {
172+
traction_engine.inertia_coefficient
173+
}
174+
}
175+
176+
fn compute_startup_acceleration(
177+
traction_engine: &RollingStock,
178+
towed_rolling_stock: &Option<TowedRollingStock>,
179+
) -> f64 {
180+
if let Some(towed_rolling_stock) = towed_rolling_stock {
181+
f64::max(
182+
traction_engine.startup_acceleration,
183+
towed_rolling_stock.startup_acceleration,
184+
)
185+
} else {
186+
traction_engine.startup_acceleration
187+
}
188+
}
189+
190+
fn compute_comfort_acceleration(
191+
traction_engine: &RollingStock,
192+
towed_rolling_stock: &Option<TowedRollingStock>,
193+
) -> f64 {
194+
if let Some(towed_rolling_stock) = towed_rolling_stock {
195+
f64::min(
196+
traction_engine.comfort_acceleration,
197+
towed_rolling_stock.comfort_acceleration,
198+
)
199+
} else {
200+
traction_engine.comfort_acceleration
201+
}
202+
}
203+
116204
#[derive(Debug, Clone, Hash, PartialEq, Serialize, Deserialize, ToSchema)]
117205
pub struct ZoneUpdate {
118206
pub zone: String,

editoast/src/models/towed_rolling_stock.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ pub struct TowedRollingStockModel {
2121
pub railjson_version: String,
2222
pub locked: bool,
2323

24+
/// In kg
2425
pub mass: f64,
26+
/// In m
2527
pub length: f64,
2628
pub comfort_acceleration: f64,
2729
pub startup_acceleration: f64,

0 commit comments

Comments
 (0)