• Create Account

# Fuzzy Inference System

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

11 replies to this topic

### #1Bozebo  Members   -  Reputation: 108

Like
0Likes
Like

Posted 26 May 2011 - 08:36 AM

Hi, I have a piece of coursework set to make an implementation of a fuzzy inference system in C++ to control a "car" that moves in the direction towards a "line" along one axis.

I feel I have a fairly good grasp of the whole purpose and reason for fuzzy logic, particularly for game AI, but I get a bit confused when it comes down to actually implementing it.

Firstly, here is a screenshot of my fuzzy inference system in matlab:

As you can see, I have 2 inputs (each with 2 membership functions), 2 rules and 1 output.
I understand the inputs well, but I don't quite see how the output values properly tie in via the rules to give a sensible output. My system should assess the current motion of the car and the distance between the car and the line to output a new car motion (change along the single axis in units per frame).

I don't think my output is doing anything useful, but I don't understand what an output actually 'does' based on the rules. Considering rules, what I thought I should be looking for was a way to assess greater or less than, but the only valid options are equal to or not equal to an input's membership function.

My application follows this structure:
//define membership functions for inputs (sigmf curves for rate of change of car and distance from line target)

//called every frame, 30 frames per second
update(){
//evaluate input membership function results
//evaluate rules based on input results
//set new rate of change of car based on output membership function
}


The part I don't understand is how an output membership function has any application towards evaluating a rate of change.
My output has 2 membership functions, and my rules should dictate which one is applied. But what are the inputs to my output membership functions? I can't seem to find a good explanation online or in my course notes, I am probably very close to getting this to work nicely but my misunderstanding is probably making it seem more complicated than it should be.

