The online racing simulator
Artificial Intelligence in Racing Simulations Project
(571 posts, started )
Quote from blackbird04217 :I stumbled upon PPJoy, which was mentioned on page one by someone when virtual control was first brought up. I successfully turned the wheel in LFS using my program. However, it doesn't center the wheel properly.

Have you tried calibrating it in LFS like a normal controller? I mean the steering program moving all the virtual axes through their whole ranges and then staying in neutral positions so that you can also click centering button in LFS.
@logittekg25 - For all intent and purposes I am only trying to work on AI; that may require me to make a world where a car can drive, but as said I really don't want to spend my time working with the physics and making a world for the cars.

@w126 - Yes, that was the first way I tried configuring it. I made my program use the arrow keys to move the steering axis; started the steering axis in dead center like my G25 would. Then went into LFS, double checked left and right arrow did nothing, and used them. Watched the axis move. At first turning left/right it would act just as turning the unconfigured wheel. But after I hit each edge of the axis limit the center was now making LFS about 15 degrees or so to the right. I made sure I was inputting the proper center spot according the what I had to work with from PPJoy and I was, I messed around for quite a while, even trying to configure the joystick from the PPJoy side.
ok, i understand

if you need any help that a noob like me may be able to do, dont hesitate to contact me
Well time for a small update, believe me when I say small.

Someone who was intrigued by this idea has been sending me PMs supporting and pushing me to do the project. I still stand between a rock and a rather hard place. I would love to do this experimental AI project with LFS for multiple reasons, a large reason being the physics and the fact that the world/environment is already created. I have spent the last several hours messing with the Virtual Joystick Program, and have successfully got a car to drive 'fairly' straight down the dragstrip. By fairly straight I mean there is some variance in the Heading of the car that I get reported through InSim. So I have currently an extremely _hacked_ condition where my car can be driven.

Is this the same from computer to computer? Who knows, is it even the same if I was to restart LFS right now? I don't know that either - I sure hope so since I just now realized I've spent 6 hours on this, I can't believe how much time went by... Anyways, even with the ability to have finally driven a car straight using this virtual controller, I am not set on using LFS as the test bed. I see many areas where the AI should know specific values; exact moment lights turn green, information about the track, tire wear, suspension damage, blown tire etc so that they can use this information to pit properly. Sure that is not entirely needed for the ability to get an AI driver going around the track, bit it is required for where I aim the experimental project to get.

---

Also there has been a lot of progress on my own 'environment' for the AI to be simulated in. The framework is 50% complete, but I've run into the issue of how I want to structure tracks, how to edit tracks etc. I have a very simple idea that is limiting; at least at first, and this will not be a graphical beauty; which I fear the worst from publicity of a non-beautiful but experimental AI project. I have been thinking that a flat plane, could represent the track, with a texture stretched over it to resemble a track; only for the humans benefit. A script file would place the reference points, which for visual representation would be shown via cones; simple and effective. This offers the ability to test a few things besides AI as well. Like for instance how it should be possible to drive by watching the cones alone;

Now with my current physics experience I am confident I can create a car that has some form of horsepower band, has a _simple_ transmission and gearing, is effected by air/rolling resistance (not downforce), and can apply the brakes. However the engine would be sub-par. If the transmission was disengaged (neutral or clutch pressed) then the engine speed would be undetermined. When it comes to turning the car, things get a bit tricky. To make a car on rails is simple and very possible; but I don't think that allows me to test my AI in situations like; driving at the limit, dealing with oversteer/understeer and other such things which are important to what I want to achieve.

---
I also looked into TORCS a bit more, downloaded it and tried it out as a player. I don't really like the physics side of things. I believe it is likely better physics than what I would end up creating in my environment, however I find most of the stuff in there very confusing. Maybe I am just over complicating things - and even if I didn't find it very confusing I do not know if I can create the AI in the experimental ways that I want to - and for that I can't tell if this would be a good test bed. Also looked into RARS more which also looks like it has lost its support a long time ago (2006).

