How to make a body go (and stay) in position

edited January 2014 in How To...

Hi, I'm new to the forum, so I hope I am on the right section...

Well, I'm trying to make a body go to a predifined position and stay there. The body is "ruled" by the laws of physic (I am using forces to guide the body) but I just can't make it go and stay where I want...

In my code the location which the body must stay is created when holding the left mouse button. I'm trying to use PID (see my code) to get the right force, but is not working... When it should stabilize it starts to oscilate again. Does any one care to help me with this problem? I would be very grateful.

Just one observation, I do not want to use "dampings" (multiply final velocity/acceleration by a constant < 1) neither any kind of libraries (I know there are some VERY good physics libraries out there, but I'm writing this code because I want to learn how to do it).

Thank you very much in advance!

Particle p = new Particle(250,250,20);

void setup()
{
  size(500,500);
  frameRate(30);
}




void draw()
{
  background(255);

  PVector interForce = new PVector(0,0);
  Particle active;

    if(mousePressed)
    {
      if(mouseButton == LEFT)
        active = new Particle(mouseX,mouseY,"gAttract");
      else
        active = new Particle(mouseX,mouseY,"gRepulse");

      interForce = active.action(p);   
    }

    p.applyForce(interForce); 
    p.checkBounds();
    p.update();
    p.display();
}




class Particle
{

  PVector pos, vel, acc;
  float sz, mass, radius = 100;  
  float damping = 1;

  //Max
  float velLimit = 10;
  float xLower = 0, xUpper = 500, yLower = 0, yUpper = 500;

  //Type of behave (neutral,repulse,attract)
  float type = 0;
  float global = 1;

  //Controller
  float error = 0;
  float errorI = 0;
  float errorD = 0;

  Particle(float X, float Y, int sizE)
  {
    pos = new PVector(X,Y);
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
    sz = sizE;
    mass = int(random(5,7));
  }

  Particle(float X, float Y, String typE)
  {
    pos = new PVector(X,Y);
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
    sz = 1;
    mass = 1;

    if(typE.equals("repulse"))
      type = 1;
    else if(typE.equals("attract"))
      type = -1;
    else if(typE.equals("gRepulse"))
      {type=1;global=100;}
    else
      {type=-1;global=100;}
  }

  void display()
  {
    noStroke();
    fill(0);
    rect(pos.x, pos.y, sz, sz);
  }


  PVector action(Particle part)
  {
    float dist = abs(dist(part.pos.x,part.pos.y,pos.x,pos.y));

    part.error = dist;
    part.errorI += dist;

    if(dist < global*radius)
    {
      PVector targetLoc = new PVector(part.pos.x, part.pos.y);
      PVector dir = PVector.sub(targetLoc, pos);
      dir.normalize();
      dir.mult(type*(part.error*0.01 + part.errorI*0.005));
      return dir.get();
    }

    return new PVector(0,0);
  }

  void applyForce(PVector forcE)
  {
    PVector applied = forcE.get();
    applied.div(mass);
    acc.add(applied);
    acc.limit(10);
  }


  void update()
  {
    vel.add(acc);
    vel.limit(velLimit);
    vel.mult(damping);
    pos.add(vel);
    acc.mult(0);
  }


  void checkBounds()
  {
    if(pos.y + vel.y > yUpper || pos.y + vel.y < yLower)
      vel.y *= -1;

    if(pos.x + vel.x > xUpper || pos.x + vel.x < xLower)
      vel.x *= -1;
  }


}

Answers

  • Answer ✓

    First of all, as you say, you are trying to achieve this using the laws of physics. This means that (in some way) you want this to happen in relation to how it would happen in nature. However, in nature, particles do not (commonly) stay put...
    So I suppose you want the particle to behave "naturally", but for some reason to stop when it reaches a target. If that is the case, I suppose you could do something like:
    -Check "distance from target"
    -if ("distance from target" < minimal distance) then:
    -set position to target position
    -set speed to 0

    This would do the work, but it would not appear natural...
    In another case, you have to imagine why a particle would stop at that position... If a particle is attracted to a target point there is no reason for its movement to stop. It simply does not lose energy.
    Perhaps if you introduce a friction of some kind. Then this could lead to the particle being at rest after a few oscillations...

    Anyway, what is the "physical" phenomenon you are trying to simulate?

  • Sorry, long time no post...

    What I was really trying to do is get a hold of PID in movement, but I just couldn't "tune" the right parameters no matter how hard I tried...

    I've settled with friction anyway... Thanks for the answer!

    I know I should have replied earlier, and I hope this don't affect my status on the forum.

Sign In or Register to comment.