Beispiel #1
0
    def update_data_logger(self, value, name):
        self.data_logger[name].append(float(value))
        self.data_logger[name].pop(0)


if __name__ == '__main__':
    finger = FingerController()
    planner = Planner()

    s = [0, 0, 0]
    m = 1e-2
    e = [0.05, 0.05, 0]
    t = [0, finger.nStages / 2, finger.nStages]

    # now we create a parabola, to get poitns from, to fit to. This is cumbersome, but easier if change trajectories in the future.
    px, py, pz = planner.create_parabola(s, m, e, t)
    rx, ry, rz = planner.create_parabola_points(1000, px, py, pz)

    plotter = False
    if plotter:
        fig = plt.figure(1)
        ax = fig.add_subplot(111, projection='3d')

        fig_e = plt.figure(2)
        ax_c = fig_e.add_subplot(411)
        ax_l = fig_e.add_subplot(412)
        ax_t = fig_e.add_subplot(413)
        ax_i = fig_e.add_subplot(414)
        ax_e = [ax_c, ax_l, ax_t, ax_i]

    finger.setup_mpcc(True)
class UserParameters:
    def __init__(self, participant, n=20):
        f_temp = FingerController()
        f_temp.setup_mpcc(False)

        self.fingers = [FingerController() for i in range(n)]
        for f in self.fingers:
            f.setup_mpcc(False)

        self.planner = Planner()
        self.participant = participant
        filen = "fittslaw_simple_p{}.csv".format(participant)
        my_data = np.genfromtxt(filen, delimiter=',')
        self.my_data = my_data[2:]

        self.pixels_per_meter = (900 / 100) * 1e3

        self.pbounds = {
            'average_activation': (1e-1, 1e0),
            'max_motor_units': (1e2, 1e3),
            'w_contour': (1e3, 1e4),
            'w_input_t': (1e-3, 1e-1),
            'w_input_xy': (1e-3, 1e-1),
            'w_input_z': (1e-3, 1e-1),
            'w_lag': (1e3, 1e4),
            'w_vel': (1e1, 1e3),
        }

        # self.bounds_transformer = SequentialDomainReductionTransformer()
        self.optimizer = BayesianOptimization(
            f=self.cost,
            pbounds=self.pbounds,
            random_state=1,
            verbose=2,
            # bounds_transformer=self.bounds_transformer
        )

    def cost(self, average_activation, max_motor_units, w_contour, w_input_t,
             w_input_xy, w_input_z, w_lag, w_vel):

        total_error = 0
        print(
            "TESTING:\n Average Activation: {} \n Motor Units: {} \n w_contour: {} \n w_input_t: {} \n w_input_xy: {} \n w_input_z: {} \n w_lag: {} \n w_vel: {}"
            .format(average_activation, max_motor_units, w_contour, w_input_t,
                    w_input_xy, w_input_z, w_lag, w_vel))
        threads = [None] * len(self.my_data)
        with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
            for d, row in enumerate(self.my_data):
                threads[d] = executor.submit(self.evaluate, average_activation,
                                             max_motor_units, w_contour,
                                             w_input_t, w_input_xy, w_input_z,
                                             w_lag, w_vel, row)

        for t in threads:
            total_error += t.result()
        print("---ERROR---\n{}\n-----------".format(total_error))
        return -1 * total_error

    def evaluate(self, average_activation, max_motor_units, w_contour,
                 w_input_t, w_input_xy, w_input_z, w_lag, w_vel, row):

        distance = []
        movement_time = []
        threads = [None] * len(self.fingers)

        mean_distance_data = row[4]
        SD_distance_data = row[5]
        mean_time_data = row[6]
        SD_time_data = row[7]

        with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
            for n_finger, finger in enumerate(self.fingers):
                threads[n_finger] = executor.submit(self.run_mpcc, finger,
                                                    average_activation,
                                                    max_motor_units, w_contour,
                                                    w_input_t, w_input_xy,
                                                    w_input_z, w_lag, w_vel,
                                                    row)

        for f in threads:
            d, mt = f.result()
            distance.append(d)
            movement_time.append(mt)

        mean_distance_simulation = np.mean(distance)
        SD_distance_simulation = np.std(distance)
        mean_time_simulation = np.mean(movement_time)
        SD_time_simulation = np.std(movement_time)
        e_mu_d = (mean_distance_simulation - mean_distance_data)**2
        e_sigma_d = (SD_distance_simulation - SD_distance_data)**2
        e_mu_mt = (mean_time_simulation - mean_time_data)**2
        e_sigma_mt = (SD_time_simulation - SD_time_data)**2
        error = e_mu_d + e_sigma_d + e_mu_mt + e_sigma_mt
        return error

    def run_mpcc(
        self,
        finger,
        average_activation,
        max_motor_units,
        w_contour,
        w_input_t,
        w_input_xy,
        w_input_z,
        w_lag,
        w_vel,
        row,
    ):
        s = [0, 0, 0]
        m = 1e-2
        e = [row[0], row[1], 0]
        t = [0, finger.nStages / 2, finger.nStages]

        px, py, pz = self.planner.create_parabola(s, m, e, t)
        rx, ry, rz = self.planner.create_parabola_points(1000, px, py, pz)

        finger.reset_mpcc(rx, ry, rz)
        finger.update_user_paras(average_activation, max_motor_units,
                                 w_contour, w_lag, w_vel, w_input_xy,
                                 w_input_z, w_input_t)

        paras = np.zeros(finger.model.npar)
        paras[finger.index["contour_weight"]] = finger.w_contour
        paras[finger.index["lag_weight"]] = finger.w_lag
        paras[finger.index["xy_input_weight"]] = finger.w_input_xy
        paras[finger.index["z_input_weight"]] = finger.w_input_z
        paras[finger.index["theta_input_weight"]] = finger.w_input_t
        paras[finger.index["velocity_weight"]] = finger.w_vel
        paras[finger.index["variance_weight"]] = finger.w_var

        finger.reset_mpcc(rx, ry, rz)
        d = (e[0]**2 + e[1]**2)**0.5
        w = row[2]
        finger.calculate_and_set_desired_velocity(d, w)

        for i in count():
            xinit = finger.step(paras, recalc=True)
            if (xinit[2] < 0 and xinit[-2] >= finger.theta[-1]
                ) or i > (row[6] + 5 * row[7]) / finger.dt:
                d_error = ((e[0] - xinit[0])**2 + (e[1] - xinit[1])**2)**0.5
                return d_error, i * finger.dt

    def solve(self, init_points=15, n_iter=5000):
        logger = JSONLogger(path="ABC_Results/user_parameters_p{}.json".format(
            self.participant))
        self.optimizer.subscribe(Events.OPTIMIZATION_STEP, logger)

        self.optimizer.maximize(
            init_points=init_points,
            n_iter=n_iter,
        )
        print(self.optimizer.max)

    def print_max(self):
        optimizer = BayesianOptimization(
            f=self.cost,
            pbounds=self.pbounds,
            random_state=1,
            verbose=2,
        )
        load_logs(optimizer,
                  logs=[
                      "ABC_Results/user_parameters_p{}.json".format(
                          self.participant)
                  ])
        x_obs = optimizer.space._params
        y_obs = optimizer.space._target
        gp = optimizer._gp
        gp.fit(x_obs, y_obs)
        print(optimizer.max)

    def plot(self, p, i):
        optimizer = BayesianOptimization(
            f=self.cost,
            pbounds=self.pbounds,
            random_state=1,
            verbose=2,
        )
        load_logs(optimizer,
                  logs=[
                      "ABC_Results/user_parameters_p{}.json".format(
                          self.participant)
                  ])

        x_obs = np.array([[res["params"][p]] for res in optimizer.res])[:i + 1]
        y_obs = np.array([res["target"] for res in optimizer.res])[:i + 1]
        gp = optimizer._gp
        gp.fit(x_obs, y_obs)

        # # kernel = Matern(nu=4.5)
        # kernel = RBF(length_scale=1e-5)
        # kernel = RationalQuadratic(length_scale=1,
        #                            alpha=10)  # length_scale_bounds=(1e-05, 100000.0), alpha_bounds=(1e-05, 100000.0)),
        # # kernel=DotProduct(sigma_0=3e7)
        sigma = 1e0
        kernel = DotProduct(sigma_0=sigma) * DotProduct(sigma_0=sigma)
        #
        gp = GaussianProcessRegressor(
            kernel=kernel,
            normalize_y=True,
            alpha=1e-6,
            n_restarts_optimizer=5,
        )

        gp.fit(x_obs, y_obs)

        # max_x = np.array([optimizer.max['params'][p]])
        # max_y = optimizer.max['target']

        xmin, xmax = self.pbounds[p]
        x = np.linspace(xmin, xmax, 100)
        num_vals = len(x)
        w_vel = np.linspace(self.pbounds[p][0], self.pbounds[p][1], num_vals)
        mu, sigma = gp.predict(w_vel.reshape(-1, 1), return_std=True)

        fig = plt.figure(i)
        ax = fig.add_subplot(111)
        ax.scatter(x_obs.flatten(), y_obs, color='g', label="observations")
        # ax.scatter(max_x, max_y, color='r', label="Max value")
        ax.plot(w_vel, mu, 'k--', label="prediction")
        ax.fill_between(w_vel,
                        mu - sigma,
                        mu + sigma,
                        label="SD Confidence",
                        alpha=0.5)
        ax.set_xlabel(p)
        ax.set_ylabel("target")
        ax.set_xlim(0, 1000)
        ax.set_ylim(-15, 1)
        plt.legend()
        counter = str(i).zfill(3)
        plt.savefig("ABC_Results\images\w_vel_p999_{}.png".format(counter))
        plt.close()
        # plt.show()

    def plot2(self):
        optimizer = BayesianOptimization(
            f=self.cost,
            pbounds=self.pbounds,
            random_state=1,
            verbose=2,
        )
        load_logs(optimizer,
                  logs=[
                      "ABC_Results/user_parameters_p{}.json".format(
                          self.participant)
                  ])

        x_obs = optimizer.space._params
        y_obs = optimizer.space._target
        gp = optimizer._gp

        # kernel = Matern(nu=4.5)
        kernel = RBF(length_scale=1e-5)
        # kernel = RationalQuadratic(length_scale=1,
        #                            alpha=10)  # length_scale_bounds=(1e-05, 100000.0), alpha_bounds=(1e-05, 100000.0)),
        # kernel=DotProduct(sigma_0=3e7)
        # sigma = 1e1
        # kernel = DotProduct(sigma_0=sigma) * DotProduct(sigma_0=sigma)

        gp = GaussianProcessRegressor(
            kernel=kernel,
            normalize_y=True,
            alpha=0.5,
            n_restarts_optimizer=25,
        )

        gp.fit(x_obs, y_obs)

        max_x = np.array([
            optimizer.max['params']['max_motor_units'],
            optimizer.max['params']['w_vel']
        ])
        max_y = optimizer.max['target']

        num_vals = 101
        heatmap = np.zeros((num_vals, num_vals))
        w_vel = np.linspace(self.pbounds["w_vel"][0], self.pbounds["w_vel"][1],
                            num_vals)
        max_motor_units = np.linspace(self.pbounds["max_motor_units"][0],
                                      self.pbounds["max_motor_units"][1],
                                      num_vals)

        # calculate heat map
        for i in range(num_vals):
            for j in range(num_vals):
                heatmap[i, j] = gp.predict(
                    np.array([max_motor_units[j], w_vel[i]]).reshape(1, -1))

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.scatter(x_obs[:, 0], x_obs[:, 1], y_obs, color='g')
        ax.scatter(max_x[0], max_x[1], max_y, color='r')
        xv, yv = np.meshgrid(max_motor_units, w_vel)
        ax.plot_wireframe(xv, yv, heatmap)
        # ax.plot_surface(xv, yv, heatmap)
        ax.set_xlabel("motor")
        ax.set_ylabel("w_vel")
        plt.show()
