The online racing simulator
More Progress!

I've worked quite hard on the project tonight, a lot of really good improvements, but none directly effect the driver behaviors or laptimes, yet. Instead I focused on a way to really see what is going on with the processing of the track data. There hasn't been much issue getting the track edges, especially once I figured out to use the PTH files (thanks to whoever mentioned that). But there had always been an issue with many tracks, actually all other tracks tested besides FE1, that prevented apex from being positioned properly on many turns.

It turns out, after adding some visual processing/debugging help that the issue was only with left hand turns. FE1 "worked" because the Corner Detection only processed apex points for right hand corners. (Apex is found by following racing line from turn exit backwards to nearest track edge). The FE1 chicane starts as a left turn, but ends in a right turn. The bug was me erroneously sending the centerLine to the corner detector when the leftTrackEdge should have been sent.

A quick load of BL1 and three corners look so much better, I can't wait to run Jared on the track. I'm confident some times will be beaten. I will have to toss away any BL1 saved/processed data and that will be a manual process, woot.

Another thing that plagued other tracks was an error getting height at a certain point in the terrain (SMX) data for the track. This is needed to make the lines visible and it seems in some cases keep the driver sane. SO3 had an interesting issue where the driver would slam on brakes and turn for no reason going down the straight. Using the dot product on two vectors that change a large amount in height effects may or may not be a reason. After a fairly good debugging session, and some help from people on my live development stream, it was tracked down to a few issues with the Terrain Quad Tree that was written to speed up line of sight checks.

Finally got to see the quad tree visualized, and woah, it is pretty neat. But it was off centered. After a bit of a hunt I figured out that some code I did to make it a "square" tossed it off center. I tossed the code. Why does it need to be a square? It doesn't! That fixed the issues noticed at SO3, but there were still a few odd balls, that I knew would creep up, triangles would only be inserted into one of the quads if, and only if, one of their vertices landed within the quad area. This lead to an interesting issue where if three points extended beyond, but through, the box, the triangle wouldn't be included.

With a little help from google, I modified the collision test:

If ANY of the triangle vertices (points) are contained within the box, collision.
If ANY of the box vertices (points) are contained within the triangle, collision.
If ANY triangle edge crosses a box edge, collision.

This solves all cases and just needed a PointInTriangle(), PointInBox() and LineToLine() tests, two of which I had already. All problems gone.*

*Actually I have seen exactly 1 failed test location at SO3 while the RacingLine is being computed visually, but it must be a super edge case, and unless I see another case popup, I'm considering this case closed.

I continued on, you thought I was done, and added a way to tweak the parameters of the Corner Detector. The corner detector isn't bad. I haven't really tuned it quite as well as desired. This new track processing visualization/debug state, whatever you want to call it!, has opened new doors. I can push a button an see the results. It occurred to me that the centerLine might be better than the racingLine for detecting corners entry and exit points while the racing line is used for braking and apex points. Seems to work fairly well, but I think the best scenario is some weird mixture of both. Currently I can only tune two parameters: MinimumStraightDistance and MaximumStraightAngle.

Lets see what tomorrow brings. I'll probably do another live stream and I will try to give about an hour notice before starting, if I can. I want to focus on tuning the corner points some more, add some more parameters to tune and maybe even test out BL1 and maybe some other tracks!

Should be lots of fun.
Attached images
I started this project more than 6 years ago! Wow. It has been a wonderful project to work on and is a constant supply of some real brain storming sessions. I probably could have done this faster if I hit the books and went with some existing algorithms used for racing AI, or followed some preset path. But the thrill of solving the problems keeps me going.

There is a never ending source of problems within this project too! Years ago it started purely theoretical, building an artificial driver that used references points and approach driving algorithms similar to how us humans drive around the track. I've stuck true to most of my root goals in the process, although in some cases I have loosened up and given in.

Given only the left and right edges of the track I computed a, reasonable, racing line to follow. I figured out how to mange a virtual controller and even control LFS from another application. Without Live for Speed and the community, my Artificial Intelligence in Racing Simulations would not be where it is today. I'd like to thank Scawen, Victor and Eric.


There are a ton of improvements to be worked on in the project, and last night I simply could not turn my brain off, making it unfortunately difficult to sleep. Here is a list of things I want to tackle, some I may have mentioned, some may be new to you.

- Corner Detector / Management: Better support for detecting corner entry and exit points, along with one or two points along the corner for speed adjustments. After reading Going Faster! I wonder if a better approach to the corner would be: *Braking Point, Corner Entry, *Brake/Throttle Transition Point, Corner Apex, *Full Throttle Point, and Corner Exit. Each of the points highlighted with a * would be modified by driver as he learns. This is just me tossing ideas around, not committing to anything just yet.. Now that I have the track "debug" viewer, it is easier to tune the corner detection algorithm. I already had a break through last night that the center line might be better to use for detection, and I wasn't wrong, but it appears maybe a combination of both center and racing line would be best.

