¿Cómo determinar qué propulsores encender para rotar la nave?

47

La configuración de la nave cambia dinámicamente, por lo que tengo que determinar qué propulsor encender cuando quiero rotar la nave en sentido horario o antihorario. Los propulsores siempre están alineados en el eje con el barco (nunca en ángulo) y están encendidos o apagados. Aquí hay una de las posibles configuraciones:

http://i.stack.imgur.com/GSBSH.png

Lo que he intentado hasta ahora es visualizar el vector de disparo y el vector de dirección al centro de masa del barco:

http://i.stack.imgur.com/ZzNzi.png

Desafortunadamente, no llegué muy lejos con eso.

migimunz
fuente
77
Te diriges en la dirección correcta con vectores de fuerza. Intenta buscar fórmulas para la velocidad ANGULAR ya que estás tratando de rotar la nave alrededor del centro de masa.
Amplify91
Me olvido de cómo hacerlo exactamente, pero básicamente son solo fuerzas en cada punto en.wikipedia.org/wiki/Center_of_mass y especialmente en.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex
1
¡Tenía exactamente la misma idea! Un consejo que puede facilitarle la tarea es que solo necesita calcular la aceleración angular y lineal una vez para cada propulsor, por lo que los cálculos pueden ser tan complejos como desee.
Markus von Broady
@ Amplify91, tu comentario realmente me ayudó a resolverlo, ¡gracias!
migimunz
1
@migimunz Estaba pensando en calcular aceleraciones por propulsor, no por tecla presionada (grupo de propulsores). Además, dar al jugador la opción de elegir qué propulsores deberían activarse y qué tecla presionar podría ser interesante (algunas personas intercambiarían rotaciones más rápidas por rotar en su lugar)
Markus von Broady

Respuestas:

22

¡Éxito! Aquí está, y está girando como debería: ingrese la descripción de la imagen aquí

Lo que he hecho es lo siguiente: para cada propulsor, calculo la magnitud del par, en relación con el centro de masa.

private function thrustTorque():Float
{
    // distToCom is the distance vector between the thruster and center of mass
    // fire angle is a unit vector representing the direction of the thruster
    var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
    var fireAngle = Math.atan2(dir.y, dir.x);
    var theta = fireAngle - distAngle;
    var torque = distToCOM.length * Math.sin(theta);
    return torque;
}

La ecuación para la mangitude de torque, según wikipedia, es T = rF sin(theta), donde:

  • r es la distancia entre el propulsor y COM
  • F es la magnitud de la fuerza aplicada (lo dejo afuera, fingiendo que es solo uno, porque solo me importa el signo).
  • theta es el ángulo entre los dos vectores

Cuando el jugador presiona hacia la izquierda, verifico el signo de torque para ese propulsor; si es menor que cero, disparo el propulsor. Es todo lo contrario para girar en sentido horario.

Esto probablemente podría mejorarse usando el producto de puntos para calcular el coseno del ángulo entre los vectores, pero eso tendrá que esperar hasta mañana.

Finalmente, aquí hay una demostración en vivo .

migimunz
fuente
Casi allí, creo. Parece no estar exactamente en el centro de masa. Usando solo las flechas izquierda / derecha, el barco puede salir fácilmente de la pantalla. Muy cerca sin embargo. Quizás el punto desde el que está midiendo está ligeramente desviado. O podría ser un problema de tiempo ya que parece estabilizarse en un buen giro después de un tiempo. Buen trabajo sin embargo.
MichaelHouse
No creo que tenga nada que ver con esta lógica. No hay nada aquí para garantizar que el vehículo no reciba una fuerza de traslación neta al disparar el conjunto de thursters seleccionados por este mecanismo. Si no se requiere mantener una fuerza de traslación neta, será necesario poder modular la fuerza de los propulsores individuales (y probablemente se convertirá en un problema mucho más difícil de resolver)
Trevor Powell
@TrevorPowell, exactamente. En aras de la simplicidad (y también de la diversión, ya que el rendimiento de su nave dependerá de qué tan bien lo diseñe), decidí que los propulsores están activados o desactivados. Probablemente incluiré un umbral para que aquellos que causan muy poco torque (y por lo tanto demasiado movimiento lateral) no se enciendan, pero exactamente cuánto es "demasiado / poco" probablemente se determinará por prueba y error.
migimunz
3
Lo que desea hacer para evitar los cálculos de ángulos es usar el producto de punto perpendicular (derivado de la definición del producto cruzado de torque T = r cross F si usa vectores 3D con z = 0). Tomas el vector (-ry, rx), que es perpendicular a r con la misma magnitud, y calculas el producto punto de ese vector con F. El resultado es T = rx * Fy - ry * Fx. Entonces abs (T) es la magnitud del par, y su signo indica dirección: T> 0 es en sentido antihorario, T <0 es en sentido horario.
Joren
1
La razón por la que funciona es fácil de ver intuitivamente: r dot F = r F cos θ. Si gira r en sentido antihorario 90 grados y toma el producto escalar, obtendrá r F sin θ porque cos (θ - 90˚) = sin (θ).
Joren
14

La expresión general 3D para el par es el producto cruzado de desplazamiento y fuerza: T = rF . En dos dimensiones, un valor escalar para el par será suficiente, y dadas solo cuatro orientaciones ortogonales para los propulsores, podemos escribir en forma por partes:

  • Fuerza en dirección + x: T = F * (-ry)
  • Fuerza en dirección -x: T = F * (ry)
  • Fuerza en dirección + y: T = F * (rx)
  • Fuerza en dirección -y: T = F * (-rx)

