Пример #1
0
def main(initial_guess, do_plot=False):

    if building_docs:
        do_plot = True

    # Specify the symbolic equations of motion.
    p, t = sym.symbols('p, t')
    y1, y2 = [f(t) for f in sym.symbols('y1, y2', cls=sym.Function)]
    y = sym.Matrix([y1, y2])
    f = sym.Matrix([y2, -p * sym.sin(y1)])
    eom = y.diff(t) - f

    # Generate some data by integrating the equations of motion.
    duration = 50.0
    num_nodes = 5000
    interval = duration / (num_nodes - 1)
    time = np.linspace(0.0, duration, num=num_nodes)

    p_val = 10.0
    y0 = [np.pi / 6.0, 0.0]

    def eval_f(y, t, p):
        return np.array([y[1], -p * np.sin(y[0])])

    y_meas = odeint(eval_f, y0, time, args=(p_val,))
    y1_meas = y_meas[:, 0]
    y2_meas = y_meas[:, 1]

    # Add measurement noise.
    y1_meas += np.random.normal(scale=0.05, size=y1_meas.shape)
    y2_meas += np.random.normal(scale=0.1, size=y2_meas.shape)

    # Setup the optimization problem to minimize the error in the simulated
    # angle and the measured angle.
    def obj(free):
        """Minimize the error in the angle, y1."""
        return interval * np.sum((y1_meas - free[:num_nodes])**2)

    def obj_grad(free):
        grad = np.zeros_like(free)
        grad[:num_nodes] = 2.0 * interval * (free[:num_nodes] - y1_meas)
        return grad

    # The midpoint integration method is preferable to the backward Euler
    # method because no artificial damping is introduced.
    prob = Problem(obj, obj_grad, eom, (y1, y2), num_nodes, interval,
                   integration_method='midpoint')

    num_states = len(y)

    if initial_guess == 'zero':
        print('Using all zeros for the initial guess.')
        # All zeros.
        initial_guess = np.zeros(num_states * num_nodes + 1)
    elif initial_guess == 'randompar':
        print(('Using all zeros for the trajectories initial guess and a '
               'random positive value for the parameter.'))
        # Zeros for the state trajectories and a random positive value for
        # the parameter.
        initial_guess = np.hstack((np.zeros(num_states * num_nodes), 50.0 *
                                   np.random.random(1)))
    elif initial_guess == 'random':
        print('Using random values for the initial guess.')
        # Random values for all unknowns.
        initial_guess = np.hstack((np.random.normal(scale=5.0,
                                                    size=num_states *
                                                    num_nodes), 50.0 *
                                   np.random.random(1)))
    elif initial_guess == 'sysid':
        print(('Using noisy measurements for the trajectory initial guess and '
               'a random positive value for the parameter.'))
        # Give noisy measurements as the initial state guess and a random
        # positive values as the parameter guess.
        initial_guess = np.hstack((y1_meas, y2_meas, 100.0 *
                                   np.random.random(1)))
    elif initial_guess == 'known':
        print('Using the known solution as the initial guess.')
        # Known solution as initial guess.
        initial_guess = np.hstack((y1_meas, y2_meas, 10.0))

    # Find the optimal solution.
    solution, info = prob.solve(initial_guess)
    p_sol = solution[-1]

    # Print the result.
    known_msg = "Known value of p = {}".format(p_val)
    guess_msg = "Initial guess for p = {}".format(initial_guess[-1])
    identified_msg = "Identified value of p = {}".format(p_sol)
    divider = '=' * max(len(known_msg), len(identified_msg))

    print(divider)
    print(known_msg)
    print(guess_msg)
    print(identified_msg)
    print(divider)

    # Simulate with the identified parameter.
    y_sim = odeint(eval_f, y0, time, args=(p_sol,))
    y1_sim = y_sim[:, 0]
    y2_sim = y_sim[:, 1]

    if do_plot:

        # Plot results
        fig_y1, axes_y1 = plt.subplots(3, 1)

        legend = ['measured', 'initial guess',
                  'direct collocation solution', 'identified simulated']

        axes_y1[0].plot(time, y1_meas, '.k',
                        time, initial_guess[:num_nodes], '.b',
                        time, solution[:num_nodes], '.r',
                        time, y1_sim, 'g')
        axes_y1[0].set_xlabel('Time [s]')
        axes_y1[0].set_ylabel('y1 [rad]')
        axes_y1[0].legend(legend)

        axes_y1[1].set_title('Initial Guess Constraint Violations')
        axes_y1[1].plot(prob.con(initial_guess)[:num_nodes - 1])
        axes_y1[2].set_title('Solution Constraint Violations')
        axes_y1[2].plot(prob.con(solution)[:num_nodes - 1])

        plt.tight_layout()

        fig_y2, axes_y2 = plt.subplots(3, 1)

        axes_y2[0].plot(time, y2_meas, '.k',
                        time, initial_guess[num_nodes:-1], '.b',
                        time, solution[num_nodes:-1], '.r',
                        time, y2_sim, 'g')
        axes_y2[0].set_xlabel('Time [s]')
        axes_y2[0].set_ylabel('y2 [rad]')
        axes_y2[0].legend(legend)

        axes_y2[1].set_title('Initial Guess Constraint Violations')
        axes_y2[1].plot(prob.con(initial_guess)[num_nodes - 1:])
        axes_y2[2].set_title('Solution Constraint Violations')
        axes_y2[2].plot(prob.con(solution)[num_nodes - 1:])

        plt.tight_layout()

        plt.show()
