miércoles, 16 de diciembre de 2020

Construyendo puentes, el componente BridgeX



Un poco para ir redondeando el año técnico quería compartir (¿documentar?) un logro técnico que perseguí por mucho tiempo con mi estación concursera y en la que por distintos motivos gasté una enorme cantidad de horas. Para dar contexto me tengo que remontar a casi una década atrás. Luego de unos primeros intentos con software de logging de concursos claramente no apropiados, porque no eran para concursos o porque eran demasiado frágiles, adopté el famoso programa N1MM (por entonces la versión anterior). Esa decisión fue, en perspectiva, mucho mas durable que lo que podría hacer suponer un simple experimento. Con el tiempo probé otros software de concurso como AATest o WinTest, pero volví al N1MM. Los programas para logging de concursos tienen una enorme cantidad de funciones pues deben operar en una enorme variedad de configuraciones, satisfacer una igualmente enorme cantidad de posibles gustos y preferencias y además estar constantemente siendo ajustado a las siempre cambiantes reglas de los concursos alrededor del mundo. Tom (N1MM) y su equipo hacen un magnífico trabajo en lograr posicionar su plataforma, gratuita, como uno de los programas top en la materia y someterlo a constantes actualizaciones (en ocasiones varias por semana) en, por lo menos que me conste, la última década. Posiblemente desde antes. El primer traspié fue que todo el resto de los programas que quería usar no eran compatibles con N1MM pues se basaban en la plataforma OmniRig, que N1MM no le dá soporte. Al principio, inocentemente presumo, crei que era una omisión involuntaria. Por eso en distintos foros de soporte plantee la cuestión y me sorprendí un poco por el tipo de respuesta airada que obtuve de algunos miembros del equipo de desarrollo, no de Tom es bueno decirlo, opinando sobre mis motivaciones equivocadas y arriesgando que era técnicamente "imposible". Con el tiempo y otras interacciones con Alex (VE3NEA), autor del OmniRig y del CW-Skimmer entre otros,  mediante me di cuenta que había algun tema dando vueltas entre ambos equipos y que no podía esperar que ninguno de los dos fuera demasiado cooperativo. La principal razón para necesitar esa integración es que varios programas obtienen información del CAT del transceptor, frecuencia en particular. Y el CW-Skimmer, que a pesar que jamás lo usé como decodificador de CW, que es tan bueno o malo (según se prefiera) como otros decodificadores, tiene uno de los filtros mas potentes que conozca. Filtros Bayesianos. Un tipo de filtro que con el tiempo trabajé bastante en investigación académica y que solo se puede implementar con técnicas DSP. Es cuestión de tiempo que se desarrolle un hábito en el sintonizar las estaciones haciendo "click" en la señal de la misma, desarrollar una técnica para agudizar la coordinación cerebro-oido prestando atención al waterfall del CW-Skimmer y otras facilidades. El CW-Skimmer es el motor atrás del potente Reverse Beacon Network, además. Con el tiempo desarrollé el dispositivo para habilitar la operación SO2R primero y SO3R después. Primero en hardware y luego en software. Nuevamente, cada vez mas dependiente de poder administrar los equipos por fuera del N1MM. Pero el N1MM seguía sin incluir al OmniRig pues "no se podía". En realidad sería muy facil desarrollar el soporte en N1MM para el OmniRig, no es novedoso siquiera pues lo hacen otros programas como AATest o WinTest, simplemente se define un transceiver que sea "OmniRig" y se envian los comandos por alli, dejando que el OmniRig "traduzca" los comandos al transceptor físico que fuera, todos los comandos que usa el N1MM son, por supuesto, soportados por OmniRig. Todo el resto es pelea de pueblo chico pero que no se puede hacer nada sobre ello. No pasó mucho tiempo para que dejara de lado semejante pamplina y desarrollara (hace casi 10 años atrás) un programa denominado MM2OR (n1MM 2 OmniRig) que básicamente es un artefacto típico de integración de sistemas, como los que he construido o sido responsable de construir docenas en mi vida profesional. Utilizar alguna de las interfaces de un software para colocar un traductor que lo haga hablar con otro, sin que naturalmente ninguno de los dos esté pensado para hacerlo. En el caso del N1MM ese punto de apalancamiento fue la comunicación serie con el transceiver. Básicamente el programa MM2OR simula un puerto serie (mediante el programa com0com) y escucha en el. Cada vez que el N1MM envía un comando al transceiver el MM2OR lo intercepta y lo envía al transceiver en su nombre, usando OmniRig. La respuesta, también por OmniRig es enviada a N1MM por el mismo puerto serie virtual. N1MM "piensa" que está hablando con un transceiver. Conceptualmente es simple, prácticamente no lo es tanto. En primer lugar había que entender que comandos usa el N1MM para comandar al transceiver, por prueba y error fui sacando que comandos envía permanentemente (status y frequencia), que comandos espera del transceptor (frecuencia y modo) y que comandos puede tirar ocasionalmente (tipo cambio de VFO, split, modo, banda, etc.). Luego encontré que el N1MM tenía bugs, por ejemplo, enviaba dos comandos juntos al transceiver, ... y esperaba las respuestas juntas (como seguramente lo hacía el transceiver). Sin embargo cuando "parseando" los dos comandos primero se proveía la respuesta a uno y luego a otro el N1MM simplemente quedaba confundido. Como anécdota solo cabe aclarar que comentado el problema con uno de los desarrolladores ni siquiera entendieron de que se trataba y porque era un problema. Como quiera que fuera, con todo éste lio era entonces posible que varios programas Y el N1MM hablaran simultaneamente con un transceiver, y luego con dos (máximo que soporta OmniRig). Nació allí el sistema SO2R que usé por muchos años con distintas combinaciones de radios. Primero con un FT100, luego un FT740 con un FT100, luego el FT100 lo reemplacé por un FT790 y finalmente agregué a la mezcla un IC706 y el FT817. Para operación normal no es necesario pues uso software de teclado y logging (AALog, BandMaster y CWType) que si es compatible con OmniRig. El tema era solo con concursos. Salvo la molestia de tener que modificar el programa MM2OR cada vez que agregaba un nuevo transceptor para "enseñarle" los comandos que el N1MM podría solicitarle (en el propio protocolo CAT del transceptor) no hubo grandes cambios. Siempre me maravilló porque los fabricantes no hicieron un solo protocolo de CAT y ya, pero no, incluso Yaesu usa prácticamente un dialecto (o un lenguaje diferente) para cada transceptor.
Todo bien, muy contento con mi estación y dedicándome a construir las capacidades concurseras en otros aspectos por más de una década.
Cuando mudé mi estación desde Córdoba a Buenos Aires y pasé de ser LU7HZ a ser LU7DID hice una inversión muy importante en renovar equipos, adquirí un Yaesu FT-2000, persiguiendo un deseo de mucho tiempo de poder operar en concursos en modo SO2V en lugar de SO2R, es decir teniendo un equipo con receptor y sub-receptor. Las ventajas son conocidas para quien hace concursos y difíciles de explicar para el que no, pero involucran velocidad de tasa, integridad de equipos y compartir antenas, cosa que no es posible con dos equipos separados. Todo muy bien. No tardé en escribir las extensiones de MM2OR para que entendiera a un FT2000 pero ahí me encontré con un escenario nuevo. N1MM podía fácilmente integrarse, reconocer y usar los dos receptores del FT2000 tirando comandos que apuntaran al VFO A o al VFO B. No fue difícil acomodar la traducción usando MM2OR y OmniRig. Pero ésta vez fue CW-Skimmer (y el resto de la suite) al que no le dió la talla. Simplemente están preparados para trabajar con dos transceivers, pero no con un transceiver con dos VFO. Existe un truco muy sencillo, modificando los archivos de inicialización del OmniRig, para que intercambie los VFO. Es decir que si los comandos son para el VFO A lo tire en realidad al VFO B y viceversa. Eso solucionaba que CW-Skimmer pudiera controlar el VFO B, pero no solucionaba que hablara con un solo VFO. 
Plantee el tema a Alex (VE3NEA) quien no entendió siquiera el problema, recomendándome que alterara los archivos de descripción para justamente intercambiar los VFO. Luego me recomendó que definiera el mismo transceptor en ambos "rig" del OmniRig, solo que uno con la definición "derecha" y el otro con la definición "cruzada". Pero eso falló pues los dos rigs tendrían que compartir el mismo puerto serie, y una vez que uno lo abre no se lo deja abrir al otro. Una falla tan trivial me hizo suponer que Alex ni siquiera le había dedicado tiempo a ponderar mi pregunta antes de contestarme, su respuesta fue demasiado errada para suponer otra cosa.
Hice entonces una primera versión del programa BridgeX, siguiendo en el mismo concepto de integración usado por MM2OR, pero esta vez con OmniRig. Un programa escuchando en un puerto virtual (diferente al físico que estaba conectado en el transceptor) recibe los comandos que están dirigidos a un transceptor FT2000 que en realidad no existe, invierte los VFO y lo manda al otro transceptor via OmniRig. El diagrama (a mano alzada) se puede ver en la figura adjunta. Pero no funciona y no funciona porque el OmniRig tiene un bug. En lugar de mantener separadas las interacciones con los puertos series OmniRig no tiene esa precaución, con lo que cae en un problema llamado "re-entrabilidad y re-usabilidad", es decir intenta usar un puerto serie mientras está "adentro" del código de usar otro. Como resultado la ejecución "pisa" el ejecutable, destruye el stack y produce toda suerte de errores exóticos. Usando éste mismo esquema a mano alzada le pregunté a Alex por el problema y me dijo que si, que podía ser un error, que quizás en algún momento en el futuro lo corregiría o que quizás permitiría que CW-Skimmer seleccionara el VFO con el que operaba, o ambas cosas. Quizás. Algún día.  O nunca, vaya uno a saber. 
El proyecto estuvo dormido por casi dos años con lo que "coexistí" con el problema al que resolví con mantener la sesión "run" del CW-Skimmer sin conexión con el transceiver y hacerlo con la sesión "S&P". Dicho de otra manera, barrer multiplicadores con "point & click" pero mantenerme fijo en el run. De todas formas el N1MM siempre sabe en que frecuencia está cada uno pues, nuevamente, si reconoce sin problemas los dos VFO.
Hasta que preparándome para el CQWW 2000 volví a retomar el proyecto pero con una vuelta. El problema era el bug de OmniRig al tratar de usar dos puertos, uno real y uno virtual (que terminaba intentando pasar comandos al transceiver por el real). Entonces, ¿porque no virtualizar todo...?
El resultado del razonamiento se describe en la figura adjunta. Básicamente replico la estrategia de virtualizar puertos, en éste caso dos puertos distintos COM10 y COM12, donde escucha BridgeX los comandos respectivos. OmniRig envia comandos a esos puertos como si fueran dos transceivers distintos, ambos FT2000 en cuanto a sus comandos CAT. El programa BridgeX recibe los comandos, en el caso de los que recibe por COM10 los pasa físicamente (por COM4) al transceiver mientras que los que recibe por puerto COM12 los pasa, también por COM4, pero invirtiendo VFO A y VFO B. Como resultado CW-Skimmer tiene una instancia sobre el transceiver en rig1 (el FT2000 que toma sus comandos) y otra instancia en rig2 (el FT2000 que invierte VFO). Como resultado ambos CW-Skimmer interactúan cada uno por su lado con distintos VFO. Y se puede hacer S&P en cada VFO por separado. Y se gana bastante en agilidad operativa. De alguna manera vuelvo a tener todas las facilidades que tenía con dos transceivers separados pero ahora con todas las ventajas de uno integrado.
El esquema lo usé en forma prototipo en CQ WW, y luego de algunos ajustes nuevamente en ARRL 10 Meters. Con excelentes resultados en ambos casos. Fue un puente que tardé muchos años en encontrarle la vuelta, y al final como en todo problema que se resuelve, la solución parece muy simple. Al punto que uno se pregunta, ¿porque habré tardado tanto tiempo en encontrarla?. La conclusión es que no hay cosas "imposibles" en materia de software, solo mas o menos ganas de hacerlas.


 

No hay comentarios:

Publicar un comentario