def test_solve():
    u = [0, 0, 0, 0]
    scenario = DoublePendulum(1, 1, 1, 1)
    t, theta1, omega1, theta2, omega2 = scenario.solve(u, 10, 1e-3)
    assert mean(theta1) <= 1e-6, (
        f"Mean Theta is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {theta1}")
    assert mean(omega1) <= 1e-6, (
        f"Mean Omega is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {omega1}")
    assert mean(theta2) <= 1e-6, (
        f"Mean Theta is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {theta2}")
    assert mean(omega2) <= 1e-6, (
        f"Mean Omega is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {omega2}")
    t, theta1, omega1, theta2, omega2 = scenario.solve(u, 10, 1e-3, "deg")
    assert mean(theta1) <= 1e-6, (
        f"Mean Theta is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {theta1}")
    assert mean(omega1) <= 1e-6, (
        f"Mean Omega is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {omega1}")
    assert mean(theta2) <= 1e-6, (
        f"Mean Theta is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {theta2}")
    assert mean(omega2) <= 1e-6, (
        f"Mean Omega is not zero when start values for Omega and Theta is zero"
        f", Mean Omega is {omega2}")
Exemple #2
0
def test_DoublePendulumCartesian():
	"""Checks if the cartesian coordinates are correct."""
	p = DoublePendulum(M1 = 2, L1 = 1.1, M2 = 0.5, L2 = 2.3)
	p.solve((np.pi/4, 0.1, np.pi/8, 0.2),10,0.1)
	for i in range(len(p.x1)):
		nt.assert_almost_equals(p.x1[i]**2 + p.y1[i]**2, 1.1**2)
	for i in range(len(p.x2)):
		nt.assert_almost_equals((p.x2[i] - p.x1[i])**2 + (p.y2[i] - p.y1[i])**2, 2.3**2)
def test_arrays_zero():
    '''
    test-function for checking if initial conditions y0=(0,0) yields zero-filled arrays
    '''
    a = DoublePendulum()
    a.solve((0.0, 0, 0.0, 0), 10, 1001)
    assert np.all(a.theta1 == 0) and np.all(a.theta2 == 0), \
           'initial conditions y0=(0,0) does not yield arrays with zeros'
def test_DoublePendulum_zeroes_as_y0():
    y0 = (0 ,0 ,0 , 0)
    obj = DoublePendulum()
    obj.solve(y0, 5, 0.0001)
    y = obj.y

    for i in y:
        assert all(i == 0), "all vals in y is not zero when they should be"
def test_DoublePendulum_null_mass():
    obj = DoublePendulum(M1=1e-15, M2=1e-15)
    y0 = (1 ,1 ,1 , 1)
    obj.solve(y0, 5, 1e-4)
    K = obj.kinetic
    P = obj.potential
    eps = 1e-13
    print(max(K), max(P))
    assert all(abs(K) < eps) and all(abs(P) < eps)
def test_solve():
	T = 10
	dt = 0.1
	pend = DoublePendulum()
	pend.solve([0.0, 0.0, 0.0, 0.0], T, dt, angles = "deg")
	t_act = np.linspace(0, T, int(T/dt))
	print(pend.t)
	for i in range(len(t_act)):
		nt.assert_equal(pend.theta1[i], 0.)
		nt.assert_equal(pend.theta2[i], 0.)
		nt.assert_equal(pend.t[i], t_act[i])
Exemple #7
0
def test_zeroes():
    """Test if solved values are zeroes if initial state is stationary."""
    var = DoublePendulum(2, 2, 2, 2)
    T = 5
    dt = 0.1
    var.solve((0, 0, 0, 0), T, dt)
    time = linspace(0, T, T / dt + 1)
    nt.assert_equal(time.all(), var.t.all())
    nt.assert_equal(0, var.theta1.all())
    nt.assert_equal(0, var.theta2.all())
    nt.assert_equal(0, var.omega1.all())
    nt.assert_equal(0, var.omega2.all())