Пример #2
0
print(divider)

# Plot results
fig_y1, axes_y1 = plt.subplots(3, 1)

legend = ['measured', 'initial guess', 'direct collocation solution']

axes_y1[0].plot(time, y1_m, '.k',
                time, initial_guess[:num_nodes], '.b',
                time, solution[:num_nodes], '.r')
axes_y1[0].set_xlabel('Time [s]')
axes_y1[0].set_ylabel('y1')
axes_y1[0].legend(legend)

axes_y1[1].set_title('Initial Guess Constraint Violations')
axes_y1[1].plot(prob.con(initial_guess)[:num_nodes - 1])
axes_y1[2].set_title('Solution Constraint Violations')
axes_y1[2].plot(prob.con(solution)[:num_nodes - 1])

plt.tight_layout()

fig_y2, axes_y2 = plt.subplots(3, 1)

axes_y2[0].plot(time, y2_m, '.k',
                time, initial_guess[num_nodes:-1], '.b',
                time, solution[num_nodes:-1], '.r')
axes_y2[0].set_xlabel('Time [s]')
axes_y2[0].set_ylabel('y2')
axes_y2[0].legend(legend)

axes_y2[1].set_title('Initial Guess Constraint Violations')
Пример #3
0
angle = solution[:num_nodes]
rate = solution[num_nodes:2 * num_nodes]
torque = solution[2 * num_nodes:]

fig, axes = plt.subplots(3)
axes[0].set_title('State and Control Trajectories')
axes[0].plot(time, angle)
axes[0].set_ylabel('Angle [rad]')
axes[1].plot(time, rate)
axes[1].set_ylabel('Angular Rate [rad/s]')
axes[2].plot(time, torque)
axes[2].set_ylabel('Torque [Nm]')
axes[2].set_xlabel('Time [S]')

# Plot constraint violations
con_violations = prob.con(solution)
con_nodes = range(2, num_nodes + 1)
N = len(con_nodes)
fig, axes = plt.subplots(3)
axes[0].set_title('Constraint Violations')
axes[0].plot(con_nodes, con_violations[:N])
axes[0].set_ylabel('Angle [rad]')
axes[1].plot(con_nodes, con_violations[N:2 * N])
axes[1].set_ylabel('Angular Rate [rad/s]')
axes[1].set_xlabel('Node Number')
axes[2].plot(con_violations[2 * N:])
axes[2].set_ylabel('Instance')