Here is the full source (it isn't pluggable yet, while I test it):
[source lang=cpp]#include <iostream>#include <math.h>//for keyboard input#include "conio.h"//for Sleep()#include "Windows.h"using namespace std;//global for Euler's/Napier's constantdouble e = 2.718281828459045235360287471352;//sigmodally shaped membership functiondouble sigmf(double x, double a, double c){ return 1 / (1 + pow(e,-a * (x - c)));}//class to encapsulate line movement and basic kinematicsclass Line{ float x; float xMax; float xSpeed; float xSpeedMax; float friction; float accel;public: Line(float sX, float sXMax, float sFriction, float sXSpeedMax, float sAccel){ x = sX; xMax = sXMax; friction = sFriction; xSpeedMax = sXSpeedMax; accel = sAccel; xSpeed = 0; } void update(){ //if a key has been pressed if(_kbhit() != 0){ switch(_getch()){ // A or a case 97: case 65: xSpeed -= accel; //apply motion down the axis if(xSpeed < -xSpeedMax) xSpeed = -xSpeedMax; //cap the speed break; // D or d case 100: case 68: xSpeed += accel; //apply motion up the axis if(xSpeed > xSpeedMax) xSpeed = xSpeedMax; //cap the speed break; } } if(xSpeed > 0){ //if moving xSpeed -= friction; //apply friction if(xSpeed > 0){ //if still moving x += xSpeed; //move if(x > xMax){ //don't go out of bounds x = xMax; xSpeed = 0; } } else { xSpeed = 0; //don't let friction make it move the other way return; } } else if(xSpeed < 0){ //if moving xSpeed += friction; //apply friction if(xSpeed < 0){ //if still moving x += xSpeed; //move if(x < 0){ //don't go out of bounds x = 0; xSpeed = 0; } } else { xSpeed = 0; //don't let friction make it move the other way return; } } } void draw(){ int i; //pad with spaces until max x marker co-ord for(i = 0;i < xMax;i ++){ cout << " "; } cout << "V\n"; //draw the max x co-ord marker //pad with spaces until x co-ord for(i = 0;i < x;i ++){ cout << " "; } cout << "|\n"; //draw the line } float getX(){ return x; } float getXMax(){ return xMax; }};//semi-pluggable fuzzy inference system classclass FuzzySystem{ double distRange, currentSteerRange; //distance input evaluation double distInput(double dist){ double sigmfResult = sigmf(dist,-0.19,-28.23) * distRange; if(dist > 0) return sigmfResult; return -sigmfResult; } double distInput(float dist){ return distInput(static_cast<double>(dist)); } //rate of change input evaluation double currentSteerInput(double currentSteer){ double sigmfResult = sigmf(currentSteer,-1.02,-5.228) * currentSteerRange; if(currentSteer > 0) return sigmfResult; return -sigmfResult; } double currentSteerInput(float dist){ return currentSteerInput(static_cast<double>(dist)); } //calculates the output from the system based on input results float output(double oDistResult, double oCurrentSteerResult){ //if dist and current steer are "right" (rule) if(oDistResult < 0){ //find a new output double newSteer = sigmf(oDistResult,1.02,5.228)*10; //cout << "newSteer: " << newSteer << endl; printf("'right'\nnewSteer: %.4f\n",newSteer); return static_cast<float>(newSteer); //if dist and current steer are "left" (rule) } else if(oDistResult > 0){ //find a new output double newSteer = sigmf(oDistResult,1.02,5.228)*10; //cout << "newSteer: " << newSteer << endl; printf("'left'\nnewSteer: %.4f\n",newSteer); return static_cast<float>(-newSteer); } else return 0.0f; //no speed, close enough to the line }public: //constructor, sets up the range for inputs FuzzySystem(double sDistRange = 60, double sCurrentSteerRange = 10){ distRange = sDistRange; currentSteerRange = sCurrentSteerRange; } //returns a new speed for the car based on the outcome of fuzzy logic float resolve(double dist, double currentSteer){ cout << dist << endl; cout << currentSteer << "\n-------------------\n"; double distResult = distInput(dist); double currentSteerResult = currentSteerInput(currentSteer); cout << "distResult: " << distResult << endl << "currentSteerResult: " << currentSteerResult << "\n-------------------\n"; float out = output(distResult, currentSteerResult); return out; } float resolve(float dist, float currentSteer){ return resolve(static_cast<double>(dist),static_cast<double>(currentSteer)); }};//class to encapsulate the car and it's associated AIclass CarAI{ Line* line; //maintain a pointer to the line FuzzySystem* fuzzy; float x, xLast, xSpeed; //returns the distance to the line float distToLine(){ return x - line->getX(); } //returns the rate of change of the car's x co-ordinate float xChange(){ return x - xLast; }public: CarAI(Line* sLine){ fuzzy = new FuzzySystem; line = sLine; x = line->getX() + 2.327f; xSpeed = 0; } //called each frame to assess car AI and apply motion void update(){ //have the fuzzy inference system control the x speed xSpeed = fuzzy->resolve(distToLine(),xChange()); //cap the speed if(xSpeed < -10) xSpeed = -10; if(xSpeed > 10) xSpeed = 10; //remember previous x co-ord xLast = x; //apply motion x += xSpeed; //clamp into range if(x < 0) x = 0; if(x > line->getXMax()) x = line->getXMax(); } void draw(){ int i; //pad with spaces until x co-ord for(i = 0;i < x;i ++){ cout << " "; } cout << "#\n"; //draw the car }};int main(){ //introduction message int dots = 1; //loop while there is no keyboard input while(_kbhit() == 0){ if(dots == 1){ //introduction message cout << "AI For Games Development - coursework\n"; cout << "0801109 - Philip Robinson\n"; cout << "Racing Line FIS test application\n\n"; cout << "A and D allow the racing line (|) to be moved left and right.\n"; cout << "V marks the maximum x co-ordinate of the racing line and the " "car.\n"; cout << "The car is denoted by a # character.\n\n"; cout << "Press any key to continue"; } cout << "."; dots ++; Sleep(600); if(dots > 3){ dots = 1; //clear the screen system("cls"); } } //make the Line object Line line(11,60,0.16f,3.0f,0.32f); //make the CarAI object CarAI car(&line); //is the update loop to keep running or not bool run = true; //sleep time in ms each frame int sleepTime = 30; //frame counter long frame = 0; //enter the main loop while(run){ //clear the screen system("cls"); //increment the frame counter frame ++; //update the racing line line.update(); //update the car car.update(); //show the frame count cout << "frame: " << frame << endl; cout << "line x: " << line.getX() << endl; //draw the line line.draw(); //draw the car car.draw(); //limit the frame rate Sleep(sleepTime); } //clear the screen system("cls"); //write closing message cout << "closing app\n"; //sleep Sleep(1000); //end the process return 0;}[/source]

Can anybody direct me to further reading on the topic, or clarify how it all goes together for me? I understand that this post is a bit ambiguous, but that only reflects my own confusion on this topic; feel free to probe me for anything else you need to know to help me. I want to get this completed soon.

Thanks in advance for any help.

### #2A Brain in a Vat  Members   -  Reputation: 317

Like
-1Likes
Like

Posted 26 May 2011 - 12:08 PM

First of all, you don't need greater than or less than. Fuzzy logic works this way. Let's say I have a rule that says:
If (A) then (B)

This means that if the truth value of A is 1, then B will be 1. If the truth value of A is 0.5, though, then B will be 0.5.

The AND operator takes the smallest of the two parameters, and the OR operator takes the largest.
So, say A=0.75 and B=0.25.

If (A and B) then C
If (A or B) then D

As a result of these rules, C == 0.25 and D == 0.75.

NOT(a) simply ( 1 - truth(a) )
Given that, and given that I'm understanding what the variables in your problem correspond to (your car is supposed to follow a line, right?), I don't think your rules make sense.

Your rules are saying something like:
"If I am to the right of the line and I'm steering right, then steer right"
"If I am to the left of the line and I'm steering left, then steer left"

To analyze your graph you need to understand what each axis is saying. Take the corner closest to the viewer. That corner is where distance is minimum, meaning you are all the way to the right of the line. It is also where currentSteer is minimum, meaning you are already steering all the way to the right. The output value steer at that corner is minimum, meaning you are saying that in that situation you should steer the car hard to the right. Does that make sense logically? You should analyze other points on the graph to see if they make sense (they don't).

First of all, assuming the output variable steer is the rate of change in the angle of your steering (rather than the value angle itself)

if (distance is right) and NOT(currentSteer is left) then (steer is left)
if (distance is left) and NOT(currentSteer is right) then (steer is right)

These rules say basically:
"If I am to the right of the line and I'm not steering left, then steer left... steer more if I'm farther to the right or if I'm not steering very much to the left"
"if I am to the left of the line and I'm not steering right, then steer right... steer more if I'm farther to the left or if I'm not steering very much to the right"

Try that out, and if that gives you a graph that seems to make sense at each point, then you're good.

### #3IADaveMark  Moderators   -  Reputation: 3321

Like
-1Likes
Like

Posted 26 May 2011 - 07:54 PM

Sigh.

I wish I understood the fascination with fuzzy logic when a simple set of response curves can do wonders. Adding in the fuzzy sets is a whole unnecessary layer.
Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC

Professional consultant on game AI, mathematical modeling, simulation modeling
Co-advisor of the GDC AI Summit
Co-founder of the AI Game Programmers Guild
Author of the book, Behavioral Mathematics for Game AI

Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

### #4Bozebo  Members   -  Reputation: 108

Like
-1Likes
Like

Posted 27 May 2011 - 12:47 AM

Sigh.

I wish I understood the fascination with fuzzy logic when a simple set of response curves can do wonders. Adding in the fuzzy sets is a whole unnecessary layer.

I agree. Especially after wrestling with this, trying to get it to work. FIS could be useful on large projects however, where different people are providing rules to be used within somebody else's application and the level of control is required, but it doesn't really help if the programmed FIS layer isn't pluggable - which mine isn't. It seems a bit too "catch-all" to be effective.

### #5Bozebo  Members   -  Reputation: 108

Like
0Likes
Like

Posted 27 May 2011 - 07:17 AM

I have something that works now:
[source lang="cpp"]#include <iostream>#include <math.h>//for keyboard input#include "conio.h"//for Sleep()#include "Windows.h"using namespace std;//global for Euler's/Napier's constantdouble e = 2.718281828459045235360287471352;//sigmodally shaped membership functiondouble sigmf(double x, double a, double c){ return 1 / (1 + pow(e,-a * (x - c)));}//class to encapsulate line movement and basic kinematicsclass Line{ float x; float xMax; float xSpeed; float xSpeedMax; float friction; float accel;public: Line(float sX, float sXMax, float sFriction, float sXSpeedMax, float sAccel){ x = sX; xMax = sXMax; friction = sFriction; xSpeedMax = sXSpeedMax; accel = sAccel; xSpeed = 0; } void update(){ //if a key has been pressed if(_kbhit() != 0){ switch(_getch()){ // A or a case 97: case 65: xSpeed -= accel; //apply motion down the axis if(xSpeed < -xSpeedMax) xSpeed = -xSpeedMax; //cap the speed break; // D or d case 100: case 68: xSpeed += accel; //apply motion up the axis if(xSpeed > xSpeedMax) xSpeed = xSpeedMax; //cap the speed break; } } if(xSpeed > 0){ //if moving xSpeed -= friction; //apply friction if(xSpeed > 0){ //if still moving x += xSpeed; //move if(x > xMax){ //don't go out of bounds x = xMax; xSpeed = 0; } } else { xSpeed = 0; //don't let friction make it move the other way return; } } else if(xSpeed < 0){ //if moving xSpeed += friction; //apply friction if(xSpeed < 0){ //if still moving x += xSpeed; //move if(x < 0){ //don't go out of bounds x = 0; xSpeed = 0; } } else { xSpeed = 0; //don't let friction make it move the other way return; } } } void draw(){ int i; //pad with spaces until max x marker co-ord for(i = 0;i < xMax;i ++){ cout << " "; } cout << "V\n"; //draw the max x co-ord marker //pad with spaces until x co-ord for(i = 0;i < x;i ++){ cout << " "; } cout << "|\n"; //draw the line } float getX(){ return x; } float getXMax(){ return xMax; }};//fuzzy inference system classclass FuzzySystem{ //ranges of membership functions double distRange, currentSteerRange, outRange, //results of membership functions distMfLeft, distMfRight, steerMfLeft, steerMfRight; //distance input membership functions double distInputMf_Left(double dist){ double sigmfResult = sigmf(dist,-0.19,-18.23); return sigmfResult; } double distInputMf_Right(double dist){ double sigmfResult = sigmf(dist,0.19,18.23); return sigmfResult; } //rate of change input membership functions double currentSteerInputMf_Left(double currentSteer){ double sigmfResult = sigmf(currentSteer,1.02,5.228); return sigmfResult; } double currentSteerInputMf_Right(double currentSteer){ double sigmfResult = sigmf(currentSteer,-1.02,-5.228); return sigmfResult; } //rate of change output membership functions double steerOutputMf(double steerOutput){ return steerOutput * 10; double sigmfResult = sigmf(steerOutput,-0.1,0.028); return sigmfResult; } //calculates the results of input membership functions void computeInputs(double dist, double steer){ //evaluate distance input membership functions distMfLeft = distInputMf_Left(dist); printf("distMf_Left value: %.4f\n",distMfLeft); distMfRight = distInputMf_Right(dist); printf("distMf_Right value: %.4f\n",distMfRight); //evaluate currentSteer input membership functions steerMfLeft = currentSteerInputMf_Left(steer); printf("steerMfLeft value: %.4f\n",steerMfLeft); steerMfRight = currentSteerInputMf_Right(steer); printf("steerMfRight value: %.4f\n",steerMfRight); } //calculates the output from the system based on input results float output(){ /* //if dist and current steer are "right" (rule) if(oDistResult < 0.01){ //find a new output double newSteer = sigmf(oDistResult,1.02,5.228); printf("rule: 'right'\nFIS output (newSteer): %.4f\n", newSteer); return static_cast<float>(newSteer); //if dist and current steer are "left" (rule) } else if(oDistResult > 0.01){ //find a new output double newSteer = sigmf(oDistResult,1.02,5.228); printf("rule: 'left'\nFIS output (newSteer): %.4f\n", newSteer); return static_cast<float>(-newSteer); } else { printf("rule: no rule applies\n\n"); return 0.0f; //no speed, close enough to the line } */ //rules/* //rule 1 //distance is right and currentSteer is right //take the largest double rule1Result; rule1Result = (distMfRight > steerMfRight)? distMfRight: steerMfRight; printf("rule 1 outcome: %.4f\n",rule1Result); //rule 2 //distance is left and currentSteer is left //take the largest double rule2Result; rule2Result = (distMfLeft > steerMfLeft)? distMfLeft: steerMfLeft; printf("rule 2 outcome: %.4f\n",rule2Result); double steerResult; //which rule was more prominent if(rule1Result > rule2Result){ steerResult = rule1Result*10; } else { steerResult = -rule2Result*10; }*/ //printf("new speed: %.4f\n",steerResult); //return steerResult; return 0; }public: //constructor, sets up the range for inputs and outputs FuzzySystem(double sDistRange = 60, double sCurrentSteerRange = 10, double sOutRange = 10){ outRange = sOutRange; distRange = sDistRange; currentSteerRange = sCurrentSteerRange; } //returns a new speed for the car based on the outcome of fuzzy logic float resolve(double dist, double currentSteer){ computeInputs(dist, currentSteer); //holds the input results based on the applied rules //double inputResultDistance, inputResultCurrentSteer; /* if (distance is right) and NOT(currentSteer is left) then (steer is left) if (distance is left) and NOT(currentSteer is right) then (steer is right) */ double steerLeft, steerRight; //if (distance is right) and NOT(currentSteer is left) then (steer is left) steerLeft = (distMfRight > 1-steerMfLeft)? steerMfLeft: distMfRight; //if (distance is left) and NOT(currentSteer is right) then (steer is right) steerRight = (distMfLeft > 1-steerMfRight)? steerMfRight: distMfLeft; printf("steerLeft: %.4f\n" "steerRight: %.4f\n", steerLeft, steerRight); printf("steerOutputMf(steerLeft): %.4f\n",steerOutputMf(steerLeft)); printf("steerOutputMf(steerRight): %.4f\n",steerOutputMf(steerRight)); //output value double out; //which member function has the greatest magnitude if(fabs(steerLeft) > fabs(steerRight)){ out = -steerOutputMf(steerLeft); } else { out = steerOutputMf(steerRight); } printf("out: %.4f\n",out); //float steerOut = // float out = output(dist, currentSteer); return out; //return 0; } float resolve(float dist, float currentSteer){ return resolve(static_cast<double>(dist),static_cast<double>(currentSteer)); }};//class to encapsulate the car and it's associated AIclass CarAI{ Line* line; //maintain a pointer to the line FuzzySystem* fuzzy; //pointer to a fuzzy inference system float x, xLast, xSpeed; //returns the distance to the line float distToLine(){ return x - line->getX(); } //returns the rate of change of the car's x co-ordinate float xChange(){ return x - xLast; }public: CarAI(Line* sLine){ fuzzy = new FuzzySystem; line = sLine; x = 30.0f; xSpeed = 0; } //called each frame to assess car AI and apply motion void update(){ //have the fuzzy inference system control the x speed xSpeed = fuzzy->resolve(distToLine(),xChange()); //cap the speed /* if(xSpeed < -10) xSpeed = -10; if(xSpeed > 10) xSpeed = 10; */ //remember previous x co-ord xLast = x; //apply motion x += xSpeed; //clamp into range if(x < 0) x = 0; if(x > line->getXMax()) x = line->getXMax(); } void draw(){ int i; //pad with spaces until x co-ord for(i = 0;i < x;i ++){ cout << " "; } cout << "#\n"; //draw the car } float getX(){ return x; }};int main(){ //introduction message int dots = 1; //loop while there is no keyboard input while(_kbhit() == 0){ if(dots == 1){ //introduction message cout << "AI For Games Development - coursework\n"; cout << "0801109 - Philip Robinson\n"; cout << "Racing Line FIS test application\n\n"; cout << "A and D allow the racing line (|) to be moved left and right.\n"; cout << "V marks the maximum x co-ordinate of the racing line and the " "car.\n"; cout << "The car is denoted by a # character.\n\n"; cout << "Press any key to continue"; } cout << "."; dots ++; Sleep(600); if(dots > 3){ dots = 1; //clear the screen system("cls"); } } //make the Line object Line line(11,60,0.16f,3.0f,0.32f); //make the CarAI object CarAI car(&line); //is the update loop to keep running or not bool run = true; //sleep time in ms each frame int sleepTime = 30; //frame counter long frame = 0; //enter the main loop while(run){ //clear the screen system("cls"); //increment the frame counter frame ++; //update the racing line line.update(); //update the car car.update(); //show the frame count cout << "frame: " << frame << endl; cout << "line x: " << line.getX() << endl; cout << "car x: " << car.getX() << endl; //draw the line line.draw(); //draw the car car.draw(); //limit the frame rate Sleep(sleepTime); } //clear the screen system("cls"); //write closing message cout << "closing app\n"; //sleep Sleep(1000); //end the process return 0;}[/source]

Only problem is it jitters back and forth when it gets very close to the line, but I can edit my membership functions to fix that.

This part confused me:
[source lang="cpp"] //if (distance is right) and NOT(currentSteer is left) then (steer is left) steerLeft = (distMfRight > 1-steerMfLeft)? steerMfLeft: distMfRight; //if (distance is left) and NOT(currentSteer is right) then (steer is right) steerRight = (distMfLeft > 1-steerMfRight)? steerMfRight: distMfLeft;[/source]

### #6Álvaro  Crossbones+   -  Reputation: 18463

Like
-1Likes
Like

Posted 27 May 2011 - 08:15 AM

Sigh.

I wish I understood the fascination with fuzzy logic when a simple set of response curves can do wonders. Adding in the fuzzy sets is a whole unnecessary layer.

I agree. Especially after wrestling with this, trying to get it to work. FIS could be useful on large projects however, where different people are providing rules to be used within somebody else's application and the level of control is required, but it doesn't really help if the programmed FIS layer isn't pluggable - which mine isn't. It seems a bit too "catch-all" to be effective.

I doubt very much that the usefulness of fuzzy logic would improve with project size.

Utility maximization is often a much better way to describe decision-making problems. In one case I built such an optimizer using a modular frame where people could add utility terms of their own, plus a tool to design curves using splines, which people used to describe their utility terms and to tweak them without touching the code. Several people have added terms an tweaked existing ones, and it works great.

### #7IADaveMark  Moderators   -  Reputation: 3321

Like
0Likes
Like

Posted 28 May 2011 - 11:57 AM

Utility maximization is often a much better way to describe decision-making problems.

Can you recommend a good book on how to model utility response curves?

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC

Professional consultant on game AI, mathematical modeling, simulation modeling
Co-advisor of the GDC AI Summit
Co-founder of the AI Game Programmers Guild
Author of the book, Behavioral Mathematics for Game AI

Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

### #8Álvaro  Crossbones+   -  Reputation: 18463

Like
-1Likes
Like

Posted 28 May 2011 - 01:38 PM

Utility maximization is often a much better way to describe decision-making problems.

Can you recommend a good book on how to model utility response curves?

Yes, your book does cover that.

But really, some common sense and experimentation will go a long long way. Just make sure your functions don't have any funny features like discontinuities or spurious local minima: C^1 cubic splines work relly well, and most of the time you want to make sure that the second derivative is positive.

### #9Bozebo  Members   -  Reputation: 108

Like
0Likes
Like

Posted 28 May 2011 - 03:59 PM

Do I need any defuzzification for my system? The magnitude of the output from the rules seems to closely represent a good new rate of change of car as it is (then I apply a sign based on which has the largest magnitude), so the whole output MF isn't really required in my system.

If I am to use defuzzification, there seems to be no concrete way to select a method based on the purpose of the FIS.

Bearing in mind that this is probably the last time I will use fuzzy inference systems...

### #10IADaveMark  Moderators   -  Reputation: 3321

Like
-1Likes
Like

Posted 28 May 2011 - 09:41 PM

Do I need any defuzzification for my system? The magnitude of the output from the rules seems to closely represent a good new rate of change of car as it is (then I apply a sign based on which has the largest magnitude), so the whole output MF isn't really required in my system.

If I am to use defuzzification, there seems to be no concrete way to select a method based on the purpose of the FIS.

If the control input that you are looking to use has continuous variable input -- e.g. a steering wheel that is not simply, "straight," "turn left," and "turn right" but rather can be turned to any angle -- then defuzzification is useless. Just simply convert the input of amount of turn needed into the amount of deflection. Same with braking force... normalize the input of how much braking you need and then map a response curve over onto how much (normalized) braking to apply.

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC

Professional consultant on game AI, mathematical modeling, simulation modeling
Co-advisor of the GDC AI Summit
Co-founder of the AI Game Programmers Guild
Author of the book, Behavioral Mathematics for Game AI

Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

### #11Álvaro  Crossbones+   -  Reputation: 18463

Like
0Likes
Like

Posted 07 September 2012 - 10:19 AM

So some joker seems to be going around really old threads like this one and modding down posts which seem perfectly nice to me. I couldn't care less about the strange reputation system on this website, but perhaps this person can actually tell us what's wrong with the posts so we can do something constructive about it...

Edited by alvaro, 07 September 2012 - 10:19 AM.

### #12IADaveMark  Moderators   -  Reputation: 3321

Like
0Likes
Like

Posted 07 September 2012 - 11:02 AM

Aforementioned joker/troll was noticed by other mods (not me) and has been... advised.
Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC

Professional consultant on game AI, mathematical modeling, simulation modeling
Co-advisor of the GDC AI Summit
Co-founder of the AI Game Programmers Guild
Author of the book, Behavioral Mathematics for Game AI

Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS