Ejemplo n.º 1
0
    def _update(self, t, t0=0, fig='on'):
        """Update function where we update the """
        MAP = self.MAP_
        t -= 1
        # if t == t0:
        #     self._build_first_map(t0,use_lidar_yaw=True)
        #     return

        correlations = np.empty(self.num_p_)
        for i in range(self.num_p_):
            #0) Extract Params from LiDAR and Joints
            lidar_scan, lidar_ts = self.lidar_._get_scan(idx=t)
            neck_angle, head_angle, _ = self.joints_._get_head_angles(
                ts=lidar_ts)
            good_lidar_idxs = self.good_lidar_idx(lidar_scan)
            l_lidar_pts = self._polar_to_cart(lidar_scan,
                                              res_rad=self.lidar_.res_rad)
            l_lidar_pts = l_lidar_pts[:, good_lidar_idxs]
            homo_l_lidar_pts = np.ones((4, l_lidar_pts.shape[1]),
                                       dtype=np.float64)
            homo_l_lidar_pts[:3, :] = l_lidar_pts

            p_curr = self.particles_[:, i]
            # p_curr[2] = self.lidar_.data_[t]['rpy'][0, 2]

            #1) Transform LiDAR Scan to global world frame
            #a) lidar -> body
            R_bl = np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle))
            T_bl = np.array([0, 0, 0.15], dtype=np.float64)
            H_bl = tf.homo_transform(R_bl, T_bl)

            #b) body -> global (only considering yaw atm)
            R_gb = tf.rot_z_axis(p_curr[2])
            T_gb = np.array([p_curr[0], p_curr[1], self.h_lidar_])
            H_gb = tf.homo_transform(R_gb, T_gb)

            #c) apply to lidar_pts
            H_gl = H_gb @ H_bl
            g_lidar_pts = H_gl @ homo_l_lidar_pts

            #d) remove ground (all points with global y < 0.0)
            non_ground_idx = g_lidar_pts[2, :] > 0.0
            g_lidar_pts = g_lidar_pts[:, non_ground_idx]

            #e) Convert  to map cell coords & Compute corr(m_t, y_t)
            m_lidar_pts = (self.lidar_._physicPos2PosVec(
                MAP, g_lidar_pts[:2, :])).astype(np.int64)
            corr = prob.mapCorrelation(MAP['map'], m_lidar_pts)
            correlations[i] = corr
        self.weights_ = prob.update_weights(self.weights_, correlations)

        #Update the best particle position
        max_idx = np.argmax(self.weights_)
        g_particle = self.particles_[:, max_idx]
        self.best_p_[:, t + 1] = g_particle
        m_particle = self.lidar_._physicPos2Pos(MAP, g_particle[:2]).astype(
            np.int64)
        self.best_p_indices_[:, t + 1] = m_particle
        self.MAP_ = MAP
        return MAP
Ejemplo n.º 2
0
    def buildMAP(self, t, x, y, theta):
        # MAP = self.MAP_
        tj0 = self.getJointTime(t)
        scan = self.lidar_.data_[t]['scan'][0]
        neck_angle, head_angle = self.joints_.data_['head_angles'][:, tj0][
            0], self.joints_.data_['head_angles'][:, tj0][1]
        body_2_lidar_rot = tf.homo_transform(
            np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle)),
            [0, 0, 0])
        ground_2_body = tf.homo_transform(tf.rot_z_axis(theta),
                                          [x, y, self.h_lidar_])
        #Got the transforms
        homoscan = np.empty((4, (self.lidar_angles).shape[1]), dtype=np.float)
        homoscan[0, :] = np.cos(self.lidar_angles) * scan
        homoscan[1, :] = np.sin(self.lidar_angles) * scan
        homoscan[2, :] = np.zeros((1, self.lidar_angles.shape[1]))
        homoscan[3, :] = np.ones(self.lidar_angles.shape[1])
        # xscan = np.cos(self.lidar_angles)*scan
        # yscan = np.sin(self.lidar_angles)*scan
        # zscan = np.zeros((1,xscan.shape[1]))
        # Onescan = np.ones(zscan.shape)
        ground_2_lidar = np.dot(ground_2_body, body_2_lidar_rot)
        # homoscan = np.vstack((xscan,yscan,zscan,Onescan))
        trans_scan = (np.dot(ground_2_lidar, homoscan)).astype(np.float16)
        ground_zz = trans_scan[2] < 0.1
        x_new = ((trans_scan[0] - self.MAP_['xmin']) //
                 self.MAP_['res']).astype(np.uint16)
        y_new = ((trans_scan[1] - self.MAP_['ymin']) //
                 self.MAP_['res']).astype(np.uint16)
        x_start = ((x - self.MAP_['xmin']) // self.MAP_['res']).astype(
            np.uint16)
        y_start = ((y - self.MAP_['xmin']) // self.MAP_['res']).astype(
            np.uint16)
        if not (self.psx == x_start and self.psy == y_start):
            self.bresenDict = {}

        self.psx = x_start
        self.psy = y_start
        for x_n, y_n, ground in zip(x_new, y_new, ground_zz):
            if abs(x_n) < self.MAP_['sizex'] and abs(y_n) < self.MAP_['sizey']:
                if (self.bresenDict.get((x_n, y_n)) is None):
                    ray_cells = bresenham2D(x_start, y_start, x_n, y_n)
                    self.bresenDict[(x_n, y_n)] = ray_cells
                else:
                    ray_cells = self.bresenDict[(x_n, y_n)]
                    self.dict_use_count = self.dict_use_count + 1
                    # print("using dict")
                x = np.asarray(ray_cells[0], dtype=int)
                y = np.asarray(ray_cells[1], dtype=int)
                x_end = x[-1]
                y_end = y[-1]
                x = x[:-1]
                y = y[:-1]
                self.log_odds_[x, y] = self.log_odds_[x, y] + np.log(
                    self.p_false_)
                self.MAP_['map'][x, y] = self.log_odds_[x, y] > np.log(1.5)
                self.log_odds_[x_end, y_end] = self.log_odds_[
                    x_end, y_end] + (1 - ground) * np.log(self.p_true_)
