def __init__(self,
              position: Position = Position(),
              orientation: float = 0):
     if type(position) is np.ndarray:
         raise TypeError(
             'You need to pass a Position to Pose. Use Position.from_array() to convert it.'
         )
     self._orientation = orientation
     self._position = position.copy()
def create_basic_hallway(orientation=0):
    return [
        Wall(
            Position(-2, 6).rotate(orientation),
            Position(-2, -6).rotate(orientation)),
        Wall(
            Position(+2, 6).rotate(orientation),
            Position(+2, -6).rotate(orientation))
    ]
Exemple #3
0
    def generate(self, pose: Pose, check_cache=False):
        if check_cache:
            if self.scan_exist(pose):
                return self.load_scan(pose)

        origin = pose.position
        orientation = pose.orientation + np.pi / 2  # The first point taken by the sensor is parallel to the y axis
        pts = []
        for beam_id in range(0, self.nb_beam):
            angle_rad = beam_id / self.nb_beam * 2 * math.pi + orientation
            end_beam = origin + Position.from_angle(angle_rad,
                                                    norm=self.max_range_beam)
            closest_inter = None
            for wall in self.walls:
                # inter = intersection_between_ray_and_segment(origin, end_beam - origin, wall.p1, wall.p2)
                inter = intersection_between_segments(origin, end_beam,
                                                      wall.p1, wall.p2)
                if inter is None:
                    continue
                if closest_inter is None or (closest_inter - origin).norm > (
                        inter - origin).norm:
                    closest_inter = inter

            if closest_inter is not None:
                point = self.sensor_model.apply_noise(origin,
                                                      closest_inter) - origin
                scan_frame_point = point.rotate(-pose.orientation)
                pts.append(scan_frame_point.to_tuple())
        scan = np.array(pts)
        self.save_scan(pose, scan)
        return scan
def intersection_between_lines(a1: Position, a2: Position, b1: Position,
                               b2: Position) -> Position:
    s = np.vstack([a1.array, a2.array, b1.array, b2.array])
    h = np.hstack((s, np.ones((4, 1))))
    l1 = np.cross(h[0], h[1])  # first line
    l2 = np.cross(h[2], h[3])  # second line
    x, y, z = np.cross(l1, l2)  # point of intersection
    if z == 0:
        raise ValueError('Parallel lines')
    return Position(x / z, y / z)
def create_bumpy_hallway():
    step_x = 0.5
    step_y = 1
    hallway_width = 3
    walls_template = [
        Wall(Position(hallway_width, 0), Position(hallway_width + step_x, 0)),
        Wall(Position(hallway_width, 0), Position(hallway_width, step_y)),
        Wall(Position(hallway_width, step_y),
             Position(hallway_width + step_x, step_y)),
        Wall(Position(hallway_width + step_x, step_y),
             Position(hallway_width + step_x, 2 * step_y))
    ]
    walls = []
    walls += walls_template
    walls += [w.copy().move(0, 4 * step_y) for w in walls_template]
    walls += [w.copy().move(0, 2 * step_y) for w in walls_template]
    walls += [w.copy().move(0, -2 * step_y) for w in walls_template]
    walls += [w.copy().move(0, -4 * step_y) for w in walls_template]

    walls += [w.copy().flix_x() for w in walls]
    return walls
Exemple #6
0
    # poses = [origin,
    #          Pose(Position( 1, 0), 0),
    #          Pose(Position( 2, 0), 0),
    #          Pose(Position( 4, 0), 0),
    #          Pose(Position( 5, 0), 0),
    #          Pose(Position( 6, 0), 0),
    #
    #          Pose(Position( 6, 1), np.deg2rad(90)),
    #          Pose(Position( 6, 4), np.deg2rad(90)),
    #          Pose(Position( 6, 8), np.deg2rad(90)),
    #          ]

    orientation = np.deg2rad(0)
    walls, poses = from_ascii_art(art,
                                  origin_offset=Position(1, 1),
                                  orientation=orientation)
    # poses = [Pose.from_values(p.x, p.y, orientation) for p in poses]
    # poses[0] = origin
    sg = ScanGenerator(walls, nb_beam=180)
    print("Generating map...")

    scans = [sg.generate(p, check_cache=True).transpose() for p in poses]
    print("done!")
    # init_tf = move.to_tf()

    icp = ICP()
    #icp.set_default()
    icp.load_from_dict(ICP.BASIC_CONFIG)
    no_penalties = [[] for p in poses]
    penalties_x = [
def normalize(vec: Position) -> Position:
    if vec.norm == 0:
        raise ZeroDivisionError
    return vec.copy() / vec.norm
 def position(self, position: Position):
     self._position = position.copy()
 def from_values(cls, x: float, y: float, orientation: float = 0) -> 'Pose':
     return cls(Position(x, y), orientation)
 def from_dict(cls, my_dict: Dict[str, float]) -> 'Pose':
     return cls(Position(my_dict['x'], my_dict['y']),
                my_dict['orientation'])
def from_ascii_art(ascii_art, origin_offset=None, orientation=0):
    print(ascii_art)
    if origin_offset is None:
        origin_offset = Position()
    grid = [[c for c in l] for l in ascii_art.splitlines()]
    cardinals = [(-1, 0), (0, -1)]
    w = len(grid[0])
    h = len(grid)
    cells = []
    origin = None
    checkpoints = {}
    for y, l in enumerate(grid):
        for x, val in enumerate(l):
            is_free = val != WALL
            if val == ORIGIN:
                origin = x, y
                checkpoints[0] = origin
            if val in NUMBERS:
                checkpoints[int(val)] = x, y
            for cx, cy in cardinals:
                px = cx + x
                py = cy + y
                if 0 <= px < w and 0 <= py < h:
                    is_free_c = grid[py][px] != WALL
                    if is_free != is_free_c:
                        # print(f"Add wall at {x},{y} in {cx},{cy}")
                        cells.append((x, y, cy == 0))

    if origin is None:
        raise RuntimeError("No origin found, missing the '*' in map")

    ox, oy = origin

    def to_real_world(cell_x, cell_y, offset=0.4):
        ax = (cell_x - ox - offset) * cell_w
        ay = (cell_y - oy - offset) * cell_h
        x = ax * cos(orientation) - ay * sin(orientation)
        y = ax * sin(orientation) + ay * cos(orientation)
        return x + origin_offset.x, y + origin_offset.y

    cell_w = 3
    cell_h = -3  # Matplotlib has the origin in the lower left corner, not the upper left conner
    walls = []
    for x, y, is_vertical in cells:
        if is_vertical:
            w = Wall(Position(*to_real_world(x, y)),
                     Position(*to_real_world(x, y + 1)))
        else:
            w = Wall(Position(*to_real_world(x, y)),
                     Position(*to_real_world(x + 1, y)))
        walls.append(w)

    if len(checkpoints) > 1:
        ordered_checkpoints = list(
            collections.OrderedDict(sorted(checkpoints.items())).values())
        # linear_path += [origin]  # So it loop
        path = [origin]
        for a, b in zip(ordered_checkpoints, ordered_checkpoints[1:]):
            path += find_shortest_path(ascii_art, a, b)
    path = subsample_path(path)
    # path = subsample_path(list(path))
    pose_path = [
        Pose.from_values(*to_real_world(x, y, offset=0.0), orientation)
        for x, y in path
    ]
    return walls, pose_path
 def move(self, x, y):
     m = Position.from_list([x, y])
     self.p1 += m
     self.p2 += m
     return self