def pose_callback(
        self, msg
    ):  # parses /pose messages into pose vertices and edges between them
        # store x,y,theta of new pose; use them to construct g2o SE2 for the pose measurement
        x = msg.pose.position.x
        y = msg.pose.position.y
        theta = msg.pose.orientation.z
        se2 = g2o.SE2(x, y, theta)  # pose measurement
        # se2 = g2o.SE2(0, 0, 0) # pose measurement with zeros; uncomment to test optimization functionality

        prev_vertex_id = self.optimizer.get_last_pose_vertex_id(
        )  # store most recent prior pose vertex id, if any, before adding new vertex (as this will override last vertex id)
        v_se2, new_vertex_id = self.optimizer.add_pose_vertex(
            se2)  # register new pose vertex with optimizer

        if prev_vertex_id != -1:  # this is not the first pose vertex, so a pose-pose edge can be calculated and added
            # calculate delta x,y,theta between prev and new poses; use them to construct g2o SE2 for the edge measurement
            delta_x = x - self.last_pose_x
            delta_y = y - self.last_pose_y
            delta_theta = msg.pose.orientation.z - self.last_pose_theta
            delta_se2 = g2o.SE2(delta_x, delta_y,
                                delta_theta)  # pose-pose edge measurement
            self.optimizer.add_pose_edge(
                [prev_vertex_id, new_vertex_id],
                delta_se2)  # register the new edge with the optimizer

        # update the x,y,theta of the most recent pose vertex, to be used to calculate the next pose-pose edge measurement
        self.last_pose_x = x
        self.last_pose_y = y
        self.last_pose_theta = theta
        return
    def add_vertex(self, id, x_estimate, fixed=False):
        v_se2 = g2o.VertexSE2()
        v_se2.set_id(id)
        se2 = g2o.SE2(x_estimate, 0, 0)
        v_se2.set_estimate(se2)
        v_se2.set_fixed(fixed)

        self.optimizer.add_vertex(v_se2)
    def graph_make(self):
        graph = PoseGraphOptimization()
        information_matrix_pose = np.identity(3)
        information_matrix_scan = np.identity(3)
        information_matrix_pose[0][0] = 1 / Q
        information_matrix_scan[0][0] = 1 / R

        for i in range(len(self.X_list)):
            graph.add_vertex(i, g2o.SE2(self.X_list[i], 0, 0))

        for j in range(len(self.transition_list)):
            graph.add_edge([j, j + 1], g2o.SE2(self.transition_list[j], 0, 0),
                           information_matrix_pose)

        for k in range(len(self.scan_diff_list)):
            graph.add_edge([k, k + 1], g2o.SE2(self.scan_diff_list[k], 0, 0),
                           information_matrix_scan)

        return graph
Beispiel #4
0
 def save_pose_edge(self, id1, id2, dx, dy, info_mtx):
     if id1 < 0 or id2 < 0:
         return
     dtheta = 0
     self.slam_file.write("EDGE_SE2 " + str(id1) + " " + str(id2) + " " + str(dx) + " " + str(dy) + " " + str(dtheta))
     for i in range(6):
         self.slam_file.write(" " + str(info_mtx.item(i)))
     self.slam_file.write("\n")
     new_info_mtx = np.identity(3)
     self.pgo.add_edge([id1, id2], g2o.SE2(dx, dy, dtheta), new_info_mtx)