Aquí, F es la magnitud de la fuerza generada por los propulsores, rx y ry son componentes x e y del vector desde el punto de pivote al propulsor. Los pares positivos tienden a rotar el barco en sentido antihorario. Usando las cuatro fórmulas anteriores, es trivial deducir el signo del par que produce cada propulsor.

Para una representación modestamente precisa de la física, no solo necesita conocer el signo del empuje, sino también su magnitud total y la inercia rotacional. Además, es posible que no desee simplemente activar todos los propulsores correctamente alineados para hacer una rotación.

Astronave

Tal como se dibuja, la potencia total de los propulsores B, D y E maximizará la rotación, pero también acelerará la nave hacia la derecha. Cerrar D evitará esto. Si, en cambio, se pretende acelerar a la derecha, pero no es una rotación en el sentido de las agujas del reloj, la forma más eficiente de hacerlo es habilitar C y F a dos tercios de la potencia total junto con D.

Si esto no está fuera del alcance de lo que está tratando de hacer, tendría que escribir algún tipo de solucionador para las ecuaciones de movimiento, claramente no es una tarea simple.

Thomas Thomas
fuente
7

Algunas cosas diferentes. Primero, debemos reconocer que este es un problema poco restringido. Es decir, hay muchas combinaciones diferentes de propulsores que pueden disparar para dar como resultado una rotación en la misma dirección. Supongo que en su situación solo hay dos estados para los propulsores, "encendido" y "apagado", y todos los propulsores producen la misma fuerza.

En segundo lugar, mirando su modelo, parece que su "centro de masa" no es realmente su centro de masa. Afortunadamente, esto no afectará sus cálculos para el par. Sin embargo, afectará sus cálculos para el centro de desplazamiento masivo. Sin embargo, no estoy seguro si le importa la precisión en ese nivel, ya que su "centro de masa" es al menos el cuadrado más cercano al verdadero centro de masa.

Tercero, si desea calcular cómo un determinado propulsor afectará la rotación, tiene razón, aunque esté utilizando una fórmula ineficiente. El par se puede calcular como r x F, que tiene magnitud r*F*sin(theta). Sin embargo, calcular los ángulos en este caso es un método ineficiente. En su lugar, debe usar la definición de par cruzado del producto directamente, ya que esto será mucho más simple usando las representaciones que tiene. Como todos sus vectores no tienen componente z, la fórmula para el producto cruzado se simplifica enormemente.

Sin cambiar los resultados de su cómputo, podemos actualizar su código

private function thrustTorque():Float
{
    var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
    return torque;
}

Eso es mucho mejor (y más rápido).

Usted sugiere en su propia respuesta que su solución es disparar todos los propulsores con torque en la dirección correcta. Ahora, eso prácticamente resuelve la pregunta que hiciste. Sin embargo, espero que en algún punto a lo largo de la línea, encuentre que su estrategia no es tan satisfactoria, si un usuario mantiene presionado el botón "rotar", y todos los propulsores con un par positivo rotan, posiblemente moviéndolos hacia arriba de rotarlos (no estoy seguro del nivel de detalle de su simulación, si realmente calcula las fuerzas de los propulsores, o si simplemente les muestra visualmente disparando y luego gira su modelo con una aceleración constante o algo así. de esta manera, desea que los propulsores estén disparando al menos aproximadamente con precisión).

No tienes en cuenta la fuerza neta en el barco. Si tuviera cantidades arbitrarias de propulsores, esto podría convertirse en un problema bastante complicado. Sin embargo, dado que nuestros propulsores tienen solo dos estados, es bastante simple de analizar. No estoy seguro de cuál es exactamente nuestro objetivo aquí, por lo que podría imaginar dos diferentes: primero, queremos minimizar la fuerza total, manteniendo el par en la dirección que queremos. En segundo lugar, queremos maximizar la relación entre el par y la fuerza total.

Por otro lado, si pudiera imaginar un control adicional de "volumen del propulsor" que afecte la potencia de todos los propulsores simultáneamente, entonces podría configurar este control para que sus dos soluciones tengan el mismo par, y verá que la segunda solución solo puede tener un desplazamiento menor que el primero. Sin embargo, debemos recordar que si es posible disparar los propulsores para que solo gire y no se mueva en absoluto, entonces ambas soluciones serán las mismas.

Entonces, vamos a ir con la segunda solución, basada en los argumentos del párrafo anterior. Ahora, al analizar la fuerza total, simplemente podemos notar que solo hay cuatro direcciones que los motores pueden apuntar. Por lo tanto, la fuerza total en la dirección x es solo el número de propulsores que apuntan hacia la izquierda menos el número que apunta hacia la derecha, y lo mismo para la dirección y.

Después de escribir hasta aquí, tengo que pensar un poco más sobre el algoritmo para optimizarlo. Creo que el resto de mi publicación es útil, así que lo estoy publicando, pero lo actualizaré cuando encuentre la mejor manera de optimizar esta configuración (he pensado en algunas formas de obtener respuestas aproximadas, pero ninguno de ellos es exacto).

Jeremy Salwen
fuente
Gracias por la respuesta (y la solución más rápida y limpia para calcular el par). Sin embargo, el círculo rojo no es el COM de la nave, es el núcleo de energía. Estoy usando un motor de física y simplemente estoy aplicando un impulso local a la nave. Estoy de acuerdo con que la solución no sea perfecta, ya que hace que sea muy divertido jugar con diferentes configuraciones, pero me encantaría saber qué se te ocurre.
migimunz
1
Puede calcular el par desde un punto de referencia arbitrario. El número resultante cambiará, pero siempre que gire la nave alrededor de este punto, que no necesita ser el centro de masa, el comportamiento físico no lo hará. De hecho, sin información sobre la distribución de masa, el centro de masa es arbitrario en sí mismo y no puede calcularse como tal.
Marca Thomas el