The online racing simulator
Simple control of AI car
EDIT: A first test is now available below: https://www.lfs.net/forum/post/2114646#post2114646


Hello programmers.

There is a mod waiting for publishing, for the purpose of being "driven" by AI, but all it would actually do is drive along uncontrolled. But I don't really want to support such a bodge mod that bypasses all realism purely so it pulls away all by itself.

But I don't want to prevent something that could be fun so I've come up with a simple idea for just a few hours of work, to allow InSim to control a local car, in a very crude way. I've done a proof of concept and can now drive an AI car from an external program. Actually it disables the AI completely and you just set values, like Steer, throttle, brake, shift, etc.

EDIT: This is only for local AI. It would be far more complicated to do it from the server - that would require new multiplayer packets and I'm not getting into that.

EDIT2: To be clear, it can work for AI that are online, but the InSim must be connected to a local computer that has its own AI on it, and those are the only AI that can be controlled by this new simple packet.

I want to confirm if this could be useful.

It's just like this:

struct IS_AIC // AI Control
{
byte Size; // 8
byte Type; // ISP_AIC
byte ReqI; // 0
byte Zero;

byte PLID; // Unique ID of AI player to control
byte Input; // Select input value to set
word Value; // Value to set
};

// Input values from from CS_NUM in Inputs.h
// Special values

// 254 - reset all
// 255 - stop control

enum
{
CS_MSX,
CS_THROTTLE,
CS_BRAKE,
CS_CHUP,
CS_CHDN,
CS_IGNITION,
CS_EXTRALIGHT,
CS_HEADLIGHTS,
CS_SIREN,
CS_HORN,
CS_FLASH,
CS_CLUTCH,
CS_HANDBRAKE,
CS_INDICATORS,
CS_GEAR,
CS_LOOK,
CS_PITSPEED,
CS_TCDISABLE,
CS_FOGREAR,
CS_FOGFRONT,
CS_NUM
};

I think you might need some minimal feedback from the car, via a request info packet, and it could tell you some things like the lights and ignition status. I suppose you can get speed / position, etc from other packets like MCI? Or maybe you need something like an MCI for one car, which you can receive on request for a local AI, and maybe it has a little more date in it?

I want to keep it simple as I don't want this to go on more than this afternoon as I have other things that I am working on.
I should emphasise that this quick thing will not be good enough for racing. You don't receive detailed or fast enough information for control of a car near the limit. This can only be used for driving cars well within their limits. It's more of a thing for cruise or lessons.
I don't have much to add, just can't wait to get my hands on this to add to our underground racing server. I can't think of needing anything else, can get coords already, and calc a path for traffic manually. I suppose if we could get coordinates from the local ai through the local insim connection, that would probably be best, though no biggie if that's too much work, can always use the server packets.

The only thing I was thinking if a driver pushes them off line, to be responsive enough to get back on line if something is in the way, ie stop, start driving again, correct steering till on line.

Edit: Another thought, are we able to get the same stats out of the local insim of the real driver? That way I could drive around and record the info with my inputs, and "replay" the values as an AI
This seems interesting!
Quote from Scawen :I think you might need some minimal feedback from the car, via a request info packet, and it could tell you some things like the lights and ignition status. I suppose you can get speed / position, etc from other packets like MCI? Or maybe you need something like an MCI for one car, which you can receive on request for a local AI, and maybe it has a little more date in it?

I think we might need info about the current revs so we know roughly when to shift up/down.

Also, what's CS_MSX? Is that steering? Because I can't find steering in the enum Uhmm
Yes, CS_MSX is steering, from left to right.

I've been trying to get that car info sorted. What I've got so far is this:

// AI CONTROL
// ----------

struct IS_AIC // AI Control
{
byte Size; // 8
byte Type; // ISP_AIC
byte ReqI; // 0
byte Zero;

byte PLID; // Unique ID of AI player to control
byte Input; // Select input value to set
word Value; // Value to set
};

// Values for Input

// CS_MSX 0 - steering : 32768 is centre
// CS_THROTTLE 1 - 0 to 65535
// CS_BRAKE 2 - 0 to 65535
// CS_CHUP 3 - shift up (set to 1 for a short time then set back to 0)
// CS_CHDN 4 - shift down
// CS_IGNITION 5 - set to 1 (auto switch off)
// CS_EXTRALIGHT 6
// CS_HEADLIGHTS 7 - 1: off / 2: side / 3: low / 4: high
// CS_SIREN 8
// CS_HORN 9
// CS_FLASH 10
// CS_CLUTCH 11 - 0 to 65535
// CS_HANDBRAKE 12 - 0 to 65535
// CS_INDICATORS 13 - 1: cancel / 2: left / 3: right / 4: hazard
// CS_GEAR 14 - for shifter (leave at 255 for sequential control)
// CS_LOOK 15 - 0: none / 4: left / 5: left+ / 6: right / 7: right+
// CS_PITSPEED 16
// CS_TCDISABLE 17
// CS_FOGREAR 18
// CS_FOGFRONT 19
// CS_NUM 20 - number of values above

