[Patch] ATC speed control

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

DoppyNL
Engineer
Engineer
Posts: 23
Joined: 21 Aug 2009 14:27

Re: [Patch] ATC speed control

Post by DoppyNL »

With the author having left 1.5 years ago, probably nobody knows, so why not try it yourself and find out?
But it doesn't hurt to find out if the original author is still around.
I hate to hi-jack someone's hard work.

------

I've downloaded the source, added the patch and compiled it, and...... it didn't work.
In short, openttd still works, the trains just don't adjust their speed.

So I tried fixing some things, but don't seem to get it to work just yet.
However, I've found the probable cause why it isn't working. The patch involves "walking down the path the train is taking" to find a train.
That bit in quotes is the problem, that doesn't work like it should. Adjusting the speed of the train is not a problem.

The original programmer tries to find out the route by himself, without checking with the pathfinder. But I don't think that would be a good idea, that would cost a lot of processor time.
I also know the pathfinder for trains seems to cache train route's for some time, so it is probably a good idea to get the pathfinder involved as well.

So, is there someone that can point me to how I can:
  • Request the planned route from the pathfinder
  • "walk" along that route to find another train (or do other stuff)
If somewhere in the code I can find an example and you can point me to there that should be fine!

All other needed code is already in the patch and I can tweak that myself. I just don't know how to do this bit.
User avatar
Vaulter
Traffic Manager
Traffic Manager
Posts: 185
Joined: 21 Dec 2004 05:35
Skype: andrey-zaharov
Location: St. Petersburg, Russia
Contact:

Re: [Patch] ATC speed control

Post by Vaulter »

did you turn ON ATC in advanced settings->vehicles->trains ? It's FALSE by default
DoppyNL
Engineer
Engineer
Posts: 23
Joined: 21 Aug 2009 14:27

Re: [Patch] ATC speed control

Post by DoppyNL »

Yes, I did.

I also played with the code to find what was wrong. See my previous post for that...
User avatar
Vaulter
Traffic Manager
Traffic Manager
Posts: 185
Joined: 21 Dec 2004 05:35
Skype: andrey-zaharov
Location: St. Petersburg, Russia
Contact:

Re: [Patch] ATC speed control

Post by Vaulter »

DoppyNL wrote:Yes, I did.

I also played with the code to find what was wrong. See my previous post for that...
It works fine with realistic train acceleration model
checked
User avatar
nex259
Engineer
Engineer
Posts: 11
Joined: 13 Mar 2009 13:52

Re: [Patch] ATC speed control

Post by nex259 »

I think that reservation check is fail if two diagonal tracks are adjacent(two diagonal tracks contain sharing tile).

example:

track (a) , (b) are diagonal tracks which adjacent to each other.
train (A) is travelling in track (a). train (B) is travelling in track (b).
When check the tile ,
(A) check:if (B) is travelling in tile sharing by (a) and (b) , (A) mis-recognize that (B) is travelling in (a) .
(B) check:if (A) is travelling in tile sharing by (a) and (b) , (B) mis-recognize that (A) is travelling in (b) .
---
Sorry my bad English...
nex259
---
Mulder
Engineer
Engineer
Posts: 5
Joined: 31 Aug 2013 07:55

Re: [Patch] ATC speed control

Post by Mulder »

So, wouldn't it be easier to implement something like this the same way that British rail signals work (some of them at least):

(This is all based on path signals, and in my mind it would work):

When a train approaches a signal, calculate the route to the next three signals (A (next), B (signal after that), C (signal at the front)).

If there is a train in between any of these signals, immediately set A to red (which will actually stop the train).

If C would be green (as if the train would be there based on the current rules), then set A & B to green.

If C would be green, B becomes amber and C becomes double amber.

A train at amber or double amber should slow down, but not stop until they hit a red. It should probably be a calculation of how much to slow down by (50% for double amber and 25% of full speed for amber).

You can look here: http://en.wikipedia.org/wiki/British_railway_signals (amber = yellow)
Seph
Engineer
Engineer
Posts: 16
Joined: 28 Mar 2012 14:17

Re: [Patch] ATC speed control

Post by Seph »

Is someone currently working on this?
User avatar
kamnet
Moderator
Moderator
Posts: 8585
Joined: 28 Sep 2009 17:15
Location: Eastern KY
Contact:

Re: [Patch] ATC speed control

Post by kamnet »

If you've read the topic, and checked the posting dates, you would know.
Seph
Engineer
Engineer
Posts: 16
Joined: 28 Mar 2012 14:17

