YAPF - Testers needed!
Moderator: OpenTTD Developers
DannyA: yes, i understand what you want to do, but it seem to me like you want the exactly opposite way of load balancing behavior: "look around and if you see any traffic jam, go there". Such "Traffic jammer" could be powerful weapon when used against competitors.
If you convince me, that it could be useful feature, I can for example add another polynomial (3 values, default = 0) for green signals. Or i can treat negative polynomial results as the positive penalties for green signals. Then you will be able to do what you want. But don't forget, that this will cause traffic jams to happen more often and last much longer (all trains will try to attend, not avoid traffic jams).
If you convince me, that it could be useful feature, I can for example add another polynomial (3 values, default = 0) for green signals. Or i can treat negative polynomial results as the positive penalties for green signals. Then you will be able to do what you want. But don't forget, that this will cause traffic jams to happen more often and last much longer (all trains will try to attend, not avoid traffic jams).
Spot on! In the wrong hands, it could indeed be quite nasty I think. :)
I was a little bit bored before, and went for a bit more graphical aproach - attached png. There's some notes there about jams etc.
I think which ever way is the simplest and has the lowest impact on performance would be best. Having a seccond polynomial would probably allow more control over exactly which signals behavied this way, and their importance, but it could become very complicated to predict how the two formulas would combine in all circumstances - to know what the penalty would be. As far as I can see, there is no difference between having a constant penalty for green signals as I suggested before, or treating negative penalties as the positive penalty for green. Increasing the constant green penalty would be the same as reducing the p0 of the red polynomial.
Some sort of programable signals, or perhaps call back script may be a better way to handle anything requiring a more complicated solution. Learning bit of lua might be on the cards for me too...
I tried to test this idea when it looked like it was working in 7130 (save), but I don't think it is a good way to test a merger - with the loops etc, but here's the results anyway:
I was a little bit bored before, and went for a bit more graphical aproach - attached png. There's some notes there about jams etc.
I think which ever way is the simplest and has the lowest impact on performance would be best. Having a seccond polynomial would probably allow more control over exactly which signals behavied this way, and their importance, but it could become very complicated to predict how the two formulas would combine in all circumstances - to know what the penalty would be. As far as I can see, there is no difference between having a constant penalty for green signals as I suggested before, or treating negative penalties as the positive penalty for green. Increasing the constant green penalty would be the same as reducing the p0 of the red polynomial.
Some sort of programable signals, or perhaps call back script may be a better way to handle anything requiring a more complicated solution. Learning bit of lua might be on the cards for me too...
I tried to test this idea when it looked like it was working in 7130 (save), but I don't think it is a good way to test a merger - with the loops etc, but here's the results anyway:
Code: Select all
Good Production Trains on track
Year Month Jammer Normal Jammer Normal
Avg Avg 4,095 3,885 55 / 70 52 / 70
2076 Jan 4200 3780 55 / 70 51 / 70
2076 Feb 3195 4290 55 / 70 50 / 70
2076 Mar 3525 2850 54 / 70 49 / 70
2076 Apr 5460 3360 54 / 70 50 / 70
2076 May 4200 4200 54 / 70 51 / 70
2076 Jun 3360 3780 56 / 70 52 / 70
2076 Jul 4035 4035 57 / 70 51 / 70
2076 Aug 4365 3525 58 / 70 51 / 70
2076 Sep 4200 4620 57 / 70 51 / 70
2076 Oct 4200 3360 57 / 70 52 / 70
2076 Nov 4875 4035 57 / 70 52 / 70
2076 Dec 4365 3945 56 / 70 52 / 70
2077 Jan 3360 3360 56 / 70 53 / 70
2077 Feb 4455 3780 55 / 70 54 / 70
2077 Mar 4785 3780 54 / 70 54 / 70
2077 Apr 3780 4620 53 / 70 55 / 70
2077 May 4200 4200 53 / 70 55 / 70
2077 Jun 3360 3780 53 / 70 54 / 70
2077 Jul 3360 3780 54 / 70 54 / 70
2077 Aug 4710 4200 55 / 70 54 / 70
2077 Sep 4110 4290 56 / 70 54 / 70
2077 Oct 4200 3690 55 / 70 53 / 70
2077 Nov 3780 4875 54 / 70 52 / 70
2077 Dec 4200 3105 55 / 70 52 / 70
- Attachments
-
- Write.YAPF.Settings.txt
- This script needs to be run in the save game to change from defaults YAPF settings to the 'Jammer/Assert' settings.
(exec write.yapf.settings.txt) - (2.07 KiB) Downloaded 303 times
-
- Look-Ahead Merger Test.sav
- The implementaion... (Don't mind my spelling)
- (215.59 KiB) Downloaded 324 times
-
- Look-Ahead Merger Idea.PNG
- The convincing...
- (373.66 KiB) Downloaded 297 times
DannyA: ok, you have convinced me that you probably know what you are doing, although i don't fully understand your merger (ie. the purpose of the loop with two way red sig.).
So I'll try to collect some pieces of time and will do it for you. Don't you want to help me with newsignals project? There I want to use LUA script for defining signal behavior. Then YAPF should only read some info from the signals and be able to decide properly. Something like "global train coordinator".
The first part should be tile edge signals. Then LUA and play with scripts until we have built the prototype.
So I'll try to collect some pieces of time and will do it for you. Don't you want to help me with newsignals project? There I want to use LUA script for defining signal behavior. Then YAPF should only read some info from the signals and be able to decide properly. Something like "global train coordinator".
The first part should be tile edge signals. Then LUA and play with scripts until we have built the prototype.
KUDr Thanks, that would be great.
The two way in a loop was just a little trick I used to allow the pathfinder to see a valid path (from a distance) which trains could never actually go down.
I'm starting to wonder a little bit about you, KUDr, and what this new signal project is really about. First you see the jammer as a weapon, then ask about me helping with something to do with LUA, who acording to the wiki "was a goddess to whom soldiers sacrificed captured weapons"! It all sounds a little bit sus to me...
Nah, just kidding. ;)
I'm sure I would enjoy helping with the new signals project very much actually - it sounds very interesting & exciting.
I've always been a bit facinated with AI programming, and wanted to learn more about it, but have never really got around to it. (no thanks to people making games like OpenTTD:) )
From reading the other wiki article on LUA, it sounds like it would be perfect for the job. Being able to customise signal behaviour with even the simplest logic could be used in place of huge bird's nests of track I think.
I suppose I had better get this bloody visual studio install fixed so I can at least compile the thing - something I've been procrastinating about for a while now.
If you could let me how I might be able to find out some more about new signals, or how I might be able to help, that would be great.
P.S - Although I don't always know what I'm doing, I always know exactly what I'm trying to do... ;)
The two way in a loop was just a little trick I used to allow the pathfinder to see a valid path (from a distance) which trains could never actually go down.
I'm starting to wonder a little bit about you, KUDr, and what this new signal project is really about. First you see the jammer as a weapon, then ask about me helping with something to do with LUA, who acording to the wiki "was a goddess to whom soldiers sacrificed captured weapons"! It all sounds a little bit sus to me...
Nah, just kidding. ;)
I'm sure I would enjoy helping with the new signals project very much actually - it sounds very interesting & exciting.
I've always been a bit facinated with AI programming, and wanted to learn more about it, but have never really got around to it. (no thanks to people making games like OpenTTD:) )
From reading the other wiki article on LUA, it sounds like it would be perfect for the job. Being able to customise signal behaviour with even the simplest logic could be used in place of huge bird's nests of track I think.
I suppose I had better get this bloody visual studio install fixed so I can at least compile the thing - something I've been procrastinating about for a while now.
If you could let me how I might be able to find out some more about new signals, or how I might be able to help, that would be great.
P.S - Although I don't always know what I'm doing, I always know exactly what I'm trying to do... ;)
That's the correct way it should work. I think that the bridge itself gives (or has to give) the penalty because of the max. speed the bridge has. The max. speed of a bridge can make fast trains to slow down on the bridge. Therefor I would prefer the choice to take the fast way and that's not the bridge.DannyA wrote:When I was looking at that in r7176, I noticed flat bridges over slopes still have the slope penalty applied.
I have read all your recent topics and the replies of KUDr. I think I know what you want but you make it to complex. What you need is a handy choice between two things:
1. The shortest route from A to B and
2. The fastest route form A to B.
The first one is a (heavy) calculation but can be made one time at the start of the train. The second one is more complex because the train has to deal with traffic on the route. It's almost impossible to calculate this at the start of the train. The only option is that the total railroad network is constantly being monitored (with very heavy load on computer memory) that the train on way can constantly make new discissions. But that is not how it works in normal railway live. In normal live it's not the train that makes discissions but a route planner (a human being with the help of a computer). The route planner makes for every train on the network the planning (where to go, what time, where to stop, which route, etc.). He has to deal with the question of cargo at stations, the railroadnetwork, the amount of trains and the type of trains. That's you're job to in game and in general not the job of the pathfinder. You can influence that by making a good network and a good signal system and using way-points to force you're trains to take a certain route. What you really need is a timetable for you're trains. By sending trains on a specific time on route you have what you want and then you're the merger (not the pathfinder). That would make the whole game more complex for the player but with a lot of extra fun.
Keep life simple...
Thanks for the comments Riti.
I like your idea of a route planner too.
The way those bridges are handled is not correct though, as the train chooses to go around the flat bridge, and over the raised one. I found that only bridges which have a speed limit lower than the max speed of the vehicle have a pathfinder penalty applied - (TrainMaxSpeed - BridgeMaxSpeed) / TrainMaxSpeed * 100 per tile.
Since I got visual studio working again I thought I'de have a crack at fixing the bridge slope bug myself. It's not immediatly obvious to me what a good way of working out if going through a tile in a cirtain direction with a bridge involves climbing a ramp or not. First impressions are that there are several ways of defining directions, slopes, etc some related with rail, some more landscape related etc, so will have to look a bit further.
I like your idea of a route planner too.
The way those bridges are handled is not correct though, as the train chooses to go around the flat bridge, and over the raised one. I found that only bridges which have a speed limit lower than the max speed of the vehicle have a pathfinder penalty applied - (TrainMaxSpeed - BridgeMaxSpeed) / TrainMaxSpeed * 100 per tile.
Since I got visual studio working again I thought I'de have a crack at fixing the bridge slope bug myself. It's not immediatly obvious to me what a good way of working out if going through a tile in a cirtain direction with a bridge involves climbing a ramp or not. First impressions are that there are several ways of defining directions, slopes, etc some related with rail, some more landscape related etc, so will have to look a bit further.
Thanks. Now how to move on? What kind of (what's in it) route planner and how do we get a route planner? Maybe first starting a new topic because this goes beyond Yapf (or KUDr doesn't mind we go on in this topic)?DannyA wrote:Thanks for the comments Riti. I like your idea of a route planner too.
Keep life simple...
RiTi:
Yeah, I reckon a new topic, maybe in suggestions if there is not already something similar would be the best way to follow that up. I need to get my head around how the existing stuff works a bit better before I can suggest new stuff or changes, so might look at fixing some other bugs - since KUDr beat me to this one...
Yeah, I reckon a new topic, maybe in suggestions if there is not already something similar would be the best way to follow that up. I need to get my head around how the existing stuff works a bit better before I can suggest new stuff or changes, so might look at fixing some other bugs - since KUDr beat me to this one...
orcaz: please, can you confirm that you are able to reproduce it in trunk (not MiniIN) before r7327 and try if it is fixed in r7327 or above?
I am not sure if it is related as I wasn't able to reproduce the problem.
r7327: -Fix: [YAPF] missing YAPF cache notification when building road on rail (new crossing) or removing road from crossing
Also please specify better what you did before it happened (if you removed the road piece from the level crossing or if you was about to do it and the problem occured just before).
thanks
I am not sure if it is related as I wasn't able to reproduce the problem.
r7327: -Fix: [YAPF] missing YAPF cache notification when building road on rail (new crossing) or removing road from crossing
Also please specify better what you did before it happened (if you removed the road piece from the level crossing or if you was about to do it and the problem occured just before).
thanks
Im sorry, I cannot reproduced the bug. Im tried to do the same thing. But nothing happened (even in MiniIN). It seem too random.
And I was about to remove the road on crossing. i click on road construction menu>click on road>click on remove road>go to location>click and the same time the eror appear. (all in pause).
And I also have remove many road from crossing using the same method but the error dont appear. And, the bug cannot be reproduced. Im also confused. But, can anyone tell me what those error means?
And I was about to remove the road on crossing. i click on road construction menu>click on road>click on remove road>go to location>click and the same time the eror appear. (all in pause).
And I also have remove many road from crossing using the same method but the error dont appear. And, the bug cannot be reproduced. Im also confused. But, can anyone tell me what those error means?
I'm trying to extend yapf to detect and penalise paths heading towards nearby intersections when there is another train heading towards the same intersection (roughly the same distance away).
Plan is to have some patch settings like these:
Max_Forsight_Distance - how far in front to look for trains - maybe 10 tiles
Min_Front_Gap - allow for this much space in front of the train
Min_Rear_Gap - allow for this much space behind the train
Intersection_Busy_Penalty - the penalty applied
Hopefully, by having an overflow loop short distance before merging tracks no priority signaling (presignals) will be required as the penalty for heading into the path of oncomming traffic will cause trains to use the loop untill the track is clear.
Like the existing setup, this will only take place when a train arrives at a branch in the tracks, and (fingers crossed) there will only be a minimal impact on performance (no1 priority).
I also needed somewhere to upload the diff...
Any help, feedback or ideas would be much appreciated, right after I get back from the movies... :)
Edit: Ran the pile transport #openttdcoop game with 1000+ trains (cpu~50%), with a counter to see how often YapfChooseRailTrack() and VehicleFromPos() were run each frame (30ms) - see att.
YapfChooseRailTrack ~ 5 calls / frame
VehicleFromPos ~ 2700 calls / frame
Looks like a few calls to VehicleFromPos from within YapfChooseRailTrack which is what I need to do will not make a big difference. Will see...
Edit - upload new diff for trunk 7484
Edit - some notes incase anyone's interested, or would like to finnish it off while I catch some Zs...
Intersection Busy Scratch:
Ideally, a complete list all vehicles, and corresponding paths through the intersection would result from running the search function. This list could then be itterated, and penaties &| bonuses applied.
Code is in place to detect an intersection, and also build a word where all bits representing directions which need to be checked are set. (None of which is tested.)
Now I need a function which takes a tile and a direction an input, then follows all possible paths in that direction recursively, checking for vehicles. Any vehicles which it finds it should add to a Vehicles_On_Approach list with the path (node chain) back to the intersection.
Problem: The search function walks in the opposite directon to the path which the approaching vehicle could take - so perhaps a ReverseTrackDir needs to be run on all nodes before the path is added.
See signal code for bridge & tunnel search handling.
VehicleFromPos: This function is a little complicated, but may be for the better in this case.
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
tile: the tile on which we are looking for vehicles
*data: anything. this is see next arg.
*proc: a callback function which is called for each vehicle on 'tile', and passed the *data argument supplied when VehicleFromPos was called.
(Is that a pointer to a void? Oh well, it fits in nicely with my understanding of most of the YAPF & openttd C code:)
Basically, you have a function which is run for each vehicle which is at the position you're searching.
If this function returns non-NULL, VehicleFromPos quits searching & returns that result, otherwise if there are other possible matches the callback is called for them.
I could use this to my advantage by having the callback function run a yapf path search as if the oncomming vehicle was at a branch. Since there is no choice, things like look-ahead could be disabled to allow full use of the cache. While yapf is walking back down the best path, if it goes through the intersection, this would trigger some code to add the vehicle and path (to intersection) to the OncommingVehicles list. This list should be checked at the start of the VehicleFromPos callback to ensure any vehcles found twice are skipped the 2nd time.
Plan is to have some patch settings like these:
Max_Forsight_Distance - how far in front to look for trains - maybe 10 tiles
Min_Front_Gap - allow for this much space in front of the train
Min_Rear_Gap - allow for this much space behind the train
Intersection_Busy_Penalty - the penalty applied
Hopefully, by having an overflow loop short distance before merging tracks no priority signaling (presignals) will be required as the penalty for heading into the path of oncomming traffic will cause trains to use the loop untill the track is clear.
Like the existing setup, this will only take place when a train arrives at a branch in the tracks, and (fingers crossed) there will only be a minimal impact on performance (no1 priority).
I also needed somewhere to upload the diff...
Any help, feedback or ideas would be much appreciated, right after I get back from the movies... :)
Edit: Ran the pile transport #openttdcoop game with 1000+ trains (cpu~50%), with a counter to see how often YapfChooseRailTrack() and VehicleFromPos() were run each frame (30ms) - see att.
YapfChooseRailTrack ~ 5 calls / frame
VehicleFromPos ~ 2700 calls / frame
Looks like a few calls to VehicleFromPos from within YapfChooseRailTrack which is what I need to do will not make a big difference. Will see...
Edit - upload new diff for trunk 7484
Edit - some notes incase anyone's interested, or would like to finnish it off while I catch some Zs...
Intersection Busy Scratch:
Ideally, a complete list all vehicles, and corresponding paths through the intersection would result from running the search function. This list could then be itterated, and penaties &| bonuses applied.
Code is in place to detect an intersection, and also build a word where all bits representing directions which need to be checked are set. (None of which is tested.)
Now I need a function which takes a tile and a direction an input, then follows all possible paths in that direction recursively, checking for vehicles. Any vehicles which it finds it should add to a Vehicles_On_Approach list with the path (node chain) back to the intersection.
Problem: The search function walks in the opposite directon to the path which the approaching vehicle could take - so perhaps a ReverseTrackDir needs to be run on all nodes before the path is added.
See signal code for bridge & tunnel search handling.
VehicleFromPos: This function is a little complicated, but may be for the better in this case.
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
tile: the tile on which we are looking for vehicles
*data: anything. this is see next arg.
*proc: a callback function which is called for each vehicle on 'tile', and passed the *data argument supplied when VehicleFromPos was called.
(Is that a pointer to a void? Oh well, it fits in nicely with my understanding of most of the YAPF & openttd C code:)
Basically, you have a function which is run for each vehicle which is at the position you're searching.
If this function returns non-NULL, VehicleFromPos quits searching & returns that result, otherwise if there are other possible matches the callback is called for them.
I could use this to my advantage by having the callback function run a yapf path search as if the oncomming vehicle was at a branch. Since there is no choice, things like look-ahead could be disabled to allow full use of the cache. While yapf is walking back down the best path, if it goes through the intersection, this would trigger some code to add the vehicle and path (to intersection) to the OncommingVehicles list. This list should be checked at the start of the VehicleFromPos callback to ensure any vehcles found twice are skipped the 2nd time.
- Attachments
-
- Intersection Busy Penalty.diff
- r7484
- (16.71 KiB) Downloaded 271 times
-
- Intersection Busy Penalty.diff
- YapfChooseRailTrack() and VehicleFromPos() calls / frame
- (16.71 KiB) Downloaded 330 times
Who is online
Users browsing this forum: Bing [Bot] and 4 guests