friction

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

friction

Postby freevryheid » Mon Mar 30, 2009 1:02 pm

Hey guys

I have a few questions based on the code below. It was compiled using freeglut on win32 with mingw32 but it should compile with glut and gcc under linux.

I suspect from the code below that the position vectors are incorrect since the force sphere doesn't only rotate about the y-axis as you'll see if you run it. I've varied the friction coefficients but can't get the spheres to rotate. Any suggestions? Lastly, how difficult would it be to model a cylindrical container instead of using four walls as shown.

Thanks

Code: Select all
// compile using:
//gcc -o isaac.exe isaac.c -lopengl32 -lglu32 -lfreeglut -lNewton

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gl/glut.h>
#include <Newton/Newton.h>

#define NUMSPHERES 5

static NewtonWorld* nWorld;
static NewtonBody* sphBody[NUMSPHERES];
static NewtonBody* floorBody;
static NewtonBody* wall1Body;
static NewtonBody* wall2Body;
static NewtonBody* wall3Body;
static NewtonBody* wall4Body;

int showaxis=1;
int showcont=1;
int fullscreen=0;
int showfps=1;

int w=640, h=480;
float fps = 10.0;
float timeStep=0.010; //fps/1000

// sphere
float sphRadius = 0.5f;
float sphMass = 1.0f;

// floor
float fwidth = 500.0f;
float fheight = 2.0f;   
float fypos = -1.0;

// walls
float width = 1.0f; // 2*sphRadius
float cwidth = 2.0f; //2.0f*width
float cheight = 6.0f;
float wypos = 0.0;


float gravity = -9.81f;

GLuint axis;
GLuint cont;

GLUquadric *sphere;
   
void initTex(void)
{
  GLuint i;
  GLboolean flag;
  GLubyte data[256]; /* texture map data */

  flag = GL_FALSE;
 
  /* generate chessboard image */
  for (i = 0; i < 64; i++)
    {
      if (!(i % 8))
   flag = !flag;
     
      if (flag) /* square is red */
   {
     data[4 * i ] = 255;
     data[4 * i+ 1] = 0;
     data[4 * i + 2] = 0;
     data[4 * i + 3] = 255;
   }
      else     /* square is white */
   {
     data[4 * i ] = 255;
     data[4 * i+ 1] = 255;
     data[4 * i + 2] = 255;
     data[4 * i + 3] = 255;
   }
     
      flag = !flag;
    }
 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGBA, 8, 8, GL_RGBA, GL_UNSIGNED_BYTE, data);
}

void FPS(void)
{
   static int frame,tb;
   int ttime;
   char s[30];
   frame++;
   ttime=glutGet(GLUT_ELAPSED_TIME);
   if (ttime - tb > 1000)
   {
      sprintf(s,"FPS: %4.2f",frame*1000.0/(ttime-tb));
      if (showfps) printf("%s\n",s);
      tb = ttime;      
      frame = 0;
   }
}

void reshape(w, h)
{
   if (h<=0) h=1;
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0f, (GLfloat)w/h, 1,1000);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(5,5,4,0,1,0,0,1,0);
}

