Informática geek, matemáticas, pensamiento crítico y alguna otra cosa de vez en cuando.

2011-01-13

Piloto automático para naves espaciales

Algún afortunado lector quizá haya jugado con el sensacional Elite de Ian Bell y David Braben. o sus aún más sensacionales continuaciones, Elite II: The Frontier y Frontier: First Encounters. Los tres son simuladores espaciales. El primero no tiene un motor físico muy realista: en Elite, la velocidad no es relativa. Hay un sistema de referencia universal, y la nave tiene una velocidad máxima dentro de ese sistema de referencia.

En cambio, en los otros dos el motor de física es mucho más realista. La velocidad actual está indicada siempre con respecto a un sistema de referencia dado, que generalmente se corresponde con el astro o planeta más próximo, y puede cambiar cuando éste lo hace. Los motores de las naves pueden acelerar y frenar, lo que impone una aceleración máxima, como es lógico, pero no hay limitación para la velocidad. Como pega en contra de ese realismo, aunque a favor de la jugabilidad, cabe nombrar que la aceleración de la nave no depende de la masa de la misma, lo cual sí que ocurriría si los motores ejercieran una fuerza de empuje máxima (F=ma). Otros detalles, aunque de menos importancia, son la falta de efectos relativistas y la omnidireccionalidad del empuje, así como el hecho de que la aceleración a la que la nave es sometida (típicamente rondando los 20 g) no podría ser soportada por un cuerpo humano. Le concedemos esas licencias de buena gana, porque el producto resultante bien lo vale.

Como los dos títulos comparten la palabra Frontier y no hay diferencias entre ellos en la parte que aquí nos interesa, me referiré a ambos colectivamente usando dicha palabra. Frontier cuenta con un piloto automático, cuyo principio de funcionamiento exacto desconozco, para viajar de un punto a otro del espacio. Sin embargo, yo al menos soy fan de desconectar el piloto automático y volar a mano, porque disfruto haciéndolo, y porque el piloto automático utiliza el motor delantero para frenar, que siempre tiene menos potencia, mientras que yo doy la vuelta a la nave para hacerlo y así puedo alcanzar una velocidad mayor y frenar a tiempo. (Es un error típico de novatos el acelerar continuamente hasta llegar al destino... y pasarse de largo por mucho, porque la potencia de frenado es la misma que la de aceleración y por lo tanto requiere el mismo tiempo acelerar que frenar).

Cuando quiero ir de punto a punto, observo la distancia al objetivo; entonces acelero hasta la mitad del trayecto y decelero hasta llegar. Los resultados suelen ser bastante buenos; en la primera aproximación quizá no me quede lo bastante cerca, pero con una o dos aproximaciones más (cada vez más cortas) el éxito está prácticamente garantizado.

Sin embargo, las batallas suelen aparecer en medio del viaje, y cuando lo hacen, me estropean los planes de navegación, porque debido a la inercia que llevo, voy acercándome al objetivo mientras dura la batalla, lo cual, cuando se va a 12.000 km/s, resulta significativo. Esto me hizo preguntarme: ¿y cómo calcular entonces el punto de frenada, para llegar cuanto antes al objetivo? La respuesta resulta no ser muy fácil para el caso de una dimensión. Cuando se da la eventualidad de una batalla, los movimientos laterales son pequeños, lo que permite considerar el caso 1D como una buena aproximación.

El método entonces sería el siguiente. El espacio necesario para frenar dada la velocidad actual viene dado por la fórmula v²/(2a), donde a es la aceleración máxima con la que podemos frenar y v la velocidad con la que se reanuda el viaje. Por razones que me costaría explicar, el punto de frenada viene dado por (x0 - v|v|/(2a))/2, donde x0 es el punto inicial, y el punto destino se asume 0. Puede ser que ya nos hayamos pasado de dicho punto, en cuyo caso es inevitable que nos pasemos de largo y tengamos que frenar hasta pararnos.

Pero, ¿qué pasa si estoy de camino hacia un planeta y de repente cambio de opinión y quiero dirigirme a otro? En ese caso, tengo una velocidad inicial cuya alineación probablemente no coincida para nada con el destino final, por lo cual no podemos usar el truco de 1D. ¿Qué puedo hacer, si quiero llegar cuanto antes?

Anticipo que no sé la respuesta. Si para el caso 1D no era fácil, para 3D es diabólico. Esto es lo que sé. Con un cambio de sistema de referencia, siempre se puede transformar el problema en uno en dos dimensiones. Se formularía así: dados un punto inicial, p0, una velocidad inicial, v0, y una aceleración máxima, amax, determinar la función que da la aceleración a aplicar en cada instante, tal que se alcance el punto (0, 0) a velocidad nula en el menor tiempo posible.

O, alternativamente, partiendo parados desde el punto (0, 0), hallar la función de aceleración necesaria para alcanzar el punto pF a una velocidad vF (como vector), en el mínimo tiempo posible. Es lo mismo pero haciendo el camino al revés e invirtiendo la velocidad.

Es un problema frustrante porque, pese a su simple planteamiento y aspecto inocente, resulta bastante esquivo. La aproximación más inmediata, que es resolverlo en 1D para cada eje, no funciona porque al aplicar la aceleración máxima por cada eje, el módulo de la aceleración es mayor que la aceleración máxima. Podemos dividir la aceleración por √2 para compensar, pero es que no es la única pega: nada nos garantiza que el tiempo que se tarda en cada eje coincida. Así que tenemos además que encontrar una aceleración máxima por eje, que cumpla dos requisitos: que el tiempo sea el mismo en cada eje, y que la suma de los cuadrados de las aceleraciones máximas coincida con el cuadrado de la aceleración máxima dada.

¿Es óptima esa solución? Pues una de dos: o no lo es, o hay infinitas soluciones óptimas. Para demostrarlo, basta ver que si rotamos el sistema de referencia en el problema original, deberíamos obtener una versión rotada de la solución, cosa que no ocurre. Los cuatro posibles vectores de la solución forman siempre un rectángulo alineado con los ejes.

En fin, ando quebrándome la cabeza con este problema.