Forums

Full Version: My AI Thesis
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone!
I'm a student from the "Politecnico di Milano" university, and I'm preparing my thesis. I decided to work in the field of Artificial Intelligence, playing around with Neural Networks and Genetic Algorithms, so I choose to develop an AI controller for VDrift with the ability to drive through different tracks all by itself.
This will resemble the work done with TORCS, resulted in an international competition (http://cig.dei.polimi.it/)

Naturally, this implies training a specific neural net (I'll use the NEAT library) with chosen inputs. Now, I know from a previous post that all the information about the car can be accessed and modified through the CAR class. I've also downloaded the last revision from the SVN repository and studied the AI class structure.

At this point a series of questions popped in my mind:

1. Where actually I do implement my bot? Does all the code go along (or replace) the one in ai.cpp file?

2. How the AI methods is called during the game?

3. Is it possible for VDrift to run in text mode only, and thus simulating thousands of laps (with only the AI car) in an acceptable time frame, in order to train the neural net? This is a critical step.

Thanks in advance for the help! I think that all the work may be integrated into VDrift.

Best regards,
Antonio Caiazzo
Hi Antonio,
Your proposal sounds awesome! Big Grin

1.
I haven't looked much into AI yet. But it looks like ai.h/ai.cpp are implementing the game AI. I don't think we've got a bot interface.

2.
in GAME::NewGame(bool playreplay, bool addopponents, int num_laps)
Code:
//load AI cars
if (addopponents)
{
    int carcount = 1;
    for (std::vector <std::pair<std::string, std::string> >::iterator i = opponents.begin(); i != opponents.end(); ++i)
    {
        //int startplace = std::min(carcount, track.GetNumStartPositions()-1);
        int startplace = carcount;
        if (!LoadCar(i->first, i->second, track.GetStart(startplace).first, track.GetStart(startplace).second, false, true))
            return false;
        ai.add_car(&cars.back(), settings.GetAIDifficulty());
        carcount++;
    }
}
in GAME::UpdateCarInputs(CAR & car)
Code:
carinputs = ai.GetInputs(&car);
in GAME::AdvanceGameLogic()
Code:
ai.Visualize(rootnode);
ai.update(TickPeriod(), &track, cars);
in GAME::LeaveGame()
Code:
ai.clear_cars();

3.
I hope Joe can comment on this one. The most simple/lazy way would be to hack the MainLoop I guess.
Code:
///the main game loop
void GAME::MainLoop()
{
    while (!eventsystem.GetQuit() && (!benchmode || replay.GetPlaying()))
    {
        CalculateFPS();
        
        clocktime += eventsystem.Get_dt();

        eventsystem.BeginFrame();

        Tick(eventsystem.Get_dt()); //do CPU intensive stuff in parallel with the GPU

        gui.Update(eventsystem.Get_dt());
        
        FinishDraw(); //sync CPU and GPU (flip the page)
        BeginDraw();
        
        eventsystem.EndFrame();
        
        PROFILER.endCycle();
        
        displayframe++;
    }
}

PS: Please feel free to ask Joe for SVN access. I would love to see an AI branch.
Wow! Thanks a lot, NaN.
Now I begin to understand much more of the game structure. I'll try to implement something very simple, just to take confidence with the current AI system.

I'm thinking of a possible bot interface, thus avoiding the need to replace the code inside the ai.cpp file and the possibility to attach different types of controller, but I'll work on this later.

By the way, I started a blog (on wordpress) where I write my AI thesis step by step, but... it's only in italian for now Tongue
http://neuroevolution.wordpress.com

NaN Wrote:PS: Please feel free to ask Joe for SVN access. I would love to see an AI branch.
Of course! Big Grin
fresbeeplayer Wrote:3. Is it possible for VDrift to run in text mode only, and thus simulating thousands of laps (with only the AI car) in an acceptable time frame, in order to train the neural net? This is a critical step.

I think you should start by looking at the car performance testing code. If you run VDrift with the option -cartest CARNAME (where CARNAME is XS or so on), game.cpp does this (in ParseArguments):
Code:
    if (!argmap["-cartest"].empty())
    {
        pathmanager.Init(info_output, error_output);
        PERFORMANCE_TESTING perftest;
        perftest.Test(pathmanager.GetCarPath(), argmap["-cartest"], info_output, error_output);
        continue_game = false;
    }

Then if you look at performance_testing.h and .cpp you'll see how a car is set up in an environment that's an infinite plane. You would need to add some code for setting up a track and replace SimulateFlatRoad with a function that does raycasts on the track to feed to the car. You can see how this is done by looking through all of the code called from AdvanceGameLogic in game.cpp.
A little update. I'm currently working on my step 3, that is "text mode only".

To kick start I decided to it graphically first, and thus created a car with a track and other little detail. It works very well (except for the Timer object not counting time for the AI controlled car).

Returning to text mode, I encountered some trouble loading the track: it seems that Track.Load() method try to create objects graphically, and than goes in segmentation fault.

I've rewritten (in my AI_TESTING class) the method Load(), including only LoadParameters(), LoadSurfaces() and LoadRoads(); but the car seem not to collide with the ground...
These 3 methods are enough to set up a track usable by a skeleton car (that is loaded by LoadDynamics())? Smile
There have been some changes in the trunk. You are writing your code relative to which revision?

Can you guarantee that the AI won't leave the road(bezier patch)? If not you will have to load the object meshes at least. They are used for collision detection. See GAME::UpdateCarWheelCollisions().
NaN Wrote:There have been some changes in the trunk. You are writing your code relative to which revision?

The latest: 2680. I run "svn update" frequently.

NaN Wrote:Can you guarantee that the AI won't leave the road(bezier patch)? If not you will have to load the object meshes at least. They are used for collision detection. See GAME::UpdateCarWheelCollisions().

Of course not: AI will often leave the road for performance improvement.
Anyway, I can not find GAME::UpdateCarWheelCollisions() :?

Thanks for the info Big Grin
Quote:Anyway, I can not find GAME::UpdateCarWheelCollisions()
It is gone. I guessed you would use an old version.

For the latest version you need to have a COLLISION_WORLD. You also need to load the track (load the objects, surfaces) and add it to the collision world game.cpp line 1786. There is no way to add track objects manually to the collision world atm, sorry.

To run the simulation have a look at AdvanceGameLogic() in game.cpp line 582.
In your main loop you need to run: collision.Update(TickPeriod()); UpdateCar(*i, TickPeriod());

If you are not using a car you have to update cardynamics manually.