Como determinar quais propulsores ativar para girar o navio?

47

A configuração do navio muda dinamicamente, por isso preciso determinar qual propulsor será ativado quando desejar girar o navio no sentido horário ou anti-horário. Os propulsores estão sempre alinhados ao eixo do navio (nunca em ângulo) e estão ligados ou desligados. Aqui está uma das configurações possíveis:

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

O que eu tentei até agora é visualizar o vetor de disparo e o vetor de direção para o centro de massa do navio:

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

Infelizmente, não fui muito longe com isso.

migimunz
fonte
7
Você está indo na direção certa com vetores de força. Tente procurar fórmulas para a velocidade ANGULAR, pois você está tentando girar a nave em torno do centro de massa.
Amplify91
Eu esqueço exatamente como fazê-lo, mas, basicamente, os seus apenas forças em cada ponto en.wikipedia.org/wiki/Center_of_mass e, especialmente, en.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex
1
Eu tive exatamente a mesma ideia! Uma dica que pode facilitar as coisas para você é que você só precisa calcular a aceleração angular e linear uma vez para cada propulsor; portanto, os cálculos podem ser tão complexos quanto você desejar.
Markus von Broady
@ Amplify91, seu comentário me ajudou a descobrir, obrigado!
26612 migimunz
1
@migimunz Eu estava pensando em calcular acelerações por propulsor, não por tecla pressionada (grupo de propulsores). Além disso, dando ao jogador uma escolha que propulsores devem ser ativados no qual tecla pressionada poderia ser interessante (algumas pessoas trocaria mais rápido girar para girar no lugar)
Markus von Broady

Respostas:

22

Sucesso! Aqui está, e está girando como deveria: insira a descrição da imagem aqui

O que fiz foi o seguinte: para cada propulsor, calculo a magnitude do torque em relação ao centro de massa.

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;
}

A equação para a mangitude do torque, de acordo com a Wikipedia, é T = rF sin(theta):

  • r é a distância entre o propulsor e o COM
  • F é a magnitude da força aplicada (deixo de fora, fingindo que é apenas uma, porque só me preocupo com o sinal).
  • teta é o ângulo entre os dois vetores

Quando o jogador pressiona para a esquerda, eu verifico o sinal de torque desse propulsor - se for menor que zero, eu aciono o propulsor. É exatamente o oposto de girar no sentido horário.

Provavelmente, isso poderia ser melhorado usando o produto escalar para calcular o cosseno do ângulo entre os vetores, mas isso terá que esperar até amanhã.

Finalmente, aqui está uma demonstração ao vivo .

migimunz
fonte
Quase lá, eu acho. Parece não estar exatamente no centro da massa. Usando apenas as setas esquerda / direita, o navio pode sair facilmente da tela. Muito perto. Talvez o ponto de onde você está medindo esteja ligeiramente fora. Ou pode ser um problema de tempo, pois parece estabilizar em uma boa rotação depois de um tempo. Bom trabalho embora.
MichaelHouse
Eu não acho que tenha algo a ver com essa lógica. Não há nada aqui para garantir que o veículo não receba uma força translacional líquida ao disparar o conjunto de disparadores selecionados por esse mecanismo. Se manter nenhuma força translacional net é um requisito, será necessário ser capaz de modular a força de propulsores individuais (e provavelmente vai se tornar um problema muito mais difícil de resolver)
Trevor Powell
@TrevorPowell, exatamente. Por uma questão de simplicidade (e também de diversão, já que o desempenho de sua nave dependerá de como você a projeta), decidi que os propulsores estão ligados ou desligados. Provavelmente incluirei um limite para que aqueles que causam muito pouco torque (e, portanto, muito movimento lateral) não sejam ativados, mas exatamente quanto é "muito / pouco" provavelmente será determinado por tentativa e erro.
22812 migimunz
3
O que você deseja fazer para evitar cálculos de ângulo é usar o produto de ponto perpendicular (derivado da definição de produto cruzado de torque T = r cruz F se você usar vetores 3D com z = 0). Você pega o vetor (-ry, rx), que é perpendicular a r com a mesma magnitude e calcula o produto escalar desse vetor com F. O resultado é T = rx * Fy - ry * Fx. Então abs (T) é a magnitude do torque e seu sinal indica a direção: T> 0 é no sentido anti-horário, T <0 é no sentido horário.
Joren
1
A razão pela qual funciona é fácil de ver intuitivamente: r ponto F = r F cos θ. Se você girar r 90 graus no sentido anti-horário e pegar o produto escalar, obtém r F sen θ porque cos (θ - 90˚) = sin (θ).
22412 Joren
14

A expressão geral 3D para o binário é o produto transversal de deslocamento e de força: t = rF . Em duas dimensões, um valor escalar para o torque será suficiente e, dadas apenas quatro orientações ortogonais para os propulsores, podemos escrever em partes:

  • Força na direção + x: T = F * (-ry)
  • Força na direção -x: T = F * (ry)
  • Força na direção + y: T = F * (rx)
  • Força na direção -y: T = F * (-rx)

Aqui, F é a magnitude da força gerada pelos propulsores, rx e ry são componentes x e y do vetor do ponto de articulação ao propulsor. Torques positivos tendem a girar o navio no sentido anti-horário. Usando as quatro fórmulas acima, é trivial deduzir o sinal do torque que cada propulsor produz.