Ejemplo n.º 3
0
	def ray_in_world(self,R_pose,head_angle, neck_angle,lidar_rays, theta):
            lidar_rays_x = lidar_rays * np.cos(theta)
            lidar_rays_y = lidar_rays * np.sin(theta)
            homo_lidar_to_head = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0.15],[0,0,0,1]])
            homo_head_to_body = tf.homo_transform(np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle)),np.array([0,0,0.33]))
            homo_body_to_ground = tf.homo_transform(tf.rot_z_axis(R_pose[2]) , np.array([R_pose[0],R_pose[1],0.93]))
            ray_ground = np.linalg.multi_dot([homo_body_to_ground , homo_head_to_body, homo_lidar_to_head, np.array( [lidar_rays_x, lidar_rays_y, np.zeros(lidar_rays_x.shape[0]), np.ones(lidar_rays_x.shape[0])] )   ])
            #ray_ground = homo_body_to_ground @ homo_head_to_body @ homo_lidar_to_head @ np.array( [lidar_rays_x, lidar_rays_y, np.zeros(lidar_rays_x.shape[0]), np.ones(lidar_rays_x.shape[0])] )
            return ray_ground[:,ray_ground[2,:] > 0.2]	
Ejemplo n.º 4
0
	def ray_in_world(self,R_pose,head_angle, neck_angle,lidar_rays, theta):
            homo_lidar_to_head = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0.15],[0,0,0,1]])
            homo_head_to_body = tf.homo_transform(np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle)),np.array([0,0,0.33]))
            homo_body_to_ground = tf.homo_transform(tf.rot_z_axis(R_pose[2]) , np.array([R_pose[0],R_pose[1],0.93]))

            homo_lidar_to_body = np.dot(homo_head_to_body , homo_lidar_to_head)
            homo_lidar_to_ground = np.dot(homo_body_to_ground,homo_lidar_to_body)
            #ray_angle = theta.reshape((1,theta.shape[0]))

            lidar_rays_x = lidar_rays * np.cos(theta)#(ray_angle)
            lidar_rays_y = lidar_rays * np.sin(theta)#(ray_angle)
            #lidar_rays_z = np.zeros((1,lidar_rays_x.shape[1]))
            #ones = np.ones((1,lidar_rays_x.shape[1]))
            ray_ground = np.dot( homo_lidar_to_ground , np.array( [lidar_rays_x, lidar_rays_y, np.zeros(lidar_rays_x.shape[0]), np.ones(lidar_rays_x.shape[0])] )) #np.vstack( (lidar_rays_x, lidar_rays_y, lidar_rays_z, ones) ) )
            return ray_ground[:,ray_ground[2,:] > 0.1]
