High gravity stability

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

High gravity stability

Postby Cannos » Wed Mar 10, 2010 3:04 pm

I have a situation where a chamfer cylinder is propped up on a ramp such that it only makes contact on two points. It will rotate about an axis through these contact points for a while before it comes to rest. However, at high gravity (-100 vs. the standard -10) it takes a really long time for this it to come to rest. Sometimes it won't come to rest at all.

Assuming this isn't a bug, I'm looking for advice on how to get this to come to rest much faster. I could play with damping parameters, but I don't want to drastically change its motion under normal conditions. Is there perhaps a way to increase the threshold at which a body automatically goes to sleep (I thought I saw some older functions for setting this type of thing)?

Here is a modification to the basic friction sample (BasicFriction.cpp) that demonstrates the problem I am talking about.

Code: Select all
/* Copyright (c) <2009> <Newton Game Dynamics>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely
*/

#include <toolbox_stdafx.h>
#include "SkyBox.h"
#include "RenderPrimitive.h"
#include "../OGLMesh.h"
#include "../SceneManager.h"
#include "../PhysicsUtils.h"
#include "../toolBox/MousePick.h"
#include "../toolBox/OpenGlUtil.h"
#include "../toolBox/DebugDisplay.h"


static void UserContactFriction (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex)
{
   dFloat Ixx;
   dFloat Iyy;
   dFloat Izz;
   dFloat mass;
   dFloat friction;
   const NewtonBody* body;
   const NewtonBody* body0;
   const NewtonBody* body1;

   // call  the basic call back
   GenericContactProcess (contactJoint, timestep, threadIndex);

   body0 = NewtonJointGetBody0(contactJoint);
   body1 = NewtonJointGetBody1(contactJoint);

   body = body0;
   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
   if (mass == 0.0f) {
      body = body1;
   }

   for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) {
      RenderPrimitive* node;
      NewtonMaterial* material;

      material = NewtonContactGetMaterial (contact);
      node = (RenderPrimitive*) NewtonBodyGetUserData (body);
      
      friction = node->m_density;
      NewtonMaterialSetContactFrictionCoef (material, friction + 0.1f, friction, 0);
      NewtonMaterialSetContactFrictionCoef (material, friction + 0.1f, friction, 1);
   }
}

static void SetDemoCallbacks (SceneManager& system)
{
   system.m_control = Keyboard;
   system.m_autoSleep = AutoSleep;
   system.m_showIslands = SetShowIslands;
   system.m_showContacts = SetShowContacts;
   system.m_setMeshCollision = SetShowMeshCollision;
//   system.m_scene = scene;
}


static void BuildFloorAndSceneRoot (SceneManager& system)
{
   NewtonWorld* world;
   RenderPrimitive* floor;
   NewtonBody* floorBody;
   NewtonCollision* floorCollision;
   OGLMesh* meshInstance;
//   dSceneNode* scene;

   world = system.m_world;

   // /////////////////////////////////////////////////////////////////////
   //
   // create the sky box,
   system.AddModel (new SkyBox ());


   // create the the floor graphic objects
   dVector floorSize (100.0f, 2.0f, 100.0f);
   dMatrix location (GetIdentityMatrix());
   location.m_posit.m_y = -5.0f;

   // create a box for floor
   floorCollision = NewtonCreateBox (world, floorSize.m_x, floorSize.m_y, floorSize.m_z, 0, NULL);

   //   meshInstance = OGLMesh::MakeBox (world, size.m_x, size.m_y, size.m_z, "GrassAndDirt.tga");
   meshInstance = new OGLMesh (floorCollision, "GrassAndDirt.tga", "metal_30.tga", "metal_30.tga");
   floor = new RenderPrimitive (location, meshInstance);
   system.AddModel (floor);
   meshInstance->Release();

   // create the the floor collision, and body with default values
   floorBody = NewtonCreateBody (world, floorCollision);
   NewtonReleaseCollision (world, floorCollision);


   // set the transformation for this rigid body
   NewtonBodySetMatrix (floorBody, &location[0][0]);

   // save the pointer to the graphic object with the body.
   NewtonBodySetUserData (floorBody, floor);

   // set a destructor for this rigid body
   NewtonBodySetDestructorCallback (floorBody, PhysicsBodyDestructor);


   // get the default material ID
   int defaultID;
   defaultID = NewtonMaterialGetDefaultGroupID (world);

   // set default material properties
   NewtonMaterialSetDefaultSoftness (world, defaultID, defaultID, 0.05f);
   NewtonMaterialSetDefaultElasticity (world, defaultID, defaultID, 0.4f);
   NewtonMaterialSetDefaultCollidable (world, defaultID, defaultID, 1);
   NewtonMaterialSetDefaultFriction (world, defaultID, defaultID, 1.0f, 0.5f);
   NewtonMaterialSetCollisionCallback (world, defaultID, defaultID, NULL, NULL, GenericContactProcess);

//   NewtonMaterialSetSurfaceThickness(world, materialID, materialID, 0.1f);
   NewtonMaterialSetSurfaceThickness(world, defaultID, defaultID, 0.0f);

   // set the island update callback
   NewtonSetIslandUpdateEvent (world, PhysicsIslandUpdate);

   // save the callback
   SetDemoCallbacks (system);

   InitEyePoint (dVector (1.0f, 0.0f, 0.0f), dVector (-40.0f, 10.0f, 0.0f));
}