Beispiel #3
0
class DataCreator:
    def __init__(self, participant):
        self.finger = FingerController()
        self.finger.setup_mpcc(False)
        self.planner = Planner()
        self.participant = participant
        filen = "fittslaw_simple_p{}.csv".format(participant)
        my_data = np.genfromtxt(filen, delimiter=',')
        self.my_data = my_data[2:]
        self.pixels_per_meter = (900 / 100) * 1e3
        self.saved_data = []

    def create(self):
        for row in self.my_data:
            s = [0, 0, 0]
            m = 1e-2
            e = [row[0], row[1], 0]
            t = [0, self.finger.nStages / 2, self.finger.nStages]

            px, py, pz = self.planner.create_parabola(s, m, e, t)
            rx, ry, rz = self.planner.create_parabola_points(1000, px, py, pz)

            self.finger.reset_mpcc(rx, ry, rz)
            self.finger.update_user_paras(300, 0.5, 2e3, 4e3, 100, 0.01, 0.01,
                                          0.01)

            paras = np.zeros(self.finger.model.npar)
            paras[self.finger.index["contour_weight"]] = self.finger.w_contour
            paras[self.finger.index["lag_weight"]] = self.finger.w_lag
            paras[
                self.finger.index["xy_input_weight"]] = self.finger.w_input_xy
            paras[self.finger.index["z_input_weight"]] = self.finger.w_input_z
            paras[self.finger.
                  index["theta_input_weight"]] = self.finger.w_input_t
            paras[self.finger.index["velocity_weight"]] = self.finger.w_vel
            paras[self.finger.index["variance_weight"]] = self.finger.w_var

            distance = []
            movement_time = []

            for n in range(100):
                self.finger.reset_mpcc(rx, ry, rz)
                d = (e[0]**2 + e[1]**2)**0.5
                w = row[2]
                self.finger.calculate_and_set_desired_velocity(d, w)

                mean_time_data = row[4]
                SD_time_data = row[5]

                for i in count():
                    xinit = self.finger.step(paras, recalc=True)
                    if (xinit[2] < 0 and xinit[-2] >= self.finger.theta[-1]):
                        d = ((e[0] - xinit[0])**2 + (e[1] - xinit[1])**2)**0.5
                        distance.append(d)
                        movement_time.append(i * self.finger.dt)
                        break

            mean_distance_simulation = np.mean(distance)
            SD_distance_simulation = np.std(distance)
            mean_time_simulation = np.mean(movement_time)
            SD_time_simulation = np.std(movement_time)
            data = [
                row[0], row[1], row[2], row[3], mean_distance_simulation,
                SD_distance_simulation, mean_time_simulation,
                SD_time_simulation
            ]
            self.saved_data.append(data)

    def save(self):
        header = ["x", "y", "w", "h", "mu_e", "sigma_e", "mu_mt", "sigma_mt"]
        with open('fittslaw_simple_p999.csv', 'w', newline='') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(header)
            writer.writerows(self.saved_data)