Ejemplo n.º 5
0
    def _build_first_map(self, t0=0, use_lidar_yaw=True):
        """ Build the first map using first lidar"""
        self.t0 = t0

        MAP = self.MAP_
        print('\n -------- Building the first map --------')

        joint_idx = np.argmin(abs(self.lidar_.data_[t0]['t'][0] - self.joints_.data_['ts'][0]))
        neck_angle, head_angle  = self.joints_.data_['head_angles'][:,joint_idx]

        R_pose = self.lidar_.data_[t0]['pose'][0]
        ray_l = self.lidar_.data_[t0]['scan'][0]

        ray_angles = np.linspace(-2.355, 2.355, len(ray_l))

        valid_id = np.logical_and((ray_l >= 0.1), (ray_l <= 30))
        ray_l = ray_l[valid_id]
        ray_angles = ray_angles[valid_id]

        lidar_to_body = self.lidar_._lidar_to_body_homo(head_angle, neck_angle)

        world_to_body_trans = np.array([R_pose[0], R_pose[1], self.h_com_])
        world_to_body_rot = tf.rot_z_axis(R_pose[2])

        world_to_body_homo = tf.homo_transform(world_to_body_rot, world_to_body_trans)

        x_val = ray_l * np.cos(ray_angles)
        y_val = ray_l * np.sin(ray_angles)
        z_val = np.zeros_like(x_val)
        ones = np.ones_like(x_val)

        points = np.vstack((x_val, y_val, z_val, ones))

        points_body = np.matmul(lidar_to_body, points)
        points_world = np.matmul(world_to_body_homo, points_body)

        points_world = points_world[:2,points_world[2,:] > self.ground_threshold_]

        map_cells = np.array(self.lidar_._physicPos2Pos(MAP, points_world))
        valid_map_id = np.logical_and(np.logical_and((map_cells[0] >= 0), (map_cells[0] < MAP['sizex'])), np.logical_and((map_cells[1] >= 0), map_cells[1] < MAP['sizey']))
        map_cells = map_cells[:,valid_map_id]

        self.log_odds_[map_cells[0], map_cells[1]] += (2 * np.log(9))

        R_pose_cells = self.lidar_._physicPos2Pos(MAP, R_pose[:2])
        self.best_p_[:, t0] = R_pose
        self.best_p_indices_[:, t0] = R_pose_cells

        x = np.append(map_cells[0], R_pose_cells[0])
        y = np.append(map_cells[1], R_pose_cells[1])
        contors = np.array([y, x]).T.astype(np.int)

        mask = np.zeros_like(self.log_odds_)
        cv2.drawContours(image=mask, contours=[contors], contourIdx=0, color=np.log(self.p_false_), thickness=cv2.FILLED)

        self.log_odds_ += mask

        MAP['map'] = 1*(self.log_odds_>self.logodd_thresh_)
        # End code
        self.MAP_ = MAP
Ejemplo n.º 6
0
    def _lidar_to_body_homo(self, head_angle, neck_angle):

        rot_neck = tf.rot_z_axis(neck_angle)
        # trans_neck = np.array([0,0,0])

        neck_homo = tf.homo_transform(rot_neck, [0, 0, 0])

        rot_head = tf.rot_y_axis(head_angle)
        # trans_head = np.array([0,0,0])
        head_homo = tf.homo_transform(rot_head, [0, 0, 0])

        body_to_head_homo = np.array([[1, 0, 0, 0], [0, 1, 0, 0],
                                      [0, 0, 1, 0.33], [0, 0, 0, 1]])

        body_to_head = np.dot(np.dot(body_to_head_homo, neck_homo), head_homo)

        head_to_lidar_homo = np.array([[1, 0, 0, 0], [0, 1, 0, 0],
                                       [0, 0, 1, 0.15], [0, 0, 0, 1]])

        lidar_to_body_homo = np.dot(body_to_head, head_to_lidar_homo)

        return lidar_to_body_homo
