@@ -5,6 +5,7 @@ use editoast_schemas::rolling_stock::EffortCurves;
5
5
use editoast_schemas:: rolling_stock:: Gamma ;
6
6
use editoast_schemas:: rolling_stock:: RollingResistance ;
7
7
use editoast_schemas:: rolling_stock:: RollingStock ;
8
+ use editoast_schemas:: rolling_stock:: TowedRollingStock ;
8
9
use editoast_schemas:: train_schedule:: Comfort ;
9
10
use editoast_schemas:: train_schedule:: Distribution ;
10
11
use editoast_schemas:: train_schedule:: MarginValue ;
@@ -68,40 +69,63 @@ pub struct PhysicsRollingStock {
68
69
69
70
#[ derive( Debug , Default ) ]
70
71
pub struct SimulationParameters {
72
+ /// In kg
71
73
pub total_mass : Option < f64 > ,
72
74
pub total_length : Option < f64 > ,
73
75
pub max_speed : Option < f64 > ,
74
76
}
75
77
76
78
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 {
78
84
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
79
90
let length = params
80
91
. total_length
81
92
. map ( |tl| tl * 1000.0 )
82
- . unwrap_or ( traction_engine_length)
93
+ . unwrap_or_else ( || traction_engine_length + towed_rolling_stock_length )
83
94
. round ( ) as u64 ;
84
95
85
96
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 ;
87
102
88
103
let max_speed = f64:: min (
89
104
traction_engine. max_speed ,
90
105
params. max_speed . unwrap_or ( traction_engine. max_speed ) ,
91
106
) ;
92
107
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
+
93
117
Self {
94
118
effort_curves : traction_engine. effort_curves ,
95
119
base_power_class : traction_engine. base_power_class ,
96
120
length,
97
121
mass,
98
122
max_speed,
99
123
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,
102
126
gamma : traction_engine. gamma ,
103
- inertia_coefficient : traction_engine . inertia_coefficient ,
104
- rolling_resistance : traction_engine . rolling_resistance ,
127
+ inertia_coefficient,
128
+ rolling_resistance,
105
129
power_restrictions : traction_engine. power_restrictions . into_iter ( ) . collect ( ) ,
106
130
electrical_power_startup_time : traction_engine
107
131
. electrical_power_startup_time
@@ -113,6 +137,70 @@ impl PhysicsRollingStock {
113
137
}
114
138
}
115
139
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
+
116
204
#[ derive( Debug , Clone , Hash , PartialEq , Serialize , Deserialize , ToSchema ) ]
117
205
pub struct ZoneUpdate {
118
206
pub zone : String ,
0 commit comments