// Special values for Input

// 254 - reset all
// 255 - stop control

// Send an SMALL_AII with UVal set to PLID to receive current information about a car

struct IS_AII // AI Info
{
byte Size; // 64
byte Type; // ISP_MCI
byte ReqI; // ReqI from the SMALL_AII request packet
byte Zero;

CompCar Info; // As in the MCI packet

// as in outgauge

byte Flags; // AIFLAGS_xelelow
byte Gear; // Reverse:0, Neutral:1, First:2...
byte Sp2;
byte Sp3;

float Spare;
float RPM; // RPM
unsigned ShowLights; // Dash lights (see DL_x in OutGauge section below)

unsigned SPU0;
unsigned SPU1;
unsigned SPU2;
unsigned SPU3;
};

#define AIFLAGS_IGNITION 1 // detect if engine running
//
#define AIFLAGS_CHDN 4 // downshift lever currently held
#define AIFLAGS_CHUP 8 // upshift lever currently held
This sounds great! As you say though, we might need some more feedback data about the car, since OutSim works only for a single car (and not from external views, if I can suggest that it be made to work for all views Smile). Since you added dash lights from the OutGauge definition, maybe you could add the main data from OutSim as well? This would add pitch and roll to heading, which would make a good foundation for external computation of AI control (of course, if OutSimWheel data can be added as well, and maybe torque, that would be excellent).

If I'm not mistaken, using this in combination with the PTH format should allow us to make our own driving/racing AI - but for better usability, it would then be great if we were able to load a custom PTH file (for LA layouts, but also custom layouts in existing configs, e.g. BL1 with a ramp to skip the chicane, not just BLX and such).
Quote from Bokujishin :This sounds great! As you say though, we might need some more feedback data...

OutSim is limited to the user's car in multiplayer or the currently viewed car in singleplayer(replay), thus would be a bad approach if you also plan on driving yourself.

To have the AI driving while your player could also still drive, i guess the minimum would be a CompCar for the AI itself, possibly the whole MCI to make it also aware of other cars. Paths etc. in my opinion can be user implemented.

From my understanding, MCI is only available to those with admin password, which would limit the possibility for "server guests". this is false information, you need to set an interval when testing Wink

I like this proposal, and it looks to me that it is simple enough in the current draft to allow for a lot of different possibilities.
It's true we don't actually need paths with this system, since we can indeed handle them externally entirely (they would still be useful to make OutSim's IndexedDistance work, but that's another topic, namely telemetry).

MCI packets are available to everyone, as long as your InSim is configured to receive them from the IS_ISI packet. I guess you edited while I was typing Big grin

So Scawen's draft should be enough to have basic car control, well under the limits, and more data could allow us to make AI get closer to the limit (car pitch and roll could be used to determine the car's behavior, instead of only position and heading, and their derivatives if speed/acceleration are not included).
Or I guess some form of deep learning could work around those limitations? Though it would probably be wasteful to go that route, with all the possible car/setup combos.
I've replaced that CompCar part with OutSimMain as it's more informative and relevant. I think you need MCI for general awareness.

I don't really want to get into setting intervals for AII packets and you can just request them with a SMALL_AII for now.

I think my testing is done, I can control a car through AIC, even if I haven't tested every possible thing. I seem to be getting info out from AII OK, even if I haven't checked ever single value.

So I'll prepare a simple patch zip.
This is amazing Scawen, excited to try it!
EDIT: A new update is available below: https://www.lfs.net/forum/post/2114731#post2114731


OK, here is the test patch. The only new thing is AI control and data reporting through InSim.

docs/InSim.txt is included with this new section:


// AI CONTROL
// ==========

struct IS_AIC // AI Control
{
byte Size; // 8
byte Type; // ISP_AIC
byte ReqI; // 0
byte Zero;

byte PLID; // Unique ID of AI player to control
byte Input; // Select input value to set
word Value; // Value to set
};

// Values for Input

// CS_MSX 0 - steering : 32768 is centre
// CS_THROTTLE 1 - 0 to 65535
// CS_BRAKE 2 - 0 to 65535
// CS_CHUP 3 - shift up (set to 1 for a short time then set back to 0)
// CS_CHDN 4 - shift down
// CS_IGNITION 5 - set to 1 (auto switch off)
// CS_EXTRALIGHT 6
// CS_HEADLIGHTS 7 - 1: off / 2: side / 3: low / 4: high
// CS_SIREN 8
// CS_HORN 9
// CS_FLASH 10
// CS_CLUTCH 11 - 0 to 65535
// CS_HANDBRAKE 12 - 0 to 65535
// CS_INDICATORS 13 - 1: cancel / 2: left / 3: right / 4: hazard
// CS_GEAR 14 - for shifter (leave at 255 for sequential control)
// CS_LOOK 15 - 0: none / 4: left / 5: left+ / 6: right / 7: right+
// CS_PITSPEED 16
// CS_TCDISABLE 17
// CS_FOGREAR 18
// CS_FOGFRONT 19
// CS_NUM 20 - number of values above