- Improved RacingLine: The current racing line is good. Okay maybe that is a stretch, but it is not terrible. A great improvement would be to make the braking zones straight. The driver seems to have the most trouble with spins due to braking at the threshold while turning, something that we humans avoid. After the corners are detected, the racingline processor will know where the straights/corners are, and with a different set of parameters should be able to make a second pass creating a better line. Still won't be the most optimal, for that would need to consider late apex corners and corner sacrificing. But that will wait for future iterations.

- Wall Detection: If you have ever seen the driver attempt to lap some South City courses, you will have heard some scrapes and even seen the occasional slam into the wall. Almost like the driver gets cars for free and is immortal. The track edges as defined by the PTH file are good, nice and close to the walls, in a few cases just barely on the wrong side. The racing line can add a safety buffer, but I think the best way to do this is to make a wall detector and only add the safety buffer if there is a wall found within 1-3 meters of the track edge. Should be simple to detect, but a bit time consuming. Results could be useful.

- Tuning Driving Logic v2: Most of the logic in this state is within the first or second iteration. I am shocked the driver does fairly well, in most cases slightly better lap times than Live for Speed AI drivers on "Learner" difficulty. But a few things must be tuned and iterated on. First, threshold braking shouldn't slam on the brakes to 100% and hope the car slows. Technically I wrote logic to lift, just doesn't always happen as planned. The corner speed is also constant from entry to apex, so if the corner is long and has one spot that needs to be slow, the entire area is slow, great example is turn 1 at BL1. Part of this can be helped with better corner detection, but the other part is slowly applying the throttle earlier than apex, when possible, and finding a way to balance the car closer to the limit. These two areas would greatly reduce lap times, in combination with better corners/racing line, it might be able to compete with LFS AI on "Quick" difficulty, maybe.

- Driving Logic v3: DLv2 was written last year and it seriously demotivated me. Turns out the failures was due to inconsistent lag between getting LFS data and sending controller input. That happens when you run at 20fps on the best of days, even we humans have a hard time with that. Driving Logic v3 won't be built to drive the race track FAST. Instead, it will aim for precision. Following the racing line, or a different line, precisely. That doesn't mean the driver should go slow, but that it will be precise above quick. The reason for that would be the plan to take DLv3 and build upon it so the "line to follow" gets updated by some other part of the ai decisions (when to pass a car, go into pits, etc) and it will need to be precise so that when given a line with only two car widths between a wall and opponent car, the artificial driver can safely drive between them. Won't be aiming to implement passing logic for quite some time though.

-Shift Points: The current up/down shift detection works fairly well for a subset of the cars, although it was primarily tuned for the XRG. The turbo cars and UF1 are absolute failures as they downshift like you would going to get groceries. Really, at about 2500rpm I believe on some cars. The current logic uses the "power band" which is the range from torqueRPM to powerRPM and then extends up/down by a certain percentage. Unfortunately, that isn't how the engine curves work, and in some cars the power band is too large, like the turbo cars where torqueRPM is relatively low and powerRPM is still high, which is why they wait so long to downshift. I still want to avoid giving the data to the driver, but it could be tricky to find a function the performs well on all/most cars given only idleRPM, torqueRPM, powerRPM and maxRPM values. Will keep trying.

Those are the big points and problem areas that I would like to address. Most of them I have ideas for, others I don't yet have ideas for but know they are important enough to keep in mind. Detecting the corners for instance, is a really tricky problem that I've barely scratched the surface of. Detecting the corners on FE1 is very different than the corners on KY1 or AS3, but I'll need the algorithm to do it successfully.
Quote from blackbird04217 :- Wall Detection: [...]only add the safety buffer if there is a wall found within 1-3 meters of the track edge. Should be simple to detect, but a bit time consuming. Results could be useful.

Does your driver have some kind of random behavour? My post relies on Jared not doing the perfect lap each lap.

I think a better aproach would be to have a "severity of failure".
On the inside/apex you may have: tarmac, flat grass, a tiny curb, a huge curb, any kind of objet and a wall. (from low to high severity)
On the outside you may have: tarmac, a wide low curb (+synthetic turf), a small curb, a high curb... a wall.

While driving we are not always pushing to the limit, we decide our strategy on the fly or prior the starting the sesion. On an endurance race we won't attack the curbs much, but on a qualifying session we might prefer going too fast on corner exit and touch the grass than being too slow and pottentially lose more time.
That is a great line of thought, and I realize we don't always push to our limits, but that might be a bit tricky to work into the project.

His driving behavior is not exactly random, actually now with the new PC it is fairly consistent, but he can have slight variations based on the latency from getting data from LFS, processing data, and sending it back through inputs in the virtual controller. I have an idea how to time this, but it is kinda complex, and I'm not sure it is necessary.

The part about your post that really stands out for an idea is marking the apex and exits for curbing. For the most part this is already done in the PTH files Live for Speed provides (not marking corners) by the path running over synthetic turf/wide curbing while avoiding the higher curbs and walls. It might be possible to make the "wall detector" do a bit more lifting and support the detection of these curbs, for instance, FE1 has a curb that eventually rolls some of the cars, it should be avoided. While other curbs might actually be safe to run over.

