The online racing simulator
Artificial Intelligence in Racing Simulations Project
(570 posts, started )
People are always reading
Yep. We are always reading. Keep up the good work. Thumbs up
I'm also following this thread with attention, as you already know. Smile
I just modified his XRG setup a little bit, I had modified it last night for the Braking limit detection (had to increase the braking force per wheel and shift the braking balance toward the rear (drive wheels). When I came back I noticed the best lap of 240 laps was 1.00.40 (or maybe even 1:01.40 ... which led me to thinking what would happen if I reduced his braking forces ...

Well, he set a new personal best of 59.07 on this set with about 100Nm less braking force than the original set. This makes sense when you add the fact that he was fastest in the FZ5 because it didn't brake as well. Of course this will all change when I get the new driver logic in, I hope to have him complete his braking in the braking zone, and accelerate after the apex, leaving the corner entry for minimal braking/acceleration changes.

I'm really looking forward to that new logic, just want all the pieces ready and to put in some valuable thought before starting it. Hopefully the laptimes will improve further, but it could get worse. My plan is to have him start with ultra safe braking distances and entry speeds, and have him slowly work on entering the corner faster and decreasing the braking distance.
I have spent a fair bit of the day trying to find a way to get a number from 0 to N that detects the understeer limit of the car but so far I have been unsuccessful at this task. Too many factors change too many things when it comes to understeering. For instance I had the thought to use the angle between the facingDirection and motionDirection, much like I would be computing oversteer. But compare this angle to what I would expect it to be with certain steering inputs to detect the understeer limit.

I was unable to get results I liked, even with a lot of tweaking, which would again only be useful for the XRG. I believe this is because speed also plays another factor in the understeer limit, more than just steering input and that angle between facing and motion direction. I then had the thought to try longitudinal force, but that force can be quite high, and actually will be just under the real turning limit, when understeering.

I'm taking the server down for a bit and going to do some races to see if some inspiration takes over. Otherwise I may just ignore the understeer limit detection for now, it might not be very important anyway.
Have you taken the dimensions of the chassis into consideration? When going through tight corners the result of angular velocity could be significant compared to linear, and front/middle/rear points on the chassis would be going at somewhat different directions, which skews your motionDirection. Width plays a much smaller role than length but might be relevant in some cases.

It's my personal belief that z-axis angular acceleration is the most important source for short-time judgment when humans drive, in sim or RL. I don't have a good source to prove this though.

@keling The motionDirection I use is what the actual movement of the cars CG so it would remain 0,0,0 if the car was just rotating in place, and would only be the direction of the linear velocity otherwise. I do get what you are saying, a point on the front bumper of the car will be moving differently than a point on the rear bumper when the car is rotating, if the rotation is fast enough compared to linear motion they would even move in opposite directions.

The Z-Axis in LFS is the Up, so that would be the yaw rotation you are talking about. I don't have any real proof to this either but I would certainly agree this rotation is the real "seat of the pants" feeling one has for detecting the behavior of the car. I am sure the longitudinal and lateral forces also play a fair amount for seat of pants feeling, but probably none is as important at that yaw acceleration.

---

Yesterday and last night progress was a bit slower than it has been. I struggled most of the day with the understeer detector before finally giving up on that. It took a while to get back into the swing of things, I went racing online for a whole 2 races of... wow. It isn't what it used to be.

After finally getting back into the code I decided to modify the shift point code. I made the code much more readable/maintainable than it was before and adjusted both the downshift and upshift points, at least for the XRG. However I still need to come up with a new algorithm for this, as the power range is too different for each car. XRG now shifts at 3700 to 6500 rpm. The UF1 still doesn't downshift because the way this calculation is done. I noticed on the FZ5 (I think) that the upshift point is well above redline, although there is some redline protection in the shifting logic to shift anyway.

For now the shifting logic remains what I wrote before, which essentially computes the range from maximumTorqueSpeed to maximumEngineSpeed and takes a little extra on both sides. (Consider maximumTorqueSpeed to be 0, and maximumEngineSpeed to be 1, the shifting points are -0.5 and 1.35). The obvious flaw here is some cars have a really wide range for this, and -0.5 in the UF1 places the downshift point at like 1500 rpm, same with the upshift point for the FZ5... Some cars, like the XRG, have a smaller range. In any situation the logic needs work in the future, suffice to say I modified the shifting points.

Making that change got me wondering if I could be smarter about the braking logic. The current turning/throttle/braking logic works on several values, these values represent the angle of the racing track at different locations: nearAngle, soonAngle, farAngle and farFarAngle. The farAngle and farFarAngle were introduced to get the driver to brake for T1 after speeding down the straight. nearAngle is the angle of the racing-line where the driver is aimed at driving at the given moment, and soonAngle is some distance in front of that.

I simply adjusted the speeds set for nearAngle and soonAngle, since he goes a little too slowly in the corners, and left the farAngle and farFarAngle speeds the same. This actually dramatically decreased his lap times for the better. With the new corner logic, I also decided to make him not hit the brakes after corner exit, which he would do on some occasions. This made him faster still, although that depends on the car because in some of the higher powered RWD cars he actually invokes too much wheel spin.

After these changes I saw him do a 58.21. It got me really excited, but he still doesn't modify his braking point or entry speed which would really help him speed up, I think. Theoretically it should after several laps anyway. I am still reserved about having the driver 'learn' the track and change his own behavior, but doing it with the reference points and modifying braking point / entry speed seems like a reasonable thought to me because that is how we humans drive quickly.

So I got all pumped up and declared I'm just going to put the new driver logic together with ducktape (hack it up and see if it works) real quickly... And I did start to, but then fell into the trap that I was going to create a giant mess and it would be worse later on, so I moved all the corner logic into a corner manager and made it so the reference points for these corner phases can be moved. I even tested this by moving the braking point back on T1 and the apex back on T1 and T4 of FE1, and they moved as expected. Although the only points the AI currently use/care about is the apex, all others are ignored until driving logic 2.0.
Maybe I'll come back on a little later tonight but I think I'm done with my updates for today. I got the basic skeleton of the new Driver Logic going, and even have the driver modifying his brake points - although it is currently unsafe as he can (and does) modify the brake point to a point that he can no longer brake for the corner. He will eventually also modify corner entry speed as well, but for the proof of concept things are looking pretty good!

After running 10 to 15 laps with the new driving logic, modifying only brake points (by large values), he can bring his lap times from the 1:17s to 1:07s. I can't wait until this gets some more development, threshold braking and accelerating and - with any luck driving the corner closer to the limit.

I somewhat feel I've rushed into the new logic though, and that more planning should have taken place because I'm literally just winging it right now, with a "lets see what happens" attitude.

I'm going to leave him running with the old driver logic for the time being so he can do more consistent laps without failing.
I've been thinking about the project some more, go figure, and I'm not entirely sure how to proceed. Should I focus one 1 car? If I am going to focus on a single car I'm going to aim for the LX6, even though this entire time has been spent with the XRG. I am contemplating this because there is a fair bit of these little values that pop up fairly often that need to be tweaked for a particular car: shift points, limit detectors, desired steering points, etc. Even the speed at which throttle can be cranked up or off in certain situations.

An initial part of this project was to get the artificial driver to not require this tuning and fiddling, but I don't think that is possible. Every car has different powerbands, shifting points, and even steering changes. To go around a corner with a 100ft radius in the XRG might only take 15 degrees of steering wheel input, while the same 100ft radius turn in the FOX would take 25 degrees. To make matters worse, it is also greatly influenced by the setup.

So do I abandoned the approach, or start making a table of variables that need tuning for each car? When possible I hope to have the artificial driver figure out the value himself, and the entire project I have attempted to do this: shift points are determined by looking at torqueRPM and powerRPM as I've described several times.

---

Since I started driving logic 2.0 this weekend I've also been thinking a lot on how I want to implement this logic. I've already seen the driver modify his braking points and that is pretty damn amazing. I give him over cautious braking distances and corner entry speeds, so he will start very safe and slow. Then he approaches the turn and modifies the braking point because he reaches the entry speed and still has 100 meters of braking distance before the entry. Works perfectly!

Except when it doesn't. See if he keeps modifying his braking point just like that then after 15-16 laps or so he eventually modifies it too far, and this is not a good thing because then he typically falls off the corner. So my immediate thought was to keep several points of reference for the corners. At a minimum there would be the default, safe, and risky braking points, entry speeds and all other corner information about each corner. The idea being that default never changes, it is what originally got computed. Safe is the last known very safe distance/speed/information, and risky is the one that just changed.

The risky information becomes safe after some number of laps of safely making it through the corner without issue or really breaking the limits too far. That will be tricky to code. The unfortunate thing about this is it will slow down his learning by a significant amount. Luckily what I saw with the first tests modifying the braking distance it only took about 10 to 15 laps before he went from 1:17s to 1:06s with a fairly incomplete set of driving logic.

I need to find a balance. Just modifying the value each lap is unsafe but counting safe laps before modifying the value will slow his "learning" of the track. I don't like to think of this as him learning, because he isn't really learning anything, just modifying his information about the track.

---

The other thing I've been thinking about, related to focusing on a single car or not, is whether I should modify how the driver deals with corners. A few days ago I modified his steering behavior by changing one value, instantaneous drop of 1.25 seconds per lap in most cars, finally allowing him to get closer to the racing line he created. The idea is to follow some idea of "turn points", that would belong in the corner information. Each corner would have some number of these points, about 5 or 10, which would describe the location of the racing line. Instead of finding a point on the racing line 10 meters, 50 meters or 100 meters ahead of the car, the driver would look at those 5 or 10 turn points to know where the line is in that particular corner.

This would actually be a significant change, even though the desired behavior would be very similar. This change should keep him on the racing line, at least for the most part, but would do it in a different way.

If you think of turn one at FE1, and split it into 10 sections from the entry of the turn to the exit of the turn, each section crossing perpendicular to the racing line (maybe centerline) then each of these sections would be a "turn point". Each section would contain information like:

PositionOfRacingLine This is where the driver ultimately wants the car
LeftTrackEdge The furthest to the left of the track, no more space.
RightTrackEdge Ditto for the right edge.
AimingPoint A position that the driver uses to modify the steering behavior, this is the location he attempts to steer towards

With that information I could then later add more:

PositionOfDefensiveLine
PositionOfPassingLine
... etc ...

The primary idea here would be to have the driver modify the AimingPoint of each of these corner sections / points which should make it so I don't need to modify that steering value for each car, because in theory the driver would move the AimingPoint left/right depending on how close he was to the racing line when he crossed that section, making him turn more or less next lap(s) if he was far away.

This wouldn't be very hard to write, but it would take a fair bit of time to deal with. Along the lines of this idea would be to make the driver change his logic along a straight portion of track so that he goes straight for the entry point of the next corner. Unfortunately, some of the straights are not so straight, so that doesn't quite work and adds a bit more complexity that I really didn't want! I'm not entirely sure I will add this turn section/points logic to Driving Logic 2.0 or not, but I'm sharing my thoughts as I have them, as I always have.
mpr replay
Here is the mpr file of yesterday's race you requested
Attached files
weird AI challenge.mpr - 297.8 KB - 325 views
Interesting, I do see the issue but I don't know what caused it. Probably just over corrected a value momentarily with the steering logic.

For those wondering, the issue is found on the last turn of the last lap the artificial driver turns steering wheel full left for just a moment.
I've taken time now and again attempting to get the driver to successfully drive at other tracks without too much luck, until now! I've finally got him driving another track without issue.

BL1 - he falls off at the end of the straight, doesn't brake in time.
WE1 - he falls off at the chicane, not braking in time and understeering.
AS2 - is a mess with understeer and sometimes touching grass into oversteer.
SO1 - Mostly works but he understeers into walls for some help, damaging the car.
SO2 - Now works pretty well. He kisses one wall trying to take a corner too sharp.

There are still several tracks that I can't test, so I might work on the track processors some more. Actually as of 15 minutes ago SO2 didn't even work. The track processors would fail because the point it started iterating through the track was not considered a straight and the algorithm didn't look for a straight, it just failed. I made it look for a straight and continue again and now SO2 is working.

michal 1279 sparked this interest in new tracks again when he had mentioned that FE3 is pretty similar to FE1, sharing about half the track. I let the track processors use the PTH file and it did work but currently there is an issue with bridges, even if the track doesn't go over the bridge. The racing line height needs to be set to the height of the track and to do this I have a function to compute the heights at each point. It takes a vertical line that is pretty high and pretty low and tests each triangle for collision until it finds one. The algorithm does not continue looking after the first collision. So if a bridge is involved sometimes it will grab high, and sometimes it will grab low.

This was noticed awhile back at AS2, the artificial driver would try steering incorrectly as he passed under the bridge before turn 1. I've had plans to fix it but haven't really paid much attention to it, I think I'll give an attempt at fixing this issue shortly, because with it fixed the driver could theoretically drive FE3 without an issue. I used keyboard input to get him across the bridge and he seemed to do the rest of the track pretty good. The question would be if he brakes properly after the bridge, because that builds up quite a bit of speed and it could be a potential area for him to fall off the track.

In letting him run at FE3 I noticed the corner detectors could use a little work too. I'm not sure how or what I want to do with them, but it seemed obvious to me that the right/left/left/right should not be considered a single corner. It also makes sense on FE1 that the back "straight" becomes some form of corner, even if it doesn't need much braking it may need to be considered a corner in some manner.

Regarding the corner processing there are still a handful of other known issues, such as for KY1 the turns are so subtle that the processor considers them "straights" which causes it not to work and doesn't allow the driver to run on the track - he needs to know about the corners to drive there, certainly will need to once DLv2 gets implemented.

Another issue with the corner processing is finding the apex location, sometimes it doesn't do so well at placing the apex where it makes sense, sometimes it fails to place it at all which is even worse but a known edge case I've left strangling for now. The current logic for finding the apex is to start at the corner exit and work backwards toward the corner entry until the distance to the inside of the corner starts increasing. If the corner entry is found before the increase starts no apex was found.

Now that I've fixed the start straight issue and I see him driving at SO2 I wonder what other SO tracks he might be able to do. I know he doesn't do so well going through the chicane like in SO1, (I haven't tried SO1R), and I wonder if he would like turning up the hill after coming down like in SO5? I'll let him run some more laps, so far SO2 seems to be his best track, best being the closest to the WR time.

---

In one of those why "why does that need to be ..." moments I figured an easier way to fix the steering logic. Why does the steering logic need to care about the height of the racing line, or car? No amount of steering control will fix a difference in height. So I simply set the Y values to zero before doing the steering logic computations and voila the problem has been solved without the need to normalize the heights for bridges and such! For some reason I thought I had done this already but it appears I had not. It would still be nice to normalize the points just so that the AIRS debug visuals make sense, but now the driver doesn't need this for driving. For some reason I'm yet to figure out the racing line at SO3 doesn't really like to work at the top of the hill, it seems to be far under the track, and this is what prompted my thought. So now it works, and in theory should also work at FE3... Just a note, a third drivable track for the airs_artificial_driver in the XRG has become SO3. A few taps through the chicane for turning too tightly, but not enough for damage.
I didn't get a chance to work on the project today or yesterday, but I haven't really written my updates for the progress of the night before. Which really wasn't that much progress, but I flattened out the angle detection for both steering input and throttle/brake logic.

Doing this for the steering logic allowed him to run at SO3, for some reason the height detector doesn't work as well as expected here. I will need to look into this issue to understand it better, but I fixed the AI logic by ignoring the Y axis (up in airs world) when detecting the angle he is trying to steer towards. This immediately helped him go around the track better, but his throttle/braking inputs were still using some angles that included the Y axis, so I modified those as well.

Someone noticed that I was happy when he broke into the 1:08's at SO2, but after making the throttle/braking changes he got down to min 1:07's! Which makes SO2 his best combination when compared to the WR times. This change didn't effect FE1 quite as much as I initially thought it would. I figured with the light elevation changes ignoring the height in the angle computation would have helped a little more, but the driver is still in the very low 58's, although he can also reach the very low 57's now and again. Almost like he gets lucky every now and again.

I've also noticed the steering issue michal 1279 pointed out happening a bit more often and leaving small rubber marks on the straight. I have an idea to check out, might be an issue if the angle between desiredDirection and forwardDirection is actually 0. I believe this might be the case because ignoring the Y value in the angle computation would increase the odds of this happening. I'll check that a bit later tonight, and hopefully he will stop scrubbing off his speed.

In the handful of laps I've had him do at SO2 it is obvious the fuel load plays more of a role in his lap times at this combo than it ever has at FE1, also after I changed the angle computation for throttle/braking, he started using more fuel.
Here is a quick replay of the airs_artificial_driver doing 5 laps at FE1 in the XRG with full fuel (still using Driving Logic v1)

EDIT: Added airs_artificial_driver doing 3 laps at FE1 with XRG with 2% fuel.
Attached files
airs_driving_fe1_20150306.mpr - 68.2 KB - 277 views
airs_driving_fe1_20150306_3lap.spr - 135.1 KB - 268 views
Well, I have implemented the basics of Driving Logic v2 and I am both pretty impressed with what happens and at the same time quite saddened. I've got the driver modifying the braking and entry points, I can go into detail about this if anyone cares to note, it is similar to what I laid out for a plan, although slightly different.

The first lap the driver is extremely cautious with a time of 1:40ish on the first lap and 1:27ish on the second lap. Each corner entry speed is set to a grandma speed of 30 mph, and braking distances are much longer than needed. The driver checks his limit values (need to get understeer working) and will modify the speed as he see's fit. After 5 laps though the speeds and braking points have been modified and he is already in the 1:09s and steadily improving by a second or more a lap, which is pretty neat to watch.

However he isn't modifying his entry speed as safely as I'd like. I've tried a few times to make it be safe and yet he keeps failing at the tight right hand turn before the final chicane/turn complex. I've just modified something else that will hopefully help (he waits until Corner Exit to modify entry speed now, whereas before he was modifying it during apex) but my hopes for this helping is actually pretty slim. I believe he will still find a point that he fails at, it may take longer, or may be a different point - although I suspect it will remain that same failure point (the right hander before the final chicane-turn complex).

It was quite interesting to see him figure out how to drive down to a 59.5x all based on modifying his speed/braking points. But I've lost a little hope in this algorithm because it will be very tricky to make it happen safely.

I've also lost a little hope because when I think about dodging traffic I'll need to modify a line, and although he follows the racing line fairly well, with the driving logic v2 it is more difficult to just modify the line I want him to drive and DLv1 was actually pretty good about following the line with no other information, so I could easily just modify the line and he would (theoretically) follow it just as well. However DLv1 is pretty well coded for the XRG which was something I tried to avoid but found pretty difficult. You want the driver to go fast, and that typically means adjusting values until he does it fast - but then those values don't work for other cars or setups.

Another let down of DLv2 was has been the realization that even once he gets one corner nice and fast, he will push it over the limit and adjust back to a slightly slower speed. I theorize that this will mean (if he was actually doing all corners safely all the time) that he would have very rare best laps and not drive nearly as consistent as the logic in DLv1. I could be wrong with that, but I believe it is what would happen.

I haven't yet tried him with a new car in DLv2 but I suspect that is where that logic will shine - particularly with the cars with slick tires since he feels the limits much better (minus understeering). I'll give that a go as soon as I finish running his current test. 14 laps in and he just did a 1:01.19.

Sad to say but that odd turning glitch seems to have gotten worse. Maybe I just need to restart LFS at this point to fix it, I searched for potential issues and was unable to find something that looked to be a cause.

EDIT: The last changes (including entry phase and apex phase) helped stabilize him in the mid 58 to mid 59s, with a more inconsistent laptime as I was expecting, but at least he could continue driving. I stopped him at 30 laps so I could test a different car. Results for the a different car will be coming soon.

As expected the DLv2 really REALLY shines when it comes to driving the other cars and learning their braking points, this does actually give me some more encouragement but I certainly need to rethink how to go about things, the new driving logic has taken at least 10 seconds off the artificial_drivers personal best time in the FOX, something that would not have been capable with DLv1 without retuning the entire logic. So this gives me some hope, but DLv2 has a long ways to go still.
I am losing a bit of steam on the project, Driving Logic v2 was not quite as successful as I had hoped and I'm not entirely sure it is worth spending a lot of time tuning. It shows great promise in some ways, as I was expecting, but when it comes to choosing defensive lines, or passing other cars the corner logic won't actually be as useful - although it is closer to what a human would use for reference points, so I am a little torn at the moment and that is causing my to lose momentum on the project.

I've been considering a hybrid of the original logic "follow this line" and the new logic (which still follows the same line except modifies the braking point and entry speed). If I went with this idea, I would use most of the initial code from Driving Logic v1 except that I would make a table of for the angles of the racing track and the safe, risky and very risky speeds at those angles as well as keep track of a safe, risky and very risky braking distance for various speeds. The trick would be getting the driver to build those tables in a manner that is actually safe.

DLv2 was meant to modify the braking point and entry speed only when very safe to do so, but it turned out much more challenging to program that logic than expected. Tuning it more would allow DLv2 to shine more brightly, but that will make it difficult to add passing lines and defensive lines at a later date, unless I restrict passing to the "straights" which I really would like to avoid, that is how the LFS AI currently work.

Just losing some energy, might be time to take another break and work on some other projects for now. Only time will tell though, what I can say is this project is not dead.

As for progress, today I spent a lot of time tracking down the reason for those strange steering issues and finally got to the bottom of it after at least 5 hours of digging. Immediately upon fixing the old, and extremely mysterious issue of driving 10 meters to the left of the line returned. I still don't understand how, but I reverted the code and then readded the changes and the issue was gone. This is extremely confusing to me, had he crossed the line constantly it would make more sense, but to follow the racing line exactly 10m on the outside of the track at all times is something that would need to be coded for, and the debug visuals all indicate he has the correct information... The issue has disappeared again, but it is pretty odd.
Good luck for the future.
Quote from just2fast :...Or in other words.... wait until a google bot will break all lfs world records!!Frown

Wasn't that thing called MARUS?!?!?!
I apologize for not wanting to read the entire thread so I can find out how do I actually put this new AI to an use. Halp please?
Quote from bogdani.cojocaru :I apologize for not wanting to read the entire thread so I can find out how do I actually put this new AI to an use. Halp please?

You can't. It's currently a WIP project by Blackbird.
Quote from bogdani.cojocaru :I apologize for not wanting to read the entire thread so I can find out how do I actually put this new AI to an use. Halp please?

You can't use BlackBird's AI logic. But sometimes he leaves it to run itself in circles on his server. You can join and watch Smile
Yea, I haven't been running the server, project is currently in a holding pattern, but it will be back when I get some ideas, inspiration and motivation to work on it again. Just watch the thread and the server will be back someday. I am tempted to see what happens with the new Westhill configs, if the PTH and SMX files have been released yet.
Another bump after long break. I have finally upgraded from my Core 2 Duo, and one of the things on this that had started holding this project back a bit was my old PC chugging while running LFS and AIRS together. I'm pretty confident this new PC would have no troubles at all. I have not installed the virtual controller yet, but I kinda would like to see if the driver is more consistent.

Still a bit low on steam as far as making more improvements though, that Driving Logic v2 with the modified brake points showed a lot of promise but it doesn't quite work properly, which has taken a lot of my energy away.
Today I've booted up LFS again in quite some time. I still have not yet installed or configured the virtual controller, or got the AIRS driver running, but I did start a multi-class crash fest at FE1 to watch the LFS AI run each other over.

This is such an interesting problem space. How to teach the AI driver when to be aggressive and make a move, vs when to hold back. I still need to get him running his line properly, and I am hoping the new quad-core PC will have more horsepower to be more consistent. In order to move forward I will first need to move backwards to understand and fix the issues I created with Driver Logic v2, and possibly do some code cleanup and optimizations.

Artificial Intelligence in Racing Simulations Project
(570 posts, started )
FGED GREDG RDFGDR GSFDG