<jupyter_start><jupyter_text><jupyter_code>import re
import numpy as np
import matplotlib.pyplot as plt
import random
import cv2
from joblib import Parallel, delayed
from tqdm import tqdm

def read_pgm(filename, byteorder='>'):
    with open(filename, 'rb') as f:
        buffer = f.read()
    try:
        header, width, height, maxval = re.search(
            b"(^P5\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n]\s)*)", buffer).groups()
    except AttributeError:
        raise ValueError("Not a raw PGM file: '%s'" % filename)
    return np.frombuffer(buffer,
                            dtype='u1' if int(maxval) < 256 else byteorder+'u2',
                            count=int(width)*int(height),
                            offset=len(header)
                            ).reshape((int(height), int(width)))<jupyter_output><empty_output><jupyter_text>Load GMapping map<jupyter_code>!wget -q http://dev.sschultze.de:9999/map.pgm
map = read_pgm("map.pgm")
map = cv2.rotate(map, cv2.ROTATE_90_COUNTERCLOCKWISE)[30:335, 70:295]
plt.figure(dpi=100)
plt.axis("off")
plt.imshow(map.transpose(), cmap="gray")<jupyter_output><empty_output><jupyter_text>Ray Marching AlgorithmOur approach is able to estimate the position of a robot in a two-dimensional space based on two-dimensional distance values obtained via LiDAR. When training the neural network, the presence of matching ground truths in the form of absolute coordinates is crucial. However, in the real world, this is generally not the case. To solve this problem, we used the SLAM implementation of GMapping in ROS to generate a map. Then, we applied a ray marching dataset generation algorithm to generate LiDAR-coordinate pairs:![gmapping_dataset_generation.gif](https://github.com/svenschultze/Lidar-Localization-DL/blob/main/images/gmapping_dataset_generation.png?raw=true)<jupyter_code>relevant_pixels = map == 254

coords = relevant_pixels.nonzero()
coords = list(zip(*coords))
c = random.choice(coords)
MAX_RANGE = 200 # @param
def pixel_path(angle):
    img = np.zeros((MAX_RANGE * 2 - 1, MAX_RANGE * 2 - 1))
    angle = np.radians(angle % 360)

    origin = (MAX_RANGE, MAX_RANGE)

    dx = int(round(MAX_RANGE * np.cos(angle))) + origin[0]
    dy = int(round(MAX_RANGE * np.sin(angle))) + origin[1]
    destination = (dx, dy)

    img = cv2.line(img, origin, destination, (1), 1)
    path = np.transpose(img.nonzero())

    path = np.array(sorted(path, key=lambda destination: np.linalg.norm(np.array(origin) - np.array(destination))))
    return path - MAX_RANGE
PIXEL_PATHS = [pixel_path(angle) for angle in range(360)]
def scan_direction(origin, angle):
    path = PIXEL_PATHS[angle]

    try: 
        for x, y in path + origin:
            if map[x, y] == 0:
                return min(np.linalg.norm(origin - np.array((x, y))) / MAX_RANGE, 1)
    except:
        return 1

    return 1
def scan(origin):
    return np.array([scan_direction(origin, angle) for angle in range(360)])
s = scan(c)
thetas = np.flip(np.arange(0, 360, 360 / len(s)))
plt.figure(dpi=200)
ax = plt.subplot(111, polar=True, projection='polar')
ax.set_ylim(0, 1.2)
ax.plot(np.radians(thetas), np.roll(np.flip(s), 90))<jupyter_output><empty_output><jupyter_text>Generate Dataset<jupyter_code>X = Parallel(n_jobs=-1)(delayed(scan)(c) for c in tqdm(coords))
np.save("datasetX.npy", np.array(X))
np.save("datasetY.npy", np.array(coords))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1477565018576736, 'fraction_numerical': 0.021434695627322094, 'mean_word_length': 3.6666666666666665, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '138738', 'license': 'MIT', 'n_tokens_mistral': 1292, 'n_tokens_neox': 1229, 'n_words': 287, 'path': 'notebooks/pgm_map_to_dataset.ipynb', 'repo_name': 'svenschultze/Lidar-Localization-DL', 'size': '3499'}