def calc_properties(self): """Calculates the segment's center of mass with respect to the bottm center of the pelvis (Ls0) and the segment's inertia in the global frame but about the segment's center of mass. """ # center of mass self._center_of_mass = self.pos + self.rot_mat * self.rel_center_of_mass # inertia in frame f w.r.t. segment's COM self._inertia = inertia.rotate_inertia(self.rot_mat, self.rel_inertia)
def calc_properties(self): """Sets the center of mass and inertia of the solid, both with respect to the fixed human frame. """ try: try: # Here is v_a = R * v_b, where A is global frame and B is # rotated frame relative to A. self._center_of_mass = (self.pos + self._rot_mat * self.rel_center_of_mass) except AttributeError as err: err.message = err.message + \ '. You must set the orientation before attempting ' + \ 'to calculate the properties.' raise except AttributeError as e: print(e.message) self._inertia = inertia.rotate_inertia(self._rot_mat, self.rel_inertia)
def calc_rel_properties(self): """Calculates mass, relative center of mass, and relative/local inertia, according to formulae in Appendix B of Yeadon 1990-ii. If the stadium solid is arranged anteroposteriorly, the inertia is rotated by pi/2 about the z axis. """ # There are two cases of stadium solid degeneracy to consider: # t0 = 0, and t0 = t1 = 0. The degeneracy arises when b has a # denominator of 0. The case that t1 = 0 is not an issue, then. # The way the case of t0 = 0 is handled is by switching the two stadia. # Note that thi affects how the relative center of mass is set, but # does not affect the mass or moments of inertia calculations. # The case in which t0 = t1 = 0, we set b to 1. That is because t = t0 # (1 + bz) is going to be zero anyway, since t0 = 0. D = self.density h = self.height if self.degenerate_by_t0: # Swap the stadia. r0 = self.stads[1].radius t0 = self.stads[1].thickness r1 = self.stads[0].radius t1 = self.stads[0].thickness else: r0 = self.stads[0].radius t0 = self.stads[0].thickness r1 = self.stads[1].radius t1 = self.stads[1].thickness a = (r1 - r0) / r0 if t0 == 0: # Truncated cone, since both thicknesses are zero. # b can be anything, because t = t0(1 + bz) = (0)(1 + bz) = 0. b = 1 else: b = (t1 - t0) / t0 self._mass = D * h * r0 * (4.0 * t0 * self._F1(a,b) + np.pi * r0 * self._F1(a,a)) zcom = D * (h**2.0) * (4.0 * r0 * t0 * self._F2(a,b) + np.pi * (r0**2.0) * self._F2(a,a)) / self.mass if self.degenerate_by_t0 and t0 != 0: # We swapped the stadia, and it's not a truncated cone. # Must define this intermediate because zcom above is still what # must be used for the parallel axis theorem below. adjusted_zcom = h - zcom else: adjusted_zcom = zcom self._rel_center_of_mass = np.array([[0.0],[0.0],[adjusted_zcom]]) # moments of inertia Izcom = D * h * (4.0 * r0 * (t0**3.0) * self._F4(a,b) / 3.0 + np.pi * (r0**2.0) * (t0**2.0) * self._F5(a,b) + 4.0 * (r0**3.0) * t0 * self._F4(b,a) + np.pi * (r0**4.0) * self._F4(a,a) * 0.5 ) # CAUGHT AN (minor) ERROR IN YEADON'S PAPER HERE. The Dh^3 in the # formula below is missing from the second formula for Iy^0 on page 73 # of Yeadon1990-ii. Iy = (D * h * (4.0 * r0 * (t0**3.0) * self._F4(a,b) / 3.0 + np.pi * (r0**2.0) * (t0**2.0) * self._F5(a,b) + 8.0 * (r0**3.0) * t0*self._F4(b,a) / 3.0 + np.pi * (r0**4.0) * self._F4(a,a) * 0.25) + D * (h**3.0) * (4.0 * r0 * t0 * self._F3(a,b) + np.pi * (r0**2.0) * self._F3(a,a))) Iycom = Iy - self.mass * (zcom**2.0) Ix = (D * h * (4.0 * r0 * (t0**3.0) * self._F4(a,b) / 3.0 + np.pi * (r0**4.0) * self._F4(a,a) * 0.25) + D * (h**3.0) * (4.0 * r0 * t0 * self._F3(a,b) + np.pi * (r0**2.0) * self._F3(a,a))) Ixcom = Ix - self.mass*(zcom**2.0) self._rel_inertia = np.mat([[Ixcom,0.0,0.0], [0.0,Iycom,0.0], [0.0,0.0,Izcom]]) if self.alignment == 'AP': # rearrange to anterorposterior orientation self._rel_inertia = inertia.rotate_inertia( inertia.rotate_space_123([0, 0, np.pi/2]), self.rel_inertia)