Steeering behaviours

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

Recommended Posts

Hi. I'm having a little trouble with this simple task (ARGH). I'm trying to implement the basic steering behaviours of the agents. What I have is: the Seek behaiour: Vector3f Steering::Seek(Vector3f &targetPos, Agent* agent) { Vector3f desiredVelocity = targetPos - agent->GetWorldPosition(); desiredVelocity.Normalize(); desiredVelocity *= agent->GetMaxSpeed(); std::string str; SharedTools::VectorToString(desiredVelocity, str); FE_LOG("DesiredVelocity -> "+str); return desiredVelocity - agent->GetVelocity(); } Here is how I usse it: Update(double elapsedTime) { Vector3f steeringForce = Steering::Seek(m_pathToTravel.GetElementAt(m_pathToTravel.Size()-1), this); Vector3f accelaration = steeringForce / m_mass; m_velocity += accelaration * (float)elapsedTime; m_velocity.Truncate(m_maxSpeed); SetWorldPosition(GetWorldPosition() + (m_velocity * (float)elapsedTime)); } When I put the maxVelocity value to 1 this thing works properly, and when the value is less than 1 it works, but when I put 2 or 5 or something greater than that, the agent don't stop! It continues moving like there's no tomorrow! Any ideia suggestions???

Share on other sites
There is no MaxVelocity in your code. do you mean m_maxSpeed?

edit:

A suggestion:

It may be a good idea to ensure that desiredVelocity doesnt exceed (targetPos - agent->GetWorldPosition())
You want to seek the target, not double it ;)

[Edited by - Steadtler on June 16, 2006 2:47:01 PM]

Share on other sites
Hi!

try not multiplying your accelaration by elapsedTime (only multiply in the position update).

Greetings!

Vicente

Share on other sites

steeringForce.Truncate(m_maxForce);

in the code:

Update(double elapsedTime)
{

Vector3f steeringForce = Steering::Seek(m_pathToTravel.GetElementAt(m_pathToTravel.Size()-1), this); //Arrive(m_pathToTravel.GetElementAt(m_pathToTravel.Size()-1), DEC_MEDIUM, this);

steeringForce.Truncate(m_maxForce);

Vector3f accelaration = steeringForce / m_mass;

m_velocity += accelaration * (float)elapsedTime;

m_velocity.Truncate(m_maxSpeed);

Vector3f newPos = GetWorldPosition() + (m_velocity * (float)elapsedTime);

SetLocalRotation(GetRotation(Vector3f(0,1,0), newPos - GetWorldPosition()));

SetWorldPosition(newPos);

}

And now it doesn't fly away. But in the beggining it starts to walk to the wrong direction and then it keeps ok with the normal behaviour. :S Damned!
What could it be now??? ARGH

Share on other sites
You're mixing mass/accel/force too much. I fixed some things in your code:

