Limiting velocity, torque and sliding

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Limiting velocity, torque and sliding

Postby Henry00 » Sat Sep 24, 2011 2:09 pm

Hi everyone,

I have been working on a racing game recently and I am facing a problem.

Problem1: NewtonBodyAddVelocity
I am adding velocity to move the player forward, it starts out perfectly, it goes faster and faster, but after a while you are so fast you fall out of the newton world.
Is there a way to limit the velocity, maybe it's some simple math I am missing?

Problem2: newtonBodyAddTorque
I am adding a torque in whatever direction player is wanting to drive, but it's thesame issue as above, after a while I don't want it to spin so fast!

Problem3: Sliding
I have a velocity and a rotation, but when I rotate it's not instantly responding but it will slowly slide towards the correct velocity direction.
Does someone know math to rotate the velocity?

Thanks for everything you helped with already!
Greets,
Henry00³

Image
00Laboratories
Solutions for Developers
http://00laboratories.com/
Henry00
 
Posts: 37
Joined: Mon Aug 01, 2011 7:29 pm
Location: Germany

Re: Limiting velocity, torque and sliding

Postby JernejL » Sat Sep 24, 2011 3:50 pm

ofcourse you can limit the velocity by implementing a upper cap for velocity size.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Limiting velocity, torque and sliding

Postby Henry00 » Sat Sep 24, 2011 5:26 pm

PROBLEM 1 SOLVED

JernejL wrote:ofcourse you can limit the velocity by implementing a upper cap for velocity size.


Thanks I managed to do this, it would have been easier if you told me keyword vector length though, but thanks this solved problem 1, the others still remain though :)

PROBLEM 3 SOLVED

Just put this in update for anyone reading this topic, where rotz is my car rotation
Code: Select all
      ---------------------------
      --  REMOVE SLIPPERY      --
      ---------------------------
      local vecx2, vecy2, vecz2 = newton.bodyGetVelocity(self.physicsBody)
      veclen = math.sqrt(vecx2 * vecx2 +  vecy2 * vecy2)
      vecx2 = math.sin(math.rad((rotz*-1))) * veclen
      vecy2 = math.cos(math.rad((rotz*-1))) * veclen
      newton.bodySetVelocity(self.physicsBody, vecx2, vecy2, vecz2)


Does anyone have an idea what to do with Problem 2?
00Laboratories
Solutions for Developers
http://00laboratories.com/
Henry00
 
Posts: 37
Joined: Mon Aug 01, 2011 7:29 pm
Location: Germany

Re: Limiting velocity, torque and sliding

Postby JoeJ » Sun Sep 25, 2011 6:32 am

There's a thread about problem 2:

http://www.newtondynamics.com/forum/viewtopic.php?f=9&t=6570


Your solution for problem 3 works only on the plane, but not in 3D space (trouble in loopings).
You might want to measure velocity length as you do, but use the body matrix to construct the new velocity:

vec3 oldvel = newtonBodyGetVelocity(carbody)
float measuredLength = sqrt (oldvel.x*oldvel.x + oldvel.y*oldvel.y + oldvel.z*oldvel.z)
float interpolate = 0.8 // "grip"
vec3 newVel = interpolate * (carbody->orientationMatrix->forwardAxisVector * measuredLength)
+ (1.0 - interpolate) * oldVel

This forces velocity always to go forward relative to car, but it seems this is also true for your solution.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Limiting velocity, torque and sliding

Postby Henry00 » Sun Sep 25, 2011 10:13 am

Thanks for the reply JoeJ, the only problem is that I don't know matrix math, and I haven't found any good matrix library.
Isn't there a way to write this in a more simple way?

Code: Select all
      if keyboard.pressedKeys[keyboard.keys.a] then
         newton.bodyAddTorque(self.physicsBody, 0, 0, 15)
      end
      if keyboard.pressedKeys[keyboard.keys.d] then
         newton.bodyAddTorque(self.physicsBody, 0, 0, -15)
      end


