HAMSatTracker: Parte 4 (Software)

mayo 02, 2023 circuiteando 0 Comments

Llegamos a al última parte del proyecto, el programa tanto para PC/Adroid como para la Raspberry Pi. Encargado de controlar la antena y calcular la posición del satélite con respecto a nuestra posición.

Ventana principal

En un primer momento, dado que quería que fuese multiplataforma, opté por una página web y el programa para la Raspberry Pi en Python, ya que había una librería para el cálculo de las órbitas de los satélites. Pero necesitaba montar un servidor web en la Raspberry, y su instalación y configuración, junto con los centenares de archivos que creaba un proyecto "simple" en el entorno que estaba utilizando, además del rendimiento de Python en este pequeño procesador (Raspberry Pi), me hizo desechar todo el código y empezar de nuevo.

Elegí Go como lenguaje de programación. No lo había usado nunca, pero me gusta aprovechar estos proyectos para aprender nuevos lenguajes, librerías, herramientas, etc. 

Go cumple varios criterios que tenía en mente:

  • Ser más rápido que Python (es parecido a C++).
  • Tener una librería para poder hacer el cálculo de las trayectorias.
  • Se compila en un solo ejecutable (no necesita instalar nada).
  • Tener frameworks para GUI multiplataforma.

A parte de lo anterior Go ofrece otras características, como sintaxis simple y concurrencia embebida en el propio lenguaje. Cosa que utilicé sobre todo en el programa de la Raspberry Pi, dado que el hardware es concurrente en naturaleza, utilicé todos los hilos que pude. Se trata más de un ejercicio de aprendizaje, ya que no son necesarios en muchos casos. Además en Go los "hilos" (Gorutinas) son mucho más ligeros que en otros lenguajes de programación, por lo que se pueden usar decenas y decenas de ellos sin preocuparse mucho por su impacto en el rendimiento.

La librería para el desarrollo de la interfaz gráfica ha sido Fyne. Parecía la más madura y con mayor comunidad detrás. Permitiendo además compilar binarios para Gnu/Linux y Android sin tener que instalar y configurar dichos sistemas o SDKs. Lo hace a través de virtualización, creando entornos ya configurados y de solo unos pocos gigas de tamaño en disco, usando un solo comando.  

Todo esto a grandes rasgos, ya se han usado más librerías para la comunicación de datos, drivers para leer el voltaje de la batería y más cosas. Así como el driver para los motores, que lo he tenido que hacer desde cero, por lo poco que hay en Go. Y quería que fuera concurrente, no siendo muy importante la precisión o rendimiento del mismo, me aventuré a ello.

Sin más rodeos, estas son las principales características de los programas: 

Para PC/Android 

  • Visualización de posición y velocidad de un satélite seleccionado, así como la hora actual en local y UTC.
  • Configuración de los parámetros de los motores.
  • Configuración de la posición donde está situada la antena (observador).
  • Compensación de la holgura en los engranajes (backlash).
  • Configuración de los límites de movimiento de la antena durante el seguimiento automático del satélite.
  • Control de los motores de forma manual sin limitaciones.
  • Configuración de la apariencia de la aplicación, incluyendo un tema claro y otro oscuro.
  • Visualización del voltaje de la batería, así como una alarma configurable por bajo voltaje.
  • Actualización los datos TLE para el cálculo de órbitas directamente desde la página web de la NASA.
  • Búsqueda de un satélite entre los descargados en el proceso anterior.
  • Mostrar el log del programa para solucionar posibles errores.
  • Mandar comandos de control y recibir datos de la antena (Raspberry Pi).
  • Apagado de los motores de forma remota.
  • Interfaz en dos idiomas: inglés y español.
  • Pruebas para comprobar el correcto funcionamiento de los motores.

Para Raspberry Pi Zero W

  • Recibir comandos del programa de PC/Android para movimiento de los motores.
  • Calcular la órbita de un satélite seleccionado en la aplicación y mandar de forma periódica los datos de posición de vuelta a la misma.
  • Capacidad de operar autónomamente en caso de desconexión de la aplicación durante el seguimiento de un satélite.
  • Transmisión de los datos en modelo publicador/subscriptor usando NATS.
  • Datos de los mensajes en formato binario compacto CBOR. Lo que lleva a comunicaciones más cortas y con comprobación de integridad. Antes de realizar cualquier tarea, se comprueba que los datos recibidos sean válidos.
  • Posibilidad de posicionar los motores en pasos, en vueltas (con decimales) o en ángulo.
  • Sincronizarse con la hora del programa al iniciarse la conexión.
  • Utilizar múltiples hilos de ejecución para paralelizar las tareas.