Vector3f Steering::Seek(Vector3f &targetPos, Agent* agent){   Vector3f desiredVelocity = targetPos - agent->GetWorldPosition();   desiredVelocity.Normalize();   // this seems not to be ok. reason: as we aproach the target, we will be    unable   //  to decelerate until we miss it at full speed. But maybe it's what you want here...   desiredVelocity *= agent->GetMaxSpeed();   // this returns difference of velocities, this is not "force"   return desiredVelocity - agent->GetVelocity();}   Vector3f steeringVelDiff = Steering::Seek(m_pathToTravel.GetElementAt(m_pathToTravel.Size()-1), this);    // this is somewhat "around-the-globe", so I prefer using "maxAccel" instead of "maxForce".   Vector3f force = steeringVelDiff * m_mass;   force.Truncate(m_maxForce);   Vector3f acceleration = force / m_mass;   m_velocity += acceleration * (float)elapsedTime;   m_velocity.Truncate(m_maxSpeed);   Vector3f newPos = GetWorldPosition() + (m_velocity * (float)elapsedTime);   //updating the rotation (heading)   SetLocalRotation(GetRotation(Vector3f(0,1,0), newPos - GetWorldPosition()));   SetWorldPosition(newPos);   //[...]

But generally, it seems to be correct. Maybe it's your path that's calculated wrong (that can happen with grid-aligned paths, that a character wants to get to the center of current grid at first, instead of to the target).

Share on other sites
Quote:
 Original post by defferYou're mixing mass/accel/force too much. I fixed some things in your code:*** Source Snippet Removed ***But generally, it seems to be correct. Maybe it's your path that's calculated wrong (that can happen with grid-aligned paths, that a character wants to get to the center of current grid at first, instead of to the target).

Thanks a lot for the help!
But As I said before, now I get the desired behaviour except in the beggining.
When the agent starts to move, it wonders... It walks to the wrong side, then goes to the goal then start walking in the wrong direction, and then it goes to the target. And When I move the agent to another point, it behaves normally. Without running away from the target.
Seems theres some kind of numerical problem in the beggining! Could it be the elapsed time or something like that?

When I take off the elapsed time it gets really crazy and not working.

By the way, that line of code
steeringForce *= m_mass;

doesn't bring nothing new :S

Share on other sites
Quote:
 Original post by gorogoroWhen the agent starts to move, it wonders... It walks to the wrong side, then goes to the goal then start walking in the wrong direction, and then it goes to the target. And When I move the agent to another point, it behaves normally. Without running away from the target.

1. Does the agent have a single goal the entire time (well, except when you change it by hand, of course), or is it following some spline-path? Try to make this as simple as spossible while still debugging.
2. Are you in possesion of a step-by-step debugger? Use it to find out what is happening in the beginning. That's what I did when I was writing my steering routines.
3. More debug output. I recommend (again!) using some kind of line-manager, that would display lines on the screen, that anybody can add anytime at runtime. You could then simply visualise your vectors.

Quote:
 Original post by gorogoroSeems theres some kind of numerical problem in the beggining! Could it be the elapsed time or something like that?

Who knows, you didn't show us where the elapsedTime comes from. Is it not negative (which sometimes happens with poorly-written timers)?

Quote:
 Original post by gorogoroBy the way, that line of code*** Source Snippet Removed ***doesn't bring nothing new :S

Of course not, since:
1. It is not related to the problem.
2. Mass is most likely == 1, isn't it? (just guessing here[grin]).

But if you are introducing mass to the routine, at least do it right.

Share on other sites
Quote:
Original post by deffer
Quote:
 Original post by gorogoroWhen the agent starts to move, it wonders... It walks to the wrong side, then goes to the goal then start walking in the wrong direction, and then it goes to the target. And When I move the agent to another point, it behaves normally. Without running away from the target.

1. Does the agent have a single goal the entire time (well, except when you change it by hand, of course), or is it following some spline-path? Try to make this as simple as spossible while still debugging.
2. Are you in possesion of a step-by-step debugger? Use it to find out what is happening in the beginning. That's what I did when I was writing my steering routines.
3. More debug output. I recommend (again!) using some kind of line-manager, that would display lines on the screen, that anybody can add anytime at runtime. You could then simply visualise your vectors.

Quote:
 Original post by gorogoroSeems theres some kind of numerical problem in the beggining! Could it be the elapsed time or something like that?

Who knows, you didn't show us where the elapsedTime comes from. Is it not negative (which sometimes happens with poorly-written timers)?

Quote:
 Original post by gorogoroBy the way, that line of code*** Source Snippet Removed ***doesn't bring nothing new :S

Of course not, since:
1. It is not related to the problem.
2. Mass is most likely == 1, isn't it? (just guessing here[grin]).

But if you are introducing mass to the routine, at least do it right.

I'm just testing this steering routine to implement the others! So the agent only have a goal. Steer to a point, nothing more :).

Yes, I've tried the step by step debug method, but it >censored< up the time variable.. So I'm printing out messages..

And yes, the mass is 1 :\$

About the time I have no ideia how it is made. It was made by the dudes who are working in the rendering engine. I'm just the guy in the corner trying to make some AI for the game :S.

[Edited by - Timkin on June 19, 2006 9:13:17 PM]

Share on other sites
Quote:
 Original post by gorogoroYes, I've tried the step by step debug method, but it >censored< up the time variable.. So I'm printing out messages..

Clamp the time difference in each loop from, say, 0 to 0.01 second. This will alow you to debug as well as remove any possible timer glitches.

[Edited by - Timkin on June 19, 2006 9:37:17 PM]

Share on other sites
Quote:
Original post by deffer
Quote:
 Original post by gorogoroYes, I've tried the step by step debug method, but it >censored< up the time variable.. So I'm printing out messages..

Clamp the time difference in each loop from, say, 0 to 0.01 second. This will alow you to debug as well as remove any possible timer glitches.

Here is a sample of the file debuging values of elapsedTime variable.

.07.04.0049.0052

sometimes I get these huge values
.0046.0066.0049.0051.0048.0047.0047.245630.0073.0062.0056.0054

or this:

.0087.0081.01.01.0096.0066

So I changed the Update code to something like this:

void SpiderAgent::Update(double elapsedTime){		if(elapsedTime > 0.0099)		elapsedTime = 0.0065;	std::string text;	SharedTools::RealToString(elapsedTime, text);	text.append("\n");		file.Write(text);		Vector3f steeringForce = Steering::Seek(m_pathToTravel.GetElementAt(m_pathToTravel.Size()-1), this); 	steeringForce.Truncate(m_maxForce);	Vector3f accelaration = steeringForce / m_mass;	m_velocity += accelaration * (float)elapsedTime;	m_velocity.Truncate(m_maxSpeed);	Vector3f newPos = GetWorldPosition() + (m_velocity * (float)elapsedTime);	//updating the rotation (heading)	SetLocalRotation(GetRotation(Vector3f(0,1,0), newPos - GetWorldPosition()));	SetWorldPosition(newPos);}

But that if is really really ugly. And things are kept hard coded. :s
By the way with this if statment the thing works just fine.

[Edited by - Timkin on June 19, 2006 9:53:50 PM]

1. 1
Rutin
26
2. 2
3. 3
4. 4
5. 5

• 11
• 10
• 13
• 20
• 14
• Forum Statistics

• Total Topics
632950
• Total Posts
3009384
• Who's Online (See full list)

There are no registered users currently online

×