예제 #1
1
    def test_rotate_inertia(self):
        """Are we obtaining the global inertia properly?"""

        # Create parameters.
        label = "seg1"
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # This inertia matrix describes two 1kg point masses at (0, 2, 1) and
        # (0, -2, -1) in the global reference frame, A.
        seg1._rel_inertia = mat([[10.0, 0.0, 0.0], [0.0, 2.0, -4.0], [0.0, -4.0, 8.0]])

        # If we want the inertia about a new reference frame, B, such that the
        # two masses lie on the yb axis we can rotate about xa through the angle
        # arctan(1/2). Note that this function returns R from va = R * vb.
        seg1._rot_mat = inertia.rotate_space_123((arctan(1.0 / 2.0), 0.0, 0.0))

        seg1.calc_properties()

        I_b = seg1.inertia

        expected_I_b = mat([[10.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 10.0]])

        testing.assert_allclose(I_b, expected_I_b)
예제 #2
0
    def test_rotate_inertia(self):
        """Are we obtaining the global inertia properly?"""

        # Create parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # This inertia matrix describes two 1kg point masses at (0, 2, 1) and
        # (0, -2, -1) in the global reference frame, A.
        seg1._rel_inertia = mat([[10.0, 0.0, 0.0], [0.0, 2.0, -4.0],
                                 [0.0, -4.0, 8.0]])

        # If we want the inertia about a new reference frame, B, such that the
        # two masses lie on the yb axis we can rotate about xa through the angle
        # arctan(1/2). Note that this function returns R from va = R * vb.
        seg1._rot_mat = inertia.rotate_space_123((arctan(1.0 / 2.0), 0.0, 0.0))

        seg1.calc_properties()

        I_b = seg1.inertia

        expected_I_b = mat([[10.0, 0.0, 0.0], [0.0, 0.0, 0.0],
                            [0.0, 0.0, 10.0]])

        testing.assert_allclose(I_b, expected_I_b)
예제 #3
0
    def test_print_properties(self):
        """Ensures the proper printing of segment mass properties. """

        # Create parameters.
        label = "seg1"
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # For capturing print.
        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()

        # Calling print_properties before calc_properties should still work.
        seg1.print_properties()
        sys.stdout = old_stdout

        des_str = open(os.path.join(os.path.split(__file__)[0], "segment_print_des.txt"), "r").read()

        self.assertEquals(mystdout.getvalue(), des_str)

        # Use the __str__method.
        # It's just a fluke that we need to append an additional newline char.
        self.assertEquals(seg1.__str__() + "\n", des_str)
예제 #4
0
def test_rotate_inertia():
    """Are we obtaining the global inertia properly?"""

    density = 1.5
    height = 4
    height_vec = array([[0], [0], [height]])

    # One thickness is 0.
    r0 = 5; t0 = 0; r1 = 2; t1 = 2;

    stad1 = Stadium('Ls1: umbilicus', 'thicknessradius', t0, r0)
    stad2 = Stadium('Lb1: mid-arm', 'thicknessradius', t1, r1)

    solidA = StadiumSolid('solid', density, stad1, stad2, height)

    # This inertia matrix describes two 1kg point masses at (0, 2, 1) and
    # (0, -2, -1) in the global reference frame, A.
    solidA._rel_inertia = mat([[10.0, 0.0, 0.0],
                             [0.0, 2.0, -4.0],
                             [0.0, -4.0, 8.0]])

    # If we want the inertia about a new reference frame, B, such that the
    # two masses lie on the yb axis we can rotate about xa through the angle
    # arctan(1/2). Note that this function returns R from va = R * vb.
    solidA._rot_mat = inertia.rotate_space_123((arctan(1.0 / 2.0), 0.0, 0.0))

    solidA.calc_properties()

    I_b = solidA.inertia

    expected_I_b = mat([[10.0, 0.0, 0.0],
                        [0.0, 0.0, 0.0],
                        [0.0, 0.0, 10.0]])

    testing.assert_allclose(I_b, expected_I_b)
예제 #5
0
    def test_print_properties(self):
        """Ensures the proper printing of segment mass properties. """

        # Create parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # For capturing print.
        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()

        # Calling print_properties before calc_properties should still work.
        seg1.print_properties()
        sys.stdout = old_stdout

        des_str = open(
            os.path.join(os.path.split(__file__)[0], 'segment_print_des.txt'),
            'r').read()

        self.assertEquals(mystdout.getvalue(), des_str)

        # Use the __str__method.
        # It's just a fluke that we need to append an additional newline char.
        self.assertEquals(seg1.__str__() + '\n', des_str)
