Skip to content

Commit 28be602

Browse files
committed
Change: More implementation work on pantographs
1 parent ba7cf2b commit 28be602

File tree

4 files changed

+141
-12
lines changed

4 files changed

+141
-12
lines changed

source/OpenBVE/Parsers/Train/TrainDatParser.cs

+110-8
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
6060
}
6161
}
6262
TrainDatFormats currentFormat = TrainDatFormats.openBVE;
63-
const int currentVersion = 15311;
63+
const int currentVersion = 18000;
6464
int myVersion = -1;
6565
for (int i = 0; i < Lines.Length; i++) {
6666
if (Lines[i].Length > 0) {
@@ -152,6 +152,8 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
152152
Train.Handles.EmergencyBrake = new TrainManager.EmergencyHandle();
153153
Train.Handles.HasLocoBrake = false;
154154
double[] powerDelayUp = { }, powerDelayDown = { }, brakeDelayUp = { }, brakeDelayDown = { }, locoBrakeDelayUp = { }, locoBrakeDelayDown = { };
155+
int numberOfPantographs = 1;
156+
double pantographLocation = -1;
155157
int powerNotches = 0, brakeNotches = 0, locoBrakeNotches = 0, powerReduceSteps = -1, locoBrakeType = 0, driverPowerNotches = 0, driverBrakeNotches = 0;
156158
TrainManager.MotorSoundTable[] Tables = new TrainManager.MotorSoundTable[4];
157159
for (int i = 0; i < 4; i++) {
@@ -675,6 +677,20 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
675677
} else {
676678
CarUnexposedFrontalArea = a;
677679
} break;
680+
case 11:
681+
if (a <= 0.0)
682+
{
683+
Interface.AddMessage(MessageType.Error, false, "NumberOfPantographs is expected to be positive at line " + (i + 1).ToString(Culture) + " in " + FileName);
684+
}
685+
else
686+
{
687+
numberOfPantographs = (int)a;
688+
}
689+
break;
690+
case 12:
691+
//Do no validation here, as we don't necessarily yet know the length of a car
692+
pantographLocation = a;
693+
break;
678694
}
679695
} i++; n++;
680696
} i--; break;
@@ -961,6 +977,19 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
961977
MaximumAcceleration = AccelerationCurves[i].StageOneAcceleration;
962978
}
963979
}
980+
981+
if (pantographLocation < 0 || pantographLocation > CarLength)
982+
{
983+
//Pantograph location is relative from the front of the car
984+
//Somone will probably want to add one outside the physical model, so just warn...
985+
Interface.AddMessage(MessageType.Warning, false, "A PantographLocation of " + pantographLocation.ToString(Culture) + " places it outside the bounds of the car in file " + FileName);
986+
}
987+
988+
if (numberOfPantographs > Cars)
989+
{
990+
Interface.AddMessage(MessageType.Error, false, "A total of " + numberOfPantographs.ToString(Culture) + " were defined, when the train has " + Cars.ToString(Culture) + " cars in file " + FileName);
991+
numberOfPantographs = Cars;
992+
}
964993
// assign motor cars
965994
if (MotorCars == 1) {
966995
if (FrontCarIsMotorCar | TrailerCars == 0) {
@@ -1010,6 +1039,84 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
10101039
}
10111040
}
10121041
}
1042+
// assign pantograph cars
1043+
if (numberOfPantographs == Cars)
1044+
{
1045+
//One pantograph per car
1046+
for (int i = 0; i < Train.Cars.Length; i++)
1047+
{
1048+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1049+
}
1050+
}
1051+
else if (numberOfPantographs == MotorCars)
1052+
{
1053+
//Assign pantograph to all motor cars
1054+
for (int i = 0; i < Train.Cars.Length; i++)
1055+
{
1056+
if (Train.Cars[i].Specs.IsMotorCar)
1057+
{
1058+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1059+
}
1060+
}
1061+
}
1062+
else if (numberOfPantographs == 1)
1063+
{
1064+
// With single pantograph, assign to the first motor car
1065+
for (int i = 0; i < Train.Cars.Length; i++)
1066+
{
1067+
if (Train.Cars[i].Specs.IsMotorCar)
1068+
{
1069+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1070+
break;
1071+
}
1072+
}
1073+
}
1074+
else if (numberOfPantographs == 2)
1075+
{
1076+
if (MotorCars >= 2)
1077+
{
1078+
// Assign pantographs to the first and last motor cars
1079+
for (int i = 0; i < Train.Cars.Length; i++)
1080+
{
1081+
if (Train.Cars[i].Specs.IsMotorCar)
1082+
{
1083+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1084+
break;
1085+
}
1086+
}
1087+
for (int i = Train.Cars.Length - 1; i > 0; i--)
1088+
{
1089+
if (Train.Cars[i].Specs.IsMotorCar)
1090+
{
1091+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1092+
break;
1093+
}
1094+
}
1095+
}
1096+
else
1097+
{
1098+
//Assign evenly
1099+
int i = (int)Math.Ceiling(0.25 * (double)(Cars - 1));
1100+
int j = (int)Math.Floor(0.75 * (double)(Cars - 1));
1101+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1102+
Train.Cars[j].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1103+
}
1104+
}
1105+
else
1106+
{
1107+
//Assign using motor cars algo
1108+
double t = 1.0 + numberOfPantographs;
1109+
double r = 0.0;
1110+
double x = 1.0;
1111+
while (true) {
1112+
double y = x + t - r;
1113+
x = Math.Ceiling(y);
1114+
r = x - y;
1115+
int i = (int)x;
1116+
if (i >= Cars) break;
1117+
Train.Cars[i].Pantograph = new TrackFollower(Program.CurrentHost, Train);
1118+
}
1119+
}
10131120
double MotorDeceleration = Math.Sqrt(MaximumAcceleration * BrakeDeceleration);
10141121
// apply brake-specific attributes for all cars
10151122
for (int i = 0; i < Cars; i++) {
@@ -1184,15 +1291,10 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
11841291
{
11851292
Train.Cars[i].Coupler = new TrainManager.Coupler(0.9 * DistanceBetweenTheCars, 1.1 * DistanceBetweenTheCars, Train.Cars[i / 2], null, Train);
11861293
}
1187-
1188-
Train.Cars[i].CurrentCarSection = -1;
1189-
Train.Cars[i].ChangeCarSection(CarSectionType.NotVisible);
1190-
Train.Cars[i].FrontBogie.ChangeSection(-1);
1191-
Train.Cars[i].RearBogie.ChangeSection(-1);
1192-
Train.Cars[i].Coupler.ChangeSection(-1);
1294+
1295+
Train.Cars[i].PantographPosition = pantographLocation;
11931296
Train.Cars[i].FrontAxle.Follower.TriggerType = i == 0 ? EventTriggerType.FrontCarFrontAxle : EventTriggerType.OtherCarFrontAxle;
11941297
Train.Cars[i].RearAxle.Follower.TriggerType = i == Cars - 1 ? EventTriggerType.RearCarRearAxle : EventTriggerType.OtherCarRearAxle;
1195-
Train.Cars[i].BeaconReceiver.TriggerType = i == 0 ? EventTriggerType.TrainFront : EventTriggerType.None;
11961298
Train.Cars[i].BeaconReceiverPosition = 0.5 * CarLength;
11971299
Train.Cars[i].FrontAxle.Follower.Car = Train.Cars[i];
11981300
Train.Cars[i].RearAxle.Follower.Car = Train.Cars[i];

source/OpenBVE/Simulation/TrainManager/Car/Car.Bogie.cs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ internal Bogie(Train train, Car car)
4444
CarSections = new CarSection[] { };
4545
FrontAxle = new Axle(Program.CurrentHost, train, car);
4646
RearAxle = new Axle(Program.CurrentHost, train, car);
47+
ChangeSection(-1);
4748
}
4849