Writing and testing that sounds like a nightmare at the moment, but something that will stew on my mind like most of the problems I have been tackling.
I have a request from anyone that wants to help. Make table like:

car, downshift, upshift
uf1, 3500, 5000,
xfg, xxx, yyy,
xrg, xxx, yyy,

and so on for each of the cars. These don't need to be perfect, but it might be helpful for me to know what are roughly appropriate points for each car.

*Obviously this depends a little bit on the gearing and LFS setups unfortunately allow complete range of gearing options. What I am asking for is a general baseline, if you were to shift at the same rpm in each gear, for every setup/corner/track, what would those points be?

EDIT: What I am asking for shouldn't actually depend on different setups at all. If you want to think about it a different way, if you were creating a setup, what RPM would you be aiming for the up/down shift at?
You can use these based on the G27 leds. The 1st value is when the first led light opens. I guess downshifting could be down about 500. And upshift about the same as the 2nd value is the redline.

Also there can be a "limit" while turning on how fast it will upshift. Maybe the upshift rpm +100(and some delay) or something?

Also got to say im always staying up to date on this post, watching from my cave! Great progress so far!
Thanks that should give me something to start off with. Another user is running some tests for me also regarding the shift points and with any luck that change will be quite easy to add and hopefully for some cars any way he will be faster.

Good thought on the down/up shifting when in corner, currently same logic is used whether on straight or not but in a corner he might want to wait a bit longer just to try keeping the car more stable. Ideally he will enter corner in appropriate gear, already slowed to desired corner speed.
Tim, please come to the server a.s.a.p. - Jared got mental
Be there in about 10-15 minutes. You might well I guess there is no way for you to restart without joining race. Hmmm. Soon.
I can restart him with /command but his behaviour is getting worse and worse. Can't even do a lap now...
I've made note of these issues and will give select users controls through the insim to be able to reset the behavior. It seems learning algorithms managed to break things. I'm not sure the initial cause, because the driver -was- doing okay, but then ... a possible cause just hit me that my checkpoints might not be wide enough, and it may be possible to sneak by one without detection. I will have to look into that.

It appeared that the driver continued to subtract entry speed from the corner until the desired speed was set to -Xmph. That isn't possible. You can't possibly go negative miles per hour, and so he was attempting to brake and stall repeatedly, and continued to move the braking point further and further back. Kinda interesting. But then I just saw it happen again in the XFG, a car I had seen him drive okay in earlier in the day.

In other news, thanks to Michal and DarkKostas I was able to do some math and I think I've found a better mathematical description for shifting points. This has not yet been implemented, but I think I will do the following:

shiftDown = torqueRpm - (idleRpm * 0.1f);
shiftUp = limitRpm - ((limitRpm - powerRpm) * 0.1f);

Basically downshift slightly below the maximum amount of torque the engine produces, (10% idle speed). And upshift slightly before redline / engine limit, (10% difference between power and limit). Interestingly, if I wanted the driver to save a bit of fuel, increasing both of these values slightly, less revs would be used. Probably won't be doing that, but will leave a comment about doing so, also these values could be tweaked to allow the driver to push the shift point a bit during cornering. By lowering the percentage in shiftUp, he would get closer to limitRpm before shifting. Can't wait to see this iteration of shifting. Could actually make an impact on laptimes in some of the cars, particularly UF1 and turbos.

EDIT: After just a single flying lap with the new shifting logic, Jared beat his personal best at BL1 in the XRT by .74 seconds! At this rate he might get faster than the LFS ai on "Ok" difficulty soon! Also streaming live at:

Live Stream still up, the turbo cars seem to be about a second a lap faster at FE1.
Couldn't sleep again tonight, brain just racing. The new shifting logic is good for the most part, beating personal bests in a lot of cars, including the XRG which had been the most tuned car for shift points. However there is a slight issue with some cars/setups that cause the driver to get stuck in an up/down shift loop as the engine speed continues to be lower/higher triggering the shifting.

I've added the admin functionality and even a way to kill and restart the airs application. Of course that will only work if airs didn't crash and is only stuck in some odd state like he was earlier/yesterday.

I also fixed the issue where the driver attempted to drive a corner at negative miles-per-hour. Obviously that isn't going to work. Even in reverse.

Then I went exploring different tracks for fun, I had remembered he did fairly well at SO2 previously. He doesn't anymore. I know the cause I added more iterations to the racing line, which pulls it closer to the walls and he bumps into a few of them. This will have to wait until I get the wall detection working.

Lying in bed I had a bit of an "aha" moment regarding corners. There has been an issue with sweepers, current test case for them is AS2, but even the bendy hill of FE1 would count, or the front straight bend. It appears in some of these locations the racing line barely moves from the center line. I'm not sure why that is, maybe need stronger hinge forces on the racing line processor. While thinking about this, still not solved, it occurred to me I could have two different corner types, kNormalCorner and kSweepingCorner. And immediately my mind jumped to having kDecreasingRadiusCorner, kIncreasingRadiusCorner and kHairPinCorner. Which lead to thinking how I might detect what sort of corner the corner is, and for a hairpin it would be relatively easy to check what the direction of travel is coming into the corner, and what the direction of travel is exiting the corner. If this is somewhere more than say 140-150 degrees, not Fahrenheit or Celsius, then it would be a hair pin. Now, I am not sure this is any significant find, but I think it could provide the driver with more info. I think each corner should have only constant information, things that never change: a start position, end position, average radius, min radius, max radius and type. Maybe even wall/curbing info, and nearest to edge.