Ejemplo n.º 7
0
    def _mapping(self, t=0, use_lidar_yaw=True):
        """Build the map """
        t -= 1
        # Extract a ray from lidar data
        MAP = self.MAP_
        print('\n--------Building the map--------')

        #0) Extract Params from LiDAR and Joints
        lidar_scan, lidar_ts = self.lidar_._get_scan(idx=t)
        neck_angle, head_angle, _ = self.joints_._get_head_angles(ts=lidar_ts)
        good_lidar_idxs = self.good_lidar_idx(lidar_scan)
        l_lidar_pts = self._polar_to_cart(lidar_scan,
                                          res_rad=self.lidar_.res_rad)
        l_lidar_pts = l_lidar_pts[:, good_lidar_idxs]
        homo_l_lidar_pts = np.ones((4, l_lidar_pts.shape[1]), dtype=np.float64)
        homo_l_lidar_pts[:3, :] = l_lidar_pts
        if use_lidar_yaw:
            yaw = self.lidar_.data_[t]['rpy'][0, 2]
            t_gb_x, t_gb_y, _ = self.best_p_[:, t]

        else:
            t_gb_x, t_gb_y, yaw = self.best_p_[:, t]
        p_curr = np.array([t_gb_x, t_gb_y, yaw], dtype=np.float64)

        #1) Transform LiDAR Scan to global world frame
        #a) lidar -> body
        R_bl = np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle))
        T_bl = np.array([0, 0, 0.15], dtype=np.float64)
        H_bl = tf.homo_transform(R_bl, T_bl)

        #b) body -> global (only considering yaw atm)
        R_gb = tf.rot_z_axis(yaw)
        T_gb = np.array([t_gb_x, t_gb_y, self.h_lidar_])
        H_gb = tf.homo_transform(R_gb, T_gb)

        #c) apply to lidar_pts
        H_gl = H_gb @ H_bl
        g_lidar_pts = H_gl @ homo_l_lidar_pts

        #d) remove ground (all points with global y < 0.0)
        non_ground_idx = g_lidar_pts[2, :] > 0.0
        g_lidar_pts = g_lidar_pts[:, non_ground_idx]

        #e) Use bresenham2D to get free/occupied cell locations
        g_curr_pose = p_curr
        m_curr_pose = self.lidar_._physicPos2Pos(MAP, g_curr_pose[:2])
        m_lidar_pts = self.lidar_._physicPos2PosVec(MAP, g_lidar_pts[:2, :])
        for ray in range(g_lidar_pts.shape[1]):
            m_lidar_pt = m_lidar_pts[:, ray]
            ret = bresenham2D(m_curr_pose[0], m_curr_pose[1], m_lidar_pt[0],
                              m_lidar_pt[1]).astype(int)
            free_coords = ret[:, :-1]
            occupied_coords = ret[:, -1]

            #f) Update Log Odds Map (increase all the free cells)
            log_pos = np.log(self.p_true_ / (1 - self.p_true_))
            log_neg = np.log(self.p_false_ / (1 - self.p_false_))
            self.log_odds_[tuple(occupied_coords)] += log_pos
            self.log_odds_[tuple(free_coords)] += log_neg

        MAP['map'][self.log_odds_ >= self.logodd_thresh_] = 1
        MAP['map'][self.log_odds_ < self.logodd_thresh_] = 0
        self.MAP_ = MAP
Ejemplo n.º 8
0
    def _update(self,t,t0=0,fig='on'):
        """Update function where we update the """
        if t == t0:
            self._build_first_map(t0,use_lidar_yaw=True)
            return
        # for one particle

        MAP = self.MAP_
        # joint_idx = np.where(self.lidar_.data_[t]['t'][0]<=self.joints_.data_['ts'][0])[0][0]
        joint_idx = np.argmin(abs(self.lidar_.data_[t]['t'][0] - self.joints_.data_['ts'][0]))
        neck_angle, head_angle = self.joints_.data_['head_angles'][:, joint_idx]

        ray_l = self.lidar_.data_[t]['scan'][0]

        ray_angles = np.linspace(-2.355, 2.355, len(ray_l))

        valid_id = np.logical_and((ray_l >= 0.1), (ray_l <= 30))
        ray_l = ray_l[valid_id]
        ray_angles = ray_angles[valid_id]

        lidar_to_body = self.lidar_._lidar_to_body_homo(head_angle, neck_angle)

        x_val = ray_l * np.cos(ray_angles)
        y_val = ray_l * np.sin(ray_angles)
        z_val = np.zeros_like(x_val)
        ones = np.ones_like(x_val)

        points = np.vstack((x_val, y_val, z_val, ones))

        points_body = np.matmul(lidar_to_body, points)

        correlations = np.zeros(self.num_p_)

        for i in range(self.num_p_):
            R_pose = self.particles_[:,i]

            world_to_body_trans = np.array([R_pose[0], R_pose[1], self.h_com_])
            world_to_body_rot = tf.rot_z_axis(R_pose[2])
            world_to_body_homo = tf.homo_transform(world_to_body_rot, world_to_body_trans)

            points_world = np.matmul(world_to_body_homo, points_body)

            points_world = points_world[:2,points_world[2,:] > self.ground_threshold_]

            map_cells = np.array(self.lidar_._physicPos2Pos(MAP, points_world))
            valid_map_id = np.logical_and(np.logical_and((map_cells[0] >= 0), (map_cells[0] < MAP['sizex'])),
                                          np.logical_and((map_cells[1] >= 0), map_cells[1] < MAP['sizey']))
            map_cells = map_cells[:, valid_map_id]

            correlations[i] = prob.mapCorrelation(MAP['map'], map_cells)

        self.weights_ = prob.update_weights(self.weights_, correlations)

        best_particle_id = np.argmax(self.weights_)
        R_pose = self.particles_[:,best_particle_id]

        #if t % 100 == 0:
        #    print(self.weights_)

        self.best_p_[:,t] = R_pose
        self.best_p_indices_[:,t] = self.lidar_._physicPos2Pos(MAP, R_pose[:2])

        world_to_body_trans = np.array([R_pose[0], R_pose[1], self.h_com_])
        world_to_body_rot = tf.rot_z_axis(R_pose[2])
        world_to_body_homo = tf.homo_transform(world_to_body_rot, world_to_body_trans)

        points_world = np.matmul(world_to_body_homo, points_body)

        points_world = points_world[:2, points_world[2, :] > self.ground_threshold_]

        map_cells = np.array(self.lidar_._physicPos2Pos(MAP, points_world))
        valid_map_id = np.logical_and(np.logical_and((map_cells[0] >= 0), (map_cells[0] < MAP['sizex'])),
                                      np.logical_and((map_cells[1] >= 0), map_cells[1] < MAP['sizey']))
        map_cells = map_cells[:, valid_map_id]

        self.log_odds_[map_cells[0], map_cells[1]] += (2 * np.log(9))

        R_pose_cells = self.best_p_indices_[:,t]

        x = np.append(map_cells[0], R_pose_cells[0])
        y = np.append(map_cells[1], R_pose_cells[1])
        contors = np.array([y, x]).T.astype(np.int)

        mask = np.zeros_like(self.log_odds_)
        cv2.drawContours(image=mask, contours=[contors], contourIdx=0, color=np.log(self.p_false_),
                         thickness=cv2.FILLED)

        self.log_odds_ += mask

        MAP['map'] = self.log_odds_

        self.MAP_ = MAP
        return MAP