4950
internal void UpdateObjects(double TimeElapsed, bool ForceUpdate)

source/OpenBVE/Simulation/TrainManager/Car/Car.cs

+26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using LibRender2;
34
using LibRender2.Camera;
45
using LibRender2.Cameras;
@@ -52,7 +53,12 @@ internal partial class Car : AbstractCar
5253
internal Coupler Coupler;
5354

5455
internal double BeaconReceiverPosition;
56+
/// <summary>Recieves all safety system beacons</summary>
5557
internal TrackFollower BeaconReceiver;
58+
59+
internal double PantographPosition;
60+
/// <summary>Provides current collection etc.</summary>
61+
internal TrackFollower Pantograph;
5662
/// <summary>Whether loading sway is enabled for this car</summary>
5763
internal bool EnableLoadingSway = true;
5864
/// <summary>A reference to the base train</summary>
@@ -66,6 +72,23 @@ internal partial class Car : AbstractCar
6672
internal CameraAlignment InteriorCamera;
6773

6874
internal bool HasInteriorView = false;
75+
76+
public override Dictionary<PowerSupplyTypes, PowerSupply> AvailablePowerSupplies
77+
{
78+
get
79+
{
80+
if (Pantograph != null)
81+
{
82+
return Pantograph.AvailablePowerSupplies;
83+
}
84+
else
85+
{
86+
//Not fitted, so return empty collection
87+
return new Dictionary<PowerSupplyTypes, PowerSupply>();
88+
}
89+
90+
}
91+
}
6992

