domingo, 10 de agosto de 2025

Simulando loops de una montaña rusa con R (y GPT-5)

Estos días medio occidente le está contando a la otra mitad en redes sociales que el recién lanzado ChatGPT 5 es una castaña que no sabe sumar, ni dibujar mapas, ni hacer ninguna de las cosas para las que no fue concebido. Yo he querido comprobar si al menos sabe escribirme una rutina para simular la cinemática en un loop de una montaña rusa y, qué cosas, me debe tener cariño porque lo ha niquelado.

En concreto buscamos calcular cómo evolucionan en el tiempo: la posición, la velocidad y las fuerzas G que afectarían a los pasajeros para cualquier tipología de loop definido a partir de una matriz de coordenadas 2D.

En el prompt le doy toda la información básica requerida sobre la física que gobierna el movimiento a simular (conservación de la energía, gravedad y fuerza centrífuga, y ejecución de la simulación en el dominio del tiempo):

"Write R code to simulate the forces affecting a train on a rollercoaster:
  • The rollercoaster is defined by discrete points on two vectors x (ground axis) and y (height axis), in the way: x=c(0, 1, 2, 3, 4, 5,...) and y=c(0, 0, 0.5, 1, 2, 3.5, 5,...)
  • The simulation must be done time dependant in dt constant time steps. This means you'll have to interpolate along the definitory points of the rollercoaster, not just give a force value for each rollercoaster point, calculating the progress of the train along the path
  • The train is defined by a punctual mass m (but this should be irrelevant since it cancels on all equations) starting from point (0,0) at initial speed v0 left to right
  • You must calculate the sum of two forces: Fg=m*g and Fc=m*v^2/r, where Fg is the gravity force and always points down and Fc is the centrifugal force trying to evade the rollercoaster in a perpendicular direction
  • Apply energy conservation: 1/2*m*v0^2=m*g*H to obtain each v speed
Do you need something else before beginning?"


El primer resultado ya ha sido muy bueno. El único error que ha cometido es calcular los vectores de fuerza centrípeta (normal hacia el centro de la curva), cuando le dejé claro que debía calcular la fuerza centrífuga (normal hacia el exterior), que es la componente que junto con la gravedad nos proporciona el sumatorio de fuerzas G percibidas por un pasajero.

Toda la geometría la ha clavado, ha hecho interpolaciones con splines para calcular la simulación en pasos temporales equiespaciados (y por lo tanto saltos espaciales variables), y ha usado la fórmula de la curvatura de una curva paramétrica que yo no conocía:

kappa(s) = |x'y'' - y'x''| / (x'2 + y'2)3/2

estimando perfectamente todas esas derivadas a partir de los datos discretos. La curvatura es el inverso del radio en cada punto de la curva, necesario para calcular la fuerza centrífuga instantánea.

~~~

He simulado dos casos típicos: un loop circular y otro con forma de clotoide (curva que minimiza los saltos bruscos en la curvatura y que estudiamos en 'Clotoides, las curvas que cuidan de tu cuello'). Para ambas simulaciones los parámetros de velocidad de entrada y altura máxima del loop son los mismos. La versión circular es una tipología antigua que ya no se usa por los motivos que veremos:



Para completar el ejercicio he pedido también a ChatGPT que genere una función que haga el cálculo al revés: partiendo de una fuerza G que queremos se mantenga constante en todo el loop, debe obtener la geometría que la proporciona y que será una solución única. Ahora ya no estamos simulando el loop sino diseñándolo.

Además le he pedido que añada un pequeño tramo "clotoidal" inicial para adaptar la fuerza G de partida (gravedad pura de 1G), a la fuerza constante deseada en el loop. Para esta función de nuevo ChatGPT se ha obstinado en usar la fuerza centrípeta en lugar de la fuerza centrífuga, pero con avisarle una vez ha sido suficiente para que corrija:



El resultado para las tres tipologías de loop: circular, clotoide y aceleración G constante, se muestra a continuación. Los vectores rojos representan la magnitud vectorial de la fuerza G total experimentada por un hipotético pasajero en cada punto. He tomado el criterio de usar la dirección de la fuerza de la gravedad y de la fuerza centrífuga, mostrándose ambas como vectores en gris.