I am really interested in this project, and hopefully more people will keep pushing me to continue with it, however I am quite stuck. I do think my best option is to suck it up and write my own environment; which would at least give my AI the information it needs instead of coming up with loads of hacky solutions, that take much longer in development and are likely to break down with the wind from a breath across the room ...

So I turn to the public, those who have been interested from the beginning; those who filled this thread with tons of great ideas, what are thoughts on a an environment that doesn't look so good, likely doesn't feel great for driving but at least achieves the AI going around tracks in the experimental methods I've come up with? Meaning I would not let the AI effect physics, or really know about the physics (besides the 'feeling sensor'). I want to do this, but I don't want to do it with all the constraints that I seem to be limited to.

Sorry for the wall of text, and thanks for supporting!
Trying to be as unbiased as possible here, but if you're using this as an ultimate goal to gain experience - and I believe it doesn't come down to AI alone -, you might as well go for the complete environment.
Personally I think making an LFS-based AI would still be the most interesting endeavour, though I can see how that's hard to do. However at the same time you're automatically limited to rather human-like input (from the exact InSim reported position you can calculate the reference to your "track markers" and just feed your AI the track marker position information, in whatever presentation format you want to use) and output (I guess you're using PPJoy with a IOCTL controlled joystick device, so you can only control the axes, but have no influence/knowledge of actual acceleration or tyre grip levels).

Using a self-written simulation makes the required AI intelligence sort of "easier" to reach, since it won't have trouble with the highly detailed physics, but at the same time it's going to eat quite a bit of time just making that environment + sim. And even then, isn't the AI supposed to *not* know the physics to begin with and only work in a sense of "turning the steering wheel 15° left at this reference point constellation worked well" instead of knowing actual tyre grip? That could just as well work for LFS, though slightly more sophisticated of course.
Do remember that in making my own environment I would still separate the AI from the physics. Please don't think that I would allow the AI to have anything besides the "Feeling Sensor" for physics; besides the possibility of getting 'tire wear' information - for pit stop use only.

LFS does present a nice place to show things off, but it presents said challenges. I am leaning towards my own environment, except as stated -the setup time has already been a solid week and I still have a black screen. Of course it would have been a little more than a black screen if I had any idea of how I want to create a track. A flat plane is looking like a good answer, even if it is not graphically beautiful.
Good luck man. But my input would be No line to folow more of a 3 car width (For pasing lane) and time to make the Differnt steps of the attempt correct prevention. maybe it would lead you back towards the no set line theroy. Plus adding the outside edges plus this (zone) is just and idea. Sounded good in my head. But I will deffintely check in and dont be a stranger on MSN if you need some input imedietly. =)
I haven't made my mind which of the rock hard choices I will end up going down, however I played with my LFS connections again tonight, also with PPJoy - the virtual joystick emulator and I have hacked it up to something I think it reasonable although it could likely cause issues in the future; I do hope not. I then got OutGauge and OutSim to report information to me. I do not know if I need both of them giving me information but I have the capabilities to do so if I want/need.

I then proceeded to start on the very basics of the AI structure. Really, I didn't get to deep at all. There is an AIWorld. It holds information like all the reference points, driving lines or anything else that the AI driver will need to use to navigate the track. I created message handlers that will translate InSim, OutSim and OutGauge messages into useful things for the AIWorld and AIDriver to use. I bound the following controls in LFS to my virtual controller;

Steering, Throttle, Brake and Clutch (analog controls)
Up Shift, Down Shift, Handbrake (digital controls)

I will consider adding; Ignition, H-Shifter and a few other controls later on.

-----------

My current idea is to have the AI Driver to return a structure something like;

AIControlOutput //Output in the sense the AI is telling the game what is happening.
In this structure is a float for the analog controls, and booleans (maybe even a bitfield) for the digital controls. When AIDriver::Update() is called, this structure is returned. This is all said and good, but now I need to design the more technical parts of how I want this to be used.

I was thinking about a "AICarStateInput" structure, which contains things that the AIDrivers "physical sensor" needs to know. Position, Direction (of travel), ?Speed?, Heading, AngularRotation - etc; But this is hopefully where the physics should end; the point is so the AI can't compute "turn X% + frictionFromTires() = output" instead they have to 'feel' whether the car is oversteering or understeering. Which leads me into a small mathematical problem; Using Direction and Heading how does one calculate understeer / oversteer?!?