void clrDisplay(void)
{
   glClearColor(0.0,0.0,0.0,1.0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void drawContainer()
{
   glColor3f(1, 1, 0);
   glPushMatrix();
   //base
   glBegin(GL_LINE_LOOP);
      glVertex3f(-width,0,width);
      glVertex3f( width,0,width);
      glVertex3f( width,0,-width);
      glVertex3f(-width,0,-width);
   glEnd();
   //top
   glBegin(GL_LINE_LOOP);
      glVertex3f(-width,cheight*width,width);
      glVertex3f( width,cheight*width,width);
      glVertex3f( width,cheight*width,-width);
      glVertex3f(-width,cheight*width,-width);
   glEnd();
   //corner 1
   glBegin(GL_LINES);
      glVertex3f(-width,0,width);
      glVertex3f(-width,cheight*width,width);
   glEnd();
   //corner 2
   glBegin(GL_LINES);
      glVertex3f(width,0,width);
      glVertex3f(width,cheight*width,width);
   glEnd();
   //corner 3
   glBegin(GL_LINES);
      glVertex3f(-width,0,-width);
      glVertex3f(-width,cheight*width,-width);
   glEnd();
   //corner 4
   glBegin(GL_LINES);
      glVertex3f(width,0,-width);
      glVertex3f(width,cheight*width,-width);
   glEnd();
   glPopMatrix();
}


void drawAxis(void)
{
   glPushMatrix();
   glColor3f(1, 0, 0);
   glBegin(GL_LINES);
      glVertex3f(0, 0, 0);
      glVertex3f(10, 0, 0);
   glEnd();
   glColor3f(0, 1, 0);
   glBegin(GL_LINES);
      glVertex3f(0, 0, 0);
      glVertex3f(0, 10, 0);
   glEnd();
   glColor3f(0, 0, 1);
   glBegin(GL_LINES);
      glVertex3f(0, 0, 0);
      glVertex3f(0, 0, 10);
   glEnd();
   glPopMatrix();
}

void showSpheres(void)
{
   int i,j;
   dFloat location[4][4];
   glColor3f(1.0f,1.0f,1.0f);
   glEnable(GL_TEXTURE_2D);
   for (i=0;i<NUMSPHERES;i++)
   {
      glPushMatrix();
      NewtonBodyGetMatrix(sphBody[i], &location[0][0]);
      glMultMatrixf(&location[0][0]);
      gluSphere(sphere,sphRadius,12,12);
      glPopMatrix();
   }
   glDisable(GL_TEXTURE_2D);
}   

void display(void)
{
   clrDisplay();

   if (!glIsList(axis))
   {
      axis = glGenLists(1);
      glNewList(axis, GL_COMPILE);
         drawAxis();
      glEndList();   
   }

   if (!glIsList(cont))
   {
      cont = glGenLists(1);
      glNewList(cont, GL_COMPILE);
         drawContainer();
      glEndList();   
   }

   showSpheres();
   if (showfps) FPS();
   if (showaxis) glCallList(axis);
   if (showcont) glCallList(cont);

   glutSwapBuffers();
}

void idleFunc(void)
{
   glutPostRedisplay();   
}

void timerFunc(int val)
{

   if (val)
   {
      NewtonUpdate(nWorld, timeStep);
      idleFunc();
      glutTimerFunc(fps,timerFunc,1);
   }
}

void keyboard(unsigned char key, int x, int y)
{
   if (key == 27)
   {
      glutLeaveMainLoop();
   }
   else if (key == 'a')
   {
      showaxis=!showaxis;
   }
   else if (key == 'c')
   {
      showcont=!showcont;
   }
   else if (key == 'p')
   {
      showfps=!showfps;
   }
   else if (key == 'f')
   {
      fullscreen=!fullscreen;
      if (fullscreen)
      {
         glutFullScreen();
      }
      else
      {
         glutReshapeWindow(w,h);
         glutPositionWindow(0,0);
      }
      printf("fullscreen %d\n",fullscreen);
   }
}

void* PhysicsAlloc (int sizeInBytes)
{
   return malloc (sizeInBytes);
}
 
void PhysicsFree (void *ptr, int sizeInBytes)
{
   free (ptr);
}
 
void cleanUp (void)
{
   NewtonDestroy (nWorld);
}
 
void sphPhysicsApplyForceAndTorque (const NewtonBody* body)
{
   dFloat mass;
   dFloat Ixx;
   dFloat Iyy;
   dFloat Izz;
   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
   dFloat force[3]={0.0f, mass*gravity, 0.0f};
   //dFloat torque[3]={1.0f, 0.0f, 0.0f};
   NewtonBodySetForce (body, &force[0]);
   //NewtonBodySetTorque (body, &torque[0]);
}

void driverPhysicsApplyForceAndTorque (const NewtonBody* body)
{
   dFloat mass;
   dFloat Ixx;
   dFloat Iyy;
   dFloat Izz;
   NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
   dFloat force[3]={0.0f, 100.0*mass*gravity, 0.0f};
   dFloat torque[3]={0.0f, 100.0f, 0.0f};
   NewtonBodySetForce (body, &force[0]);
   NewtonBodySetTorque (body, &torque[0]);
}

void setLoc(dFloat a[4][4],dFloat b[4][4])
{
   int i,j;
   
   for (i=0;i<4;i++)
   {
      for (j=0;j<4;j++)
      {
         b[i][j]=a[i][j];
      }
   }   
}

void initNewton(void)
{
   int i=0;
   float sphI = (2.0/5.0)*sphMass*sphRadius*sphRadius;
   dFloat sphForce[3]={0.0f,sphMass*gravity,0.0f};
   //dFloat sphTorque[3]={1.0f,0.0f,0.0f};
   dFloat x=0,y=0,z=0;
   
   dFloat sx[5] = {-0.5, 0.5, 0.5,-0.5, 0.0};
   dFloat sy[5] = { 1.5, 1.5, 1.5, 1.5, 2.0};
   dFloat sz[5] = { 0.5, 0.5,-0.5,-0.5, 0.0};
   
   dFloat location0[4][4] = {{1.0,0.0,0.0,0.0},
                       {0.0,1.0,0.0,0.0},
                       {0.0,0.0,1.0,0.0},
                       {0.0,0.0,0.0,1.0}};

   dFloat location[4][4];
                  
   printf("NPE Version: %d\n",NewtonWorldGetVersion(nWorld));
   NewtonCollision *collision;
   nWorld = NewtonCreate (PhysicsAlloc, PhysicsFree);
   
   ///////////////////////////////////////////////////// spheres
   // create spheres
   for (i = 0;i<NUMSPHERES;i++)
   {
      collision = NewtonCreateSphere (nWorld, sphRadius, sphRadius, sphRadius, NULL);
      sphBody[i] = NewtonCreateBody (nWorld, collision);
      if (i<4)
      {
         NewtonBodySetForceAndTorqueCallback (sphBody[i], sphPhysicsApplyForceAndTorque);
      }
      else
      {
         NewtonBodySetForceAndTorqueCallback (sphBody[i], driverPhysicsApplyForceAndTorque);
      }
      NewtonBodySetMassMatrix (sphBody[i], sphMass, sphI, sphI, sphI);
      NewtonBodySetForce (sphBody[i], &sphForce[0]);
      setLoc(location0,location);
      x=sx[i];
      y=sy[i];
      z=sz[i];
      location[3][0]=x;
      location[3][1]=y;
      location[3][2]=z;
      NewtonBodySetMatrix (sphBody[i], &location[0][0]);
   }

   ///////////////////////////////////////////////////// floor
   // create the floor
   collision = NewtonCreateBox (nWorld, fwidth, fheight, fwidth, NULL);
   floorBody = NewtonCreateBody (nWorld, collision);
   setLoc(location0,location);
   x =  0.0f;
   y = fypos;
   z =  0.0f;
   location[3][0]=x;
   location[3][1]=y;
   location[3][2]=z;
   NewtonBodySetMatrix (floorBody, &location[0][0]);
 
   ///////////////////////////////////////////////////// wall 1
   // create wall 1
   collision = NewtonCreateBox (nWorld, cwidth, cheight, cwidth, NULL);
   wall1Body = NewtonCreateBody (nWorld, collision);
   setLoc(location0,location);
   x =  2.0f;
   y =  wypos;
   z =  0.0f;
   location[3][0]=x;
   location[3][1]=y;
   location[3][2]=z;
   NewtonBodySetMatrix (wall1Body, &location[0][0]);
   
   ///////////////////////////////////////////////////// wall 2
   // create wall 2
   collision = NewtonCreateBox (nWorld, cwidth, cheight, cwidth, NULL);
   wall2Body = NewtonCreateBody (nWorld, collision);
   setLoc(location0,location);
   x =  0.0f;
   y =  wypos;
   z = -2.0f;
   location[3][0]=x;
   location[3][1]=y;
   location[3][2]=z;
   NewtonBodySetMatrix (wall2Body, &location[0][0]);

   ///////////////////////////////////////////////////// wall 3
   // create wall 3
   collision = NewtonCreateBox (nWorld, cwidth, cheight, cwidth, NULL);
   wall3Body = NewtonCreateBody (nWorld, collision);
   setLoc(location0,location);
   x = -2.0f;
   y =  wypos;
   z =  0.0f;
   location[3][0]=x;
   location[3][1]=y;
   location[3][2]=z;
   NewtonBodySetMatrix (wall3Body, &location[0][0]);
   
   ///////////////////////////////////////////////////// wall 4
   // create wall 4
   collision = NewtonCreateBox (nWorld, cwidth, cheight, cwidth, NULL);
   wall4Body = NewtonCreateBody (nWorld, collision);
   setLoc(location0,location);
   x =  0.0f;
   y =  wypos;
   z =  2.0f;
   location[3][0]=x;
   location[3][1]=y;
   location[3][2]=z;
   NewtonBodySetMatrix (wall4Body, &location[0][0]);

   // Release collision
   NewtonReleaseCollision (nWorld, collision);

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

   // Set default material properties
   //NewtonMaterialSetDefaultSoftness (nWorld, defaultID, defaultID, 0.05f);
   //NewtonMaterialSetDefaultElasticity (nWorld, defaultID, defaultID, 0.4f);
   //NewtonMaterialSetDefaultCollidable (nWorld, defaultID, defaultID, 1);
   NewtonMaterialSetDefaultFriction (nWorld, defaultID, defaultID, 1.9f, 1.09f);
   
}

void initGL(void)
{
   glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
   glutInitWindowSize(w,h);
   glutInitWindowPosition(0,0); 
   glutCreateWindow("Amit's demo - Press ESC to exit");
   
   glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
   
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutIdleFunc(idleFunc);
   glutTimerFunc(0, timerFunc, 1);

   sphere=gluNewQuadric();
   gluQuadricTexture(sphere,1);
   initTex();
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   initNewton();
   initGL();
   glutMainLoop();
   cleanUp();
   return 0;
}


freevryheid
 
Posts: 7
Joined: Sat Oct 25, 2008 9:22 pm

Re: friction

Postby freevryheid » Mon Mar 30, 2009 1:37 pm

I can now get the spheres to spin by changing the default friction:

Code: Select all
NewtonMaterialSetDefaultFriction (nWorld, defaultID, defaultID, 0.1f, 0.09f);


but the spin is all weird.
freevryheid
 
Posts: 7
Joined: Sat Oct 25, 2008 9:22 pm

Re: friction

Postby Julio Jerez » Mon Mar 30, 2009 3:06 pm

whay do you mean teh spin is wierd?
you are aplying a fix torque that will tend to spin the ball along a vetical axis,
that in combination with frintion will produce spin that can not be predited by intuition?

is this 2.0, can you sopwu a video?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: friction

Postby freevryheid » Wed Apr 01, 2009 8:35 am

I'm using the 1.53 version.

Here's a video of the spin:

http://freevryheid.x10hosting.com/spin.wmv

Also, any suggestions regarding the cylindrical container?
freevryheid
 
Posts: 7
Joined: Sat Oct 25, 2008 9:22 pm

Re: friction

Postby Julio Jerez » Wed Apr 01, 2009 9:45 am

-you should use 2.0,
-the spin looks correct to me you are applying a perpetual torque to the all the spheres, therefore it is upredictable to guess how it should spin.
I do not now what you mean by cilindrical container?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 12 guests

cron