[ODE] Re: Combining inertias

Adam Rotaru adam_rotaru at yahoo.com
Mon Feb 18 11:03:01 2002


  Hi,
    
  I revisited a mail about adding masses from the
December archives.  
Russ rcommended the dMassAdd() function, saying that
it basically
adds the inertia matrices and computes the new CM.
Gregor Veble replied:

> [...] 
> Then indeed the matrix elements of inertias (be sure
that they are
> defined in the same frame of reference) must be
added, however, additional
> contributions come from the masses themselves; for
the matrix element J_ij
> of the total inertia each mass m_k contributes an
additional 
> 
> m_k * (r_k - R)_i * (r_k - R)_j, 
> 
> where (r_k - R)_i are the components of the vector
from the center of mass
> of the total joint body as calculated before to the
center of mass of the
> k-th body.
>
> If I am wrong, someone jump in and save me :)


I got confused by this, cause both explanations seemed
right.
I think I figured it out: the dMass structure always
stores
the inertia matrix relative to the reference point of
the body,
and not its local CM.  Therefore, when you use
dMassTranslate,
that will modify the inertia matrix, and add the
component mentioned
by Gregor. So everybody is right.  Am I?


Below is a simple test program.
cheers,
  --adam

#include <stdio.h>
#include <stdlib.h>
#include <ode/ode.h>

#ifdef MSVC
#pragma warning(disable:4244 4305)  // for VC++, no
precision loss complaints
#endif


void printMass(struct dMass & dmass)
{
  printf("  mass=%g  center=(%g %g %g)\n", dmass.mass,
    dmass.c[0], dmass.c[1], dmass.c[2]);
  printf("  I=(");
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) printf("%g ",
dmass.I[i*4+j]);
  printf(")\n");
}


int main(int argc, char **argv)
{
  //dWorldID world;
  //dBodyID body;
  dMass dmass0;
  dMass dmass1;
  dMass dmass2;

  //world = dWorldCreate();
  //body = dBodyCreate(world);
  //dBodySetPosition(body, 0, 0, 0.5);

  float mass = 0.5f;
  float side = 0.2f;

  printf("First create a block of mass %g, sides (%g
%g %g):\n", 2.0*mass,
    side, side, 2.0*side);
  dMassSetBox(&dmass0, 1.0, side, side, 2.0*side);
  dMassAdjust(&dmass0, 2.0*mass);
  printMass(dmass0);

  printf("Then create the same block by putting two
halves together:\n");
  printf("Create a cube of mass %g, side %g:\n", mass,
side);
  dMassSetBox(&dmass1, 1.0, side, side, side);
  dMassAdjust(&dmass1, mass);
  printMass(dmass1);

  printf("Translate it by (0 0 %g):\n", 0.5*side);
  dMassTranslate(&dmass1, 0, 0, 0.5*side);
  printMass(dmass1);

  printf("Create a cube of mass %g, side %g:\n", mass,
side);
  dMassSetBox(&dmass2, 1.0, side, side, side);
  dMassAdjust(&dmass2, mass);
  //printMass(dmass2);

  printf("Translate it by (0 0 %g):\n", -0.5*side);
  dMassTranslate(&dmass2, 0, 0, -0.5*side);
  printMass(dmass2);

  printf("Add the two:\n");
  dMassAdd(&dmass1, &dmass2);
  printMass(dmass1);

  //dBodySetMass(body, &dmass1);

  //dWorldDestroy(world);

  return 0;
}




__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com