Essentially move the braking point out of the corner management and into some "memories" or other management for the driver to work from. His memories would then add brake point, brake/throttle transition point, full throttle point, desired entry speed and other such values that he can modify over time to learn the track.

While watching Jared lap at Blackwood in the FXR it became obvious I need to -eventually- do something about the first few laps. If he is learning from scratch the first few laps are slow enough that even coldest of tires are not pushed to their limits. But if he has already learned the track, then he tends to push too hard for brand new tires. What I was thinking about doing was to take the desiredCornerSpeed and reduce it by 15% for the first lap, 10% for the second lap, 5% for the third and by then the tires should be ready. If not the concept can be tweaked, as can the actual percentages used. This got me to thinking about the braking distance, during turn 1 of the first lap his speed will often be much slower than a flying lap. I haven't figure out how to do it, but maybe holding some "average maximum speed reached" before braking began and use that against current speed to see where the new brake point should be.

Have I mentioned how much is involved in this project and how difficult, but entertaining, it is?

It has also crossed my mind that the turbo cars need better launch and shifting logic. Essentially the turbo cars should not be lifting to shift, I just added the information so the driver can tell if the car is a turbo car or not, did you know the mrt has a turbo?, but I haven't yet hooked it up to shifting. Is it safe to shift without lifting in all turbo cars, or will some of them burn up the clutch? May need to make/add "endurance" vs "hotlap" logic. Heck it wouldn't hurt to shift without lifting in some other cars, for a hotlap mode, but not for every lap!

For now my main focus is trying to find a way to compute good corner data. I'll keep doing small iterative tasks like the shifting and such along side it to fill the gap, but primarily looking to solve the track for corners in a fairly good and reliable way.
I didn't get much done yesterday, but did fix an issue with the shifting logic. With the new engine speeds the driver would up/down/up/down/up/down in a loop for some cars/setups and needed more delay when upshifting. I added a short circuit for that delay if he is on the brakes.

I started digging into the cold tires at startup on a live stream last night, but ended it as there was no clean way, (clean as in readable and maintainable codewise) to give the driver this knowledge. It isn't a particularly tricky thing to add, but it is a little more tricky to keep it consistent with the code base and maintainable. The information doesn't belong in the racecar, but that is really all I (currently) have access to from InSim message processing.

Anyways, enough about what didn't happen. Here are some things to do on my immediate list:

DONE: Admin list needs to be brought up to date when first connecting.
DONE: Driver needs laps knowledge, for cold tire purposes.
DONE: The HACK written to detect current corner and phase needs to be rewritten. Currently most tracks still unusable because this returns wrong information. Technically only made it better, it is still pretty much a giant hack.

And more things to do on a high priority list, but both of these will wait until the Corner Manager and Memories are separated from each other, maybe after/during new corner processing is written?

- Brake point modification needs to be limited.
- Auto saving and loading of driver memories.

It would be nice to have the following:

- Driver having contact information, stop and reset/restart.
DONE: Driver action for starting from stop, slowly. Which is what should be used after a spin. reused old states with restricted throttle usage.
- Driver reseting / restarting if he gets stuck somehow.
I never wrote back last night because not much progress happened. I did manage to add a new !best / !pb command that shows you Jared's PB in the car/track he is driving, or !laps for the same, probably adding a !wr soon.

Then while attempting to sleep, honestly why can't the grand ideas come to me during normal hours so I could just work on them, I thought of a fix for the issue detecting the current corner / phase the car is in. So wrote it on the white board and continued fighting to get some Zzz's. This morning I woke and before work quickly tossed in a few lines, and after a missed logic error or two had it working. Jared can now drive around AS1 and AS5. And actually probably -most- tracks.

AS5 has a warning about track edge not found, I think this is for an apex issue, but he can drive it. The corner logic/processing will be changing shortly anyway so nothing to really worry about. The only tracks I -know- he can't perform at right now would be those with a bridge, like FE3, KY3. Actually reminds me, I need to update my PTH files because apparently my KY file is outdated somehow? I thought I had him running there once.

I let him run some laps at AS5 to learn it in the XRG and after some number of laps he found his average of mid 4:08's. His best being a 4:06.45, but the inconsistency of lap times using DLv2 really shows the weakness on the longer tracks. As one corner becomes good, others bad. Current logic increases +1 mph speed through corner if all below limit, or lowers speed -3 mph if any sensor went above the limit. This logic needs to change after the new corner/memories are created. I also need to figure out a way to "lock" a memory, but this can be tricky because if done too soon, he won't have the best laps possible, and done to late and one of the other corners could fail. More thinking required.