La aplicación de la Raspberry puede lanzar hasta 10 hilos simultáneos en un momento dado:

  • El de la aplicación principal que se mantiene la a espera de comandos por parte del programa de PC/Adroid.
  • El reloj sincronizado con la aplicación corre en otro de forma paralela.
  • El calculo continuo de la posición del satélite en otro.
  • Durante el seguimiento del satélite el control del movimiento lo realiza otro hilo.
  • Al mandar mover los motores, cada uno de los tres driver corre en un hilo diferente, y a su vez cada driver lanza otro hilo para mandar y contar cada pulso hacia los motores.

La interacción entre el programa en la Raspberry Pi (unidad de la antena) y el de PC/Android (programa) ocurre de la siguiente manera: al enchufar la unidad de la antena se une a la red local wifi si está disponible, o en caso contrario crea su propio punto wifi al que conectar el programa. Se abre este y una vez configurado, se actualiza la lista de satélites, una vez hecho esto se selecciona o busca al que se quiera seguir. Al pulsar en empezar se conecta con la unidad de la antena y esta calcula periódicamente su posición y manda los datos de vuelta al programa, para visualizarlos junto con el voltaje de la batería.

Cuando se está en parámetros para tener visión directa con el satélite se pulsa en seguir, en este momento la antena se empieza a mover y va continuamente actualizando su posición. Pudiendo empezar con el uso de la radio para la comunicación, y aunque se bloquee el programa o se pierda la conexión wifi, la antena seguirá al satélite hasta quedar fuera del rango de movimiento, se desconecte la batería o se re-conecte con el programa.

Los programas están compilados para las siguientes arquitecturas:

  • Amd64 y 386 para linux: GoHamSatTraker, que es el programa para PC.
  • Arm64 y arm para Android: GoHamSatTraker, pero para móvil y tablet.
  • Arm6 y arm7: Antennaserver_X, que es programa para la Raspberry Pi. La Zero W usa la arm6 y las más modernas la versión para arm7.
Comentar que la versión para el sistema operativo de la Raspberry Pi Zero W ha sido: 2022-09-22-raspios-bullseye-armhf-lite.img.xz. Puede que algunos scripts no funcionen en otras versiones.
 

Descripción de ventanas

A continuación se muestran todas las ventanas del programa de PC/Android junto con la descripción de cada apartado y botón.


Ventana principal (siguiendo un satélite)

Durante el seguimiento o cálculo de un satélite al pulsar el botón de Start/Inicio se muestra la: latitud, longitud, distancia, período, azimut, elevación, altitud y velocidad del satélite seleccionado. 

Más abajo nos incida la hora en formato UTC y local, los botones para iniciar/parar el cálculo e iniciar/parar el seguimiento/tracking del satélite.

Debajo de los botones se encuentra el voltaje de la batería y una barra de estado que indica si estamos conectados y a que IP. Además de si se están realizado cálculos o moviendo la antena para seguir al satélite.

Ventana de apariencia

En esta ventana se puede personalizar la interfaz, pudiendo elegir entre 5 tamaños de letra, el color principal de la aplicación y el tema/theme de la misma. Que puede ser claro/light u oscuro/dark.

Ventana de configuración Nº 1

Pinchando en el menú de la aplicación (tres rallas horizontales en la esquina superior derecha) podemos navegar entre las distintas ventanas. En la ventana de configuración, como se aprecia en la imagen superior, tenemos los siguientes campos:

  • Language/Lenguaje: elegimos entre inglés o español.
  • Amsat Url: por defecto está la dirección web de donde se baja el archivo con las órbitas de los satélites de radioaficionado de la NASA, pero se puede cambiar por otra distinta.
  • Data directory/directorio de datos: nos informa del directorio donde se guardan las preferencias y configuración de la aplicación. No se puede modificar.
  • Host IP/IP del anfitrión: se indicar la dirección de la unidad de la antena (Raspberry Pi).
  • Interval/intervalo: especifica el intervalo en milisegundos en que se quiere recibir mensajes de la antena.
  • Low battery/batería baja: se indica el voltaje en el que se quiere que salte la alarma de la batería.
 
Ventana de configuración Nº 2

Continuando hacia abajo en la ventana de configuración nos encontramos con:

  • Latitude/latitud: latitud del observador (antena) en grados.
  • Longitude/longitud: longitud del observador (antena) en grados.
  • Elevation/elevación: elevación en metros del observador (antena). Se obtiene de un GPS o mapa, al igual que los datos anteriores.
  • Elevation (steps)/elevación (pasos): son los pasos o pulsos que tiene que dar el motor de elevación hasta empezar a moverse al cambiar de dirección.
  • Azimuth (steps)/azimut (pasos):lo dicho anteriormente pero para el motor de azimut.
  • Rotation (steps)/rotación (pasos): lo dicho anteriormente pero para el motor de rotación.
 