It is easy to calculate if the car is _not_ experiencing _any_ oversteer / understeer; meaning all 4 wheels have grip - Direction and Heading are parallel in that situation. The angle between the two vectors would give me the amount of slip angle, but how do I compute whether that is oversteer/understeer...

Please don't get you're hopes up for me using LFS as the test bed, where as I do want to, it has challenges that could be destructive, or time consuming. So where as I at least started something in LFS does not mean that I am going to use LFS yet. I am currently fooling around with my AI in a UF1 at the dragstrip. I think that should be a rather simple combo to start with, then make it more complex as time goes.
I'm not sure if my OutSim class does this for me or if it comes from LFS directly (I'm at work, so I can't look at my source code at the moment), but in the OutSim packet I have a velocity Vector3 that is aligned with the current heading/pitch/roll, so the Y axis is always the longitudinal speed (forward axis), whereas the X axis is the lateral one and Z is up/down, of course. You can then calculate the angle of the XY vector (= drift angle), or normalize it and just use the X component as "oversteer" factor. Basically any lateral motion is "oversteer" in this case (since the car always wants to go forward, not sideways), though of course in the corners there will always be some amount of lateral slip. So yeah, I just described taking the difference between direction and heading in a more complicated way

Understeer on the other hand is a failure of the car to follow where your front tyres are pointing. To calculate this you need to take your steer input and together with the car's max steer angle (from the setup, or hardcoded for now) calculate the actual heading of your front tyres. Then just take the difference of tyre heading and car velocity vector. Don't forget to set the wheel turn compensation in LFS to be linear, though! Of course if your car oversteers and you don't do anything against it, your front tyres will now also point somewhere else than the car is going, so this does not count as understeer obviously. The oversteer factor has to take precedence in this case ("it's only understeer if there is no oversteer").

That's at least from my point of view a reasonably accurate calculation approach of getting the over-/understeer state, if you want to directly feed this information to the AI logic is up to you. Personally I would, maybe only in an abstracted form of "no, little, medium, heavy, catastrophic over-/understeer," since a human doesn't really know the exact angle anyway. Of course this info could also be attained indirectly from how your reference points move in relation to how you want them to move, but that just seems to be a very hard way with many pitfalls just to find out what a human race driver immediately knows without having to think about it.
So then, are you thinking that my AI physics sensor should simply be a state that gets computed before the Driver gets to play with it?

I've been thinking that the AIWorld is the main point of access for the developer using the AI. They will feed in the Inputs and retrieve the Outputs in the form of structures; kinda like the AIControlOutput structure. The AIDriver knows about the world only from it's sensors. So in this situation, the world gets to know the physical position, direction and heading and can compute the sliding state of the car.

My original idea had the AIDriver knowing the condition of the front tires and rear tires; WITHIN_LIMIT, NEAR_LIMIT, AT_LIMIT and OVER_LIMIT. So the original idea here was; (IF REAR_TIRES <= AT_LIMIT _AND_ FRONT_TIRES > AT_LIMIT) the car is in STATE_UNDERSTEER. Also twist it around to compute oversteer. In this scenario the AI has no knowledge of whats going on; but can easily make up a reason - that is until I was also going to use a check like (IF FRONT_TIRES > AT_LIMIT _AND_ IsBrakingHard()) then the car is losing traction because of threshold braking and in this case the prevention layer would release the brakes a bit.

Time to get down and dirty and design all the little inputs and outputs the program would need to communicate to/from with the AIWorld. Some I've thought about - likely only the obvious ones.

- A list of vectors to be used as left or right track edges. (Needed?)
- A list of vectors to be used as the 'best known line'. (Needed?) [Even if needed, it will be used in a different way than most current algorithms, which is the idea behind this experimental AI in the first place.]
- A list of vectors to be used as the reference points.
- Accurate physical state of the car; Position, Velocity, Direction, Heading etc...
- Accurate car gauge / control information; RPM, Speed, Selected Gear Maybe this includes the current control positions too like SteeringWheel state of MAX_LEFT, HARD_LEFT, MID_LEFT, SLIGHTY_LEFT, NEAR_CENTER etc... Considering the AI knows what they did with the controls may this is not useful or even needed.
- Accurate car properties information; Hi and Low of the Powerband, 5-speed, 6-speed, FWD/RWD and other properties that don't change about the car but the driver still needs to know this info.

