• Advertisement
Sign in to follow this  

Oscillation with sin()

This topic is 4338 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

I want a vehicle to go back and forth with the sin func (in radians/C++) I did:
void CVehicle :: Update(double time_elapsed)
{
  Vector2D SteeringForce = Vector2D(1*sin(time_elapsed),0);
  
  //Acceleratio Force/Mass
  Vector2D acceleration = SteeringForce / m_dMass;
  
  //update velocity
  m_vVelocity += acceleration * time_elapsed;
  
  //make sure that it doesn't go past the max
  m_vVelocity.Truncate(m_dMaxSpeed);
  
  //update position
  m_vPosition += m_vVelocity * time_elapsed;
  
  //update heading
  if(m_vVelocity.LengthSq() > 0.000001)
   {
     m_vHeading = Vec2DNormalize(m_vVelocity);
     m_vSide = m_vHeading.Perp();
   }
}

and then called Vehicle.Update(time); time+=0.01; but instead of going back and forth it slowly oscillates more and more (back and forth) untill it zoom of the screen!? Why does it do this? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
There is at least one problem in the code, and a second principle problem.

The one in the code is how you use time_elapsed. For computing the force a continuous time should be used (i.e. a time starting at a moment and increasing linearly with, err, elapsed time). From that force you compute the current acceleration (what is okay), but then you compute the current velocity by increasing using the product of current acceleration and the same time_elapsed. I would expect the multiplicant being a time delta elapsed since the previous simulation step. The same applies to the time_elapsed used in the integration of the position.

So either the usage at computing the force or the usage at computing the velocity/position is wrong IMHO. Since you say that the movement's magnitude is increasing uncontrolled, it must be the use at computing velocity/position.

The other thing is that integration ever accumulates errors, but I think the problem above is the one you observe atm.

[Edited by - haegarr on April 7, 2006 4:07:34 AM]

Share this post


Link to post
Share on other sites
Since you are physicaly steering a car by a force you have to make a controll system with error feedback based on cars position. It's not a simple task. What you probably wanna do is just to update cars position by your sinus function.

void Car::update(float delta_time) {
m_angle += delta_time * m_speed_constant;
m_pos.x = x0 + m_amplitude * sin( m_angle );
}

Share this post


Link to post
Share on other sites
When you do this

Vector2D SteeringForce = Vector2D(1*sin(time_elapsed),0);

you are using time elapsed, i'm assuming this is like 1/60th of a second or
something. So this will create very small force to the right since
sin(1/60) is a very small number. You probably want something like

sin(time) not sin(delta_time)

Anyways to give you some help here.


If you want to move forward and oscilate left and right...
An equation for moving on a sin wave is

f(t) = A*cos(w*t)

where A is the amplitude, w is the angular velocity, and t is time(not the delta time)

take the derivative 2 times

f'(t) = A*w*sin(w*t)
f"(t) = A*w*w*cos(w*t)

This just gives you the sideways component of velocity, you also need to add the forward component, I'm assuming it's just moving at constant speed.

So your velocity function would look like

v(t) = a(t) * dt
v(t) = A*w*w*cos(w*t) * goal_right * dt
+ forward_speed * goal_heading -- this is the forward component

where goal_heading and goal_right are the basis vectors to your target.

This will only work if you store 2 headings, the heading of the goal and the vehicles local orientation. above used the goal heading.
You can constuct your local orientation by

heading = v / |v|
right = perp(heading)




[Edited by - robert_p on April 7, 2006 1:51:16 PM]

Share this post


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

  • Advertisement