Jump to content
  • Advertisement
Sign in to follow this  
dnaxx

Car steering along a line

This topic is 4457 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello! I want to automatically let a car drive along a racing track which is build up of simple controlpoints (waypoints) which are connected through lines (e.g. v2). I know the directional vector from these lines, and the viewvector (where the car points to) from the car. The car has full physics, so it can only be controlled with the commands "steer" (left/right), "accelerate" and "break". Currently I measure the distance between the car and the lines connecting the controlpoints and when it exceeds a certain amount, a left/right steering command is fired. The driving looks "ok", but the car does not follow the lines. Are there better (and not too complex!) approaches/improvements that can be easily integrated into an existing application (which can use my existing commandos)? Thank you,

Share this post


Link to post
Share on other sites
Advertisement
Quote:

Original post by dnaxx
Are there better (and not too complex!) approaches/improvements that can be easily integrated into an existing application (which can use my existing commandos)?

Well, this is definitely not a trivial task, considering you want the models to actually steer themselves, and not just "stay" on the racing line...

Here's how I'd go about this... I would specify the racing line to be followed as a series of connected bezier curves and -considering the length of each segment- I would evaluate a sufficient number of points that make up the entire curve. These points can be precalculated and saved as "per track" data. I think you should be able to get a quite good resolution of points per track length in order to get a good response, but as you'll see this won't require extra cpu overhead, only memory. Furthermore, if you feel like working on it a bit more, you can adjust the number of reference points on the racing line, based on the curvature of the current segment. E.g. you'll want more points in a corner, than in a long straight part.