// Cannos - apply higher gravity
void applyHighGravityCB(const NewtonBody* body, float timestep, int threadIndex)
{
   dFloat Ixx;
   dFloat Iyy;
   dFloat Izz;
   dFloat mass;

   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
   dVector force (0.0f, -mass * 100.0f, 0.0f);
   NewtonBodySetForce (body, &force.m_x);
}


void Friction (SceneManager& system)
{
   int zCount;
   int defaultMaterialID;
   dFloat spacing;
   NewtonWorld* world;
   NewtonBody* body;

   world = system.m_world;

   // create the sky box and the floor,
   BuildFloorAndSceneRoot (system);

   defaultMaterialID = NewtonMaterialGetDefaultGroupID (system.m_world);
    // Cannos - don't override friction, just use defaults
   //NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, NULL, NULL, UserContactFriction);

   // create a friction Ramp
   dVector location (cameraEyepoint + cameraDir.Scale (40.0f));
    // Cannos - pitch slightly less (was 20 degrees)
   dMatrix matrix (dPitchMatrix (11.0f * 3.141592f / 180.0f));
   matrix.m_posit = location;
   matrix.m_posit.m_x -= 5.0f;
   matrix.m_posit.m_y -= 12.0f;
   matrix.m_posit.m_z -= 20.0f;
   dVector size (40.0f, 0.2f, 40.0f, 0.0f);
   body = CreateGenericSolid (system.m_world, &system, 0, matrix, size, _BOX_PRIMITIVE, defaultMaterialID);

   OGLMesh* geo;
   RenderPrimitive* node;
   node = (RenderPrimitive*) NewtonBodyGetUserData (body);
   geo = new OGLMesh(NewtonBodyGetCollision (body), "metal_30.tga", "metal_30.tga", "metal_30.tga");
   node->SetMesh (geo);
   geo->Release();

    // Cannos - don't create the random shapes, just the chamfer cylinder below
   zCount = 0;
   spacing = 2.0f;
   dVector origin (matrix.m_posit);
   origin.m_z -= 10.0f;

   // create
   for (int i = 0; i < zCount; i ++) {
      dFloat z;
      dFloat x;
      dFloat mass;
      dVector size (1.0f, 0.5f, 2.0f, 0.0f);

      z = origin.m_z;
      x = origin.m_x + (i - zCount / 2) * spacing;

      mass = 1.0f;
      matrix.m_posit.m_x = x;
      matrix.m_posit.m_y = FindFloor (system.m_world, x, z) + size.m_y * 0.5f;
      matrix.m_posit.m_z = z;
      
      body = CreateGenericSolid (system.m_world, &system, mass, matrix, size, _BOX_PRIMITIVE, defaultMaterialID);

      // save a coeficienet of friction in the the primitive
      RenderPrimitive* node;
      node = (RenderPrimitive*) NewtonBodyGetUserData (body);
      node->m_density = i * 0.03f;
   }

    // Cannos -  Create chamfer cylinder with higher gravity callback
   dVector cylSize (5.0f, 1.0f, 0.0f, 0.0f);
    float angle = 0.5f;
    dVector front(sinf(angle), cosf(angle), 0.0f);
    dVector right(0.0f, 0.0f, 1.0f);
    dVector up = front * right;
    dMatrix cylMtx(front, up, right, dVector(-20.0f, 1.0f, -7.0f));
    body = CreateGenericSolid(system.m_world, &system, 1.0f, cylMtx, cylSize, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID);
    NewtonBodySetForceAndTorqueCallback(body, applyHighGravityCB);

   InitEyePoint (dVector (1.0f, 0.0f, 0.0f), dVector (-70.0f, 10.0f, 0.0f));   
}
Cannos
 