I can't think of anymore at the moment, but I am sure there are more.
Just a quick update here for those interested;

I have been doing some more of the technical design, for ease of use (to switch from project to project) I decided to make AIWorld be the main point of access. The project/simulator has no idea about the AI Drivers, or anything about that. Instead it has a bunch of different structures to communicate with the world. I have still been working with LFS at this time, though the AI part of the project should be able to be placed in any other project.

I've named the project as well. A.I.R.S. Short for; Artificial Intelligence for Racing Simulations. I am not looking at creating gaming AI - and as stated before I have no idea or intentions of this AI actually being competitive as it is all experimental. That said my main connection with LFS is written inside the "LFS_to_AIRS" conversion file. This file has handlers that receive InSim, OutSim and OutGauge messages, and using these messages it will update the AIWorld.

I also have an idea of how I want the driver to deal with the world through the PhysicalSensor, VisualSensor and CarController; however not all the details have been worked out. The limitations -should- be placed within the sensors themselves, before it even gets to be used in the AI brain, however since I want to allow the AI to follow a line directly (as the first stage) then the sensors will likely need to change or something.

I have setup my very first, very simple, test situation at the autocross park. About 50 meters in front of the starting location I placed two green cones; for human use and saved that file as "AI_VIEW". I also placed a blue cone in the center of the two green ones, and named that "AI_DRIVE". The Ai Drive layout will be loaded since currently I look for the blue cone - and I realize this will get more challenging when it comes times to support additional tracks - and make that the AI's destination. The AIWorld starts in state AIWS_GRID_WAIT, which means the driver is waiting for the lights to come on. then it will move into stage AIWS_GRID_WARM, which means the driver should shift into first and get some throttle input to increase engine revs. Finally the state will change into AIWS_RACE_GREEN, which the AI should start driving.

However, currently I need to work on the shifting. I did shift the car into first, although it doesn't happen in the game so I need to work on the "CarControl" class; which will end up being where driver reaction times come into play and the whole "PrepareTo(SHIFT)" thing will come in to make things more realistic for the AI, although harder on the programmer!

I've also been thinking about my "layered" driving system, where the first layer makes the controls that the driver wants to happen; even if its 100% throttle in an LX6 while cornering. Then the next layer looks at the controls from that, and modifies it; so that the throttle is not 100% since this layer knows it is likely a bad idea. The next layer handles things that have become a problem; understeer/oversteer etc. And of course another layer will handle the shifting and other actions of the driver to keep the car within the preferred power-band. I have yet to figure out technically how I want to pull it off. And I also have yet to figure out how to add the 'emotions' to the AI; the stress/business that effects things like reaction time and sensory input.

Of course that will come in time, for now I just want to drive the car from the start point, through the green cones; and then add more points for the car to follow. Of course this is following a predetermined driving line without any visual sensor input; but I've got to make sure I can drive the LFS car before I try the experimental stuff!

Thanks for reading, hope you enjoy and show the support!
wow, this is getting to be quite the project, i wonder if the devs are secretly eyeing this thread :hide:

i think the layered driving idea is the best overally, because if something goes wrong you will also know where...either that or i am not thinking right at all
Okay, something that needs to be added to the prevention layer (when I get there) is the ability to detect when the drive wheels will/are spinning. The same will go for braking, I will need to detect if wheels are locked.

I have very little physical information about the car that is being driven and somehow I need to detect wheel speed - which is impossible, and also one of those things that the AI shouldn't need to know about. (A player doesn't measure the wheel speed when they are in the car - except perhaps by the tachometer/speedometer and judging of the reference points . . .).

Ok, after thinking about this for a while now I think I finally answered this in my post! I believe, since the AI knows the speed they are traveling - they can compare this to the speed of the speedometer; and see that they are applying too much throttle.

