Calculate speed/velocity of an object

edited April 2018 in Questions about Code

/** * Patterns. * * Move the cursor over the image to draw with a software tool * which responds to the speed of the mouse. */ void setup() { size(640, 360); background(102); }

void draw() { // Call the variableEllipse() method and send it the // parameters for the current mouse position // and the previous mouse position variableEllipse(mouseX, mouseY, pmouseX, pmouseY); }

// The simple method variableEllipse() was created specifically // for this program. It calculates the speed of the mouse // and draws a small ellipse if the mouse is moving slowly // and draws a large ellipse if the mouse is moving quickly

void variableEllipse(int x, int y, int px, int py) { float speed = abs(x-px) + abs(y-py); stroke(speed); ellipse(x, y, speed, speed); println(speed); }

Hello, I want to calculate the speed of a moving object as they do in the example above. However, pmouseX calculates the parameters of the previous position automatically and I am not sure how to do it manually for another object. What I want to do is to compare the x,y positions from the Kinect in order to calculate the speed of the user. I saw several examples and I think that I need to use Vectors(https://processing.org/examples/accelerationwithvectors.html) and calculate the velocity by subtracting the current point from the previous. However, as the Kinect captures 30frames per second I think that I need to create an ArrayList that gets the frames each second(with the position) and compare them with the previous. I am confused and not sure how I could implement that though. Any help would be appreciated. Thanks

Tagged:

Answers

  • Velocity requires two differentials:

    Differential w.r.t. space aka delta x, or dx for short

    Differential w.r.t. time aka delta t, or dt for short

    For each frame you capture the position and the time. In your code, you are getting position. For time do something like:

    float timePrev;  //GLOBAL scope
    
    timePrev=millis();  //In your draw(): Update previous time when you are done with your prev frame
    

    so now to calculate velocity between two contiguos frames:

    float dx=[pos current frame[ - [position prev frame];  //Up to you how you calculate position using your kinect 
    float dt = millis() - timePrev;  
    float velocity=dx/(dt/1000.0); 
    println("Current velocity is "+velocity+" [your units]/seconds");
    

    Notice I calculate velocity is in seconds. This is a pseudo-code which you can easily integrate in your code.

    Kf

  • Thanks for your reply. I am still confused though. Why do I need to calculate millis? Can't I just check the position changed between frames as they do here to calculate speed? https://processing.org/examples/pattern.html This example calculates speed by adding the difference between x and previous x and y with previous (x-px) +(y-py); For my case I also need to compare two values However, I didn't try this yet as I am not sure how to get the previous position (like pMouse which is predefined). If you could give a more detailed example would be really helpful as I am not really experienced with processing.

  • You save those values yourself.

    You know that setup runs once and then draw runs every frame, at a rate of 30 fps.

    Then:

    float prevTime;
    PVector prevPos;
    
    void setup(){
      size(400,600);
      prevPosition=new PVector();
    }
    
    void draw(){
    
      //....Get current postion and time
      PVector currPos=new PVector(...x,...y);  //From kinect
      float currTime=millis();  //Current time
    
      //Process current and prev position: Calculate velocity for instance
      //...
    
    
      //Update previous position
      prevPosition=...;
      prevTime=currTime;
    
    }
    

    Kf

  • Thanks! I don't know how simple this but I am not sure how to do it. For example how can I manually substruct the previous mouseX (instead of using pmouseX). This is the example you gave me, so how can I get the difference between the current and the previous so I can calculate the velocity?

       float prevTime;
        PVector prevPos;
    
    
        void setup(){
          size(400,600);
          prevPos=new PVector();
        }
    
        void draw(){
          float currTime=millis();  //Current time 
          //....Get current postion and time
          PVector currPos=new PVector(mouseX,mouseY);  
    
    
    
          //Process current and prev position: Calculate velocity for instance
         // float dx=[pos current frame[ - [position prev frame];  
          //PVector dx = PVector.sub(currPos,prevPos);
          float dx = [currPos] -  [prevPos];
          float dt = millis() - prevTime;  
          float velocity=dx/(dt/1000.0); 
    
    
    
          //Update previous position
          prevPos=currPos;
          prevTime=currTime;
    
          println(velocity);
        }
    
  • Answer ✓

    Ok, so in my previous code I choose dx to be one of my variables but this is a bad choice... as we are working in 2D where our dimensions are labeled x and y.

    Instead of dx, I will use deltaPos referring to delta position, or in other words, the difference in position:

    deltaPos= [currPos] - [prevPos];

    Updated [tested] code below. Notice that you don't really need to divide by time. I did use time since it is part of the velocity concept as this was your original question. However, you can get away by not dividing by time but just performing the subtraction of the mouse coordinates. However, your final value will be off by a factor of 1/refreshTime, where refreshTime is the time it takes to refresh a frame. If we assume a perfect computer, it can be delivering your fame at a rate of 30 fps, or a refreshTime=(1.0/30) seconds. For some purposes this assumption works. This assumption will not>/u> hold if your sketch does not deliver at 30fps as in the case you are performing heavy computation in draw. So in a nutshell, the following

    PVector velocity=deltaPos.mult(1.0/dt);

    can be replaced with

    PVector velocity=deltaPos.mult(1/framerate()); //(approx same as before)

    or

    PVector velocityLIKE=deltaPos.mult; //It will be related to velocity but it will be off by a factor, as discussed above

    Kf


    float prevTime;
    PVector prevPos;
    
    
    void setup() {
      size(400, 600);
      prevPos=new PVector();
    }
    
    void draw() {
      float currTime=millis();  //Current time 
      //....Get current postion and time
      PVector currPos=new PVector(mouseX, mouseY);  
    
    
    
      //Process current and prev position: Calculate velocity for instance
      PVector deltaPos = PVector.sub(currPos, prevPos);
      float dt = (millis() - prevTime)/1000.0;  
      PVector velocity=deltaPos.mult(1.0/dt);  
    
      //Update previous position
      prevPos=currPos;
      prevTime=currTime;
    
      println("Current velocity magnitude: "+velocity.mag()+" pixels/second");
    }
    
  • Yes, it works.Thank's a lot for explaining!

Sign In or Register to comment.