Ventana de configuración Nº 3

Siguiendo con la ventana de configuración:

  • Desplegable motor: en él podemos seleccionar el motor que vamos a configurar.
  • Min.Range (degrees)/rango mínimo (grados): es el ángulo mínimo, grados que podemos mover la antena respecto a la posición inicial cuando el programa está siguiendo automáticamente un satélite.
  • Max.Range (degrees)/rango máximo (grados): lo dicho anteriormente pero aplicado al angulo máximo.
  • Steps per revolution/pasos por vuelta: son los pasos o pulsos necesarios por el driver del motor para dar una vuelta completa.
  • Gears multiplicator/multiplicador de engranajes: es el ratio que tiene un engranaje conectado a ese motor, en la imagen es cuatro, por lo que el driver deberá dar 800 por 4 pulsos, cuatro vueltas del motor para dar una en el engranaje.
  • Speed/velocidad: velocidad en vueltas por minuto (RPM) del motor.
  • Enable/habilitado: indica si se enciende o no ese motor.
  • Inverted/invertido: indica si la señal de habilitación anterior tiene la lógica invertida.
  • Botón Close/cerrar: cierra la ventana de configuración.
  • Botón Download TLS data/bajar datos TLS: descarga los datos de las orbitas de satélites de la dirección especificada al principio de la configuración.
  • Botón Motors limits test/prueba de límites de motores: prueba todos los motores intentando dar una vuelta completa en cada dirección. Así se verifica si se respetan los límites impuestos. Hay que tener cuidado por si hay que desconectar la antena en caso de golpear algo. Y sabiendo que la posición inicial se toma como referencia, y supone que se encuentra la antena al conectar el programa en horizontal y apuntando al norte.
  • Botón Simulate 90 pass/simular pase a 90 grados: simula un pase de norte a sur pasando justo por encima, para comprobar el movimiento de la antena.
  • Botón Disable motors/deshabilitar motores: apaga todos los motores de la antena.
Aviso durante el apagado de motores

Al pulsar el botón descrito anteriormente, el programa pide confirmación, ya que la antena caerá desde la posición en la que se encuentre en ese momento. Este mensaje aparecerá también al bajar el voltaje de la batería al valor de alarma, después de mostrar el aviso de la imagen inferior.

Aviso por bajo voltaje en la batería
Ventana de control manual de motores

Mediante el menú de la aplicación podemos acceder al control manual de los motores. No se respetan los límites de la configuración por lo hay que tener cuidado. Y sirve para medir los pasos (steps) que se tienen de holgura en los engranajes, probar los motores o posicionar correctamente la antena. 

Si la antena no está correctamente, en horizontal y mirando al norte, podemos hacer correcciones desde esta ventana, ya que no se actualiza la posición actual de la antena al moverla.

El funcionamiento es muy sencillo, cada motor tienen un deslizable donde se indican los pasos (steps) a dar por cada pulsación de los botones que se sitúan encima de él. Pudiendo elegir entre 1 y el número necesario para dar una vuelta completa (del engranaje acoplado a él si tuviera).

Más abajo se encuentran los botones:

  • Stop/parada: para los motores.
  • Initial position/posición inicial: mueve la antena a la posición inicial.
  • Close/cerrar: cierra la ventana y vuelve a la pantalla principal.

   Búsqueda de un satélite

Si se empieza a escribir el nombre de un satélite y se despliega el menú, aparecerán todos los satélites que comiencen por lo indicado.  

Lista de todos los satélites

Si se despliega sin escribir nada, muestra una lista de todos los satélites que contiene el archivo de orbitas descargado.

Ventana de log

Desde el menú del programa también se accede al log, pudiendo ver los mensajes del funcionamiento interno del programa o errores que se puedan producir.

Algunos de los botones cambian de texto según el estado del programa, como es el caso del botón de inicio o seguimiento, que cambian a parar o siguiendo una vez son pulsados, y vuelven a su estado anterior al pulsarse de nuevo o producirse algún error. 

También pueden aparecer sombreados/deshabilitados si no se está conectado a la antena o está en un modo que no es compatible.

Al no estar conectado no se pueden hacer las pruebas de motores
Botones deshabilitados al no estar conectado

