1-
1+
22using Microsoft . CodeAnalysis . VisualBasic . Syntax ;
33using Microsoft . Xna . Framework ;
44using Orts . Common ;
5+ using Orts . Formats . Msts ;
56using Orts . Parsers . Msts ;
67using ORTS . Scripting . Api ;
78using System ;
@@ -15,16 +16,35 @@ namespace Orts.Simulation.RollingStocks.SubSystems.PowerSupplies
1516{
1617 public class Battery : ISubSystem < Battery >
1718 {
19+ TrainCar Car ;
1820 public BatterySwitch BatterySwitch { get ; protected set ; }
1921 public float NominalVoltageV = 72 ;
2022 public float VoltageV { get ; protected set ; }
2123 public float CurrentCapacityJ { get ; protected set ; }
2224 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+ }
2443 public Interpolator ChargeVoltageCurve ;
2544 public PowerSupplyState State ;
2645 public Battery ( MSTSWagon wagon )
2746 {
47+ Car = wagon ;
2848 BatterySwitch = new BatterySwitch ( wagon ) ;
2949 }
3050 public virtual void Parse ( string lowercasetoken , STFReader stf )
@@ -45,6 +65,12 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
4565 case "maxcapacity" :
4666 MaxCapacityJ = stf . ReadFloatBlock ( STFReader . UNITS . Energy , MaxCapacityJ ) ;
4767 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 ;
4874 case "chargevoltagecurve" :
4975 ChargeVoltageCurve = new Interpolator ( stf ) ;
5076 break ;
@@ -70,10 +96,13 @@ public virtual void Copy(Battery other)
7096 }
7197 public virtual void Initialize ( )
7298 {
73- CurrentCapacityJ = MaxCapacityJ ;
99+ CurrentCapacityJ = 0.7f * MaxCapacityJ ;
100+ if ( ChargingVoltageV == 0 ) ChargingVoltageV = NominalVoltageV * 1.15f ;
74101 if ( ChargeVoltageCurve == null )
75102 {
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 } ) ;
77106 }
78107
79108 BatterySwitch . Initialize ( ) ;
@@ -86,21 +115,43 @@ public virtual void Save(BinaryWriter outf)
86115 {
87116 BatterySwitch . Save ( outf ) ;
88117 outf . Write ( CurrentCapacityJ ) ;
89- outf . Write ( EnergyFlowW ) ;
90118 }
91119 public virtual void Restore ( BinaryReader inf )
92120 {
93121 BatterySwitch . Restore ( inf ) ;
94122 CurrentCapacityJ = inf . ReadSingle ( ) ;
95- EnergyFlowW = inf . ReadSingle ( ) ;
96123 }
97124 public virtual void Update ( float elapsedClockSeconds )
98125 {
99126 BatterySwitch . Update ( elapsedClockSeconds ) ;
100127
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+ }
103155 }
104-
105156 }
106- }
157+ }
0 commit comments