{"id":19141347,"url":"https://github.com/thealbertdev/gopigo3_rpi_slam","last_synced_at":"2026-03-01T10:34:25.053Z","repository":{"id":104041497,"uuid":"432747401","full_name":"TheAlbertDev/gopigo3_rpi_slam","owner":"TheAlbertDev","description":null,"archived":false,"fork":false,"pushed_at":"2021-11-28T15:19:14.000Z","size":7377,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-22T19:15:01.984Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheAlbertDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-28T15:17:54.000Z","updated_at":"2024-06-03T10:57:50.000Z","dependencies_parsed_at":"2023-04-28T18:46:57.807Z","dependency_job_id":null,"html_url":"https://github.com/TheAlbertDev/gopigo3_rpi_slam","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TheAlbertDev/gopigo3_rpi_slam","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheAlbertDev%2Fgopigo3_rpi_slam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheAlbertDev%2Fgopigo3_rpi_slam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheAlbertDev%2Fgopigo3_rpi_slam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheAlbertDev%2Fgopigo3_rpi_slam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheAlbertDev","download_url":"https://codeload.github.com/TheAlbertDev/gopigo3_rpi_slam/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheAlbertDev%2Fgopigo3_rpi_slam/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29966854,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T09:33:09.965Z","status":"ssl_error","status_checked_at":"2026-03-01T09:25:48.915Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T07:22:54.264Z","updated_at":"2026-03-01T10:34:25.036Z","avatar_url":"https://github.com/TheAlbertDev.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gmapping y SLAM en GoPiGo3\n\nEn la última sesión, generamos un mapa de la estancia en la que se encontraba GoPiGo3 (GPG3) utilizando su LiDAR y un algoritmo de seguimiento de pared que hacía que el robot navegara de manera autónoma por la estancia. El nodo *gmapping* recogía las distancias publicadas por el LiDAR junto con la odometría publicada por los motores del GPG3 para generar dicho mapa. Mientras que esto se hacía con un rendimiento medianamente aceptable, no era este el caso cuando le pedíamos a GPG3 que calculara las rutas posibles entre dos localizaciones del mapa para desplazarse. En ese instante, la Raspberry Pi (RPi) que controla el GPG3 está corriendo un sistema operativo (Linux), gestionando la conexión WiFi, transmitiendo en remoto su Escritorio mediante VNC, corriendo el master de ROS, ejecutando RViz con los pertinentes modelos 3D, calculando las rutas entre localizaciones, controlando los motores, haciendo *streaming* de la cámara, etc. Mucha carga computacional para una simple RPi. Por suerte, ROS es una red distribuida de nodos (¡su principal punto fuerte!), por lo que podemos repartir la carga computacional entre diferentes máquinas/ordenadores.\n\nEn esta sesión vamos a crear una red ROS distribuida en dos máquinas: la RPi y nuestro ordenador (PC). La primera se encargará de simplemente controlar los motores (que no la trayectoria a realizar) y publicar su odometría, encender el LiDAR y publicar las distancias medidas, y encender la cámara para publicar sus imágenes. Respecto la sesión anterior, la RPi **no** calculará el recorrido a realizar, **no** gestionará el master de ROS (y toda la gestión de paquetes que ello supone), **no** transmitirá su Escritorio mediante VNC, y **no** mostrará RViz ni sus modelos 3D. En cambio, ahora el PC será quien ejecute el master de ROS, quién ejecute RViz y sus modelos 3D, y quien calcule las trayectorias.\n\n## Estructura del repositorio\n\nPara esta sesión utilizaremos el repositorio disponible en: https://github.com/TheAlbertDev/gopigo3_rpi_slam\n\n\u003e Si visitas el repositorio, haces uso de él y te ha ayudado, dale amor con una ⭐️\n\u003e Su humilde autor te lo agradecerá 😉\n\nEl repositorio cuenta con dos carpetas: `pc` y `rpi`. Ambos son *workspaces* de ROS. El primero es el que ejecutaremos desde el ordenador, mientras que el segundo lo ejecutaremos en la RPi.\n\n## Sincronización de fecha y hora\n\n\u003e Esta sección es importante que la leáis para profundizar en aspectos del funcionamiento de ROS y en su gestión en el día a día de un desarrollador de ROS, pero esto ya se os viene dado. **No hace falta que hagáis nada de esta sección.**\n\nAntes de empezar con la sesión, cabe tener en cuenta el aspecto de sincronización entre máquinas. Para que la red funcione correctamente, es importante que los nodos funcionen de forma sincronizada (es decir, que todas las máquinas tengan la misma fecha y hora). Para asegurar que esto ocurre, se hace uso de una utilidad llamada [chrony](https://chrony.tuxfamily.org/). Esta utilidad se debe de instalar en cada una de las máquinas que se unan a la red ROS. Una de las máquinas hará de servidor (es decir, será quien indique la fecha/hora a utilizar) y las otras máquinas simplemente cogerán la fecha y hora indicada por el servidor.\n\nPara instalar la utilidad, utilizamos el siguiente comando en cada una de las máquinas (en esta sesión , tanto en el PC como en la RPi):\n\n```shell\nsudo apt-get install chrony\n```\n\n### Configuración del servidor\n\nUna vez instalado chrony, debemos configurarlo. Para el caso del servidor, ejecutamos el siguiente comando para abrir/editar la configuración:\n\n```shell\nsudo nano /etc/chrony/chrony.conf\n```\n\nSe nos abrirá [nano](https://www.nano-editor.org/) con la configuración. Al final del archivo, añadimos las siguientes líneas:\n\n```\nlocal stratum 8\nallow 192.168.4.1\n```\n\nEn este caso, la IP indicada es la de la RPi, pero si fuera otra IP o tuvierais que trabajar con más máquinas, simplemente indicadlas ahí. Guardamos y cerramos el editor (\u003ckbd\u003eCONTROL\u003c/kbd\u003e+\u003ckbd\u003eO\u003c/kbd\u003e y después \u003ckbd\u003eCONTROL\u003c/kbd\u003e+\u003ckbd\u003eX\u003c/kbd\u003e).\n\nAhora, debemos de reiniciar chrony para aplicar los cambios:\n\n```shell\nsudo /etc/init.d/chrony stop\nsudo /etc/init.d/chrony start\n```\n\n### Configuración de los clientes\n\nLos clientes son las máquinas que preguntan al servidor qué fecha/hora es. En este caso, la RPi. Vamos a abrir la configuración de chrony:\n\n```shell\nsudo nano /etc/chrony/chrony.conf\n```\n\nY añadimos la siguiente línea al final de la configuración:\n\n```\nserver 192.168.4.18 minpoll 0 maxpoll 5 maxdelay .05\n```\n\n**Importante:** la IP que aparece en la configuración es dinámica. Esto quiere decir que 192.168.4.18 es la IP que tiene mi ordenador en el momento de redactar este documento, pero en otro ordenador (o en este ordenador pero en otro momento), es muy probable que la IP sea otra. **Pon ahí la IP de tu ordenador.** Puedes obtener la IP de tu ordenador ejecutando en el terminal:\n\n```shell\nip a\n```\n\nGuardamos y cerramos el editor (\u003ckbd\u003eCONTROL\u003c/kbd\u003e+\u003ckbd\u003eO\u003c/kbd\u003e y después \u003ckbd\u003eCONTROL\u003c/kbd\u003e+\u003ckbd\u003eX\u003c/kbd\u003e) y reincidamos chrony:\n\n```shell\nsudo /etc/init.d/chrony stop\nsudo /etc/init.d/chrony start\n```\n\nCon todo esto, ¡ya debemos tener nuestras máquinas sincronizadas!\n\n## Creación del mapa\n\nYa lo hicimos la sesión anterior, pero vamos a hacerlo otra vez con un mapa un poco más \"complicado\" y veremos como ahora podemos crearlo en un plis-plas.\n\n### Conectarse a la RPi\n\nEn esta sesión prescindiremos de VNC para conectarnos a la RPi y lo haremos mediante SSH.\n\n\u003e **Consejo importante para futuros ingenieros:** si está la opción de conexión mediante Escritorio remoto o SSH con terminal, escoged la que más cómoda os sea, pero si los recursos (capacidad de computación, calidad de la conexión de red, etc.) son limitados, utilizad el terminal. Está allí para ayudaros. Aprendedla a utilizar y acostumbraros a ella y, incluso sin recursos limitados, la preferiréis antes que una conexión mediante Escritorio remoto. Os lo prometo.\n\nAbrimos un terminal en nuestro PC y ejecutamos el siguiente comando:\n\n```shell\nssh pi@192.168.4.1\n```\n\nSi es la primera vez que nos conectamos, nos saldrá un mensaje que nos pide responder *yes* o *no*. Escribimos *yes* y \u003ckbd\u003eENTER\u003c/kbd\u003e. Si no nos pregunta nada, pues no hay que hacer nada. Seguidamente nos pedirá contraseña. Escribimos `raspberry` y \u003ckbd\u003eENTER\u003c/kbd\u003e (al indicar contraseñas, estas no aparecen en el terminal por seguridad, así que aunque parece que no estáis escribiendo, sí que lo estáis haciendo).\n\nSi todo ha ido bien, ahora tenemos un terminal donde estamos dentro de la RPi.\n\n### Iniciar el master de ROS en el PC y lanzar RViz y gmapping\n\nDe vuelta al PC, vamos a iniciar RViz para iniciar la creación del mapa. Vamos al siguiente directorio:\n\n```shell\ncd ~/Desktop/gopigo3_rpi_slam/pc\n```\n\n\u003e Los *workspaces* tanto del PC como de la RPi ya te se han sido descargados en su lugar para que los tengas disponibles. **No tienes que descargar nada.**\n\nUna vez allí, compilamos el *workspaces*, hacemos que todo él sea ejecutable, y hacemos un `source` de las variables de entorno :\n\n```shell\ncatkin_make\nchmod -R +x ./*\nsource devel/setup.sh\n```\n\nAhora sí, ejecutamos el siguiente *launch file* que, como seguro que nos acordamos, nos lanzará a la vez `roscore` si no está corriendo ya. **Importante:** debéis pasar al *launch file* el parámetro `lidar_model` en el que indicaréis el modelo de LiDAR que utilizáis (`yd` para el modelo azul, `rp` para el modelo negro).\n\n```shell\nroslaunch gopigo_slam gopigo3_slam.launch lidar_model:=yd\n```\n\nSe abrirá RViz y veréis un modelo blanco 3D de GoPiGo3, pero no veréis ni láser, ni mapa, ni nada,... ¿Razón? No hemos arrancado GPG3 y nadie está publicando distancias (LiDAR) ni odometría (motores) con los que hacer el mapa. Vamos a arrancar el GPG3.\n\n### Iniciar el LiDAR, los motores y el seguimiento de pared\n\nNos vamos al terminal conectado a la RPi y nos dirigimos al directorio:\n\n```shell\ncd ~/Desktop/gopigo3_rpi_slam/rpi\n```\n\nY, antes de arrancar nada, reflexionemos... \"¿Quién es el master en mi red de ROS?\" Exactamente. En nuestro caso, el master es el PC, no la RPi. Por ello, tenemos que decirle a ROS quién es el master y dónde puede encontrarlo. Para ello, se hace uso de las variables de entorno. Ejecutamos el siguiente comando:\n\n```shell\nexport ROS_MASTER_URI=http://192.168.4.18:11311/\n```\n\nComo en el caso de la configuración de chrony, debemos de indicar la IP del PC. Modificar la IP del comando anterior y ejecutadlo. (Si ya lo habéis ejecutado antes de modificar la IP, simplemente volvedlo a ejecutar con la IP buena).\n\n\u003e En el directorio en el que os encontráis actualmente hay un fichero llamado `set_env_vars.sh`. Este contiene justo la instrucción anterior de tal modo que si hacéis:\n\u003e\n\u003e ```shell\n\u003e source set_env_vars.sh\n\u003e ```\n\u003e\n\u003e Estaréis ejecutando el comando. Es más cómodo y a la vez permite ir añadiendo comandos que necesitéis ejecutar con regularidad (como podría ser el hacer un `source devela/setup.sh`.\n\u003e Si ejecutáis este archivo, acordaros de editar la IP que contiene y poner la de vuestro PC.\n\nUna vez indicado el master, aseguraros que el GPG3 está dentro del mapa/estancia, que tiene la pared a su derecha, compilamos el *workspace*, hacemos el `source` pertinente y lanzamos el *launch file* (indicando el modelo de LiDAR que utilizáis):\n\n```shell\ncatkin_make\nchmod -R +x ./*\nsource devel/setup.sh\nroslaunch gopigo_control autonomous_navigation.launch lidar_model:=yd\n```\n\nSi hemos seguido las instrucciones, el LiDAR empezará a funcionar y el GPG3 empezará a moverse siguiendo la pared a su derecha.\n\n### Guardar el mapa\n\nVolvemos al PC y ahora debemos ver que se va generando un mapa en RViz de manera mucho más fluida que en la sesión anterior. Esperamos a que se complete el mapa (idealmente, esperaremos que el robot recorra todo el mapa) y una vez hecho el mapa lo guardamos. Para guardarlo, primero vamos (en un terminal nuevo) a la carpeta donde queremos guardar el mapa y allí lo guardamos. Lo hacemos con los siguientes comandos:\n\n```shell\ncd ~/Desktop/gopigo3_rpi_slam/rpi/src/gopigo_slam/maps\nrosrun map_server map_saver -f mimapa\n```\n\nUna vez guardado, abrimos el archivo `.pgm` para ver que se ha guardado correctamente. Si ha sido el caso, vamos al terminal de la RPi y detenemos el robot (\u003ckbd\u003eCONTROL\u003c/kbd\u003e+\u003ckbd\u003eC\u003c/kbd\u003e) y luego volvemos al PC y cerramos RViz.\n\n## Navegación autónoma punto a punto\n\nYa con el mapa creado, vamos a hacer que el robot vaya de una localización a otra de manera autónoma calculando la mejor ruta. Para ello, en el PC ejecutamos el siguiente comando:\n\n```shell\nroslaunch gopigo_slam gopigo3_navigation.launch lidar_model:=yd map_file:=mimapa\n```\n\nIndicad vuestro modelo de LiDAR y el nombre del mapa que habéis creado antes. Se os abrirá el RViz con el mapa cargado, pero una vez más, sin ver bien el modelo 3D del GPG3 ni las lecturas del LiDAR. Aún falta arrancarlo.\n\nNos vamos al terminal de RPi y ejecutamos:\n\n```shell\nroslaunch gopigo_control slave_navigation.launch lidar_model:=yd\n```\n\nEl LiDAR empezará a funcionar y los motores estarán listos para recibir instrucciones del PC sobre a dónde debe de ir.\n\nVolvemos al RViz del PC y ahora debemos de ver el modelo del GPG3 renderizado correctamente y las medidas del LiDAR junto a un mapa de costes. El mapa de costes es un mapa que muestra en azul las zonas del mapa que tienen asociado un menor coste, mientras que las zonas rojas muestran las zonas de mayor coste. El nodo navigation calcula la mejor ruta calculando la que supone un menor coste. Por eso, las paredes aparecen sombreadas en rojo indicando que pasar a través de ella supone un alto coste (lo cual evita que el robot intente traspasarlas).\n\nAntes de empezar a navegar, hay que indicar al robot en qué localización del mapa se encuentra (seguramente os pasará que las lecturas del LiDAR no están alineadas con vuestro mapa). El robot se puede auto-localizar si lo fuéramos moviendo por el mapa (con el key_telop, por ejemplo), pero podemos indicarle directamente dónde se encuentra mediante la herramienta 2D Pose Estimation (flecha verde). Con la herramienta seleccionada, clicamos en la localización del mapa en el que se encuentra el robot y, **sin soltar el clic**, movemos el ratón hacia la dirección/orientación del robot. Una vez indicada la orientación, soltamos el clic. Si hemos acertado (y si no es el caso, repetimos esta acción hasta que lo logremos), se alineará el mapa con las lecturas del LiDAR (no hace falta una alineación milimétrica).\n\nAhora sí, todo listo para navegar. Seleccionamos la herramienta 2D Nav Goal (fecha roja) y, al igual que con el 2D Pose Estimation, clicamos la localización a la que queramos que vaya el GPG3 y sin soltar indicamos la orientación final.\n\nSi lo hemos hecho todo correctamente, deberemos de ver cómo el robot va perfectamente al destino indicado. ¡Enhorabuena! Tómate tus 5 minutos para jugar un poco con el robot y su navegación. Te lo has ganado.\n\n## Navegación autónoma en ruta\n\nPor último, vamos a hacer que el robot vaya automáticamente a diferentes localizaciones. Es decir, que haga una ruta. Además, en cada punto de la ruta, haremos que el robot tome una fotografía.\n\nSi no has detenido ningún terminal, estás de suerte. Tienes la mitad del trabajo hecho. Si no es el caso, vuelve a arrancar RViz con el mapa y también el LiDAR y los motores del GPG3.\n\nLo primero que haremos es arrancar la cámara. En un terminal de RPi nuevo (es decir, abre un nuevo terminal en tu PC y conéctate a ella mediante SSH) y ves al directorio del *workspace*:\n\n```shell\ncd ~/Desktop/gopigo3_rpi_slam/rpi\n```\n\nIndica el master (puedes utilizar el archivo `set_env_vars.sh` si lo has modificado anteriormente), haz un `source`del *workspace* y lanza el *launch file* de la cámara:\n\n```shell\nsource set_env_vars.sh\nsource devel/setup.sh\nroslaunch raspicam_node camerav2_1280x960_10fps.launch enable_raw:=true camera_frame_id:=\"base_scan\"\n```\n\nA continuación, vamos a asegurarnos que la ruta existente es válida para nuestro mapa. Vamos al directorio (en el PC)\n\n```shell\ncd ~/Desktop/gopigo3_rpi_slam/pc/src/gopigo3_route/src\n```\n\ny abrimos el fichero `route.yml`. Veremos una serie de puntos/localizaciones a los que queremos que GPG3 vaya y tome una fotografía. El nombre de la fotografía también se indica para cada punto. Todas las fotografías se guardaran en la carpeta `photos` existente en el directorio inmediatamente superior al que nos encontramos.\n\nSi los puntos son correctos, ya podemos ejecutar el comando:\n\n```shell\nrosrun gopigo3_route follow_the_route.py\n```\n\nSi todo funciona correctamente, veremos cómo el robot empieza a dirgirse a la primera localocalización y hace una fotografía al llegar a ella. Así con los diferentes puntos hasta finalizar la ruta indicada.\n\nUna vez finalizada, comprueba que las fotografías se han almacenado correctamente en la carpeta `~/Desktop/gopigo3_rpi_slam/pc/src/gopigo3_route/photos`.\n\nCon esto ya hemos logrado nuestro objetivo. ¡Juega con diferentes rutas!\n\n## Conclusiones\n\nEn esta sesión hemos visto cómo desplegar una red ROS distribuida donde se ejecutan nodos en nuestro PC y en una Raspberry Pi. Esto tiene un impacto más que evidente en el desempeño de la red/proyecto.\n\nHemos realizado el mapa de manera autónoma mediante un algoritmo de seguimiento de pared para, posteriormente, poder navegar automáticamente de punto a punto del mapa utilizando la ruta de menor coste.\n\nFinalmente, hemos programado una ruta a seguir por GPG3 de tal modo que en cada punto de la misma el robot tome una fotografía.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthealbertdev%2Fgopigo3_rpi_slam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthealbertdev%2Fgopigo3_rpi_slam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthealbertdev%2Fgopigo3_rpi_slam/lists"}