1
-
1
+
2
2
using Microsoft . CodeAnalysis . VisualBasic . Syntax ;
3
3
using Microsoft . Xna . Framework ;
4
4
using Orts . Common ;
5
+ using Orts . Formats . Msts ;
5
6
using Orts . Parsers . Msts ;
6
7
using ORTS . Scripting . Api ;
7
8
using System ;
@@ -15,16 +16,35 @@ namespace Orts.Simulation.RollingStocks.SubSystems.PowerSupplies
15
16
{
16
17
public class Battery : ISubSystem < Battery >
17
18
{
19
+ TrainCar Car ;
18
20
public BatterySwitch BatterySwitch { get ; protected set ; }
19
21
public float NominalVoltageV = 72 ;
20
22
public float VoltageV { get ; protected set ; }
21
23
public float CurrentCapacityJ { get ; protected set ; }
22
24
public float MaxCapacityJ = 3.6e7f ;
23
- protected float EnergyFlowW ; // < 0 discharging, > 0 charging
25
+ protected float PowerW ; // Power demanded by the power supply, not implemented
26
+ protected float MaxChargingPowerW = 10000 ;
27
+ protected float ChargingVoltageV ;
28
+ protected bool IsCharging
29
+ {
30
+ get
31
+ {
32
+ if ( Car is MSTSLocomotive locomotive )
33
+ {
34
+ return locomotive . LocomotivePowerSupply . AuxiliaryPowerSupplyOn ;
35
+ }
36
+ else if ( Car . PowerSupply != null )
37
+ {
38
+ return Car . PowerSupply . ElectricTrainSupplyOn ;
39
+ }
40
+ return false ;
41
+ }
42
+ }
24
43
public Interpolator ChargeVoltageCurve ;
25
44
public PowerSupplyState State ;
26
45
public Battery ( MSTSWagon wagon )
27
46
{
47
+ Car = wagon ;
28
48
BatterySwitch = new BatterySwitch ( wagon ) ;
29
49
}
30
50
public virtual void Parse ( string lowercasetoken , STFReader stf )
@@ -45,6 +65,12 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
45
65
case "maxcapacity" :
46
66
MaxCapacityJ = stf . ReadFloatBlock ( STFReader . UNITS . Energy , MaxCapacityJ ) ;
47
67
break ;
68
+ case "chargerpower" :
69
+ MaxChargingPowerW = stf . ReadFloatBlock ( STFReader . UNITS . Power , MaxChargingPowerW ) ;
70
+ break ;
71
+ case "chargervoltage" :
72
+ ChargingVoltageV = stf . ReadFloatBlock ( STFReader . UNITS . Voltage , 0 ) ;
73
+ break ;
48
74
case "chargevoltagecurve" :
49
75
ChargeVoltageCurve = new Interpolator ( stf ) ;
50
76
break ;
@@ -70,10 +96,13 @@ public virtual void Copy(Battery other)
70
96
}
71
97
public virtual void Initialize ( )
72
98
{
73
- CurrentCapacityJ = MaxCapacityJ ;
99
+ CurrentCapacityJ = 0.7f * MaxCapacityJ ;
100
+ if ( ChargingVoltageV == 0 ) ChargingVoltageV = NominalVoltageV * 1.15f ;
74
101
if ( ChargeVoltageCurve == null )
75
102
{
76
- ChargeVoltageCurve = new Interpolator ( new float [ ] { 0 , MaxCapacityJ } , new float [ ] { 0 , NominalVoltageV } ) ;
103
+ ChargeVoltageCurve = new Interpolator (
104
+ new float [ ] { 0 , MaxCapacityJ * 0.1f , MaxCapacityJ } ,
105
+ new float [ ] { 0 , 0.95f * NominalVoltageV , 1.05f * NominalVoltageV } ) ;
77
106
}
78
107
79
108
BatterySwitch . Initialize ( ) ;
@@ -86,21 +115,43 @@ public virtual void Save(BinaryWriter outf)
86
115
{
87
116
BatterySwitch . Save ( outf ) ;
88
117
outf . Write ( CurrentCapacityJ ) ;
89
- outf . Write ( EnergyFlowW ) ;
90
118
}
91
119
public virtual void Restore ( BinaryReader inf )
92
120
{
93
121
BatterySwitch . Restore ( inf ) ;
94
122
CurrentCapacityJ = inf . ReadSingle ( ) ;
95
- EnergyFlowW = inf . ReadSingle ( ) ;
96
123
}
97
124
public virtual void Update ( float elapsedClockSeconds )
98
125
{
99
126
BatterySwitch . Update ( elapsedClockSeconds ) ;
100
127
101
- CurrentCapacityJ = MathHelper . Clamp ( CurrentCapacityJ + EnergyFlowW * elapsedClockSeconds , 0 , MaxCapacityJ ) ;
102
- VoltageV = ChargeVoltageCurve [ CurrentCapacityJ ] ;
128
+ if ( IsCharging )
129
+ {
130
+ if ( ChargeVoltageCurve [ CurrentCapacityJ ] < ChargingVoltageV && CurrentCapacityJ < MaxCapacityJ )
131
+ {
132
+ // Charge the battery
133
+ float energyJ = MaxChargingPowerW * elapsedClockSeconds ;
134
+ if ( CurrentCapacityJ + energyJ > MaxCapacityJ )
135
+ energyJ = MaxCapacityJ - CurrentCapacityJ ;
136
+ CurrentCapacityJ += energyJ ;
137
+ }
138
+ // When charging, voltage is that of the battery charger
139
+ VoltageV = ChargingVoltageV ;
140
+ }
141
+ else
142
+ {
143
+ if ( PowerW > 0 && State == PowerSupplyState . PowerOn )
144
+ {
145
+ // Discharge the battery
146
+ float energyJ = PowerW * elapsedClockSeconds ;
147
+ if ( CurrentCapacityJ - energyJ > 0 )
148
+ energyJ = CurrentCapacityJ ;
149
+ CurrentCapacityJ -= energyJ ;
150
+ }
151
+ // If battery is draining, voltage will depend on the total charge
152
+ // Voltage also depends on power drawn, not implemented
153
+ VoltageV = ChargeVoltageCurve [ CurrentCapacityJ ] ;
154
+ }
103
155
}
104
-
105
156
}
106
- }
157
+ }
0 commit comments