Re: [Patch] ATC speed control

Post by Seph »

kamnet wrote:If you've read the topic, and checked the posting dates, you would know.
I did, and a recent poster seemed to be interested in picking up the torch.
gesia
Engineer
Engineer
Posts: 5
Joined: 07 Oct 2013 20:05

Re: [Patch] ATC speed control

Post by gesia »

In my tests it didn't work reliably, notably:
  • 1. on dual diagonal track it seems the two tracks are treated as one: the speed limit applies
    2. around intersections the second train accelerates towards the red signal
    3. occasionally, even on single-line track with evenly spaced block signals, the second train can't decide on a speed
... and there's probably other situations as well. However, I think this is still an improvement over the trunk implementation, because:
  • => 1. can be avoided by building diagonal track 1 tile apart
    => 2. would happen even more often in trunk (always, that is)
    => 3. still works well enough to prevent the second train from stopping/getting slower than the first train and takes care of itself after a few signal blocks
Long story short, I felt this patch was worthwhile to update for the (more or less) current trunk r26383.
Attachments
train_speed_control-r26383.patch
Note: feature is now enabled by default.
(6.52 KiB) Downloaded 175 times
Seph
Engineer
Engineer
Posts: 16
Joined: 28 Mar 2012 14:17

Re: [Patch] ATC speed control

Post by Seph »

Thank you so much gesia!! Now, who do I need to bribe to get someone getting this improved I wonder... I wish I knew anything about modding.
User avatar
kamnet
Moderator
Moderator
Posts: 8585
Joined: 28 Sep 2009 17:15
Location: Eastern KY
Contact:

Re: [Patch] ATC speed control

Post by kamnet »

Seph wrote:I wish I knew anything about modding.
Wish granted, but now you will only know about modding OpenTTD! Oh, wait, this isn't the Corrupt a Wish.

Actually, it would be great if you would take some interest in learning how to code. Fresh blood is always appreciated!
Patagonicus
Engineer
Engineer
Posts: 26
Joined: 24 Oct 2011 20:42

Re: [Patch] ATC speed control

Post by Patagonicus »

Is there a deadline on granting wishes ?

Here's another update for the newest trunk - mostly the change of settings page interface.
Attachments
train_speed_control-r27221.diff
(6.47 KiB) Downloaded 118 times
Patagonicus
Engineer
Engineer
Posts: 26
Joined: 24 Oct 2011 20:42

Re: [Patch] ATC speed control

Post by Patagonicus »

Encountered a segmentation fault due to 'other_train' being null in code.

Running a setup with 8 different patches applied, so cannot say for sure if one of the other patches caused the issue in the first place. In the attached update of the patch, I added a quick and dirty NULL check to fix the issue. Also bumped the svn revision number to 27377.

As always, I havn't really done any testing of it, just checked that I no longer get the segmentation, so use on your own risk ;)
Attachments
train_speed_control-r27377.diff
(6.36 KiB) Downloaded 122 times
Aphid
Traffic Manager
Traffic Manager
Posts: 168
Joined: 16 Dec 2011 17:08

Re: [Patch] ATC speed control

Post by Aphid »

Wouldn't it be far easier to choose a method where a train doesn't need to look ahead for another train?

Could this maybe work? -->

1) Expand speed limit to work in multiple directions (multiple numbers for each direction). So a tile has a 'global speed limit', as well as a number for each of the 'leaving directions'. For this new additional speed limit, only the location of the vehicle (train) head matters.
We're really only interested in those tiles where a train 'just passed' sufficient # of ticks ago.

Suppose we have a tile of track with speed limit V. A train passes at speed T. Let t=0 be the moment that the train leaves the tile.
Now set the max speed of this tile to 'T * h'. 'h' is the 'headway correction' speed factor.
Let 'w' be the 'ideal headway distance'. Generally w = 4 + S, where 'S' is min(2, <signal distance>). Optimally, a distance of '5' tiles is possible. To allow some leeway we thus need at least 6 tiles distance between trains -- as 5 tiles assumes the train in front never slows down (for e.g. hills).

Choose dv such that T * h * (1 + dv) ^ (w / T) = T dv is the 'relative rate of increase' of the maximum speed.
Solving this; dv = e^(T* ln(1/h) / w)
Continue increasing the max. speed of the tile and direction by multiplying by (1 + dv) each tick until it is once again 'V'.