When your car is at the starting grid, you will be able to know which point of the racing line is closest to it. As cars begin to move, you only have to check whether they are still closest to the same point as the previous frame, or whether they are now closer to the next reference point of the racing line (or the previous, if you plan on letting cars go the opposite way!) This way you can always keep track of the point of the racing line closest to the car by checking 2 distances per model and frame. (In fact you don't even have to find these distances, you only want to know which one is bigger, so you can even lose the square root to speed things up. You see what I mean...)

At any frame, you know the line segment of the racing line that the car is traversing. You can use a signed horizontal distance from it, to make the car adjust its position with left/right steering.
To allow for accelerating/braking, you can keep a "keyframe" (sort of) structure at some keypoints in the racing line, with information like optimal speed of the car at that point, a "good point" to overtake an opponent, an accident that might have occured with some offset distance to avoid and stuff like that.
The cars, while moving, should always check a sufficient number of such points "ahead" in the racing line for such information (this number should be increasing with the speed of the car) in order to be able to respond in time. Note that this procedure can be optimized to only checking a single point per frame per model.

I don't know... It depends on whether you consider it too complex to implement or integrate into your existing project...
I don't see how you'll get away with something much simpler, if you want good AI steering. It sounds quite promising to me, though.

Btw, have you checked the openSteer library?
edit:
openSteer demo link

Share this post


Link to post
Share on other sites
I haven't completely worked through your description, but I just want to add another note: The car's orientation can change when it collides with another model (e.g. another car), so the car has to realign itself after the crash.

Yes, I already looked into the opensteer library, but I did not find an easy way yet to include it. Also it seems to be quiet CPU-intensive.

Share this post


Link to post
Share on other sites
You need to implement a regulator that steers the car based on the cars deviation from its path along the spline. For example check out how a cruise controll on a car works. Basic speed regulation is to compute a error betwine disired and actual speed and use that error as a value to the controller that controlls the vehicle. For example multiply that erro by a power constant and use that value as new acceleration input to the vehicle. It will take a long time for me to explain how a better type of regulator caled PID regulator works. But if you look it up on the net you will find tons of information. To compute a steering value that aligns the vehicle with the spline just compute the distance to the spline and a difference in the spline direction and cars direction and use those vectors as error input to your steering regulator, PID, a heuristic regulator or whatever regulations you chose to use.

If you don't understand any of this i can explain it better.

Share this post


Link to post
Share on other sites
if you can steer your car by giving the front wheels a direction vector then this is pretty easy to get working.

all you would need to do is calculate a unit vector from the car to a given waypoint, then just set the steering wheel directions to that vector (or calculate the angles, however you require the input). All going well the car will always steer towards it, then obviously when you "reach" a waypoint, switch it to the next one.

I did a similar thing once when getting AI for a race game going thinking it would do for a start to get other cars racing around to check things. It works much better than you expect, and it actually shipped with that in, although it did grow to add additional controlls for speed and avoidence etc. It also looks like there is AI because if you nudge a car that is using that technique, you can see the wheels "fighting" as they opposite lock towards the waypoint, it looks very good and is very very fast.

For the next step I made a bunch of "paths" by simply getting good at driving the track, then driving a few clean laps with the car dropping waypoints at certain intervals, and these waypoints contain position and speed information (ie pos of the point and the speed I was travelling at the time). I drove one proper racing line for a lap. I then drove an "outside line" lap, then an "Inside line" lap.

With that all the AI needs to do is drive towards a given point and attempt to match the speed at that point. If you deem the point to be taken (there is a car on it that you will hit if you carry on - calculating for time and speeds of each) then you flick to the other waypoint "lap" positions etc.

It might not be as complex a system as some other options, but you will be hard pushed to see a better playing system IMHO.

As a means to get you going it is perfect becuase its so simple, very easy to debug and it really works.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dot5
if you can steer your car by giving the front wheels a direction vector then this is pretty easy to get working.

all you would need to do is calculate a unit vector from the car to a given waypoint, then just set the steering wheel directions to that vector (or calculate the angles, however you require the input). All going well the car will always steer towards it, then obviously when you "reach" a waypoint, switch it to the next one.

I did a similar thing once when getting AI for a race game going thinking it would do for a start to get other cars racing around to check things. It works much better than you expect, and it actually shipped with that in, although it did grow to add additional controlls for speed and avoidence etc. It also looks like there is AI because if you nudge a car that is using that technique, you can see the wheels "fighting" as they opposite lock towards the waypoint, it looks very good and is very very fast.

For the next step I made a bunch of "paths" by simply getting good at driving the track, then driving a few clean laps with the car dropping waypoints at certain intervals, and these waypoints contain position and speed information (ie pos of the point and the speed I was travelling at the time). I drove one proper racing line for a lap. I then drove an "outside line" lap, then an "Inside line" lap.

With that all the AI needs to do is drive towards a given point and attempt to match the speed at that point. If you deem the point to be taken (there is a car on it that you will hit if you carry on - calculating for time and speeds of each) then you flick to the other waypoint "lap" positions etc.

It might not be as complex a system as some other options, but you will be hard pushed to see a better playing system IMHO.

As a means to get you going it is perfect becuase its so simple, very easy to debug and it really works.


Simple though it may be, it seems completely unnecessary, though. What you have is a basic control theory problem in one variable - there's no need to drag AI into it.

What you want is most likely, as mentioned above, a PID controller. In fact, even simpler than that, a PD controller, since you have no steady-state(i.e., constant) error in the steering

Basically, calculate the "error" in the driving. This could be the distance to the line that you want to follow, but it would probably be better to calculate the distance to the line you want to follow from the point where the car will be in a short time(i.e., extrapolate ahead by assuming that the car moves in a straight line at it's current velocity for a certain time)

From there, calculate the derivative of the error. This is simply the error you calculated in the step above, minus the previous error you calculated.

Finally, the steering angle = P*error + D*(derivative of error), for two constants P and D. The easiest way you can figure out P and D is by a little bit of trial and error - if the car does not steer fast enough, increase P, If the car steers too fast, decrease P, if the car weaves back and forth, increase D, etc. You can find a guide to tuning PID controllers on a website with a PID tutorial.

Share this post


Link to post
Share on other sites
thank you. I have implemented DOT5's approach and at least, the car follows the track and in general the driving looks quiet realistic (to be honest: it looks like the driver has drunken to much alcohol...).

Share this post


Link to post
Share on other sites
I had a hell of a time accomplishing this not too long ago. (and accomplished is...questionable).

I ended up fitting lines between each track waypoint and having a dot float out infront of the car some distance based on its speed. It would steer towards this dot. By looking ahead it eliminates some of the over-shoot-wobble syndrome.

Also, because we also used fairly real physics, we had to detect 'corners' and compare their radius to the minimum radius of a turn the car could achieve at its current speed. I did this by fitting an arc to sequences of 3 waypoints (I'm sure there is a MUCH better way, anyone?). If it was determined that the car was going too fast to make a corner coming up, the braking distance required to achieve a safe speed is found and the point to apply the brakes is known from that.

The above works as long as the waypoints are setup perfectly. Results in alot of trial+error in setting up the tracks.

Also you WILL need some decision making AI, since you have multiple inputs (follow the track, counteract spinning out, avoid other cars, etc) all competing for the same controls (steering/gas/brakes only!).

I would probably try the "drive the car and have it drop detailed waypoint information" approach first, though.

Share this post


Link to post
Share on other sites
dnaxx,

make sure you have given a good resolution of waypoints on the track. All our "AI" (basically its just a crude low res replay if you think about it) drove very realistic and if you followed one of the cars at full speed (ie race yourself) they looked like a proper human rival, no weaving or drunkenness.

etothex,

maybe you missunderstood the actual implementation there. All the "AI" is done in approximately 5 lines of code and that handles everything to do with driving on an unblocked track. The calculations are extremely simple and I doubt you could get results as good as that with any other method. The real benefit is that the "AI" driver hang the back out and slide the cars around, often fishtailing out of turns as they try and meet the speed of the next waypoint description.

The problem with calculating errors in line deviation is it can often give unrealistic results. If a car gets knocked off line it can slow down until it can steer back onto it (this can be seen in a few commercial titles), which on a straight looks bad. They can also look quite sterile. With the approach I mentioned that does not happen and the car will gradually (and naturally) steer back on track, just as you or I might, as it gets on with the task of meeting the next waypoint conditions.

I am not saying that the approach I took was the best, but it certainly gave me a suprise as I knocked it up in 10 mins and the end result was an almost commercial quality opponent (barring overtaking etc).

It does have its drawbacks, as mentioned. You need to learn the track to a point that you can do a full pace clean lap in order to laydown the waypoints.

You then need to make sure the cars can drive it with an increase/decrease in pace for difficulty settings. This can be tricky because occasionally you can't just say "hit waypoints at 105% of the speed described" because on at least one corner it will go off track, so you need to add additional info to one or two waypoints to say "if on hard ignore the 105% (or whatever you set it at), go this speed" etc.

That said, its still much faster to implement and less error prone than pure analytical approaches.

The only major drawback is that if you want to have downloadable content or allow people to generate thier own tracks, you have no way to automatically generate the waypoints.

This can be solved by either generating waypoints as the track is used, or let the track maker supply the AI. Alternatively you can write a tool to generate them automatically.

That is the only downside, but can be solved.

If it looks good then your there, no matter how its getting the result.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!