Beispiel #5
0
    def pose_callback(self, msg):
        if not self.get_initial_pose:
            self.get_initial_pose = True
            self.initial_pose_x = msg.pose.position.x
            self.initial_pose_y = msg.pose.position.y
            rotation = (msg.pose.orientation.x, msg.pose.orientation.y,
                        msg.pose.orientation.z, msg.pose.orientation.w)
            euler = tf.transformations.euler_from_quaternion(rotation)
            self.initial_pose_theta = euler[2]
            self.init_time = rospy.get_time()

        self.t.append(rospy.get_time() - self.init_time)
        x = msg.pose.position.x - self.initial_pose_x
        y = msg.pose.position.y = self.initial_pose_y
        rotation = (msg.pose.orientation.x, msg.pose.orientation.y,
                    msg.pose.orientation.z, msg.pose.orientation.w)
        euler = tf.transformations.euler_from_quaternion(rotation)
        theta = euler[2] - self.initial_pose_theta
        self.x.append(x)
        self.y.append(y)
        self.theta.append(theta)

        # add pose vertex
        pose = g2o.SE2(x, y, theta)
        self.graph_optimizer.add_vertex(self.id, pose, 1)

        # add edge between poses
        if self.id != 1:
            relative_pose = [
                x - self.last_pose[0], y - self.last_pose[1],
                theta - self.last_pose[2]
            ]
            measurement = g2o.SE2(relative_pose[0], relative_pose[1],
                                  relative_pose[2])
            self.graph_optimizer.add_edge([self.id, self.id - 1], measurement,
                                          1)

        # add edge between pose and landmark
        measurement = [self.distance, 0]
        self.graph_optimizer.add_edge([self.id, 0], measurement, 2)

        self.last_pose = [x, y, theta]
        self.id += 1
    def add_edge(self, fromVertex, toVertex, dx, information=np.identity(3)):

        edge = g2o.EdgeSE2()
        for i, v in enumerate([fromVertex, toVertex]):
            if isinstance(v, int):
                v = self.optimizer.vertex(v)
            edge.set_vertex(i, v)

        edge.set_measurement(g2o.SE2(dx, 0, 0))  # relative pose
        edge.set_information(information)
        self.optimizer.add_edge(edge)
Beispiel #7
0
 def pose_callback(self, msg):
     x = msg.pose.position.x
     y = msg.pose.position.y
     rotation = (msg.pose.orientation.x, msg.pose.orientation.y,
                 msg.pose.orientation.z, msg.pose.orientation.w)
     euler_angle = tf.transformations.euler_from_quaternion(rotation)
     th = euler_angle[2]
     if ((x != self.last_pose[0]) and (y != self.last_pose[1])):
         self.id += 1
         pose_ = g2o.SE2(x, y, th)
         self.graph_opt.add_vertex(self.id, pose_, False)
         ms = [(x - self.last_pose[0]), (y - self.last_pose[1]),
               (th - self.last_pose[2])]
         measure = g2o.SE2(ms[0], ms[1], ms[2])
         if (id > 1):
             self.graph_opt.add_edge([self.id, self.id - 1], measure, True)
             self.graph_opt.add_edge([self.id, 0], [self.dist_, 0], False)
         self.last_pose = [x, y, th]
         self.t += 0.1
         self.t_lst.append(self.t)
         self.x_lst.append(x)
         self.y_lst.append(y)
         self.th_lst.append(th)
Beispiel #8
0
 def save_pose_vtx(self, id, x, y, theta):
     self.slam_file.write("VERTEX_SE2 " + str(id) + " " + str(x) + " " + str(y) + " " + str(theta) + "\n")
     g2o_pose = g2o.SE2(x,y,theta)
     self.pgo.add_vertex(id, g2o_pose)
Beispiel #9
0
            angles = np.radians(index)
            converted_scans = np.array(
                [np.cos(angles), np.sin(angles)]).T * scans[:, np.newaxis]
            lasers.append(np.array(converted_scans))
            x = float(tokens[2 + num_readings])
            y = float(tokens[3 + num_readings])
            theta = float(tokens[4 + num_readings])
            odoms.append([x, y, theta])

odoms = np.array(odoms)
lasers = np.array(lasers)

# Starting point
optimizer = pose_graph.PoseGraphOptimization()
pose = np.eye(3)
optimizer.add_vertex(0, g2o.SE2(g2o.Isometry2d(pose)), True)

init_pose = np.eye(3)
vertex_idx = 1
registered_lasers = []

max_x = -float('inf')
max_y = -float('inf')
min_x = float('inf')
min_y = float('inf')

for odom_idx, odom in enumerate(odoms):
    # Initialize
    if odom_idx == 0:
        prev_odom = odom.copy()
        prev_idx = 0