Ejemplo n.º 9
0
def Twoglobalpos(lidar_hit,
                 joint_angles,
                 body_angles,
                 pose=None,
                 Particles=None):
    neck_angle = joint_angles[0]  # yaw wrt body frame
    head_angle = joint_angles[1]  # pitch wrt body frame
    roll_gb = body_angles[0]
    pitch_gb = body_angles[1]
    yaw_gb = body_angles[
        2]  # using imu's yaw has better performance than pose's yaw

    # lidar wrt head
    z_hl = 0.15
    H_hl = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, z_hl],
                     [0, 0, 0, 1]])  # no rotation

    # head wrt body
    z_bh = 0.33
    T_bh = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, z_bh], [0, 0, 0,
                                                                   1]])
    Rz = tf.rot_z_axis(neck_angle)
    Rz = tf.homo_transform(Rz, np.array([0, 0, 1]))
    Ry = tf.rot_y_axis(head_angle)
    Ry = tf.homo_transform(Ry, np.array([0, 0, 1]))
    R_bh = np.dot(Rz, Ry)
    H_bh = np.dot(T_bh, R_bh)

    if Particles is None:  # for mapping
        # body wrt world
        x_gb = pose[0]
        y_gb = pose[1]
        z_gb = 0.93
        T_gb = np.array([[1, 0, 0, x_gb], [0, 1, 0, y_gb], [0, 0, 1, z_gb],
                         [0, 0, 0, 1]])

        Rb2g_yaw = tf.rot_z_axis(yaw_gb)
        Rb2g_pitch = tf.rot_y_axis(pitch_gb)
        Rb2g_roll = tf.rot_x_axis(roll_gb)
        Hb2g_yaw = tf.homo_transform(Rb2g_yaw, np.array([0, 0, 1]))
        Hb2g_pitch = tf.homo_transform(Rb2g_pitch, np.array([0, 0, 1]))
        Hb2g_roll = tf.homo_transform(Rb2g_roll, np.array([0, 0, 1]))
        R_gb = np.dot(np.dot(Hb2g_yaw, Hb2g_pitch), Hb2g_roll)
        H_gb = np.dot(T_gb, R_gb)
        # lidar wrt world
        H_gl = H_gb.dot(H_bh).dot(H_hl)
        lidar_hit = np.vstack((lidar_hit, np.ones(
            (1, lidar_hit.shape[1]))))  # 4*n
        world_hit = np.dot(H_gl, lidar_hit)
        # ground check, keep hits not on ground
        not_floor = world_hit[2] > 0.1
        world_hit = world_hit[:, not_floor]

        return world_hit[:3, :]

    else:  # for particles update
        nums = Particles.shape[1]
        poses = Particles
        particles_hit = []
        lidar_hit = np.vstack((lidar_hit, np.ones((1, lidar_hit.shape[1]))))

        for i in range(nums):
            # body wrt world
            T_gb = np.array([[1, 0, 0, poses[0, i]], [0, 1, 0, poses[1, i]],
                             [0, 0, 1, 0.93], [0, 0, 0, 1]])

            yaw_gb = poses[2, i]
            Rb2g_yaw = tf.rot_z_axis(yaw_gb)
            Rb2g_pitch = tf.rot_y_axis(pitch_gb)
            Rb2g_roll = tf.rot_x_axis(roll_gb)

            Hb2g_yaw = tf.homo_transform(Rb2g_yaw, np.array([0, 0, 1]))
            Hb2g_pitch = tf.homo_transform(Rb2g_pitch, np.array([0, 0, 1]))
            Hb2g_roll = tf.homo_transform(Rb2g_roll, np.array([0, 0, 1]))

            R_gb = np.dot(np.dot(Hb2g_yaw, Hb2g_pitch), Hb2g_roll)

            H_gb = np.dot(T_gb, R_gb)

            # lidar wrt world
            H_gl = H_gb.dot(H_bh).dot(H_hl)
            world_hit = np.dot(H_gl, lidar_hit)[:3, :]

            not_floor = world_hit[2] > 0.1
            particles_hit.append(world_hit[:, not_floor])

        return np.transpose(np.asarray(particles_hit), (1, 2, 0))