After watching that success, I tossed him back on AS1 in the XRG and noticed two interesting things, issues, about current logic. First he aims for a point ahead of himself on the racing line, I don't recall exactly how far ahead, and, just to complicate things more, that distance moves based on speed. The first turn at AS1 is a very sharp hairpin, about 160 degrees or so. Looking far enough ahead on the racing line, Jared will turn in sharply toward the wall and cut into the grass the turn back. Really odd.

So I tried him in some other cars, for fun, and the problem does get worse with speed, so the trick becomes how to fix that without messing up the steering logic for any other situations... Hmm. He does slow down for the turn and eventually takes the turn at a glacial speed of 10mph. While watching the first lap in the FOX I noticed that the newest logic addition "cold tires" has an issue. The driver will brake to 70% desiredCornerSpeed on the first lap, but then proceed to drive through the corner at 100%. Whoops.

I'll get that fixed up and likely be starting a stream shortly. If interested in following the project subscribe to the thread, and follow me on twitch: for updates when the stream goes live. *Note I also do streams iRacing races and other game development projects.
Interesting, so, I found that at FE1R I noticed the same issues I had seen at AS1, after restarting AIRS, the issue went away and the artificial driver drove normally. It seems restarting after switching to AS1 also fixed that issue. So there is some gremlin living in the track changing logic, somewhere. I know there was gremlins in the past when processing and saving the track data vs loading the preprocessed data, that may or may not still exist, but there is definitely an issue of sorts just changing tracks.

Which is weird. Because it usually works.

Tonight I haven't made much forward progress, but I have separated the code that computes/processes the track corners from the code that handles the corners while the driver is racing. I've also fixed the issue with cold tires, although still an issue where the braking points need to be adjusted. Also found a bug that caused the driver to be slightly more cautious than desired.

Basically upon entering the turn a few variables are reset that track the maximumOversteerLimit and maximumUndersteerLimit and the amount of time over the limit for each. Then between the corner entry and exit points the driver monitors the limit and adds to the timers if over. Essentially I was adding 100ms in a 10ms step. I haven't tested what happens with this, but I have a feeling it will be better in some cases, and possibly, even worse in others.

I then added "GOOD" messages when the driver keeps the same brake point and desired speed just for feedback, and when modifying turn speed, it now say +/- the amount. I did that because the "go faster" logic could add 5mph, 2mph or 1mph to the turn speed. The "go slower" logic used to only change by -3mph, but I've now decided to check the timer and use the following:

time | speedChange
< 250ms | -1mph
< 400ms | -2mph
<1000ms | -3mph
else | -5mph

That should make the AI quite a bit more aggressive, a tiny slip of over the limit will no longer cause him to back off the corner speed so much. I'm hoping this allows him to become more consistent. On AS5 his good/poor laps varied by more than 3 seconds. I am now letting him run laps at BL1 in the XRG. He has previously done 450 laps with a PB of 1:41.730 using some combination of DLv1 and DLv2, but I'm interested to see if this newly tuned DLv2 will perform any better.

EDIT: I've also noticed that KY2 PTH file is wrong, at least for me. My data/smx/KY2.pth file was last modified 7/1/2005, but the path clearly misses one of the corners of the track, even with the SMX data being displaying properly.
I didn't write an update last night, but I did make progress in multiple ways. First I started adding a foundation of code to get track/car index values. This will be used in the future memory system to make it easier to load and save without a bajillion files. I also performed some more cleanup and tiny changes that I don't quite remember everything.

Next, I got a little tired of watching Jared perform circles whenever he attempted to recover after a spin. I decided I can use the same steering logic and just limit the throttle application to like 30% or so until he gets back on track. This is working, for the most part. On occasion he will pop out of the recovery state too early. He also now detects if the car is in a severe oversteer condition (angle of 75 degrees) once that angle is reached Jared will go into a panic state that will stop the car, locking brakes to keep the same trajectory, as a driver should do when control is lost.

He can still get stuck against the wall, and I would like to also give him a "reset car" state that should help him against that situation. Ultimately reversing would be a better idea, but I don't want to consider that set of problems just yet, so reset would work pretty well, it would just need another button configured on the virtual controller, which I need to add a "ping back" command for testing controller latency anyway.

I started adding some helper functions to get the average angle of points in an area on the racing line, or center line. This was meant to make this weekends development easier, but it gave me a fair bit of trouble. Seriously made some silly mistakes, but finally got it working and upon looking at one corner, it occurred to me (and I had this thought previously) that the angle isn't very useful information because each point on the track is a different distance from the next. The radius at a point would be much more useful, and the values should be easier to detect corners than it is with some arbitrary angle.

This morning I came back to implement that, and am still attempting to get the correct radius. I'm about to start a live stream on if interested in stopping in.
Well I've been a bit busy, but haven't made progress exactly where I aimed. Funny how often that happens. I've tested and changed a lot today, I'm not even sure where to begin. The focus was meant to be on new corner detection, turns out, that crap is HARD. While I have some helper functions, and even learned how to find the center/radius of a circle that's edge briefly touches three points, I didn't get very far with corners.