예제 #6
0
def test_rotate_inertia():
    """Are we obtaining the global inertia properly?"""

    density = 1.5
    height = 4
    height_vec = array([[0], [0], [height]])

    # One thickness is 0.
    r0 = 5
    t0 = 0
    r1 = 2
    t1 = 2

    stad1 = Stadium('Ls1: umbilicus', 'thicknessradius', t0, r0)
    stad2 = Stadium('Lb1: mid-arm', 'thicknessradius', t1, r1)

    solidA = StadiumSolid('solid', density, stad1, stad2, height)

    # This inertia matrix describes two 1kg point masses at (0, 2, 1) and
    # (0, -2, -1) in the global reference frame, A.
    solidA._rel_inertia = mat([[10.0, 0.0, 0.0], [0.0, 2.0, -4.0],
                               [0.0, -4.0, 8.0]])

    # If we want the inertia about a new reference frame, B, such that the
    # two masses lie on the yb axis we can rotate about xa through the angle
    # arctan(1/2). Note that this function returns R from va = R * vb.
    solidA._rot_mat = inertia.rotate_space_123((arctan(1.0 / 2.0), 0.0, 0.0))

    solidA.calc_properties()

    I_b = solidA.inertia

    expected_I_b = mat([[10.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 10.0]])

    testing.assert_allclose(I_b, expected_I_b)
예제 #7
0
    def test_print_solid_properties(self):

        # Create parameters.
        label = "seg1"
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()
        seg1.print_solid_properties()
        sys.stdout = old_stdout
        desStr = open(os.path.join(os.path.split(__file__)[0], "segment_print_solid_des.txt"), "r").read()
        self.assertEquals(mystdout.getvalue(), desStr)
예제 #8
0
    def test_init_bad_input(self):
        """Ensures only proper constructor arguments get through. Exercises
        duck-typing.

        """
        # Create default parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Empty position.
        self.assertRaises(AttributeError, seg.Segment, label, [], rot, solids,
                color)
        # Non-numpy position.
        self.assertRaises(AttributeError, seg.Segment, label, [0, 0, 0], rot,
                solids, color)
        # Wrong dimensions.
        self.assertRaises(ValueError, seg.Segment, label, pos[1:2,:], rot,
                solids, color)
        # Empty rotation.
        self.assertRaises(ValueError, seg.Segment, label, pos, [], solids,
                color)
        # Wrong type rot.
        self.assertRaises(ValueError, seg.Segment, label, pos, pos, solids,
                color)
        # Wrong dimensions rot.
        self.assertRaises(ValueError, seg.Segment, label, pos, np.mat(pos),
                solids, color)
        # Empty solids.
        self.assertRaises(IndexError, seg.Segment, label, pos, rot, [], color)
        # Missing color.
        self.assertRaises(TypeError, seg.Segment, label, pos, rot, solids)

        # Test just having one solid; make sure we do not depend on a segment
        # having multiple solids.
        # Should not raise exception.
        seg1 = seg.Segment(label, pos, rot, [self.solidAB], color)

        # Objects in the solids list are not actually `Solid`'s.
        self.assertRaises(AttributeError, seg.Segment, label, pos, rot, ["1",
            "2"], color)
예제 #9
0
    def test_init_bad_input(self):
        """Ensures only proper constructor arguments get through. Exercises
        duck-typing.

        """
        # Create default parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Empty position.
        self.assertRaises(AttributeError, seg.Segment, label, [], rot, solids,
                          color)
        # Non-numpy position.
        self.assertRaises(AttributeError, seg.Segment, label, [0, 0, 0], rot,
                          solids, color)
        # Wrong dimensions.
        self.assertRaises(ValueError, seg.Segment, label, pos[1:2, :], rot,
                          solids, color)
        # Empty rotation.
        self.assertRaises(ValueError, seg.Segment, label, pos, [], solids,
                          color)
        # Wrong type rot.
        self.assertRaises(ValueError, seg.Segment, label, pos, pos, solids,
                          color)
        # Wrong dimensions rot.
        self.assertRaises(ValueError, seg.Segment, label, pos, np.mat(pos),
                          solids, color)
        # Empty solids.
        self.assertRaises(IndexError, seg.Segment, label, pos, rot, [], color)
        # Missing color.
        self.assertRaises(TypeError, seg.Segment, label, pos, rot, solids)

        # Test just having one solid; make sure we do not depend on a segment
        # having multiple solids.
        # Should not raise exception.
        seg1 = seg.Segment(label, pos, rot, [self.solidAB], color)

        # Objects in the solids list are not actually `Solid`'s.
        self.assertRaises(AttributeError, seg.Segment, label, pos, rot,
                          ["1", "2"], color)