def test_double_pendulum_total_energy():
    double_pendulumtest = DoublePendulum()
    theta1 = np.pi/3; theta2 = 3*np.pi/2
    omega1 = 0.15; omega2 = 0.075
    T = 40
    dt = 1e-3
    eps = 0.2
    double_pendulumtest.solve((theta1,omega1,theta2,omega2),T,dt)
    kinetic = double_pendulumtest.kinetic
    potential = double_pendulumtest.potential
    total_energy = kinetic[0] + potential[0]
    for i,j in zip(kinetic,potential):
        assert abs(i+j-total_energy) < eps
    """
Exemple #9
0
def test_double_pendulum_solve_zero():
    """Check if start in rest ((angle, angular vel) == (0,0)) returns zeros."""
    test_T = 5
    test_dt = 0.1

    test_pend = DoublePendulum(L1=5, L2=5)
    test_pend.solve((0, 0, 0, 0), test_T, test_dt)

    test_ts = np.linspace(0, test_T, test_T/test_dt)
    test_zeros = np.zeros(int(test_T/test_dt))

    np.testing.assert_array_equal(test_pend.t, test_ts)
    np.testing.assert_array_equal(test_pend.theta1, test_zeros)
    np.testing.assert_array_equal(test_pend.theta2, test_zeros)
def test_double_pendulum_initial_sol():
    double_pendulumtest = DoublePendulum()
    T = 100
    dt = 0.1
    eps = 1e-15
    t_values = np.linspace(0,T,int(T/dt))
    double_pendulumtest.solve((0,0,0,0),T,dt)
    t = double_pendulumtest.t
    theta1 = double_pendulumtest.theta1; theta2 = double_pendulumtest.theta2
    omega1 = double_pendulumtest.omega1; omega2 = double_pendulumtest.omega2
    #Tests:
    for i in range(len(t)):
        assert t[i] == t_values[i]
    for i,j,k,l in zip(theta1,omega1,theta2,omega2):
        assert abs(i) < eps
        assert abs(j) < eps
        assert abs(k) < eps
        assert abs(l) < eps
Exemple #11
0
def test_dopuble_pendulum_xy_transformation():
    """Check if motion is transformed to xy-coordinates."""
    test_T = 5
    test_dt = 0.1
    test_L1 = 2
    test_L2 = 5

    test_pend = DoublePendulum(L1=test_L1, L2=test_L2)
    test_pend.solve((pi/2, 0, pi, 0), test_T, test_dt)

    test_L1_squared = (test_pend.x1)**2 + (test_pend.y1)**2
    test_L2_squared = ((test_pend.x2 - test_pend.x1)**2
                      + (test_pend.y2 - test_pend.y1)**2)

    ex_L1_quared = test_L1**2
    ex_L2_quared = test_L2**2

    np.testing.assert_array_almost_equal(test_L1_squared, ex_L1_quared)
    np.testing.assert_array_almost_equal(test_L2_squared, ex_L2_quared)
def test_double_pendulum_angles():
    L = 2.4
    theta1 = np.pi/4; theta2 = np.pi
    omega1 = 0.2; omega2 = 0.01
    T = 50
    dt = 1e-3

    example1 = DoublePendulum(L)
    example1.solve((theta1,omega1,theta2,omega2),T,dt)
    theta1 = 45; theta2 = 180

    example2 = DoublePendulum(L)
    example2.solve((theta1,omega1,theta2,omega2),T,dt,angles = 'deg')

    kinetic1 = example1.kinetic; kinetic2 = example2.kinetic
    potential1 = example1.potential; potential2 = example2.potential

    for i,j,k,l in zip(kinetic1,potential1,kinetic2,potential2):
        assert i == k
        assert j == l
def test_properties_zeros():
    scenario = DoublePendulum(1, 1, 1, 1)
    t, theta1, omega1, theta2, omega2 = scenario.solve([0, 0, 0, 0], 10, 1e-3)
    tt = linspace(0, 10, 10004)
    zeroo = zeros(len(theta1))
    assert mean(theta1) == mean(
        zeroo), "theta1 set to zeros did not yield zeros array"
    assert mean(theta2) == mean(
        zeroo), "theta2 set to zeros did not yield zeros array"
    assert (abs(mean(t) - mean(tt)) <
            1e-2), "t was not equal to linspace(0,T,dt)"
def test_radius1():
    a = DoublePendulum()
    a.solve((0, 0.1, 3, 0.5), 10, 101)
    r2 = a.x1**2 + a.y1**2
    assert np.isclose(1**2, np.all(r2))
class Simulation:
    def __init__(self, res, fps, time, dt, scale, speed, path_depth, ag, mass,
                 length, theta, d_theta):
        self.running = False  # Simulation not started yet at this point

        # Setting simulation variables
        self.width, self.height = res
        self.fps = fps
        self.time, self.dt = time, dt
        self.points_count = self.time / self.dt
        self.scale = scale
        self.speed = speed
        self.path_depth = path_depth
        self.path = []

        # Setting variables for solve method.
        self.time_range = np.arange(0, self.time + self.dt,
                                    self.dt)  # Range of time points
        self.ag = ag  # Gravitational acceleration

        # Creating display and pendulum objects; Solving equations
        self.pendulum = DoublePendulum(mass, length, theta, d_theta)
        self.pendulum.solve(self.time_range, self.ag)
        self.display = Display(res)

    def run(self):
        """ Simulation loop. """

        # Start the simulation
        self.running = True

        i = 0  # Iterable for simulation frames
        di = int((1 / self.fps / self.dt) *
                 self.speed)  # Step size based on time density and frame rate

        # Loop
        while self.running:
            # Getting start point and all of the pendulum positions
            x_start, y_start = (int(self.width / 2), int(self.height / 3))
            x_1_scaled, y_1_scaled, x_2_scaled, y_2_scaled = self.pendulum.get_scaled_positions(
                i, self.scale)
            start_pos = (x_start, y_start)
            x_1_pos = (x_start + x_1_scaled, y_start - y_1_scaled)
            x_2_pos = (x_start + x_2_scaled, y_start - y_2_scaled)

            # Getting raw positions and velocities to show live info
            x_1_raw, y_1_raw, x_2_raw, y_2_raw = self.pendulum.get_positions(i)
            angle_1, angle_2 = self.pendulum.get_angles(i)
            velocity_1, velocity_2 = self.pendulum.get_angular_velocities(i)

            # Setting strings ready to be drawn on display
            info_str = 'Mass {} X: {:05.2f}m, Y: {:05.2f}m, Angle: {:05.1f}deg, Velocity: {:06.1f}deg/s'
            m_1_info_str = info_str.format(1, x_1_raw, y_1_raw, angle_1 % 360,
                                           velocity_1)
            m_2_info_str = info_str.format(2, x_2_raw, y_2_raw, angle_2 % 360,
                                           velocity_2)

            # Drawing rods
            self.display.draw_rod(start_pos, x_1_pos)
            self.display.draw_rod(x_1_pos, x_2_pos)

            self.display.draw_path(self.path, self.path_depth)  # Drawing path

            # Drawing bodies
            self.display.draw_body(x_1_pos)
            self.display.draw_body(x_2_pos)

            # Drawing live info
            self.display.draw_info(m_1_info_str, (10, 10))
            self.display.draw_info(m_2_info_str, (10, 38))

            # Handling events and transition into next iteration
            self.display.next_frame(int(1000 / self.fps))
            self.display.handle_events()

            # Inserting current second pendulum position into path
            self.path.append(x_2_pos)

            # Iterating and stopping the simulation at the end of solved time range
            i += di
            if i > self.points_count:
                self.running = False