Early in the day the concept of "Driving Modes" was added to the driver. He now basically has a "Practice" mode which is his default state and is where he learns the track and finds how to push the car into each corner. Then there is a "Racing" mode where he will no longer modify the memories, so he is not learning anything in racing mode just using the brake point and desired speed that was set in practice. The idea was to get more consistent laptimes to see if small tweaks are making him faster or slower, something that is very hard to test when the lap times can vary by nearly 2 seconds per lap on even small circuits.

After 150 laps driving the LX6! at AS1 most laps were with a tenth or two of the previous laps with a max change of about half a second, probably a computer hiccup. Then I went testing him in a sequential car, the FOX or FO8 I think and noticed an issue, he couldn't downshift multiple gears in a sequential gearbox if he lost control (so from 4th to 1st would only get to 3rd). While fixing that I updated the timers and noticed that there was some bad logic for how the pre-shift and post-shift pedal controls behaved, so I fixed that ALSO.

With the shifting behavior fresh in my mind, I decided to tackle something I've noticed awhile ago, Jared still used the clutch in sequential gear boxes, no need for that! So unless shifting from Reverse or Neutral or preparing for start, he will no-longer use the clutch for sequential gear boxes. That probably shaved off a tenth of a second or two. It was quite difficult to test since I didn't do any before/after runs and his PBs vary too wildly in practice mode.

I did some more fiddling with things, that I can't actually recall, setting up some framework for more driver interaction so I can send a command to put him in practice mode. While doing that I decided I really wanted to know exactly how much latency there is from LFS to AIRS and the controller. After spending a remarkably long time, and chasing an "InSim" bug that was me making a mistake in order of initialization, I finally got a way to check the latency. It is remarkably much faster than I expected. So much so I went through the trouble of adding an extra timer to double check results. Unless I've done something else wrong elsewhere.

The gist of the implementation is, I press L on the keyboard which resets timer to 0, and sends an TINY_PING to LFS while at the same time presses the "LatencyButton" on the virtual controller. When I get the TING_REPLY back from LFS I check the timer, and when I get a command back from LFS (the virtual controller presses a button for ctrl-f1 to send command /vc_ping) I check the timer for controller latency.

The results. Mind blowingly low. Seriously, 0.008 to 0.016 seconds. That is 8 to 16 milliseconds for the controller lag, (round trip). I've yet to see it higher than 20ms. I was a little surprised at this because I've seen the driver "have issues" with threshold braking. It seems to me that by the time he gets the "over braking" signal and starts lifting off the brakes, it is too late for him and the braking zone is over. There is a bit more to it than the 20ms latency, but I thought that was the primary issue.

The other part is using the speedometer vs physical speed to sense the brake lock up is a bit ineffective because, the brakes lock up long before the speedometer's speed slows. Unfortunately, there isn't much I can do about that.

A little depressing to have spent all that time and the delay is that tiny. Granted it shouldn't be big, and I am thankful it is small because that gives me one less thing to worry about.

Back to corner detection. I'm at a bit of a loss for ideas how to process the corners better, but I know this is pretty important to get right.

EDIT: I went to load WE just to see if it worked, and to my surprise, it did. Except not my debug visuals. Those are WAY off. Unfortunately although it somewhat worked, moving a brake point "2160m closer" doesn't let him lap very well. WE1 and AS1R has shown this issue, should be fixed with new corner detection / memories.
Attached images
Good morning, I've thought a bit more about the corner detection and I think I'm going to need to spend most of the day (or upcoming week) developing a few more visualization debug tools to process it well. For the moment however I have taken to a new challenge, and from the looks of it, I should plan to spend a fair bit of time failing before it goes okay.

I've made a crazy setup for the BF1, no traction control, highest pressures on R4 tires, highest positive camber angles for minimal grip, and just in case it mattered, 0 wing both front and rear. Now that I know the latency from LFS to AIRS including controller is less than 20ms, there is little reason he shouldn't be able to brake at the threshold, and I'm also hopeful to get him to be less aggressive with the throttle when exiting turns after apex. He has some trouble in high powered cars where he just spins. Let us see how it goes.

I'm no longer live streaming this embarrassment on if interested in stopping in.


EDIT: Wow. That was far more effective than I thought it would be. I added a bit of logic to check the "throttleLimit" and "brakingLimit" values to reduce inputs when necessary and even with a crazy setup on the BF1 Jared was, mostly, capable of driving. Definitely still some room for improvement, most notably in the "StartFromStopAction" which doesn't attempt to steer at all, this is where he spins and acts like a fool the most.

He can now actually come out of a corner in the BF1 whereas before as soon as he tried hitting throttle after his apex point a spin would likely occur. In some situations there is still too much oversteer, like hitting the curb at AS1. But generally much better. It might not help his "PB" or lap times much, since it is a bit more cautious, but then again, it might help him enter a turn with higher speed. Too early to know and it would really only effect higher rwd powered cars. I'll be back to development after a bit of a break.

