Skip to content

Commit 5cf62c9

Browse files
committed
Automatic merge of T1.6-rc2-41-gacd714487 and 10 pull requests
- Pull request #1086 at e10390b: Add Settings Exporter tool (copy settings to INI, etc) - Pull request #1091 at 2391bc0: Automatic speed control - Pull request #1107 at f5eb3dc: Fix DPMode when last remote is moved to front. - Pull request #1108 at 343c792: Fix Horn, Bell, and MU light conditions on AI trains - Pull request #1109 at 0190043: Fix Erroneous Detection of Departure Before Passenger Boarding Completed - Pull request #1110 at 387388e: Fix Activity Runner persists after loading exception - Pull request #1112 at 1224807: update for V1.6 - Pull request #1082 at 5845a1a: Allow variable water level in glass gauge - Pull request #1104 at f40920a: Handle simple adhesion within the axle module - Pull request #1081 at 689494b: Brake cuts power unification
12 parents 03d3d6d + acd7144 + e10390b + 2391bc0 + f5eb3dc + 343c792 + 0190043 + 387388e + 1224807 + 5845a1a + f40920a + 689494b commit 5cf62c9

File tree

2 files changed

+105
-78
lines changed

2 files changed

+105
-78
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// COPYRIGHT 2025 by the Open Rails project.
2+
//
3+
// This file is part of Open Rails.
4+
//
5+
// Open Rails is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// Open Rails is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
17+
18+
using System;
19+
20+
namespace ORTS.Common
21+
{
22+
/// <summary>
23+
/// Modified PID controller that converts requested force/acceleration to throttle or brake percent
24+
/// </summary>
25+
public class AccelerationController
26+
{
27+
public float Percent { get; private set; }
28+
public float PPercent { get; private set; }
29+
public float IPercent { get; private set; }
30+
public float DPercent { get; private set; }
31+
private float TotalError;
32+
private float LastTarget;
33+
private float LastError;
34+
private bool active;
35+
private readonly float[] Coefficients;
36+
private float ProportionalFactor;
37+
private float IntegralFactor;
38+
private float DerivativeFactor;
39+
public float Tolerance;
40+
public bool Active
41+
{
42+
set
43+
{
44+
if (active != value)
45+
{
46+
LastTarget = 0;
47+
LastError = 0;
48+
TotalError = 0;
49+
Percent = 0;
50+
active = value;
51+
}
52+
}
53+
get
54+
{
55+
return active;
56+
}
57+
}
58+
public AccelerationController(float p, float i, float d = 0)
59+
{
60+
Coefficients = new float[] { 100 * p, 100 * i, 100 * d };
61+
}
62+
protected AccelerationController(AccelerationController o)
63+
{
64+
Coefficients = o.Coefficients;
65+
}
66+
public AccelerationController Clone()
67+
{
68+
return new AccelerationController(this);
69+
}
70+
/// <summary>
71+
/// Adjust PID coefficients according to the maximum force/acceleration
72+
/// </summary>
73+
/// <param name="maxAccelerationMpSS">Maximum force or acceleration developed with controller at 100%</param>
74+
public void Adjust(float maxAccelerationMpSS)
75+
{
76+
ProportionalFactor = Coefficients[0] / maxAccelerationMpSS;
77+
IntegralFactor = Coefficients[1] / maxAccelerationMpSS;
78+
DerivativeFactor = Coefficients[2] / maxAccelerationMpSS;
79+
}
80+
public void Update(float elapsedClockSeconds, float targetAccelerationMpSS, float currentAccelerationMpSS, float minPercent = 0, float maxPercent = 100)
81+
{
82+
if (!Active) Active = true;
83+
float error = targetAccelerationMpSS - currentAccelerationMpSS;
84+
TotalError += (error + LastError) * elapsedClockSeconds / 2;
85+
PPercent = ProportionalFactor * targetAccelerationMpSS;
86+
IPercent = IntegralFactor * TotalError;
87+
DPercent = elapsedClockSeconds > 0 && DerivativeFactor > 0 ? DerivativeFactor * (error - LastError) / elapsedClockSeconds : 0;
88+
Percent = PPercent + IPercent + DPercent;
89+
if (Percent <= minPercent)
90+
{
91+
if (PPercent > minPercent && IntegralFactor > 0) TotalError = (minPercent - PPercent) / IntegralFactor;
92+
else if (TotalError < 0) TotalError = 0;
93+
Percent = minPercent;
94+
}
95+
if (Percent >= maxPercent)
96+
{
97+
if (PPercent < maxPercent && IntegralFactor > 0) TotalError = (maxPercent - PPercent) / IntegralFactor;
98+
else if (TotalError > 0) TotalError = 0;
99+
Percent = maxPercent;
100+
}
101+
LastTarget = targetAccelerationMpSS;
102+
LastError = error;
103+
}
104+
}
105+
}

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@
2020
using System.IO;
2121
using System.Linq;
2222
using Microsoft.Xna.Framework;
23-
using Orts.Common;
2423
using Orts.Formats.Msts;
2524
using Orts.Parsers.Msts;
2625
using Orts.Simulation.RollingStocks.SubSystems.Controllers;
2726
using ORTS.Common;
2827
using ORTS.Scripting.Api;
29-
using static Orts.Simulation.RollingStocks.TrainCar;
3028
namespace Orts.Simulation.RollingStocks.SubSystems
3129
{
3230
public class CruiseControl
@@ -1561,80 +1559,4 @@ public enum ControllerCruiseControlLogic
15611559
SpeedOnly
15621560
}
15631561
}
1564-
public class AccelerationController
1565-
{
1566-
public float Percent { get; private set; }
1567-
public float PPercent { get; private set; }
1568-
public float IPercent { get; private set; }
1569-
public float DPercent { get; private set; }
1570-
private float TotalError;
1571-
private float LastTarget;
1572-
private float LastError;
1573-
private bool active;
1574-
private readonly float[] Coefficients;
1575-
private float ProportionalFactor;
1576-
private float IntegralFactor;
1577-
private float DerivativeFactor;
1578-
public float Tolerance;
1579-
public bool Active
1580-
{
1581-
set
1582-
{
1583-
if (active != value)
1584-
{
1585-
LastTarget = 0;
1586-
LastError = 0;
1587-
TotalError = 0;
1588-
Percent = 0;
1589-
active = value;
1590-
}
1591-
}
1592-
get
1593-
{
1594-
return active;
1595-
}
1596-
}
1597-
public AccelerationController(float p, float i, float d=0)
1598-
{
1599-
Coefficients = new float[] {100*p, 100*i, 100*d};
1600-
}
1601-
protected AccelerationController(AccelerationController o)
1602-
{
1603-
Coefficients = o.Coefficients;
1604-
}
1605-
public AccelerationController Clone()
1606-
{
1607-
return new AccelerationController(this);
1608-
}
1609-
public void Adjust(float maxAccelerationMpSS)
1610-
{
1611-
ProportionalFactor = Coefficients[0] / maxAccelerationMpSS;
1612-
IntegralFactor = Coefficients[1] / maxAccelerationMpSS;
1613-
DerivativeFactor = Coefficients[2] / maxAccelerationMpSS;
1614-
}
1615-
public void Update(float elapsedClockSeconds, float targetAccelerationMpSS, float currentAccelerationMpSS, float minPercent = 0, float maxPercent = 100)
1616-
{
1617-
if (!Active) Active = true;
1618-
float error = targetAccelerationMpSS - currentAccelerationMpSS;
1619-
TotalError += (error + LastError) * elapsedClockSeconds / 2;
1620-
PPercent = ProportionalFactor * targetAccelerationMpSS;
1621-
IPercent = IntegralFactor * TotalError;
1622-
DPercent = elapsedClockSeconds > 0 && DerivativeFactor > 0 ? DerivativeFactor * (error - LastError) / elapsedClockSeconds : 0;
1623-
Percent = PPercent + IPercent + DPercent;
1624-
if (Percent <= minPercent)
1625-
{
1626-
if (PPercent > minPercent && IntegralFactor > 0) TotalError = (minPercent - PPercent) / IntegralFactor;
1627-
else if (TotalError < 0) TotalError = 0;
1628-
Percent = minPercent;
1629-
}
1630-
if (Percent >= maxPercent)
1631-
{
1632-
if (PPercent < maxPercent && IntegralFactor > 0) TotalError = (maxPercent - PPercent) / IntegralFactor;
1633-
else if (TotalError > 0) TotalError = 0;
1634-
Percent = maxPercent;
1635-
}
1636-
LastTarget = targetAccelerationMpSS;
1637-
LastError = error;
1638-
}
1639-
}
16401562
}

0 commit comments

Comments
 (0)