Para uma representação modesta e precisa da física, você precisa não apenas conhecer o sinal do impulso, mas também sua magnitude total e a inércia rotacional. Além disso, talvez você não queira simplesmente ativar todos os propulsores alinhados corretamente para fazer uma rotação.

Nave espacial

Conforme desenhado, a potência total dos propulsores B, D e E maximizará a rotação, mas também acelerará o navio para a direita. Desligar D impedirá isso. Se, em vez disso, se pretende acelerar a direita, mas não é uma rotação no sentido horário, o caminho mais eficiente é habilitar C e F com dois terços da potência total, juntamente com D.

Se isso não estiver além do escopo do que você está tentando fazer, seria necessário escrever algum tipo de solucionador para as equações de movimento, claramente não uma tarefa simples.

Marcks Thomas
fonte
7

Algumas coisas diferentes. Primeiro, precisamos reconhecer que esse é um problema pouco restrito. Ou seja, existem muitas combinações diferentes de propulsores que podem disparar para resultar em rotação na mesma direção. Estou assumindo que na sua situação existem apenas dois estados para os propulsores, "on" e "off", e todos os propulsores produzem força igual.

Segundo, observando seu modelo, parece que seu "centro de massa" não é realmente o seu centro de massa. Felizmente, isso não afetará seus cálculos para o torque. No entanto, isso afetará seus cálculos para o centro do deslocamento de massa. Não tenho certeza se você se importa com a precisão nesse nível, já que o seu "centro de massa" é pelo menos o quadrado mais próximo do verdadeiro centro de massa.

Terceiro, se você deseja calcular como um determinado propulsor afetará a rotação, você está certo, embora esteja usando uma fórmula ineficiente. O torque pode ser calculado como r x F, que possui magnitude r*F*sin(theta). No entanto, calcular os ângulos nesse caso é um método ineficiente. Em vez disso, você deve usar diretamente a definição de torque entre produtos, pois isso será muito mais simples usando as representações que você possui. Como todos os seus vetores não têm componente z, a fórmula para produtos cruzados simplifica bastante.

Sem alterar os resultados do seu cálculo, podemos apenas atualizar seu código

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

Isso é muito melhor (e mais rápido).

Você sugere em sua própria resposta que sua solução é acionar todos os propulsores com torque na direção certa. Agora, isso praticamente resolve a pergunta que você fez. No entanto, espero que em algum momento, você descubra que sua estratégia não é tão satisfatória, se um usuário mantém pressionado o botão "girar" e todos os propulsores com um torque positivo giram, potencialmente movendo-os para cima de rotacioná-los (não tenho certeza do nível de detalhe da sua simulação, se você realmente calcula as forças dos propulsores, ou se apenas os mostra visualmente disparando e depois gira seu modelo com uma aceleração constante ou algo assim. Dessa forma, você deseja que os propulsores disparem pelo menos aproximadamente com precisão).

Você não considera a força líquida no navio. Se você tivesse valores arbitrários de propulsor, isso poderia se transformar em um problema bastante complicado. No entanto, como nossos propulsores têm apenas dois estados, é bastante simples de analisar. Não sei exatamente qual é o nosso objetivo aqui, então pude imaginar dois diferentes: primeiro, queremos minimizar a força total, mantendo o torque na direção que queremos. Segundo, queremos maximizar a proporção de torque em relação à força total.

Além disso, se você puder imaginar um controle adicional de "volume do propulsor" que afeta a potência de todos os propulsores simultaneamente, poderá definir esse controle para que suas duas soluções tenham torque igual e você verá que a segunda solução pode ter apenas um deslocamento menor que o primeiro. No entanto, precisamos lembrar que, se for possível acionar os propulsores para que você apenas gire e não se mova, as duas soluções serão as mesmas.

Então, vamos seguir com a segunda solução, com base nos argumentos do parágrafo anterior. Agora, ao analisar a força total, podemos simplesmente observar que existem apenas quatro direções que os motores podem apontar. Assim, a força total na direção x é apenas o número de propulsores apontando para a esquerda menos o número apontando para a direita e da mesma forma para a direção y.

Depois de escrever até aqui, tenho que pensar um pouco mais sobre o algoritmo para otimizá-lo. Acho que o restante da minha postagem é útil, por isso estou publicando, mas atualizarei quando descobrir a melhor maneira de otimizar essa configuração (pensei em algumas maneiras de obter respostas aproximadas, mas nenhum deles é exato).

Jeremy Salwen
fonte
Obrigado pela resposta (e a solução mais rápida e limpa para calcular o torque). O círculo vermelho não é o COM da nave, é o núcleo de poder. Estou usando um mecanismo de física e estou apenas aplicando um impulso local ao navio. Estou bem com a solução não sendo perfeita, pois torna muito divertido brincar com diferentes configurações, mas eu adoraria saber o que você cria.
migimunz
1
Você pode calcular o torque a partir de um ponto de referência arbitrário. O número resultante mudará, mas contanto que você gire a nave em torno deste ponto, que não precisa ser o centro de massa, o comportamento físico não mudará. De fato, sem informações sobre a distribuição de massa, o centro de massa é arbitrário e não pode ser calculado como tal.
Marcks Thomas