LATER: I've been busy adding some tools to collect information for me to use to generate the new corner points in the AIRS project. I struggled a bit adding a picker (mouse to 3D ray) but the problem was actually something I overlooked about my debug rendering. The pitfalls of depending on a visual aid to declare something working: the visual aid itself must work first. Oops. Then I fixed a small bug in my game development framework TurtleBrains that had the mouse position offset by a wrong value when a menu is applied. After getting that working I finally had a way to select one of the points on the center/racing line and collect information about it. Since it would be extremely tedious, and likely not helpful to click on each node individually, I continued to add a way to select two points to get the average, min/max and distance between.

I don't know yet how helpful this will be, but I hope very. I spent nearly all day working on this tool, and it was actually a part of driving force behind the "track debugger" in the first place. The other portion being that many tracks were failing and I needed a way to figure out how and why. Below is a shot showing the track debugger and I copied the debug console output into it to show the information I've collected. Hopefully I can use this and sample several corners and straights and find good values to determine what makes a corner and what doesn't. I think I am going to separate into three (maybe four) groups, hairpins aka extremely tight corners, normal corners, sweepers and if needed a special case for KY oval corners which might be (hopefully so) considered sweepers, if not I may need an extra case for it.
Attached images
Starting to feel like I'm talking to myself again but, let us be honest, that probably happens a little more than I'd like to admit. A little progress has been made, such that I've added a debug visualization for the car controller on the AIRS window, I mimicked the LFS steering bar as well, kinda. Although I can see what LFS was receiving, now I can also see what the driver is actually trying to do, in case there is some failure.

I have also made some observations after watching the driver perform laps in the FO8 at AS5, the first set of laps was for learning purposes to dial in his corner "memories". Then I put him into "race" mode which stops him from modifying his memories and using the last set, this was added to test his consistency as the learning mode has him eventually push too hard and slow back down, then speed up again, randomly through different corners of the track. Actually in very few combos, FOX at BL1 was one, he reaches the perfect balancing point on all/most corners even in learning mode. I've attached a shot of the learning progress, you can see the lap times drop significantly as the artificial driver brakes later and enters a corner faster than the laps before. His FO8 setup is awful right now, especially for AS5, full wing, and the gearing needs work, but it provides a baseline to compare himself against.

I had noticed that his tires remained at optimum temperatures during the learning process, although they didn't start getting there until about 10 laps in. During the second and third tests I noticed his tires were over worked at the start and took 20 to 25 laps to get back to optimal temperatures. Of course this will vary wildly depending on setup, but the same setup was used in all three races. Makes me wonder if 3 "laps" at lower entry speeds will work, not to mention I've still seen him fail completely with cold tires. At least partially because he doesn't yet modify his brake point, only entry speed.

Watching him in the FO8 also made me aware of a possible improvement with his "learning" algorithm. Currently desiredCornerSpeed will increase if his "atLimit" detectors report under the limit from corner entry (yellow lines) to corner exit (green) and will decrease if found to be over limit within that same area. A very simple change would be to learn only between corner entry and apex (blue line) although a more robust iteration (when I rewrite some memory/corner stuff) would be to go from corner entry to the point where he deems it safe to get back on throttle again. It is obvious the driver has seconds to gain by exiting a corner faster, and I'm hoping to address that during these iterations. This is needed because in a few cases getting back on the power is triggering the oversteer limit momentarily and slowing his turn to glacial pace. Especially when it happens on sharp curbing like at AS1.

This project works quite like a painting, the entire project being the canvas. When painting the artist doesn't focus on one particular thing then move onto the next, because the visual effect needs to be tied together. First he will paint a rough shape of the mountains and later add more details and finally finishing touches focusing on improving one thing then coming back to it as the rest of the scene looks good. That is how I'm working this project, and it is quite neat to be able to tune one part then another and watch it all come together slowly.

Today I threw him at FOX and KY2 since test patch K8 fixed the KY2 path and have noticed something -really- odd. I haven't figured it out yet, and have even tried XRG also, it still happens. As I described above the desiredCornerSpeed monitors limits, to raise or lower. At KY2 however, it doesn't appear that ANY of the limits are being hit and yet the speed is lowered or remains the same. A few turns work okay, but others don't. This is the only track I have seen this issue at. At first I figured the banking of the oval played into it, but he does it in the long flat in-field sweeping corner as well. 30mph tops. None of his limits are near triggering. Not a clue.

Usually when I start typing an issue to you guys I solve it, Rubber Duck Debugging. In the case of this KY2 thing, though, it didn't work.

Next steps
- Collect a bunch of data on corners to build a better track walk corner detector.
- Build an improved memory system that includes
  • Collect a bunch of data on corners to build a better corner detector.
  • Build an improved memory system that includes
    • Memories that some how remain "safe" for first laps of driving.
    • Memories of the best elapsed time from corner entry to exit.
    • Memories of the best exit speed at corner exit.
    • Protection for memories to be limited, so brake point issue would get fixed.
  • Improve learning behaviors by not counting over limit when applying throttle.
  • Major steering logic iteration that will in theory, make the driver follow the racing line much better.
Anyways, for now I'll keep running some tests and he needs to get better at recovering after spins still. That StartFromStop action really needs to apply steering input, because on grass, or track edge, it is al luck whether he succeeds or not.