// Special values for Input

// 254 - reset all
// 255 - stop control

// AI car info
// -----------

// Send a SMALL_AII with UVal set to PLID to receive current information about a local car

struct OSMain // included in IS_AII - identical to OutSimMain (main data in OutSim packet)
{
Vector AngVel; // 3 floats, angular velocity vector
float Heading; // anticlockwise from above (Z)
float Pitch; // anticlockwise from right (X)
float Roll; // anticlockwise from front (Y)
Vector Accel; // 3 floats X, Y, Z
Vector Vel; // 3 floats X, Y, Z
Vec Pos; // 3 ints X, Y, Z (1m = 65536)
};

struct IS_AII // AI Info
{
byte Size; // 96
byte Type; // ISP_AII
byte ReqI; // ReqI from the SMALL_AII request packet
byte PLID;

OSMain OSData;

byte Flags; // AIFLAGS_x below
byte Gear; // Reverse:0, Neutral:1, First:2...
byte Sp2;
byte Sp3;

float RPM; // RPM
float SpF0;
float SpF1;

unsigned ShowLights; // Dash lights currently switched on (see DL_x in OutGauge section below)
unsigned SPU1;
unsigned SPU2;
unsigned SPU3;
};

#define AIFLAGS_IGNITION 1 // detect if engine running
//
#define AIFLAGS_CHUP 4 // upshift lever currently held
#define AIFLAGS_CHDN 8 // downshift lever currently held

Download: [ download removed - F3 is now available ]
To control ai, i go into spectator, spawn ai, use cheat engine to replace local vehicle with spectated vehicle, then i add it to fuel and tada, i can control ai like its my own car

I actually made an "autonomous formula student" mod before, and i used the same method, and yes it works for racing, because its all local, and works on multiplayer too Big grin

https://streamable.com/aqw7h0
Heres proof, get good scawen (joking)
-
(Krunal_01) DELETED by Krunal_01
-
(Krunal_01) DELETED by Krunal_01
Maybe safetycar-AI Or ambulance-AI can be created now?
I dont think the ai can detect walls, or roads, so it would be quite hard to program, because the ai is blind, it only does what you tell it to, it cant dodge things or do pathfinding, but you could make a safety car with a pre set route, but you'd need to program it yourself, tho yes its possible
Using the official paths or even custom ones, we can give AI "eyes". Plus we can change routes on the fly, so in a sense they will theoretically be better at navigating. Obstacles may be manageable too: we have InSim packets for those.

I strongly believe that someone experimented enough in this area will be able to make better AI than what is currently available in the game (how much they can be driven to the limit remains to be seen, though, but at least we can give them more character than what looks like a PID to follow the race line, with some offset tolerance for overtakes).
And can you load in the official paths for ai? Im not sure i havent tested the patch yet
Quote from Scawen :OK, here is the test patch. The only new thing is AI control and data reporting...

From first testing, sending an SMALL_AII returns : IS_PLH - driver not found.

edit: My bad, i forgot the part i need to set the UVal, minor bug report on the packet name i guess.

edit edit: i managed to get everything working
What would be really cool is a raycast for the ais, so it could "see", same way a laser measure would work, 5 or 3 rays for the front and same ammount for the rear would do, then it would make things easier since we could tell it to avoid obstacles

Also, Scawen, please, if you could add a way to disable auto clutch on ai, ill buy another s3 account, just please add a way to disable it
This is a really nice addition and opens doors to new possibilities.

I have a feature request (I will post it on appropriate forum as well)
It would be a nice complementary feature if we could cast ray(s) using InSim packets into touchable surfaces in the game to measure distance or test for a hit from a point and a vector. Programmers could use this data for a machine learning algorithm or simulating parking sensors
I realised that AI don't have any fuel when spawned on an open config or any map without a path. Can that be easily changed so they have 100% fuel?
Quote from NENE87 :Maybe safetycar-AI Or ambulance-AI can be created now?

That literally was my thinking. More espcially for the league last round in KY1/R when i use a AI for 2 laps and then make it vanish Big grin
Several people experienced a crash of their LFS when being on a multiplayer server where I was testing the AI packets.

Exception code: 0xc0000005
Error offset: 0x000069b0

Unfortunately I wasn't paying attention when it happened so I'm not able to reproduce it.
Input 254 does not seem to do anything right now, all controls stay in their current state.
When stopping control with input 255, the AI will immediately come to a stop and turn the engine off, as if it had no path to follow.
Quote from Bokujishin :Input 254 does not seem to do anything right now, all controls stay in their...

Input 254 doesn't appear to be doing anything here either.
There's a mistake in the packet name in the error message when the PLID is not found: "IS_PLH - driver not found"
1

Simple control of AI car
(44 posts, started )
FGED GREDG RDFGDR GSFDG