예제 #10
0
    def test_calc_properties(self):
        """Ensures proper calculation of global-frame COM and Inertia."""

        # Create parameters.
        label = "seg1"
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)
        seg1.calc_properties()

        testing.assert_allclose(seg1.center_of_mass, np.array([[seg1.rel_center_of_mass[2, 0] + 1, 2, 3]]).T)
        desXInertia = seg1.rel_inertia[2, 2]
        desYInertia = seg1.rel_inertia[1, 1]
        desZInertia = seg1.rel_inertia[0, 0]
        desInertia = np.mat(np.diag(np.array([desXInertia, desYInertia, desZInertia])))
        testing.assert_allclose(seg1.inertia, desInertia, atol=1e-10)
예제 #11
0
    def test_print_solid_properties(self):

        # Create parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()
        seg1.print_solid_properties()
        sys.stdout = old_stdout
        desStr = open(
            os.path.join(
                os.path.split(__file__)[0], 'segment_print_solid_des.txt'),
            'r').read()
        self.assertEquals(mystdout.getvalue(), desStr)
예제 #12
0
    def test_calc_properties(self):
        """Ensures proper calculation of global-frame COM and Inertia."""

        # Create parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)
        seg1.calc_properties()

        testing.assert_allclose(
            seg1.center_of_mass,
            np.array([[seg1.rel_center_of_mass[2, 0] + 1, 2, 3]]).T)
        desXInertia = seg1.rel_inertia[2, 2]
        desYInertia = seg1.rel_inertia[1, 1]
        desZInertia = seg1.rel_inertia[0, 0]
        desInertia = np.mat(
            np.diag(np.array([desXInertia, desYInertia, desZInertia])))
        testing.assert_allclose(seg1.inertia, desInertia, atol=1e-10)