Basically; with T = 100kmh, V = 200kmh, h = 0.75, S = 2 we get;
T ~ 1/20 tiles/tick.
w = 6
dv = ~ 0.24%/tick, or in other words increase the speed by 0.24% each tick.
The exponential here prevents a 'long tail' from forming (a long stretch of track/time where speed limit is reduced). Alternatively one could use a quadratic or cubic function which may be easier to deal with using integers. Similar logic happens.


Now if another train passes by before the speed has reached 'V', then lower the current max speed to its speed T(which is equal to or lower than the current max speed), and set the current dv to min(current dv, new dv).
KeldorKatarn
Transport Coordinator
Transport Coordinator
Posts: 274
Joined: 13 Apr 2010 21:31

Re: [Patch] ATC speed control

Post by KeldorKatarn »

That diagonal track issue is caused by a completely wrong implementation of the reservation check. A reservation along the north-south track reserves BOTH, the north and south direction. Simply picking the first one often results in the wrong direction and the entire checked path is wrong.

The pathfinder that follows a reservation has the correct implementation. Also the forward check needs to stop at depots because the path will otherwise reverse at the depot and scan again in opposite direction which can also cause issues.
And finall the "other train is going in other direction" check is also completely broken. Since sometimes you will compare Right-South to Left-South and such since we're not comparing the same track. Also... why the hell SHOULDN'T a train slow down if another train is heading right for it??

Here's an implementation that works. Of course the trains still accelerate towards junctions but that cannot be fixed without implementing some kind of pathfinder routine and I don't think that's in the scope of this.

Code: Select all

if (_settings_game.vehicle.train_speed_adaption) {
		int atc_speed = max_speed;

		CFollowTrackRail ft(this);
		Trackdir old_td = this->GetVehicleTrackdir();

		if (ft.Follow(this->tile, this->GetVehicleTrackdir())) {
			/* Basic idea: Follow the track for 20 tiles or 3 signals (i.e. at most two signal blocks) looking for other trains. */
			/* If we find one (that meets certain restrictions), we limit the max speed to the speed of that train. */
			int num_tiles = 0;
			int num_signals = 0;

			do {
				old_td = ft.m_old_td;

				/* If we are on a depot tile stop searching */
				if (IsDepotTile(ft.m_new_tile))
					break;

				/* Increment signal counter if we're on a signal */
				if (IsTileType(ft.m_new_tile, MP_RAILWAY) && ///< Tile has rails
					KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE && ///< Tile has exactly *one* track
					HasSignalOnTrack(ft.m_new_tile, TrackBitsToTrack(TrackdirBitsToTrackBits(ft.m_new_td_bits)))) { ///< Tile has signal
					num_signals++;
				}

				/* Check if tile has train/is reserved */
				if (KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE && ///< Tile has exactly *one* track
					HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(ft.m_new_td_bits))) { ///< Tile is reserved
					Train* other_train = GetTrainForReservation(ft.m_new_tile, TrackBitsToTrack(TrackdirBitsToTrackBits(ft.m_new_td_bits)));


					if (other_train != nullptr &&
						other_train != this && ///< Other train is not this train
						other_train->GetAccelerationStatus() != AS_BRAKE) { ///< Other train is not braking
						atc_speed = other_train->GetCurrentSpeed();
						break;
					}
				}

				/* Decide what in direction to continue: reservation, straight or "first/only" direction. */
				/* Abort if there's no reservation even though the tile contains multiple tracks. */
				TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));

				if (reserved != TRACKDIR_BIT_NONE) {
					// There is a reservation to follow.
					old_td = FindFirstTrackdir(reserved);
				}
				else if (KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
					// Tile has more than one track and we have no reservation. Bail out.
					break;
				}
				else {
					// There was no reservation but there is only one direction to follow, so follow it.
					old_td = FindFirstTrackdir(ft.m_new_td_bits);
				}

				num_tiles++;
			} while (num_tiles < 20 && num_signals < 3 && ft.Follow(ft.m_new_tile, old_td));
		}

		/* Check that the ATC speed is sufficiently large.
		   Avoids assertion error in UpdateSpeed(). */
		max_speed = max(25, min(max_speed, atc_speed));
	}
Patagonicus
Engineer
Engineer
Posts: 26
Joined: 24 Oct 2011 20:42

Re: [Patch] ATC speed control

Post by Patagonicus »

Just a small update to the previous version I posted:

- Added KeldorKatarn's suggestion
- Updated savegame versions
- Updated to r27728 (trivial)

Not tested yet...
Attachments
train_speed_control-r27728.diff
(7.52 KiB) Downloaded 131 times
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: No registered users and 23 guests