The existing implementation of the PIDF control loop is a bit of a janky mess and is in dire need of a clean-up.
Refactor existing feed-forward implementation
The existing feed-forward couples the set speed directly to the control loop's output and it barely contributes to anything at normal line speeds. At higher speeds, this feed-forward causes the control loop to keep accelerating uncontrollably.
A better solution would be to take the rate of change of the set point and use that as the feed-forward, effectively turning it into a pseudo-control derivative term.
Interpolate between set speeds
There currently is no interpolation between each speed you set the locomotive to.
RailDriver currently relies on the tune of the control loop to determine the acceleration and deceleration characteristics.
This leads to the control loop being either under-tuned or over-tuned for its main purpose.
In some cases, you can quite literally tune the control loop to make your locomotive almost instantly "jump" to your set speed... highly entertaining if you have other (be it freight or passenger) cars in tow.
A better solution is to have an interpolation between values and have this be the set point.
Then re-tune the control loop to closely track the set point.
The time scale and shape of the interpolation may be adjusted to control the acceleration and deceleration characteristics of the locomotive.
Scale P, I and D gains based on total train weight
This is a big one, especially when you are doing lengthy hauls. The more weight you have in tow, the more "sluggish" your train may seem. Also, the more likely you will see oscillations in the control loop.
Increase PID loop calculation speed
This may impact CPU usage and tick quota.
Currently, the control loop acts on every tick() which fires roughly every 10~15 milliseconds.
This heavily limits the control loop to a processing speed of 30~60 Hz. Even for a train, this isn't sufficient to provide stable performance.
A better solution may be to have the control loop execute at a fixed rate inside the governance of a while(perf(n)) statement.
This may need investigation to determine how it will be implemented and how much of an impact on performance it will have.
A possible scenario would be to have the control loop execute ten times at a fixed delay within that while(perf(n)) statement when the tick() fires. This could potentially increase the calculation speed of the control loop and allow the user to dial in the control loop calculation rate to favour performance at the expense of more intensive CPU usage and vice versa.
Refactor hillclimb/decent
This will effectively rename it to "Hill Compensation".
The concept will stay the same: Couple the locomotive's pitch angle directly to the control loop's output to assist with track grade changes.
Refactor I Term Decay
The I Term oscillates around zero while the I Term is being "bled off".
This can cause the locomotive to continue rolling in its current direction for quite some time before it comes to a complete stop.
Doing away with this oscillation will make the transition across the automatic brake system engaging a lot smoother than what it currently is.
Various housekeeping chores
Code cleanup.
Removal of comments and notes.
Remove references to non-implemented driving modes.
The existing implementation of the PIDF control loop is a bit of a janky mess and is in dire need of a clean-up.
Refactor existing feed-forward implementation
The existing feed-forward couples the set speed directly to the control loop's output and it barely contributes to anything at normal line speeds. At higher speeds, this feed-forward causes the control loop to keep accelerating uncontrollably.
A better solution would be to take the rate of change of the set point and use that as the feed-forward, effectively turning it into a pseudo-control derivative term.
Interpolate between set speeds
There currently is no interpolation between each speed you set the locomotive to.
RailDriver currently relies on the tune of the control loop to determine the acceleration and deceleration characteristics.
This leads to the control loop being either under-tuned or over-tuned for its main purpose.
In some cases, you can quite literally tune the control loop to make your locomotive almost instantly "jump" to your set speed... highly entertaining if you have other (be it freight or passenger) cars in tow.
A better solution is to have an interpolation between values and have this be the set point.
Then re-tune the control loop to closely track the set point.
The time scale and shape of the interpolation may be adjusted to control the acceleration and deceleration characteristics of the locomotive.
Scale P, I and D gains based on total train weight
This is a big one, especially when you are doing lengthy hauls. The more weight you have in tow, the more "sluggish" your train may seem. Also, the more likely you will see oscillations in the control loop.
Increase PID loop calculation speed
This may impact CPU usage and tick quota.
Currently, the control loop acts on every
tick()
which fires roughly every 10~15 milliseconds.This heavily limits the control loop to a processing speed of 30~60 Hz. Even for a train, this isn't sufficient to provide stable performance.
A better solution may be to have the control loop execute at a fixed rate inside the governance of a
while(perf(n))
statement.This may need investigation to determine how it will be implemented and how much of an impact on performance it will have.
A possible scenario would be to have the control loop execute ten times at a fixed delay within that
while(perf(n))
statement when thetick()
fires. This could potentially increase the calculation speed of the control loop and allow the user to dial in the control loop calculation rate to favour performance at the expense of more intensive CPU usage and vice versa.Refactor hillclimb/decent
This will effectively rename it to "Hill Compensation".
The concept will stay the same: Couple the locomotive's pitch angle directly to the control loop's output to assist with track grade changes.
Refactor I Term Decay
The I Term oscillates around zero while the I Term is being "bled off".
This can cause the locomotive to continue rolling in its current direction for quite some time before it comes to a complete stop.
Doing away with this oscillation will make the transition across the automatic brake system engaging a lot smoother than what it currently is.
Various housekeeping chores