However the same is not true for locking the brakes; as there are other wheels not attached to the speedometer, or even only just one wheel is locked... A player gets this information from sound, and sight in some cars. I am not about to make a sound interpreter or image detection. So I've answered have the question. Any ideas to do this accurately with minimal data available?
I thought about this a bit yesterday and while the speedo-vs.-real-speed ratio = wheel slip was pretty obvious to figure out, detecting when wheels are locked is not. I can't really think of a foolproof solution to that at the moment

Maybe as a start it's enough to just assume that straightline braking will never lock up the wheels (set tuned so it doesn't happen) and any other lockup scenarios would be handled by detecting and alleviating "understeer during braking" situations.

Also a word on the wheel slip mentioned above, note that the speedo "lags" a bit, so while accelerating you'll detect a few % negative slip (actual speed faster than speedo), while decelerating will push it a bit into the positive slip region (actual speed slower than speedo). But if you account for that it can work quite well at detecting the slip ratio of the driven wheels
Hmm thanks for that, I didn't consider that the speedometer might lag behind a bit - that will make things a little more challenging than they already are. Back on page 1 you can see that I wanted the AI to know the state of each tire; and that should have been enough to know in a context dependent environment. However with LFS I can't get the state of each tire; as far as UNDER, NEAR, AT, or OVER_LIMIT. With that information on each tire the AI can detect anything in a context dependent state.


CONTEXT SYMPTOM FIX
Braking A Tire > AT_LIMIT Less Brake Pressure
Acceleration A Drive Tire > AT_LIMIT Less Throttle Pressure
Turn+Brake Outside Front > AT_LIMIT Less brake, less turn
Turn+Accel(FWD) Outside Front > AT_LIMIT Less throttle
Turn+Accel(RWD) Outside Rear > AT_LIMIT Less throttle, slightly less turn for a moment
Turning Outside Front > AT_LIMIT Less turning force
Turning Outside Rear > AT_LIMIT Opposite lock, minimal thottle/off brakes (to shift weight towards rear)

Howerver LFS doesn't get this information; One can argue that a player doesn't receive this information but I think with sounds and feeling (including the visual slip angle feeling one gets from driving in simulations) the player can get all that information immediately. Which there was a way to do that for LFS as it is kinda needed - I think.

There are hundreds of things we know intuitively, which is hard to make an AI that knows and obeys all of those things...
is it maybe possible for them to detect when a wheel is rapidly gaining temperature from a lockup
Nope, but even then I don't feel that resembles how a player gets lockup information. Where I do not need my AI to be 100% realistic in capturing the information it needs, I do want to stay as realistic as I can, and where I can't I want to keep it seemingly realistic. For instance; detecting exact traction of the tires is not realistic - but if I was giving the 'approximate' state (UNDER, AT, OVER LIMIT) then I consider this realistic even if the values did not come from sound/visuals as they would with the player.

I've been wondering if I could use G forces on the car; however it will likely not work very well. My idea was to track the amount of g force against the car during braking, if that force goes down the brakes are locked; so apply less brakes for a moment. However this has issues, the car could have been bumped by another, or other reasons which don't represent locked wheels but a decrease in force; also the force is not always X while braking, it changes a lot.
Yes, that's what I meant with "no foolproof solution." In theory the locked tyres produce a little less than maximum braking force, but that seems far too unreliable to depend on. Apart from the countless external factors, what if the car setup is simply too front biased, for example? Sure the fronts lock up, but the increase in brake strength also makes the rears work more, counteracting the traction loss of the fronts.

You know what, just stick to ABS enabled cars
Quote from blackbird04217 :
My original idea had the AIDriver knowing the condition of the front tires and rear tires; WITHIN_LIMIT, NEAR_LIMIT, AT_LIMIT and OVER_LIMIT. So the original idea here was; (IF REAR_TIRES <= AT_LIMIT _AND_ FRONT_TIRES > AT_LIMIT) the car is in STATE_UNDERSTEER. Also twist it around to compute oversteer. In this scenario the AI has no knowledge of whats going on; but can easily make up a reason - that is until I was also going to use a check like (IF FRONT_TIRES > AT_LIMIT _AND_ IsBrakingHard()) then the car is losing traction because of threshold braking and in this case the prevention layer would release the brakes a bit.

