예제 #1
0
파일: model.py 프로젝트: jetd1/dcp
 def forward(self, *input):
     src_embedding = input[0]
     tgt_embedding = input[1]
     embedding = torch.cat((src_embedding, tgt_embedding), dim=1)
     embedding = self.nn(embedding.max(dim=-1)[0])
     rotation = self.proj_rot(embedding)
     rotation = rotation / torch.norm(rotation, p=2, dim=1, keepdim=True)
     translation = self.proj_trans(embedding)
     return quat2mat(rotation), translation
    def optimize_ransac(self, num_iter, rot_loss_w, num_ransac_iter,
                        inlier_thr, vis):
        """

        :param num_iter:
        :param rot_loss_w:
        :param num_ransac_iter:
        :param inlier_thr:
        :param vis:
        :return:
        """
        max_inliers = None
        for n in range(num_ransac_iter):
            # sample random num_points from data to optimize paramters
            print("\n training with {} data points".format(
                self.num_train_points))
            train_indx = random.sample(range(self.num_points),
                                       self.num_train_points)
            train_trans_B_G = torch.stack(
                [self.trans_B_G[i] for i in train_indx], dim=0)
            train_rot_B_G = torch.stack([self.rot_B_G[i] for i in train_indx],
                                        dim=0)
            train_trans_C_A = torch.stack(
                [self.trans_C_A[i] for i in train_indx], dim=0)
            train_rot_C_A = torch.stack([self.rot_C_A[i] for i in train_indx],
                                        dim=0)

            test_trans_B_G = torch.stack([
                self.trans_B_G[i]
                for i in range(self.num_points) if i not in train_indx
            ],
                                         dim=0)
            test_rot_B_G = torch.stack([
                self.rot_B_G[i]
                for i in range(self.num_points) if i not in train_indx
            ],
                                       dim=0)
            test_trans_C_A = torch.stack([
                self.trans_C_A[i]
                for i in range(self.num_points) if i not in train_indx
            ],
                                         dim=0)
            test_rot_C_A = torch.stack([
                self.rot_C_A[i]
                for i in range(self.num_points) if i not in train_indx
            ],
                                       dim=0)

            # start with some random guess
            quat_B_C = torch.rand(1, 3).double().requires_grad_(True)
            trans_B_C = torch.rand(1, 3).double().requires_grad_(True)
            quat_G_A = torch.rand(1, 3).double().requires_grad_(True)
            trans_G_A = torch.rand(1, 3).double().requires_grad_(True)
            optimizer = optim.Adam([quat_B_C, trans_B_C, trans_G_A, quat_G_A],
                                   lr=0.1)
            criterion = torch.nn.MSELoss(reduction='none')
            best_train_loss, best_train_quat_B_C, best_train_trans_B_C, best_train_quat_G_A, best_train_trans_G_A = \
                None, None, None, None, None

            ###################
            # optimize on the train set the B<-->C & G<-->A
            for it in range(num_iter):
                _, train_loss = compute_loss(train_trans_B_G, train_rot_B_G,
                                             train_trans_C_A, train_rot_C_A,
                                             trans_G_A, quat_G_A, trans_B_C,
                                             quat_B_C, criterion, rot_loss_w)
                optimizer.zero_grad()
                train_loss.backward()
                optimizer.step()

                if best_train_loss is None or train_loss.item(
                ) < best_train_loss:
                    best_train_loss = train_loss.item()
                    best_train_quat_B_C = quat_B_C.detach().numpy()
                    best_train_trans_B_C = trans_B_C.detach().numpy()
                    best_train_quat_G_A = quat_G_A.detach().numpy()
                    best_train_trans_G_A = trans_G_A.detach().numpy()

                if it % 100 == 0:
                    print("train_loss = {:05f}".format(train_loss.item()))

            ###################
            # find inliers
            with torch.no_grad():
                test_loss, _ = compute_loss(
                    test_trans_B_G, test_rot_B_G, test_trans_C_A, test_rot_C_A,
                    torch.from_numpy(best_train_trans_G_A),
                    torch.from_numpy(best_train_quat_G_A),
                    torch.from_numpy(best_train_trans_B_C),
                    torch.from_numpy(best_train_quat_B_C), criterion,
                    rot_loss_w)

            # include all inliers in train set
            num_inliers = 0
            for indx, l in enumerate(test_loss):
                if l.item() < inlier_thr:
                    train_trans_B_G = torch.cat(
                        (train_trans_B_G, test_trans_B_G[indx].unsqueeze_(0)),
                        dim=0)
                    train_rot_B_G = torch.cat(
                        (train_rot_B_G, test_rot_B_G[indx].unsqueeze_(0)),
                        dim=0)
                    train_trans_C_A = torch.cat(
                        (train_trans_C_A, test_trans_C_A[indx].unsqueeze_(0)),
                        dim=0)
                    train_rot_C_A = torch.cat(
                        (train_rot_C_A, test_rot_C_A[indx].unsqueeze_(0)),
                        dim=0)
                    num_inliers += 1
            print("num_inliers = {}".format(num_inliers))

            # fine tune the params
            if num_inliers == 0:
                continue
            if max_inliers is None or num_inliers > max_inliers:
                max_inliers = num_inliers
                print("training with {} data points".format(
                    train_trans_B_G.shape[0]))
                # train again
                best_loss, best_quat_B_C, best_trans_B_C, best_quat_G_A, best_trans_G_A = None, None, None, None, None
                for it in range(num_iter):
                    # optimize paramters
                    optimizer.zero_grad()
                    _, train_loss = compute_loss(train_trans_B_G,
                                                 train_rot_B_G,
                                                 train_trans_C_A,
                                                 train_rot_C_A, trans_G_A,
                                                 quat_G_A, trans_B_C, quat_B_C,
                                                 criterion, rot_loss_w)
                    if best_loss is None or train_loss.item() < best_loss:
                        best_loss = train_loss.item()
                        best_quat_B_C = quat_B_C.detach().numpy()
                        best_trans_B_C = trans_B_C[0].detach().numpy()
                        best_trans_G_A = trans_G_A[0].detach().numpy()
                    train_loss.backward()
                    optimizer.step()
                    if it % 100 == 0:
                        print("train_loss = {:05f}".format(train_loss.item()))

        best_rot_B_C, best_quat_B_C = quat2mat(torch.from_numpy(best_quat_B_C))
        best_rot_B_C, best_quat_B_C = best_rot_B_C[0].detach().numpy(
        ), best_quat_B_C[0].detach().numpy()

        print("\n for B<-->C ")
        cmd = "rosrun tf static_transform_publisher " + str(float(best_trans_B_C[0])) + ' ' + \
              str(float(best_trans_B_C[1])) + ' ' + str(float(best_trans_B_C[2])) + ' ' + str(best_quat_B_C[1]) + ' ' \
              + str(best_quat_B_C[2]) + ' ' + str(best_quat_B_C[3]) + ' ' + str(best_quat_B_C[0]) + ' ' + \
              self.base_frame + ' '+ self.camera_frame + ' 10'
        print("Run Command")
        print(cmd)

        # plot the points for visualization
        if vis:
            trans_B_G_A = self.trans_B_G.numpy().reshape(-1, 3) + np.array([
                np.matmul(self.rot_B_G[i].numpy(),
                          best_trans_G_A.reshape(-1, 3).T).T
                for i in range(self.num_points)
            ]).reshape(-1, 3)
            trans_B_C_A = np.matmul(best_rot_B_C,
                                    self.trans_C_A.numpy().reshape(
                                        -1, 3).T).T + best_trans_B_C.reshape(
                                            -1, 3)
            ax = plt.axes(projection='3d')
            ax.scatter3D(trans_B_G_A[:, 0], trans_B_G_A[:, 1], trans_B_G_A[:,
                                                                           2])
            ax.scatter3D(trans_B_C_A[:, 0],
                         trans_B_C_A[:, 1],
                         trans_B_C_A[:, 2],
                         color='red')
            scatter1_proxy = matplotlib.lines.Line2D([0], [0],
                                                     linestyle="none",
                                                     marker='o')
            scatter2_proxy = matplotlib.lines.Line2D([0], [0],
                                                     linestyle="none",
                                                     c='red',
                                                     marker='o')
            ax.legend([scatter1_proxy, scatter2_proxy],
                      ['Base to Ar from Gripper', 'Base to Ar from Camera'],
                      numpoints=1)
            plt.show()