Ejemplo n.º 10
0
    def _update(self, t, t0=0, fig='on'):
        """Update function where we update the """
        if t == t0:
            self._build_first_map(t0, use_lidar_yaw=True)
            return

        #TODO: student's input from here

        n_thresh = 5
        MAP = self.MAP_
        #trajectory update
        ranges = self.lidar_.data_[t]["scan"][0]
        lidar_t = self.lidar_.data_[t]["t"]
        lidar_pose = self.lidar_.data_[t]["pose"][0]
        #lidar_yaw = self.lidar_.data_[self.t0]["rpy"][0][2]
        joint_ind = np.abs(self.joints_.data_["ts"][0] -
                           lidar_t).argmin()  #time sync
        angles = np.array([np.arange(-135, 135.25, 0.25) * np.pi / 180.])

        #limit scan range
        indv_range = np.logical_and((ranges < 30), (ranges > 0.1))
        ranges = ranges[indv_range]
        angles = angles[0]
        angles = angles[indv_range]

        x_lidar = ranges * np.cos(angles)
        y_lidar = ranges * np.sin(angles)
        length = len(x_lidar)
        z_lidar = np.zeros(length)
        w_lidar = np.ones(length)
        p_lidar = np.vstack([x_lidar, y_lidar, z_lidar, w_lidar])

        neck_angle = self.joints_.data_["head_angles"][0][joint_ind]
        head_angle = self.joints_.data_["head_angles"][1][joint_ind]

        #lidar2body
        body_2_lidar_rot = np.dot(tf.rot_z_axis(neck_angle),
                                  tf.rot_y_axis(head_angle))
        # Transition from the body to the lidar frame (lidar is 15cm above the head. See config_slam.pdf for more details)
        body_2_lidar_trans = np.array([0, 0, 0.15])
        body_2_lidar_homo = tf.homo_transform(body_2_lidar_rot,
                                              body_2_lidar_trans)
        p_body = np.dot(body_2_lidar_homo, p_lidar)

        corr = np.zeros(self.num_p_)

        for i in range(self.num_p_):

            pose_i = self.particles_[:, i]
            world_2_body_rot = tf.rot_z_axis(pose_i[2])
            world_2_body_trans = np.array([pose_i[0], pose_i[1], 0.93])
            world_2_part_homo = tf.homo_transform(world_2_body_rot,
                                                  world_2_body_trans)
            p_world_est = np.dot(world_2_part_homo, p_body)

            ground_ind = np.argwhere(p_world_est[2] < 0.1)
            p_world_est = np.delete(p_world_est, ground_ind, 1)
            p_world_est = p_world_est[0:2, :]

            Ex = np.ceil(
                (p_world_est[0, :] - MAP['xmin']) / MAP['res']).astype(
                    np.int16) - 1
            Ey = np.ceil(
                (p_world_est[1, :] - MAP['ymin']) / MAP['res']).astype(
                    np.int16) - 1

            obst = np.vstack([Ex, Ey])

            corr[i] = prob.mapCorrelation(MAP["map"], obst)

        #update weights

        self.weights_ = prob.update_weights(self.weights_, corr)
        max_ = np.argmax(self.weights_)
        max_pose = self.particles_[:, max_]
        self.best_p_[:, t] = max_pose

        ind_x = np.ceil(
            (max_pose[0] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        ind_y = np.ceil(
            (max_pose[1] - MAP['ymin']) / MAP['res']).astype(np.int16) - 1

        self.best_p_indices_[0, t] = ind_x
        self.best_p_indices_[1, t] = ind_y

        if t == 1:

            self.best_p_indices_[0, t - 1] = ind_x
            self.best_p_indices_[1, t - 1] = ind_y

        n_eff = 1.0 / (np.sum(self.weights_)**2)

        if n_eff < self.percent_eff_p_thresh_ * self.num_p_:
            self.particles_, self.weights_ = prob.stratified_resampling(
                self.particles_, self.weights_, self.num_p_)

        #self.time_ =  np.empty(self.num_data_)

        #map_update

        world_2_body_rot = tf.rot_z_axis(max_pose[2])
        world_2_body_trans = np.array([max_pose[0], max_pose[1], 0.93])
        world_2_part_homo = tf.homo_transform(world_2_body_rot,
                                              world_2_body_trans)
        p_world_est = np.dot(world_2_part_homo, p_body)

        ground_ind = np.argwhere(p_world_est[2] < 0.1)
        p_world_est = np.delete(p_world_est, ground_ind, 1)
        p_world_est = p_world_est[0:2, :]

        #Ex = np.ceil((p_world_est[0,:] - MAP['xmin']) / MAP['res'] ).astype(np.int16)-1
        #Ey = np.ceil((p_world_est[1,:] - MAP['ymin']) / MAP['res'] ).astype(np.int16)-1

        #map into map index
        sx = np.ceil(
            (max_pose[0] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        sy = np.ceil(
            (max_pose[1] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        Ex = np.ceil((p_world_est[0, :] - MAP['xmin']) / MAP['res']).astype(
            np.int16) - 1
        Ey = np.ceil((p_world_est[1, :] - MAP['ymin']) / MAP['res']).astype(
            np.int16) - 1

        #brehensam 2D
        num = len(Ex)
        for i in range(num):
            r = bresenham2D(sx, sy, Ex[i], Ey[i])
            r = r.astype(np.int16)
            self.log_odds_[r[0], r[1]] += np.log(self.p_false_)

        self.log_odds_[Ex,
                       Ey] += (np.log(self.p_true_) - np.log(self.p_false_))

        MAP["map"] = MAP["map"].astype(np.float64)
        MAP["map"] += self.log_odds_

        MAP["map"] = 1.0 - 1.0 / (1.0 + np.exp(MAP["map"]))

        obst = MAP["map"] > self.p_thresh_
        free = MAP["map"] < 0.2
        unexp = (MAP["map"] > 0.2) & (MAP["map"] < self.p_thresh_)

        MAP["map"][obst] = 0
        MAP["map"][free] = 1
        MAP["map"][unexp] = 0.5

        #End student's input

        self.MAP_ = MAP
        return self.MAP_
Ejemplo n.º 11
0
    def _build_first_map(self, t0=0, use_lidar_yaw=True):
        """Build the first map using first lidar"""
        self.t0 = t0
        # Extract a ray from lidar data
        MAP = self.MAP_
        print('\n--------Doing build the first map--------')

        #TODO: student's input from here

        ##Get data from Lidar data, joint data & time sync

        ranges = self.lidar_.data_[self.t0]["scan"][0]
        lidar_t = self.lidar_.data_[self.t0]["t"]
        lidar_pose = self.lidar_.data_[self.t0]["pose"][0]
        lidar_yaw = self.lidar_.data_[self.t0]["rpy"][0][2]
        joint_ind = np.abs(self.joints_.data_["ts"][0] -
                           lidar_t).argmin()  #time sync
        angles = np.array([np.arange(-135, 135.25, 0.25) * np.pi / 180.])

        #limit scan range
        indv_range = np.logical_and((ranges < 30), (ranges > 0.1))
        ranges = ranges[indv_range]
        angles = angles[0]
        angles = angles[indv_range]

        #x,y positions in lidar frame

        x_lidar = ranges * np.cos(angles)
        y_lidar = ranges * np.sin(angles)
        length = len(x_lidar)
        z_lidar = np.zeros(length)
        w_lidar = np.ones(length)
        p_lidar = np.vstack([x_lidar, y_lidar, z_lidar, w_lidar])

        neck_angle = self.joints_.data_["head_angles"][0][joint_ind]
        head_angle = self.joints_.data_["head_angles"][1][joint_ind]

        ## lidar2body & body2world

        #lidar2body
        body_2_lidar_rot = np.dot(tf.rot_z_axis(neck_angle),
                                  tf.rot_y_axis(head_angle))
        # Transition from the body to the lidar frame (lidar is 15cm above the head. See config_slam.pdf for more details)
        body_2_lidar_trans = np.array([0, 0, 0.15])
        body_2_lidar_homo = tf.homo_transform(body_2_lidar_rot,
                                              body_2_lidar_trans)
        p_body = np.dot(body_2_lidar_homo, p_lidar)

        #body2world
        world_2_body_rot = tf.rot_z_axis(lidar_yaw)
        world_2_body_trans = np.array([lidar_pose[0], lidar_pose[1], 0.93])
        world_2_part_homo = tf.homo_transform(world_2_body_rot,
                                              world_2_body_trans)
        p_world = np.dot(world_2_part_homo, p_body)

        #ground removal
        ground_ind = np.argwhere(p_world[2] < 0.1)
        p_world = np.delete(p_world, ground_ind, 1)
        p_world = p_world[0:2, :]

        #map into map index
        sx = np.ceil(
            (lidar_pose[0] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        sy = np.ceil(
            (lidar_pose[1] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        Ex = np.ceil(
            (p_world[0, :] - MAP['xmin']) / MAP['res']).astype(np.int16) - 1
        Ey = np.ceil(
            (p_world[1, :] - MAP['ymin']) / MAP['res']).astype(np.int16) - 1

        #brehensam 2D
        num = len(Ex)
        for i in range(num):
            r = bresenham2D(sx, sy, Ex[i], Ey[i])
            r = r.astype(np.int16)
            self.log_odds_[r[0], r[1]] += np.log(self.p_false_)

        self.log_odds_[Ex,
                       Ey] += (np.log(self.p_true_) - np.log(self.p_false_))

        MAP["map"] = MAP["map"].astype(np.float64)
        MAP["map"] += self.log_odds_

        MAP["map"] = 1.0 - 1.0 / (1.0 + np.exp(MAP["map"]))

        obst = MAP["map"] > self.p_thresh_
        free = MAP["map"] < 0.2
        unexp = (MAP["map"] > 0.2) & (MAP["map"] < self.p_thresh_)

        MAP["map"][obst] = 0
        MAP["map"][free] = 1
        MAP["map"][unexp] = 0.5

        #End student's input

        self.MAP_ = MAP
Ejemplo n.º 12
0
    def _update(self, t, t0=0, fig='on'):
        """Update function where we update the """

        # MAP = self.MAP_
        if t == t0:
            self._build_first_map(t0, use_lidar_yaw=True)
            return

        #TODO: student's input from here
        tj0 = self.getJointTime(t)
        neck_angle, head_angle = self.joints_.data_['head_angles'][:, tj0][
            0], self.joints_.data_['head_angles'][:, tj0][1]
        body_2_lidar_rot = tf.homo_transform(
            np.dot(tf.rot_z_axis(neck_angle), tf.rot_y_axis(head_angle)),
            [0, 0, 0])
        scan = self.lidar_.data_[t]['scan'][0]
        xscan = np.cos(self.lidar_angles) * scan
        yscan = np.sin(self.lidar_angles) * scan
        zscan = np.zeros((1, xscan.shape[1]))
        Onescan = np.ones(zscan.shape)
        corr = []
        for i in range(self.num_p_):
            pose_i = self.particles_[:, i]
            ground_2_body = tf.homo_transform(tf.rot_z_axis(
                pose_i[2]), [pose_i[0], pose_i[1], self.h_lidar_])
            #Got the transforms
            ground_2_lidar = np.dot(ground_2_body, body_2_lidar_rot)
            homoscan = np.vstack((xscan, yscan, zscan, Onescan))
            trans_scan = np.dot(ground_2_lidar, homoscan)
            # vp = np.vstack((xscan,yscan))
            # print("zz",min(trans_scan[1]))
            trans_scan = trans_scan[:, abs(trans_scan[0]) < 20]
            trans_scan = trans_scan[:, abs(trans_scan[1]) < 20]
            x_ind, y_ind = self.getMapCoord(trans_scan[0], trans_scan[1])

            occupied_indices = np.vstack((x_ind, y_ind))
            corr.append(mapCorrelation(self.MAP_['map'], occupied_indices))
        # print(self.num_p_)
        # corr.append(self.getCorrMap(self.MAP_['map'],x_ind,y_ind))
# space = 0.02
# xs = np.arange(pose_i[0]-space,pose_i[0]+space,space/4)
# ys = np.arange(pose_i[1]-space,pose_i[1]+space,space/4)
#self.weights_[i] = self.weights_[i]*np.sum(mapCorrelation(self.MAP_['map'], np.array([self.MAP_['xmin'],self.MAP_['xmax']]), \
# np.array([self.MAP_['ymin'],self.MAP_['ymax']]), vp, xs, ys))
#self.weights_[i] = self.weights_[i]*mapCorrelation(self.MAP_['map'],occupied_indices)

#self.weights_ = self.weights_/np.sum(self.weights_)
        corr = np.asarray(corr)
        self.weights_ = prob.update_weights(self.weights_, corr)
        best_p_i = np.argmax(self.weights_)
        best_p = self.particles_[:, best_p_i]
        x = best_p[0]
        y = best_p[1]
        theta = best_p[2]
        self.buildMAP(t, x, y, theta)
        self.best_p_[:, t] = best_p
        self.best_p_indices_[:, t] = self.getMapCoord(x, y)

        #End student's input

        # self.MAP_ = MAP
        return self.MAP_