Durante el seguimiento de un satélite, al estar moviendo la antena el programa, solo se deshabilitan los botones relacionados con azimut y elevación, permitiendo mover el de rotación en tramos de 10 grados. El control deslizante de rotación no tiene efecto durante el seguimiento de un satélite.

El código fuente de ambos programas se encuentra en el repositorio. Dejo una descripción de la estructura del mismo:

  • Assets: se encuentran las traducciones y los iconos utilizados por el programa.
  • Bin: ejecutables finales para cada arquitectura. Destaca el archivo natsServer.conf, que contiene la configuración del servidor de mensajes.
  • Cmd: contiene el código de entrada de ambas aplicaciones.
  • Internal/app/sattrk: un archivo con todos los manejadores de eventos (handler.go), otro con los mensajes (msg.go), otro con las diferencias para el tema de la interfaz gráfica (theme.go) y el que se encarga de la creación de todas las ventanas (ui.go).
  • Pkg: contiene los paquetes de aplicación: Board con todo lo relacionado con la placa de circuito impreso, Core con el código central y compartido por ambas aplicaciones y Validator con un validador personalizado para las entradas de texto de la interfaz gráfica.
  • Resource: contiene el código para compilar los iconos y traducciones e insertarlos en el binario ejecutable.
  • Raspberry_AP: contiene el script e instrucciones de como crear el punto de acceso wifi.
  • AntennaToRaspberry.sh: script encargado de copiar el ejecutable y la configuración a la Raspberry Pi, incluye instrucciones de como instalar un servicio para que se inicie automáticamente al arrancar.
  • MakeBuilds.sh: script que realiza la compilación de los dos programas en todas las arquitecturas mencionadas anteriormente en este artículo.

 

Conclusiones y posibles mejoras

Las conclusiones finales de todo el proyecto una vez finalizado son varias. Primero comentar que como todo proyecto que se precie, el tiempo previsto se ha dilatado una barbaridad. Entre paradas por motivos varios, la falta de documentación de algunas librerías y ciertos comportamientos del framework a la hora del diseño de la interfaz gráfica, han llevado a tardar mucho más de lo esperado en el apartado de software.

El framework no está preparado para un desarrollo profesional, su rendimiento en Android deja que desear y no ofrece la posibilidad de acceder a funciones de dispositivos dentro de Android, como los acelerómetros y GPS por comentar algunos. Si tuviera que hacer un programa compilado multiplataforma que incluya Android en un futuro, consideraría Flutter.

En cuanto al diseño 3D, pues me ha ayudado a mejorar un poco en ese apartado y he introducido los ensamblajes, que no había usado nunca. Siendo el tema mecánico más complicado de lo que pueda parecer a primer momento. Ha habido que estudiar algunos conceptos y como diseñar engranajes según las fuerzas y ratio requerido, tienen muchos más parámetros de los que parece.

A la placa de circuito impreso (PCB) le he dado un aspecto más profesional al utilizar más la capa de serigrafía e introducir dibujos en la misma. Así como hacer más fácil la portabilidad de los archivos de diseño al crear una biblioteca interna con todos los componentes utilizados.

La antena ha sido la primera que he construido y al final funciona, pero su robustez y peso no son sus punto fuertes.

Al final como todos los anteriores proyectos, realiza su cometido y me ha ayudado a seguir aprendiendo. Y como todo es mejorable, dejo una pequeña lista de posibles mejoras y todos los archivos y documentos en el repositorio para los que lo quieran construir o tomarlo como base para su proyecto.

  • En cuanto a la aplicación ya lo he comentado unos párrafos más arriba.
  • Para la antena hubiera sido mejor utilizar secciones de alambre mucho más largas y poder curvarlos con algún utensilio sin necesidad de tanta soldadura y empalmes.
  • También es interesante probar a usar cinta de cobre y pegarla sobre la pieza impresa para fijar los elementos conductores. No siendo a presión como las demás, si no usar dos mitades y un tornillo. Ambas con cinta pegada y la inferior soltada al cable de la radio, de esta manera se pueden quitar dichos elementos y desarmar por completo la antena.
  • Utilizar otro material par el brazo de la antena, uno que pese menos y así poder utilizar la versión más larga.
  • Otra opción es modificar y reforzar la pieza donde se une la antena a la base motorizada, la que tiene el motor de rotación, y desplazar y/o modificar el peso para que la antena esté perfectamente contrabalanceada.
  • En la PCB, incluir los mosfets para utilizar un driver externo que los requiera directamente.
Estas son las que se me ocurren en estos momentos. Y si has llegado hasta aquí, muchas gracias por haberlo leído y espero que te haya gustado.

0 comentarios: