...
Each body comes with a reference frame in which the body is fixed. This reference frame has an orientation and a position, or equivalently, an origin. Now, as modelers, we know where the mass center of each body is, independent of any reference frames. However, the setMassCenter() function requires that, when we communicate the mass center to OpenSim, we express the mass center location from the body's origin, and in the basis (orientation) of the reference frame. In doing so, we actually define the reference frame (that is, its origin and orientation in the body). The mass center is fixed regardless of how OpenSim internally represents it; it is the definition of the reference frame that we can varyis at our discretion when we use setMassCenter(). We could specify the mass center to be (0, 0, 0); : this would just mean that the origin of the body's frame is at its mass center; it would not affect the inertial properties on its own. What it doesaffect is how we subsequently express the position and orientation of joints and display geometry in the body's frame (which, again, we defined at our discretion).
So, below, we provide different values to setMassCenter()for the 2 bodies, despite the fact that they have same mass center (that is, the same distribution of mass). What does differ between the 2 bodies is the location of their origin. (Note: We've presented one perspective of the situation. An alternative perspective is that we, the modelers, are given a frame, and must place our body in this frame. We can choose where we place the body in this frame, and we do so via the values we give to setMassCenter() and setIinertia().)
Code Block |
---|
// Prepare inertia properties for the 2 primary segments of the cat. double segmentalAxialMomentOfInertia = JIratio * segmentalTransverseMomentOfInertia; double Ixx = segmentalAxialMomentOfInertia; double Iyy = segmentalTransverseMomentOfInertia; double Izz = segmentalTransverseMomentOfInertia; double Ixy = 0; double Ixz = 0; double Iyz = 0; using SimTK::Inertia; Inertia segmentalInertia = Inertia(Ixx, Iyy, Izz, Ixz, Ixz, Iyz); // Anterior half of cat. using OpenSim::Body; Body * anteriorBody = new Body(); anteriorBody->setName("anteriorBody"); anteriorBody->setMass(segmentalMass); // By choosing the following as the mass center, we choose the origin of // the anteriorBody frame to be at the body's positive-X extent. That is, // the anterior body sits to the -X direction from its origin. anteriorBody->setMassCenter(Vec3(-0.5 * segmentalLength, 0, 0)); anteriorBody->setInertia(segmentalInertia); // Posterior half of cat (same mass properties as anterior half). Body * posteriorBody = new Body(); posteriorBody->setName("posteriorBody"); posteriorBody->setMass(segmentalMass); // Posterior body sits to the +X direction from its origin. posteriorBody->setMassCenter(Vec3(0.5 * segmentalLength, 0, 0)); posteriorBody->setInertia(segmentalInertia); |
...