This is all I am doing right now, I can also Get the Torque, so I tried a vector length to limit it, but it seems NewtonSetTorque is exactly thesame as NewtonAddTorque, which is rather lame, I expect it to be exactly the values I give it, not an increasing value.

Sorry for the trouble..
00Laboratories
Solutions for Developers
http://00laboratories.com/
Henry00
 
Posts: 37
Joined: Mon Aug 01, 2011 7:29 pm
Location: Germany

Re: Limiting velocity, torque and sliding

Postby JoeJ » Sun Sep 25, 2011 1:06 pm

Ok, first i'll fuse all together...

Code: Select all
 

vector steeringAngVel; // turning
vector steeringLinVel; // thrust

// input...

      steeringAngVel = vector (0, 0, 0) // note: you used torque, i use angular velocity here
      steeringLinVel = vector (0, 0, 0)

      if keyboard.pressedKeys[keyboard.keys.a] then
         steeringAngVel = vector (0, 0, 1.5)
      if keyboard.pressedKeys[keyboard.keys.d] then
         steeringAngVel = vector (0, 0, -1.5)
     
      if keyboard.pressedKeys[keyboard.keys.w] then
         steeringLinVel = vector (0, 0.5, 0) // assuming y axis goes forward
      if keyboard.pressedKeys[keyboard.keys.s] then
         steeringLinVel = vector (0, -0.5, 0)


// callback...

    matrix = BodyGetMatrix()
 
    vector curAngVel = BodyGetOmega() // get body angular velocity in GLOBAL space
    vector globalSteeringAngVel = matrix.Rotate (steeringAngVel); // rotate from local space to global
    vector targetAngVel = curAngVel + globalSteeringAngVel;

    vector curLinVel = BodyGetVelocity() // get body linear velocity in GLOBAL space
    vector globalSteeringLinVel = matrix.Rotate (steeringLinVel); // rotate from local space to global
    vector targetLinVel = curLinVel + globalSteeringLinVel;


    // limit...
    if (targetAngVel.Length() > MAX_OMEGA) targetAngVel = targetAngVel / curAngVel.Lenght() * MAX_OMEGA;
    if (targetLinVel.Length() > MAX_VEL) targetLinVel = targetLinVel / curLinVel.Lenght() * MAX_VEL;

if (tryThatFirst) // set velocities directly
{
    NewtonBodySetOmega (targetAngVel);
    NewtonBodySetVelocity (targetLinVel);
}
else // calculate force and torque to reach wanted velocities, which is better
{
    vector force = (targetLinVel - curLinVel) * (mass / timestep); // mass got from BodyGetMassMatrix
    NewtonBodyAddForce (torque);


    targetAngVel -= curAngVel;
    vector torque = targetAngVel / timestep;
    torque = matrix.Unrotate (torque);
    torque.x *= Ixx; // Inertia got from BodyGetMassMatrix
    torque.y *= Iyy;
    torque.z *= Izz;
    torque = matrix.Rotate (torque);
    NewtonBodyAddTorque (torque);
}


I hope that's correct.
To keep as simple as possible there's no interpolation stuff, which you can add later to remove some stiffness.

Are all vector operations clear to you? Length() is sqrt(x*x +y*y + z*z)
The only matrix ops are:
Rotate () = RotateVector() in Julios dMatrix.h = TrnsDir() in my code from older thread
Unrotate () = UnrotateVector() in Julios dMatrix.h = TinvDir() in my code from older thread

My matrix code from old threat is 20 years old and i wrote it when i was at the same level you are now.
I copy pasted most of it from resources found in internet, and didn't understood most of it, but that was ok.
You should do the same!

You can try to translate to basic, post code and ask where something is unclear.


EDIT:
To keep the "rotating velocity" trick,
replace the line
vector targetLinVel = curLinVel + globalSteeringLinVel;
with:
vector targetLinVel = matrix.frontVec * curLinVel.Length() + globalSteeringLinVel;
but that works only in forward direction for now.

EDIT2:
A better idea:
vector targetLinVel = matrix.frontVec * matrix.frontVec.Dot(curLinVel) + globalSteeringLinVel;
... handles backwards too
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 0 guests