예제 #3
0
    def optimize(self, num_iter, rot_loss_w, vis):
        # start with some random guess
        quat_B_C = torch.rand(1, 3).requires_grad_(True)
        trans_B_C = torch.rand(1, 3).requires_grad_(True)
        quat_G_A = torch.rand(1, 3).requires_grad_(True)
        trans_G_A = torch.rand(1, 3).requires_grad_(True)
        optimizer = optim.Adam([quat_B_C, trans_B_C, trans_G_A, quat_G_A],
                               lr=0.1)
        criterion = torch.nn.MSELoss(reduction='none')
        best_quat_B_C, best_trans_B_C, best_loss = None, None, None

        ###################
        # optimize the B<-->C & G<-->A
        for it in range(num_iter):
            _, loss = compute_loss(self.trans_B_G, self.rot_B_G,
                                   self.trans_C_A, self.rot_C_A, trans_G_A,
                                   quat_G_A, trans_B_C, quat_B_C, criterion,
                                   rot_loss_w)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            if best_loss is None or best_loss > loss.item():
                best_loss = loss.item()
                best_quat_B_C = quat_B_C.detach().numpy()
                best_trans_B_C = trans_B_C[0].detach().numpy()
                best_trans_G_A = trans_G_A[0].detach().numpy()

            print("iter = {:04d} loss = {}".format(it, loss.item()))

        best_rot_B_C, best_quat_B_C = quat2mat(torch.from_numpy(best_quat_B_C))
        best_rot_B_C, best_quat_B_C = best_rot_B_C[0].detach().numpy(
        ), best_quat_B_C[0].detach().numpy()

        print("\n for B<-->C ")
        print(" org_rot = {} \n pred_rot = {}".format(self.gt_rot_B_C.numpy(),
                                                      best_rot_B_C))
        print(" org_trans = {} \n pred_trans = {}".format(
            self.gt_trans_B_C.numpy(), best_trans_B_C))

        print("\n for G<-->A ")
        print("org_trans = {} \n pred_trans = {}".format(
            self.gt_trans_G_A.numpy(), best_trans_G_A))

        # plot the points for visualization
        if vis:
            trans_B_G_A = self.trans_B_G.numpy().reshape(-1, 3) + np.array([
                np.matmul(self.rot_B_G[i].numpy(),
                          best_trans_G_A.reshape(-1, 3).T).T
                for i in range(self.num_points)
            ]).reshape(-1, 3)
            trans_B_C_A = np.matmul(best_rot_B_C,
                                    self.trans_C_A.numpy().reshape(
                                        -1, 3).T).T + best_trans_B_C.reshape(
                                            -1, 3)
            ax = plt.axes(projection='3d')
            ax.scatter3D(trans_B_G_A[:, 0], trans_B_G_A[:, 1], trans_B_G_A[:,
                                                                           2])
            ax.scatter3D(trans_B_C_A[:, 0],
                         trans_B_C_A[:, 1],
                         trans_B_C_A[:, 2],
                         color='red')
            scatter1_proxy = matplotlib.lines.Line2D([0], [0],
                                                     linestyle="none",
                                                     marker='o')
            scatter2_proxy = matplotlib.lines.Line2D([0], [0],
                                                     linestyle="none",
                                                     c='red',
                                                     marker='o')
            ax.legend([scatter1_proxy, scatter2_proxy],
                      ['Base to Ar from Gripper', 'Base to Ar from Camera'],
                      numpoints=1)
            plt.show()