EDIT: Added a new debug tool that I can't believe I've lived without for so long. This is AMAZING almost like, real-time telemetry. The screenshot with two graphs show the new tool, the top graph shows the various "at limit" sensor values, and the bottom shows the controller values over time. Green being throttle, (or overthrottle sensor), red being brake, (or overbraking sensor), Orange being steering, (or oversteer sensor) and blue on the bottom is clutch use. The screenshots are during the launch of BF1 without traction control, exiting a corner and braking for a corner in the extreme setup.
Attached images
Screen Shot 2016-01-26 at 7.46.31 PM.png
Keep going man, looking good.
You aren't talking to your self, but I don't feel the need to litter your topic with reactions every time. Great to be able to follow your project so closely. Keep those messages coming please.
Quote from Yisc[NL] :You aren't talking to your self, but I don't feel the need to litter your topic with reactions every time. Great to be able to follow your project so closely. Keep those messages coming please.

This. Smile
Plus I don't have time this week to come over to your twitch stream or server, but be sure that I'm still watching this closely Wink
Quote from Yisc[NL] :but I don't feel the need to litter your topic with reactions every time

Nailed it. I guess we are all like that, silently watching your amazing progress and detailed reports. Thanks for that!
Not much progress for today. Watched him fail to learn at WE1 like he was at KY2. Looking through the code it appears to be some issues with estimating the distance he gets away from the racing line, which seems to affect his desired corner speed. I tweaked it and seems okay for WE1 except for T3, which is a really long turn and I guess there is a point between two of the track nodes the spreads out. Have not retested KY2.

I did however go through WE1 and AS1 and collect a bunch of track data, see attached image, which took some time. I'd like to do at least a few more full tracks, BL1, KY2, FE2, but it is pretty time consuming and boring work and I'm only "hopeful" that doing this gives me ideas or shows me values to use. I can say this would be much easier to FEED the driver than it would be to compute during the track walk, but I'm trying to give the driver as little information as possible.

While writing this post I decided I'd proof of concept an idea I have for showing the corners and such a little easier than flying around the whole track, so in 2D space I render out the track at a constant width, (not the tracks actual width), and for kicks I added the racing line on it. My idea here, once I get the new corner detection ready, is to show what areas of the track is straight vs turn, which should be easier to debug than flying around the track, even though it does lose a little precision. (theoretically I could render out a larger copy).

Not bad for 20 minutes work, I essentially implemented a track map feature, it should even work for super large tracks, scaling down as needed, lets try. Indeed it works, although this shows the lost precision. Still color coded corner vs straight will be super clear and useful.
Attached images
So the fixes from yesterday, regarding distance from racingline accuracy, did seem to help a bit more at KY2 than it did at WE1. I've let Jared train for about 110 laps or so and have now locked him in race mode so he is not learning at the moment. I am going to let him run at least 65 laps without training as a baseline, possibly even a few stints of that just because more data makes it more accurate statistically speaking. It looks like his laps will be in the mid 2:18's. After getting that data, I think tomorrow evening, maybe, I will implement the ideas I have for the new steering logic and, this would be the crucial part, nothing else. Then let him run again, with the identical memories and see if that change alone helps or hurts any.

It is very possible it hurts his laptimes initially because there are a few turns on KY2 where he slides away from his racing line, and the new steering logic will probably make him turn harder there in an attempt to follow the line more accurately. That said there is one or two corners where he actually cuts on his racing line, although that probably helps his laptimes also... The goal here is not to be faster, or slower, but to collect the data to see what effect the changes had. I suspect he will be slightly slower ...

But I also suspect he might get faster, at KY2 anyway, after I let him relearn his memories, after running the tests. The theory here is a few turns he is actually not near the limits of the car, but slows down on them because he gets too far away from the white line. Initially this was my attempt to help with "severe understeer" since I still don't have an understeer limit detector. That is on my wishlist, but I don't know how to do it with the information provided. Maybe by building some form of table that says at X speed and Y steering angle desiredYaw is Z. That seems rather fluidy though.

For tonight I am going to do some more data collection. Time consuming. Questionable whether it is worth it. Lets hope it is.

This weekend I may or may not work on the corner detection, I may instead rework the way the driver stores his memories and track a way to save the memories that had best exit speed and best elapsed time from corner entry to exit, and include in that a way to fix up his "brake before previous corner" issue. Or at least, if he does start braking before previous corner, he should probably remain in the brake zone. I think my first approach will be to make it so the brake zone must be within the range of the previous corner exit and the current corner entry. But with the new corner detection I worry a bit that some of the new straights will be too short, and I may need to go for the more complicated method.

EDIT: Looks like something wonky happened here when computing the racing line!! Woah.

EDIT 2: I've collected track data for acouple more tracks then started working on that visualization from last night again, it works, mostly for FE1, but it seems to have some bugs with BL1 (at the very least) so I can't trust the visualization quite yet. Still, pretty neat to see where the corners are being generated without flying around the entire track.
Attached images

Artificial Intelligence in Racing Simulations Project
(570 posts, started )