Posts: 129
Joined: Thu Mar 04, 2010 5:41 pm

Re: High gravity stability

Postby Julio Jerez » Wed Mar 10, 2010 3:23 pm

round shape in theory do never come to rest.
increasing the Gravity just makes that the rest treshohold is never low enoght to make teh shape at rest.

do you need to have a 10 time strongett than eath gravity.
That is going to cause a whole lot of problems in othe areas too.

a body travelling two secund in free fall with normal gravity will move
h = 0.5 * 10 * 2 * 2 = 20 meter
if the gravity is 100 then it moves
h = 0.5 * 100 * 2 * 2 = 200 meters
that very hard to controll.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: High gravity stability

Postby Cannos » Wed Mar 10, 2010 3:53 pm

Well, maybe my whole world is too large, but without increasing gravity significantly my simulation looks like its in slow motion. I'll try making the world and gravity both smaller. Does that make sense?

The other approach I'm considering is adding a suspension to the chamfer cylinder like a raycast vehicle. It won't be making direct contact with the ground meaning I'll have to simulate frictional forces myself, but it will stabilize on an uneven surface.
Cannos
 
Posts: 129
Joined: Thu Mar 04, 2010 5:41 pm

Re: High gravity stability

Postby Julio Jerez » Wed Mar 10, 2010 5:01 pm

what are you doing?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: High gravity stability

Postby Stucuk » Wed Mar 10, 2010 5:13 pm

You should make the objects you sent to Newton use a realistic scale (Scale down everything you send) and then scale up the matrix's Newton gives you. So your Rendering Side will render at unrealistic sizes, but the newton side would have the world at a realistic size. That way newton should react realistically and you don't need to change your renderer's scale.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: High gravity stability

Postby Cannos » Wed Mar 10, 2010 5:20 pm

The goal is just to push a somewhat cylindrically shaped object across a surface that is mostly flat, but could contain some bumps or ramps. I use a chamfer cylinder so that it will smoothly push up a ramp instead of colliding and tumbling like a box or cylinder might do.

I ended up scaling my world down by 0.1 and setting gravity back to normal (-10). The effect is the same and appears that it comes to rest much more quickly! [Edit - I only scaled the physics world, not the rendering, just as you suggested Stucuk]

So here's my next question. Are there any guidelines for good ranges of gravity or object size? My gravity is now standard -10 and my cylinder has a radius of 0.5, but I may want to increase gravity slightly or make the cylinder smaller to give a larger sense of speed. I know somewhere floating point precision will start to be an issue with the simulation, but I want to see if there's a generally accepted minimum size for rigid bodies. Thank you for the help!
Cannos
 
Posts: 129
Joined: Thu Mar 04, 2010 5:41 pm

Re: High gravity stability

Postby Stucuk » Wed Mar 10, 2010 6:45 pm

Cannos wrote:[Edit - I only scaled the physics world, not the rendering, just as you suggested Stucuk]


I never stated you should change the rendering, just to scale down anything that goes to Newton and scale up anything that comes out of Newton(I.E The Matrix's it gives you for the position of objects). Newton works best when 1 Unit = 1 Meter (At least when using realistic values for gravity etc).
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: High gravity stability

Postby Cannos » Wed Mar 10, 2010 7:06 pm

Sorry, bad grammar on my part. What I meant was that I did exactly as you suggested. I kept the rendering the same and only scaled the physics world. Sorry for the confusion.
Cannos
 
Posts: 129
Joined: Thu Mar 04, 2010 5:41 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 0 guests