Otros hubieran preferido vectores de igual magnitud pero apuntando hacia el interior, como suma de la respuesta normal a la gravedad más la fuerza centrípeta, lo que representaría la fuerza real con la que el vagón reacciona a la presión que ejercemos sobre él. A mí no obstante siempre me ha parecido más intuitivo el criterio centrífugo, al menos visualmente (hacer clic para verlos en un GIF animado de alta resolución):







Las simulaciones se han hecho hasta completar ~3/4 partes del giro completo porque el camino de bajada es simétrico respecto a la subida en todos los parámetros de velocidad, distancias y fuerzas G.

Como no podía ser de otro modo, por conservación de la energía la velocidad mínima que logran los viajeros es la misma en las dos primeras montañas rusas al ser de la misma altura, pero ahí terminan las similitudes. Viendo el gráfico queda claro por qué ya no se diseñan loops puramente circulares:
  • En el encuentro entre el tramo recto y el inicio del loop circular los pasajeros sufren una fuerte sacudida, pasando instantáneamente de percibir solo su propio peso sobre el vagón a la suma de dicho peso más toda la fuerza centrífuga.
  • Pero es que además en ese momento se va a velocidad máxima y para más inri la gravedad y la fuerza centrífuga son paralelos, dando lugar a un gran pico absoluto de fuerza percibida de 6,3G.
  • Otro hándicap del loop circular es que en la parte alta, al ser el radio de giro constante en todo el recorrido y por lo tanto bastante grande, la fuerza centrífuga es insuficiente para sujetarnos con firmeza contra el vagón. Los 0,3G que se tienen en ese momento pueden generar una sensación de ingravidez incómoda precisamente cuando estamos boca abajo.

La clotoide viene a solucionar todos los problemas anteriores. Con ella la llegada de las fuerzas G es progresiva, se alcanza un pico más llevadero de 4,2G ya iniciada la subida, y en la parte alta gracias a la reducción del radio de giro disfrutamos de buena sujeción.

El loop de fuerza G constante, para el cual he escogido replicar los 4,2G de la montaña rusa "clotoidal" pura, lo validamos con el simulador. Vemos tanto en la representación vectorial como en la gráfica de fuerzas G que el resultado es perfecto.

Aquí puede verse cómo varían la velocidad y la fuerza G percibida con el tiempo en cada recorrido. Se considera que 6G es la máxima fuerza admisible con seguridad así que la montaña rusa circular entra en terreno peligroso (hacer clic para ver una comparativa conjunta de las tres gráficas):







Sin tener ni idea de diseño de montañas rusas, me atrevería a decir que el mayor problema de la curva circular no es la magnitud de la fuerza G alcanzada como tal, que además se da durante un muy corto lapso de tiempo, sino el hecho de que llega de forma abrupta lo que puede provocar una fuerte sacudida en el cuello de los desprevenidos viajeros.

Consideraciones y simplificaciones hechas:
  • No se ha tenido en cuenta la pérdida de velocidad por rozamiento (aire y railes), lo que en un caso real obliga a aumentar la velocidad de entrada para garantizar que se cubre el loop.
  • Se ha considerado un solo vagón puntual. En un tren real con varios vagones unos introducirán inercias sobre otros suavizando un poco aceleraciones y desaceleraciones, haciendo algo menos radical el viaje.
  • Parámetros de montaña rusa realista: el Dragon Khan tiene loops de entorno a 30m de desnivel con velocidades de entrada rondando 100km/h.

~~~

Terminamos con versiones creativas en cianotipo de las imágenes vectoriales. Si no te parecen bonitas careces de sentido de la estética y no mereces estar aquí leyendo, vete! (hacer clic para ver en alta resolución):







Y aquí una iteración final de la geometría G constante con 2 loops completos, mostrándose sin tramo inicial de adaptación. Para una velocidad de entrada de 100km/h y una aceleración buscada de 4,2G, tenemos loops de 25m de altura y 166,5m de longitud total, completándose en 7,1s (hacer clic para ver en alta resolución):




~~~

Repositorio con el código R: GitHub.

No hay comentarios:

Publicar un comentario

Por claridad del blog, por favor trata de utilizar una sintaxis lo más correcta posible y no abusar del uso de emoticonos, mayúsculas y similares.