Beispiel #1
0
 def pixel_to_world(self, pixel_coords):
     """
     Convert map pixel coordinates to world coordinates
     Note that this does not check whether the coordinates
     are in bounds.
     :param pixel_coords: either a n-elem numpy array [x, y] or a n x 2 array with n points
     :return: same as input, but in world coordinates
     """
     return pixel_to_world(pixel_coords, self._origin, self._resolution)
def get_physical_coords_from_drawing(map_shape, resolution, origin,
                                     drawing_coords):
    """
    Inverse of the get_drawing_coordinates_from_physical function

    :param map_shape: shape of the map
    :param resolution: resolution of the map
    :param origin: origin of the map
    :param drawing_coords:  drawing coordinates
    :return: phusical coordinates from drawing
    """
    # this makes a copy to make sure that we do not change original coords
    drawing_coords = np.array(drawing_coords)
    assert drawing_coords.ndim <= 2
    assert drawing_coords.shape[drawing_coords.ndim - 1] == 2
    assert np.array(map_shape).ndim == 1
    drawing_coords[..., 1] = map_shape[0] - 1 - drawing_coords[..., 1]
    return pixel_to_world(drawing_coords, origin, resolution)
Beispiel #3
0
    def _override_primitive_kernels(self, motion_primitives, footprint,
                                    use_full_kernels):
        resolution = motion_primitives.get_resolution()
        print('Setting up motion primitive kernels..')
        for p in motion_primitives.get_primitives():

            primitive_start = pixel_to_world(np.zeros((2, )), np.zeros((2, )),
                                             resolution)
            primitive_states = p.get_intermediate_states().copy()
            primitive_states[:, :2] += primitive_start

            full_cv_kernel_x = []
            full_cv_kernel_y = []
            for pose in primitive_states:
                kernel = get_pixel_footprint(pose[2], footprint, resolution)

                kernel_center = (kernel.shape[1] // 2, kernel.shape[0] // 2)
                kernel = np.where(kernel)

                px, py = world_to_pixel(pose[:2], np.zeros((2, )), resolution)
                full_cv_kernel_x.append(kernel[1] + (px - kernel_center[0]))
                full_cv_kernel_y.append(kernel[0] + (py - kernel_center[1]))

            full_cv_kernel_x = np.hstack(full_cv_kernel_x)
            full_cv_kernel_y = np.hstack(full_cv_kernel_y)
            full_cv_kernel = np.column_stack(
                (full_cv_kernel_x, full_cv_kernel_y)).astype(np.int32)

            row_view = np.ascontiguousarray(full_cv_kernel).view(
                np.dtype(
                    (np.void,
                     full_cv_kernel.dtype.itemsize * full_cv_kernel.shape[1])))
            _, idx = np.unique(row_view, return_index=True)
            full_cv_kernel = np.ascontiguousarray(full_cv_kernel[idx])

            if use_full_kernels:
                self.set_primitive_collision_pixels(p.starttheta_c,
                                                    p.motprimID,
                                                    full_cv_kernel)
            else:
                min_x, max_x = np.amin(full_cv_kernel[:, 0]), np.amax(
                    full_cv_kernel[:, 0])
                min_y, max_y = np.amin(full_cv_kernel[:, 1]), np.amax(
                    full_cv_kernel[:, 1])

                temp_img = np.zeros((max_y - min_y + 1, max_x - min_x + 1),
                                    dtype=np.uint8)
                temp_img[full_cv_kernel[:, 1] - min_y,
                         full_cv_kernel[:, 0] - min_x] = 255
                _, contours, _ = cv2.findContours(temp_img.copy(),
                                                  cv2.RETR_EXTERNAL,
                                                  cv2.CHAIN_APPROX_NONE)
                contour = contours[0].reshape(-1, 2)

                perimeter_kernel = np.column_stack(
                    (contour[:, 0] + min_x,
                     contour[:, 1] + min_y)).astype(np.int32)

                self.set_primitive_collision_pixels(p.starttheta_c,
                                                    p.motprimID,
                                                    perimeter_kernel)

        print('Done.')
Beispiel #4
0
def run_sbpl_tricycle_motion_primitive_planning(
        number_of_angles, target_v, target_w, tricycle_angle_samples,
        primitives_duration, footprint_scale, do_debug_motion_primitives):
    original_costmap, static_path, test_maps = get_random_maps_squeeze_between_obstacle_in_corridor_on_path(
    )

    test_map = test_maps[0]
    resolution = test_map.get_resolution()

    motion_primitives = forward_model_tricycle_motion_primitives(
        resolution=resolution,
        number_of_angles=number_of_angles,
        target_v=target_v,
        tricycle_angle_samples=tricycle_angle_samples,
        primitives_duration=primitives_duration,
        front_wheel_rotation_speedup=10,
        refine_dt=0.10,
        v_samples=1)

    if do_debug_motion_primitives:
        debug_motion_primitives(motion_primitives)

    add_wall_to_static_map(test_map, (1, -4.6), (1.5, -4.6))
    footprint = IndustrialTricycleV1Dimensions.footprint() * footprint_scale

    plan_xytheta, plan_xytheta_cell, actions, plan_time, solution_eps, environment = perform_single_planning(
        planner_name='arastar',
        footprint=footprint,
        motion_primitives=motion_primitives,
        forward_search=False,
        costmap=test_map,
        start_pose=static_path[0],
        goal_pose=static_path[-10],
        target_v=target_v,
        target_w=target_w,
        allocated_time=np.inf,
        cost_scaling_factor=4.,
        debug=False,
        use_full_kernels=True)

    params = environment.get_params()
    costmap = environment.get_costmap()

    img = prepare_canvas(costmap.shape)
    draw_world_map_with_inflation(img, costmap)
    start_pose = static_path[0]
    start_pose[:2] -= test_map.get_origin()
    goal_pose = static_path[-10]
    goal_pose[:2] -= test_map.get_origin()

    trajectory_through_primitives = np.array([start_pose])

    plan_xytheta_cell = np.vstack(
        ([environment.xytheta_real_to_cell(start_pose)], plan_xytheta_cell))
    for i in range(len(actions)):
        angle_c, motor_prim_id = actions[i]
        collisions = environment.get_primitive_collision_pixels(
            angle_c, motor_prim_id)
        pose_cell = plan_xytheta_cell[i]
        assert pose_cell[2] == angle_c
        collisions[:, 0] += pose_cell[0]
        collisions[:, 1] += pose_cell[1]

        primitive_start = pixel_to_world(pose_cell[:2], np.zeros((2, )),
                                         test_map.get_resolution())
        primitive = motion_primitives.find_primitive(angle_c, motor_prim_id)
        primitive_states = primitive.get_intermediate_states().copy()
        primitive_states[:, :2] += primitive_start

        trajectory_through_primitives = np.vstack(
            (trajectory_through_primitives, primitive_states))

    for pose in trajectory_through_primitives:
        draw_robot(img,
                   footprint,
                   pose,
                   params.cellsize_m,
                   np.zeros((2, )),
                   color=70,
                   color_axis=(0, 2))

    # draw_trajectory(img, params.cellsize_m, np.zeros((2,)), plan_xytheta)
    draw_robot(img, footprint, start_pose, params.cellsize_m, np.zeros((2, )))
    draw_robot(img, footprint, goal_pose, params.cellsize_m, np.zeros((2, )))
    magnify = 2
    img = cv2.resize(img,
                     dsize=(0, 0),
                     fx=magnify,
                     fy=magnify,
                     interpolation=cv2.INTER_NEAREST)
    cv2.imshow("planning result", img)
    cv2.waitKey(-1)
Beispiel #5
0
def forward_model_tricycle_motion_primitives(resolution,
                                             number_of_angles,
                                             target_v,
                                             tricycle_angle_samples,
                                             primitives_duration,
                                             front_wheel_rotation_speedup,
                                             v_samples,
                                             refine_dt=0.1):

    max_front_wheel_angle = IndustrialTricycleV1Dimensions.max_front_wheel_angle(
    )
    front_wheel_from_axis = IndustrialTricycleV1Dimensions.front_wheel_from_axis(
    )
    max_front_wheel_speed = IndustrialTricycleV1Dimensions.max_front_wheel_speed(
    )
    front_column_model_p_gain = IndustrialTricycleV1Dimensions.front_column_model_p_gain(
    )

    def forward_model(pose, initial_states, dt, control_signals):
        current_wheel_angles = initial_states[:, 0]
        next_poses, next_angles = tricycle_kinematic_step(
            pose,
            current_wheel_angles,
            dt,
            control_signals,
            max_front_wheel_angle,
            front_wheel_from_axis,
            max_front_wheel_speed,
            front_column_model_p_gain,
            model_front_column_pid=False)
        next_state = initial_states.copy()
        next_state[:, 0] = next_angles[:]
        next_state[:, 1] = control_signals[:, 0]
        next_state[:, 2] = 0.  # angular velocity is ignored
        return next_poses, next_state

    pose_evolution, state_evolution, control_evolution, refine_dt = control_choices_tricycle_exhaustive(
        forward_model,
        wheel_angle=0.,
        max_v=target_v,
        exhausitve_dt=refine_dt * front_wheel_rotation_speedup,
        refine_dt=refine_dt,
        n_steps=1,
        theta_samples=tricycle_angle_samples,
        v_samples=v_samples,
        extra_copy_n_steps=primitives_duration - 1,
        max_front_wheel_angle=max_front_wheel_angle,
        max_front_wheel_speed=max_front_wheel_speed)

    primitives = []
    for start_theta_discrete in range(number_of_angles):
        current_primitive_cells = []
        for primitive_id, (ego_poses, controls) in enumerate(
                zip(pose_evolution, control_evolution)):
            ego_poses = np.vstack(([[0., 0., 0.]], ego_poses))
            start_angle = angle_discrete_to_cont(start_theta_discrete,
                                                 number_of_angles)
            poses = from_egocentric_to_global(
                ego_poses,
                ego_pose_in_global_coordinates=np.array([0., 0., start_angle]))

            # to model precision loss while converting to .mprim file, we round it here
            poses = np.around(poses, decimals=4)
            last_pose = poses[-1]
            end_cell = np.zeros((3, ), dtype=int)

            center_cell_shift = pixel_to_world(np.zeros((2, )), np.zeros(
                (2, )), resolution)
            end_cell[:2] = world_to_pixel(center_cell_shift + last_pose[:2],
                                          np.zeros((2, )), resolution)
            perfect_last_pose = np.zeros((3, ), dtype=float)
            end_cell[2] = angle_cont_to_discrete(last_pose[2],
                                                 number_of_angles)

            current_primitive_cells.append(tuple(end_cell))

            perfect_last_pose[:2] = pixel_to_world(end_cell[:2], np.zeros(
                (2, )), resolution)
            perfect_last_pose[2] = angle_discrete_to_cont(
                end_cell[2], number_of_angles)

            action_cost_multiplier = 1

            primitive = MotionPrimitive(
                primitive_id=primitive_id,
                start_theta_discrete=start_theta_discrete,
                action_cost_multiplier=action_cost_multiplier,
                end_cell=end_cell,
                intermediate_states=poses,
                control_signals=controls)
            primitives.append(primitive)

    return MotionPrimitives(resolution=resolution,
                            number_of_angles=number_of_angles,
                            mprim_list=primitives)
Beispiel #6
0
def forward_model_diffdrive_motion_primitives(resolution,
                                              number_of_angles,
                                              target_v,
                                              target_w,
                                              w_samples_in_each_direction,
                                              primitives_duration,
                                              refine_dt=0.05):
    def forward_model(pose, state, dt, control_signals):
        new_pose = kinematic_body_pose_motion_step(
            pose=pose,
            linear_velocity=control_signals[:, 0],
            angular_velocity=control_signals[:, 1],
            dt=dt)
        next_state = state.copy()
        next_state[:, 0] = control_signals[:, 0]
        next_state[:, 1] = control_signals[:, 1]
        return new_pose, next_state

    pose_evolution, state_evolution, control_evolution, refine_dt, control_costs = control_choices_diff_drive_exhaustive(
        max_v=target_v,
        max_w=target_w,
        forward_model=forward_model,
        initial_state=(0., 0.),
        refine_dt=refine_dt,
        exhausitve_dt=refine_dt * primitives_duration,
        n_steps=1,
        w_samples_in_each_direction=w_samples_in_each_direction,
        enable_turn_in_place=True,
        v_samples=1)

    primitives = []
    for start_theta_discrete in range(number_of_angles):
        current_primitive_cells = []
        for primitive_id, (ego_poses, controls) in enumerate(
                zip(pose_evolution, control_evolution)):
            ego_poses = np.vstack(([[0., 0., 0.]], ego_poses))
            start_angle = angle_discrete_to_cont(start_theta_discrete,
                                                 number_of_angles)
            poses = from_egocentric_to_global(
                ego_poses,
                ego_pose_in_global_coordinates=np.array([0., 0., start_angle]))

            # to model precision loss while converting to .mprim file, we round it here
            poses = np.around(poses, decimals=4)
            last_pose = poses[-1]
            end_cell = np.zeros((3, ), dtype=int)

            center_cell_shift = pixel_to_world(np.zeros((2, )), np.zeros(
                (2, )), resolution)
            end_cell[:2] = world_to_pixel(center_cell_shift + last_pose[:2],
                                          np.zeros((2, )), resolution)
            perfect_last_pose = np.zeros((3, ), dtype=float)
            end_cell[2] = angle_cont_to_discrete(last_pose[2],
                                                 number_of_angles)

            current_primitive_cells.append(tuple(end_cell))

            perfect_last_pose[:2] = pixel_to_world(end_cell[:2], np.zeros(
                (2, )), resolution)
            perfect_last_pose[2] = angle_discrete_to_cont(
                end_cell[2], number_of_angles)

            # penalize slow movement forward and sudden jerns
            if controls[0, 0] < target_v * 0.5 or abs(
                    controls[0, 1]) > 0.5 * target_w:
                action_cost_multiplier = 100
            else:
                action_cost_multiplier = 1

            primitive = MotionPrimitive(
                primitive_id=primitive_id,
                start_theta_discrete=start_theta_discrete,
                action_cost_multiplier=action_cost_multiplier,
                end_cell=end_cell,
                intermediate_states=poses,
                control_signals=controls)
            primitives.append(primitive)

    return MotionPrimitives(resolution=resolution,
                            number_of_angles=number_of_angles,
                            mprim_list=primitives)
Beispiel #7
0
def debug_motion_primitives(motion_primitives, only_zero_angle=False):
    angle_to_primitive = check_motion_primitives(motion_primitives)

    all_angles = normalize_angle(
        np.arange(motion_primitives.get_number_of_angles()) * np.pi * 2 /
        motion_primitives.get_number_of_angles())
    print('All angles: %s' % all_angles)
    print('(in degrees: %s)' % np.degrees(all_angles))

    for angle_c, primitives in angle_to_primitive.items():
        print('------', angle_c)
        for p in primitives:

            if np.all(p.get_intermediate_states()[0, :2] ==
                      p.get_intermediate_states()[:, :2]):
                turn_in_place = 'turn in place'
            else:
                turn_in_place = ''
            print(turn_in_place, p.endcell,
                  p.get_intermediate_states()[0],
                  p.get_intermediate_states()[-1])
            final_float_state = pixel_to_world(
                p.endcell[:2], np.zeros((2, )),
                motion_primitives.get_resolution())
            final_float_angle = angle_discrete_to_cont(
                p.endcell[2], motion_primitives.get_number_of_angles())
            try:
                np.testing.assert_array_almost_equal(
                    final_float_state,
                    p.get_intermediate_states()[-1][:2])
            except AssertionError:
                print("POSE DOESN'T LAND TO A CELL", final_float_state,
                      p.get_intermediate_states()[-1])

            try:
                np.testing.assert_array_almost_equal(
                    final_float_angle,
                    p.get_intermediate_states()[-1][2],
                    decimal=3)
            except AssertionError:
                print("ANGLE DOESN'T LAND TO AN ANGLE CELL",
                      np.degrees(final_float_angle),
                      np.degrees(p.get_intermediate_states()[-1][2]))

        endcells = np.array([p.endcell for p in primitives])
        image_half_width = np.amax(np.amax(np.abs(endcells), 0)[:2]) + 1
        zoom = 10
        img = np.full(
            (zoom * image_half_width * 2, zoom * image_half_width * 2, 3),
            255,
            dtype=np.uint8)
        resolution = motion_primitives.get_resolution() / zoom
        origin = np.array(
            (-image_half_width * motion_primitives.get_resolution(),
             -image_half_width * motion_primitives.get_resolution()))

        for p in primitives:
            draw_arrow(img,
                       p.get_intermediate_states()[0],
                       0.7 * motion_primitives.get_resolution(),
                       origin,
                       resolution,
                       color=(0, 0, 0))

            draw_trajectory(img,
                            resolution,
                            origin,
                            p.get_intermediate_states()[:, :2],
                            color=(0, 200, 0))
            draw_arrow(img,
                       p.get_intermediate_states()[-1],
                       0.5 * motion_primitives.get_resolution(),
                       origin,
                       resolution,
                       color=(0, 0, 200))
        cv2.imshow('a', img)
        cv2.waitKey(-1)
        if only_zero_angle:
            return