7093
internal Car(Train train, int index, double CoefficientOfFriction, double CoefficientOfRollingResistance, double AerodynamicDragCoefficient)
7194
{
@@ -75,13 +98,16 @@ internal Car(Train train, int index, double CoefficientOfFriction, double Coeffi
7598
FrontAxle = new Axle(Program.CurrentHost, train, this, CoefficientOfFriction, CoefficientOfRollingResistance, AerodynamicDragCoefficient);
7699
RearAxle = new Axle(Program.CurrentHost, train, this, CoefficientOfFriction, CoefficientOfRollingResistance, AerodynamicDragCoefficient);
77100
BeaconReceiver = new TrackFollower(Program.CurrentHost, train);
101+
BeaconReceiver.TriggerType = index == 0 ? EventTriggerType.TrainFront : EventTriggerType.None;
78102
FrontBogie = new Bogie(train, this);
79103
RearBogie = new Bogie(train, this);
80104
Doors = new Door[2];
81105
Doors[0].Width = 1000.0;
82106
Doors[0].MaxTolerance = 0.0;
83107
Doors[1].Width = 1000.0;
84108
Doors[1].MaxTolerance = 0.0;
109+
CurrentCarSection = -1;
110+
ChangeCarSection(CarSectionType.NotVisible);
85111
}
86112

87113
internal Car(Train train, int index)

source/OpenBveApi/Routes/Track/PowerSupply.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
public class PowerSupply
55
{
66
/// <summary>The voltage type supplied</summary>
7-
internal readonly PowerSupplyVoltageTypes VoltageType;
7+
public readonly PowerSupplyVoltageTypes VoltageType;
88
/// <summary>The voltage supplied</summary>
9-
internal readonly double Voltage;
9+
public readonly double Voltage;
1010
/// <summary>The maximum amperage supplied</summary>
11-
internal readonly double Amperage;
11+
public readonly double Amperage;
1212
/// <summary>The contact height</summary>
13-
internal readonly double ContactHeight;
13+
public readonly double ContactHeight;
1414

1515
/// <summary>Creates a new power supply</summary>
1616
public PowerSupply(PowerSupplyVoltageTypes voltageType, double voltage, double amperage, double contactHeight)

0 commit comments

Comments
 (0)