# Plot objective value
fig, ax = plt.subplots(1)
ax.set_title('Objective Value')
Пример #4
0
def main(initial_guess, do_plot=False):

    # Specify the symbolic equations of motion.
    p, t = sym.symbols('p, t')
    y1, y2 = [f(t) for f in sym.symbols('y1, y2', cls=sym.Function)]
    y = sym.Matrix([y1, y2])
    f = sym.Matrix([y2, -p * sym.sin(y1)])
    eom = y.diff(t) - f

    # Generate some data by integrating the equations of motion.
    duration = 50.0
    num_nodes = 5000
    interval = duration / (num_nodes - 1)
    time = np.linspace(0.0, duration, num=num_nodes)

    p_val = 10.0
    y0 = [np.pi / 6.0, 0.0]

    def eval_f(y, t, p):
        return np.array([y[1], -p * np.sin(y[0])])

    y_meas = odeint(eval_f, y0, time, args=(p_val,))
    y1_meas = y_meas[:, 0]
    y2_meas = y_meas[:, 1]

    # Add measurement noise.
    y1_meas += np.random.normal(scale=0.05, size=y1_meas.shape)
    y2_meas += np.random.normal(scale=0.1, size=y2_meas.shape)

    # Setup the optimization problem to minimize the error in the simulated
    # angle and the measured angle.
    def obj(free):
        """Minimize the error in the angle, y1."""
        return interval * np.sum((y1_meas - free[:num_nodes])**2)


    def obj_grad(free):
        grad = np.zeros_like(free)
        grad[:num_nodes] = 2.0 * interval * (free[:num_nodes] - y1_meas)
        return grad

    # The midpoint integration method is preferable to the backward Euler
    # method because no artificial damping is introduced.
    prob = Problem(obj, obj_grad, eom, (y1, y2), num_nodes, interval,
                integration_method='midpoint')

    # Set some IPOPT options.
    prob.addOption('linear_solver', 'ma57')

    num_states = len(y)

    if initial_guess == 'zero':
        # All zeros.
        initial_guess = np.zeros(num_states * num_nodes + 1)
    elif initial_guess == 'randompar':
        # Zeros for the state trajectories and a random positive value for
        # the parameter.
        initial_guess = np.hstack((np.zeros(num_states * num_nodes), 50.0 *
                                   np.random.random(1)))
    elif initial_guess == 'random':
        # Random values for all unknowns.
        initial_guess = np.hstack((np.random.normal(scale=5.0,
                                                    size=num_states *
                                                    num_nodes), 50.0 *
                                   np.random.random(1)))
    elif initial_guess == 'sysid':
        # Give noisy measurements as the initial state guess and a random
        # positive values as the parameter guess.
        initial_guess = np.hstack((y1_meas, y2_meas, 100.0 *
                                   np.random.random(1)))
    elif initial_guess == 'known':
        # Known solution as initial guess.
        initial_guess = np.hstack((y1_meas, y2_meas, 10.0))

    # Find the optimal solution.
    solution, info = prob.solve(initial_guess)
    p_sol = solution[-1]

    # Print the result.
    known_msg = "Known value of p = {}".format(p_val)
    guess_msg = "Initial guess for p = {}".format(initial_guess[-1])
    identified_msg = "Identified value of p = {}".format(p_sol)
    divider = '=' * max(len(known_msg), len(identified_msg))

    print(divider)
    print(known_msg)
    print(guess_msg)
    print(identified_msg)
    print(divider)

    # Simulate with the identified parameter.
    y_sim = odeint(eval_f, y0, time, args=(p_sol,))
    y1_sim = y_sim[:, 0]
    y2_sim = y_sim[:, 1]

    if do_plot:

        # Plot results
        fig_y1, axes_y1 = plt.subplots(3, 1)

        legend = ['measured', 'initial guess',
                  'direct collocation solution', 'identified simulated']

        axes_y1[0].plot(time, y1_meas, '.k',
                        time, initial_guess[:num_nodes], '.b',
                        time, solution[:num_nodes], '.r',
                        time, y1_sim, 'g')
        axes_y1[0].set_xlabel('Time [s]')
        axes_y1[0].set_ylabel('y1 [rad]')
        axes_y1[0].legend(legend)

        axes_y1[1].set_title('Initial Guess Constraint Violations')
        axes_y1[1].plot(prob.con(initial_guess)[:num_nodes - 1])
        axes_y1[2].set_title('Solution Constraint Violations')
        axes_y1[2].plot(prob.con(solution)[:num_nodes - 1])

        plt.tight_layout()

        fig_y2, axes_y2 = plt.subplots(3, 1)

        axes_y2[0].plot(time, y2_meas, '.k',
                        time, initial_guess[num_nodes:-1], '.b',
                        time, solution[num_nodes:-1], '.r',
                        time, y2_sim, 'g')
        axes_y2[0].set_xlabel('Time [s]')
        axes_y2[0].set_ylabel('y2 [rad]')
        axes_y2[0].legend(legend)

        axes_y2[1].set_title('Initial Guess Constraint Violations')
        axes_y2[1].plot(prob.con(initial_guess)[num_nodes - 1:])
        axes_y2[2].set_title('Solution Constraint Violations')
        axes_y2[2].plot(prob.con(solution)[num_nodes - 1:])

        plt.tight_layout()

        plt.show()
Пример #5
0
print(identified_msg)
print(divider)

# Plot results
fig_y1, axes_y1 = plt.subplots(3, 1)

legend = ['measured', 'initial guess', 'direct collocation solution']

axes_y1[0].plot(time, y1_m, '.k', time, initial_guess[:num_nodes], '.b', time,
                solution[:num_nodes], '.r')
axes_y1[0].set_xlabel('Time [s]')
axes_y1[0].set_ylabel('y1')
axes_y1[0].legend(legend)

axes_y1[1].set_title('Initial Guess Constraint Violations')
axes_y1[1].plot(prob.con(initial_guess)[:num_nodes - 1])
axes_y1[2].set_title('Solution Constraint Violations')
axes_y1[2].plot(prob.con(solution)[:num_nodes - 1])

plt.tight_layout()

fig_y2, axes_y2 = plt.subplots(3, 1)

axes_y2[0].plot(time, y2_m, '.k', time, initial_guess[num_nodes:-1], '.b',
                time, solution[num_nodes:-1], '.r')
axes_y2[0].set_xlabel('Time [s]')
axes_y2[0].set_ylabel('y2')
axes_y2[0].legend(legend)

axes_y2[1].set_title('Initial Guess Constraint Violations')
axes_y2[1].plot(prob.con(initial_guess)[num_nodes - 1:])