예제 #13
0
    def test_init_real_input(self):
        """Ensures the constructor for valid input makes correct calculations.

        """
        # Create parameters.
        label = "seg1"
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # Check that parameters were set.
        assert seg1.label == label
        assert (seg1.pos == pos).all()
        assert (seg1.rot_mat == rot).all()
        assert seg1.solids == solids
        assert seg1.nSolids == len(solids)
        assert seg1.color == color

        # -- Check the other constructor actions.
        # Setting orientations of all constituent solids.
        assert (seg1.solids[0].pos == pos).all()
        assert (seg1.solids[0]._rot_mat == rot).all()
        pos2 = np.array([[6], [2], [3]])
        assert (seg1.solids[0].end_pos == pos2).all()

        # 2nd solid in the segment.
        assert (seg1.solids[1].pos == pos2).all()
        assert (seg1.solids[1]._rot_mat == rot).all()
        # See definition of solids in setUp().
        pos3 = pos2 + np.array([[6], [0], [0]])
        assert (seg1.solids[1].end_pos == pos3).all()

        # 3rd solid in the segment.
        assert (seg1.solids[2].pos == pos3).all()
        assert (seg1.solids[2]._rot_mat == rot).all()
        # See definition of solids in setUp().
        pos4 = pos3 + np.array([[7], [0], [0]])
        assert (seg1.solids[2].end_pos == pos4).all()

        # Other segment-wide attributes we define.
        assert (seg1.end_pos == pos4).all()
        assert (seg1.length == (5 + 6 + 7)).all()

        # -- The constructor then calls calc_rel_properties().
        desMass = self.solidAB.mass + self.solidBC.mass + self.solidCD.mass
        testing.assert_almost_equal(seg1.mass, desMass)

        desRelCOM = (
            self.solidAB.mass * self.solidAB.rel_center_of_mass
            + self.solidBC.mass * (self.solidBC.rel_center_of_mass + np.array([[0, 0, 5]]).T)
            + self.solidCD.mass * (self.solidCD.rel_center_of_mass + np.array([[0, 0, 11]]).T)
        ) / desMass
        testing.assert_allclose(seg1.rel_center_of_mass, desRelCOM)

        # Helper definitions
        relCOM_AB = self.solidAB.rel_center_of_mass
        relCOM_BC = np.array([[0, 0, self.solidAB.height]]).T + self.solidBC.rel_center_of_mass
        relCOM_CD = np.array([[0, 0, self.solidAB.height + self.solidBC.height]]).T + self.solidCD.rel_center_of_mass

        # Inertia for each direction.
        desXInertia = (
            self.solidAB.rel_inertia[0, 0]
            + self.solidAB.mass * (relCOM_AB[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
            + self.solidBC.rel_inertia[0, 0]
            + self.solidBC.mass * (relCOM_BC[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
            + self.solidCD.rel_inertia[0, 0]
            + self.solidCD.mass * (relCOM_CD[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
        )
        desYInertia = (
            self.solidAB.rel_inertia[1, 1]
            + self.solidAB.mass * (relCOM_AB[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
            + self.solidBC.rel_inertia[1, 1]
            + self.solidBC.mass * (relCOM_BC[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
            + self.solidCD.rel_inertia[1, 1]
            + self.solidCD.mass * (relCOM_CD[2, 0] - seg1.rel_center_of_mass[2, 0]) ** 2
        )
        desZInertia = self.solidAB.rel_inertia[2, 2] + self.solidBC.rel_inertia[2, 2] + self.solidCD.rel_inertia[2, 2]
        # Combine components into array.
        desRelInertia = np.diag(np.array([desXInertia, desYInertia, desZInertia]))
        # Compare.
        testing.assert_allclose(seg1.rel_inertia, desRelInertia)
예제 #14
0
    def test_init_real_input(self):
        """Ensures the constructor for valid input makes correct calculations.

        """
        # Create parameters.
        label = 'seg1'
        pos = np.array([[1], [2], [3]])
        rot = inertia.rotate_space_123([pi / 2, pi / 2, pi / 2])
        solids = [self.solidAB, self.solidBC, self.solidCD]
        color = (1, 0, 0)

        # Create the segment.
        seg1 = seg.Segment(label, pos, rot, solids, color)

        # Check that parameters were set.
        assert seg1.label == label
        assert (seg1.pos == pos).all()
        assert (seg1.rot_mat == rot).all()
        assert seg1.solids == solids
        assert seg1.nSolids == len(solids)
        assert seg1.color == color

        # -- Check the other constructor actions.
        # Setting orientations of all constituent solids.
        assert (seg1.solids[0].pos == pos).all()
        assert (seg1.solids[0]._rot_mat == rot).all()
        pos2 = np.array([[6], [2], [3]])
        assert (seg1.solids[0].end_pos == pos2).all()

        # 2nd solid in the segment.
        assert (seg1.solids[1].pos == pos2).all()
        assert (seg1.solids[1]._rot_mat == rot).all()
        # See definition of solids in setUp().
        pos3 = pos2 + np.array([[6], [0], [0]])
        assert (seg1.solids[1].end_pos == pos3).all()

        # 3rd solid in the segment.
        assert (seg1.solids[2].pos == pos3).all()
        assert (seg1.solids[2]._rot_mat == rot).all()
        # See definition of solids in setUp().
        pos4 = pos3 + np.array([[7], [0], [0]])
        assert (seg1.solids[2].end_pos == pos4).all()

        # Other segment-wide attributes we define.
        assert (seg1.end_pos == pos4).all()
        assert (seg1.length == (5 + 6 + 7)).all()

        # -- The constructor then calls calc_rel_properties().
        desMass = self.solidAB.mass + self.solidBC.mass + self.solidCD.mass
        testing.assert_almost_equal(seg1.mass, desMass)

        desRelCOM = (
            self.solidAB.mass * self.solidAB.rel_center_of_mass +
            self.solidBC.mass *
            (self.solidBC.rel_center_of_mass + np.array([[0, 0, 5]]).T) +
            self.solidCD.mass *
            (self.solidCD.rel_center_of_mass + np.array([[0, 0, 11]]).T)
        ) / desMass
        testing.assert_allclose(seg1.rel_center_of_mass, desRelCOM)

        # Helper definitions
        relCOM_AB = self.solidAB.rel_center_of_mass
        relCOM_BC = (np.array([[0, 0, self.solidAB.height]]).T +
                     self.solidBC.rel_center_of_mass)
        relCOM_CD = (
            np.array([[0, 0, self.solidAB.height + self.solidBC.height]]).T +
            self.solidCD.rel_center_of_mass)

        # Inertia for each direction.
        desXInertia = (self.solidAB.rel_inertia[0, 0] + self.solidAB.mass *
                       (relCOM_AB[2, 0] - seg1.rel_center_of_mass[2, 0])**2 +
                       self.solidBC.rel_inertia[0, 0] + self.solidBC.mass *
                       (relCOM_BC[2, 0] - seg1.rel_center_of_mass[2, 0])**2 +
                       self.solidCD.rel_inertia[0, 0] + self.solidCD.mass *
                       (relCOM_CD[2, 0] - seg1.rel_center_of_mass[2, 0])**2)
        desYInertia = (self.solidAB.rel_inertia[1, 1] + self.solidAB.mass *
                       (relCOM_AB[2, 0] - seg1.rel_center_of_mass[2, 0])**2 +
                       self.solidBC.rel_inertia[1, 1] + self.solidBC.mass *
                       (relCOM_BC[2, 0] - seg1.rel_center_of_mass[2, 0])**2 +
                       self.solidCD.rel_inertia[1, 1] + self.solidCD.mass *
                       (relCOM_CD[2, 0] - seg1.rel_center_of_mass[2, 0])**2)
        desZInertia = (self.solidAB.rel_inertia[2, 2] +
                       self.solidBC.rel_inertia[2, 2] +
                       self.solidCD.rel_inertia[2, 2])
        # Combine components into array.
        desRelInertia = np.diag(
            np.array([desXInertia, desYInertia, desZInertia]))
        # Compare.
        testing.assert_allclose(seg1.rel_inertia, desRelInertia)