Maybe im wrong but there is a difference that you are drifting a bit out of the corner by slightly loosing the front grip, or fully loosing the traction on the front wheels ang get unsteerable. You sholdun't get the information from the physical side, but it could used as plan "B" with corretion variables, like reaction, experience. Maybe sound detection and/or detecting the steering issue would be more accurate.


Quote from blackbird04217 :
- A list of vectors to be used as the 'best known line'. (Needed?)

Yes, you do need this, but this must be created from the ai-s experience.

Quote from blackbird04217 :
- Accurate car gauge / control information; RPM, Speed, Selected Gear Maybe this includes the current control positions too like SteeringWheel state of MAX_LEFT, HARD_LEFT, MID_LEFT, SLIGHTY_LEFT, NEAR_CENTER etc... Considering the AI knows what they did with the controls may this is not useful or even needed.
- Accurate car properties information; Hi and Low of the Powerband, 5-speed, 6-speed, FWD/RWD and other properties that don't change about the car but the driver still needs to know this info.

The more detailed the data the more later you sould use it. It could simulate the experience level of a driver. A beginner would concentrate on to stay on the track more than watching the RPM, and shifting points.
The thing is that the AI needs to get some information from the physical side, no matter how you look at it. As said I do not want to get exact values; but most importantly I do not want the AI to "physically move or control the car". That is my objective in detaching the AI from physics. There are things that must come from the physics side of a game/simulator in order to make the AI in the first place; being the amount of traction at each tire, the current position and orientation of the car. The cars velocity and angular rotation as well. All these physical things make up the "AIPhysicalSensor" which will tell the AIDriver what is currently happening to the car.

Like stated, I am not aiming to make sound detection, image processors or anything obscure - just taking a different approach on how racing AI is done, and I am aiming this approach at AI in Simulations vs AI in Games. Big difference as we know. The AI in games needs to be fun for the player, while the AI in the simulation does not aim to be fun to drive with. (If it is actually competitive for someone than GREAT but I don't have my hopes that high yet, especially for the LFS side of this that has been started.

EDIT: About the RPM and the sensors for the car information, this isn't to simulate a beginner vs experienced racer. The RPM from the GaugeSensor could be exactly as our ears are. Since it could have an inaccuracy to it +/- 200 RPM I would guess. (That is a range/accuracy of within 400rpm from hearing, while the driver could also look and get a better reading. Before I start adding a lot of inaccuracy to the project, I first need to get the AI to successfully navigate a track; even if they stay well below the limits.
I didn't say that on thy first try you shouldt make a minimal working thing but for the end product, you should consider to use some kind of experience scale to make it competitive for beginner/moderate/pro drivers. The ideal would be to have the could AI learn from the players too (braking point, lines etc.) but on the beginning it's not an important pice of the project .

Ok, i think i got it. You use the phisics to recreate the datas a normal driver would get by driving, and not to directly feed it to the AI. I think this way the AI could be more idependent. Sorry for the misunderstandig
No problem about the misunderstanding, especially since it is now understood! But I think now you see how using LFS is limiting to me in ways that I don't want it to be.

As for "Beginner" to "Pro" difficulty range I think that will be tweaked by changing the accuracy of the drivers estimations. Of course, this assumes I can even achieve some competitive level of driving, which as said; I have my doubts - but certainly have my hopes as well.
are you sure you dont want the AI to react to sounds, because i feel like it would be the easiest reliable way around the problem.

if you program them to react a cirtain way when they hear the skid sound, then you should be all set
Yes I am completely sure I do not want to code something that detects sounds and then processes the sound to see if it is a tire squeal, if so which tire and how much grip is lost. A simple number from the physics department can go a long ways; and still keep it within the limits of my project.

Example; Why make this sound processor to detect engine speed, when the RPM value is easily given and available? Just use the value, perhaps add some inaccuracy as described above and the AI seems to 'hear' the engine even when the value comes from the car. The point of this project is not to work on sound processing and/or image processing.

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