Skip to content

Commit 8c1d787

Browse files
committed
Mitigate wagons having invalid position
1 parent 6b62c2a commit 8c1d787

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,6 +1693,8 @@ public virtual void Copy(MSTSWagon copy)
16931693
CarWidthM = copy.CarWidthM;
16941694
CarHeightM = copy.CarHeightM;
16951695
CarLengthM = copy.CarLengthM;
1696+
FrontArticulation = copy.FrontArticulation;
1697+
RearArticulation = copy.RearArticulation;
16961698
TrackGaugeM = copy.TrackGaugeM;
16971699
CentreOfGravityM = copy.CentreOfGravityM;
16981700
InitialCentreOfGravityM = copy.InitialCentreOfGravityM;

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,7 +2912,7 @@ public void SetUpWheels()
29122912
// and the rest left out.
29132913

29142914
// Force articulation if stock is configured as such
2915-
// Otherwise, use default behavior which gives articulation if there are no axles forward/reareward on the model,
2915+
// Otherwise, use default behavior which gives articulation if there are no axles forward/rearward on the model,
29162916
// disables articulation on engines, and only allows articulation with 3 or fewer axles, but not 1 axle
29172917
bool articulatedFront = (FrontArticulation == 1 ||
29182918
(FrontArticulation == -1 && !WheelAxles.Any(a => a.OffsetM.Z < 0) && WagonType != WagonTypes.Engine && WheelAxles.Count != 1 && WheelAxles.Count <= 3));
@@ -3020,8 +3020,17 @@ public void ComputePosition(Traveller traveler, bool backToFront, float elapsedT
30203020
if (p.SumWgt > 1.5f)
30213021
p0.AddPartLocation(1, p);
30223022
}
3023-
// Determine facing direction and position of train car
3024-
p0.FindCenterLine();
3023+
if (Parts.Count == 2)
3024+
{
3025+
// Train car lacks sufficient parts to locate using linear regression
3026+
p0.Dir = Parts[1].Dir;
3027+
p0.Pos = Parts[1].Pos;
3028+
}
3029+
else
3030+
{
3031+
// Determine facing direction and position of train car
3032+
p0.FindCenterLine();
3033+
}
30253034
Vector3 fwd = new Vector3(p0.Dir[0], p0.Dir[1], -p0.Dir[2]);
30263035
// Check if null (0-length) vector
30273036
if (!(fwd.X == 0 && fwd.Y == 0 && fwd.Z == 0))
@@ -3739,7 +3748,7 @@ public class TrainCarPart
37393748
public double[] SumPos = new double[3]; // Sum of component locations [x, y, z]
37403749
public double[] SumPosZOffset = new double[3]; // Sum of component locations [x, y, z] times Z-offsets
37413750
public float[] Pos = new float[3]; // Position [x, y, z] of this part, calculated with y-intercept of linear regression
3742-
public float[] Dir = new float[3]; // Oritentation [x, y, z] of this part, calculated with slope of linear regression
3751+
public float[] Dir = new float[3]; // Orientation [x, y, z] of this part, calculated with slope of linear regression
37433752
public float SumRoll; // Sum of all roll angles of components
37443753
public float Roll; // Roll angle of this part
37453754
public bool Bogie; // True if this is a bogie
@@ -3804,7 +3813,7 @@ public void FindCenterLine()
38043813
// 2D Least regression between the offsets (along longitudinal axis of rail vehicle)
38053814
// and actual positions in 3D space, repeated 3 times for each dimension in 3D.
38063815

3807-
// Follows format of y = M * x + B where x is the foward/backward position along the train car axis
3816+
// Follows format of y = M * x + B where x is the forward/backward position along the train car axis
38083817
// and y is the actual (x, y, or z) position in 3D space. We need to determine vectors B (the 3D
38093818
// position of this part) and M (the 3D orientation of this part) using the offsets and positions added previously.
38103819

@@ -3819,18 +3828,15 @@ public void FindCenterLine()
38193828
Dir[i] = (float)((SumWgt * SumPosZOffset[i] - SumZOffset * SumPos[i]) / denominator);
38203829
// The position (B) is defined as 'B = [sum(y) - M * sum(x)] / N', where N is the total
38213830
// weight, x is the offset, y is the 3D position, and M is the direction value from earlier.
3822-
// This uses an equivalent form that doesn't use the result of the above calulcation to avoid
3831+
// This uses an equivalent form that doesn't use the result of the above calculation to avoid
38233832
// precision errors from the value being converted to a float.
38243833
Pos[i] = (float)((SumZOffsetSq * SumPos[i] - SumZOffset * SumPosZOffset[i]) / denominator);
38253834
}
38263835
}
3827-
else
3836+
else // Improperly defined wagon, fallback to basic calculation
38283837
{
38293838
for (int i = 0; i < 3; i++)
3830-
{
38313839
Pos[i] = (float)(SumPos[i] / SumWgt);
3832-
Dir[i] = 0;
3833-
}
38343840
}
38353841

38363842
Roll = SumRoll / (float)SumWgt;

0 commit comments

Comments
 (0)