Transformações Homogêneas para Poses de Robôs
Objetivos de Aprendizagem
- Juntar uma orientação e uma posição numa transformação e lê-la como a pose do referencial no referencial .
- Compor poses ao longo de uma cadeia de referenciais cancelando índices, e reconhecer uma cadeia multiplicada na ordem errada.
- Inverter uma pose com e , sem inversa geral de matriz, e explicar por que o atalho falha quando a matriz tem escala.
- Distinguir deslocar um referencial ao longo de eixos fixos (pré-multiplicação) de deslocá-lo ao longo dos próprios eixos (pós-multiplicação).
- Detectar e reparar a perda de ortonormalidade que produtos longos acumulam em ponto flutuante.
Contexto e Motivação
homogeneous-coordinates-and-2d-affine-transformations acrescentou um 1 a cada ponto para que a translação virasse produto de matrizes, usou 0 para direções, que assim ignoram a translação, e mostrou que a ordem de uma composição muda o resultado. 3d-transformations-and-composing-the-model-matrix levou isso para matrizes , com escala inclusive. Esses fatos ficam assumidos aqui.
A robótica usa as mesmas matrizes com duas mudanças. O bloco superior esquerdo fica restrito a uma rotação (sem escala, sem cisalhamento), o que torna a inversa exata e quase de graça. E há muitos referenciais ao mesmo tempo: a base do robô, uma câmera, um objeto detectado, uma garra, cada elo do braço. Toda transformação carrega, portanto, dois índices, e a maior parte dos bugs vem de lê-los ao contrário. O objetivo é uma notação em que um produto errado pareça errado antes de ser executado.
Teoria Central
Uma pose como matriz 4x4
Com as convenções de rotation-matrices-and-rigid-body-orientation (vetores coluna, guardando os eixos de escritos em ), a pose de em é
em que é a origem de escrita em . Essas matrizes formam o grupo especial euclidiano , os movimentos de corpo rígido. Agindo sobre um ponto com coordenada homogênea 1, converte coordenadas em em coordenadas em :
Então tem duas leituras, como as rotações tinham: a pose de vista de , que leva o referencial até o referencial , e o conversor que leva coordenadas de para . As palavras "de" e "para" trocam de lugar entre as duas leituras. A documentação do tf2 do ROS 2 alerta justamente para isso: transformar um referencial e transformar dados representados nele são, nas palavras dela, "directly inverse", e as transformações que o tf2 publica usam a formulação de referencial.
Composição ao longo de uma cadeia
Se é conhecido em e em , então
Os índices internos se cancelam, , e o produto de dois movimentos rígidos continua rígido. A parte de posição mostra por que a ordem importa: é girado para antes de ser somado. Uma cadeia só é legítima quando cada segundo índice é igual ao primeiro índice seguinte; qualquer outro produto é uma matriz sem significado, mesmo com o formato certo.
A inversa sem inversa geral
Resolver para só exige :
O custo é uma transposição (nenhuma conta) e um produto matriz-vetor , e o resultado é exato a menos do arredondamento desse produto. Dois atalhos parecidos estão errados. Transpor a matriz inteira joga para a última linha. Usar como nova translação esquece que está escrito em e a inversa precisa dele em . A fórmula também depende de : uma model matrix de computação gráfica com escala tem um bloco superior esquerdo que não é ortogonal, e aí só a inversa geral funciona.
Deslocando um referencial: eixos fixos ou eixos do corpo
Seja um deslocamento. Como nas rotações, o lado em que ele multiplica decide a que referencial pertencem o eixo e o deslocamento (Modern Robotics, Seção 3.3.1):
Pré-multiplicar gira em torno de um eixo do referencial fixo (a origem dele gira em volta do eixo fixo) e depois translada por em coordenadas fixas. Pós-multiplicar translada por ao longo dos eixos do próprio corpo e depois gira em torno do novo eixo do corpo, o que deixa a nova origem no lugar.
Mantendo R uma rotação
Todo produto arredonda, e uma pose atualizada por muitos incrementos pequenos, como ao integrar um giroscópio ou acumular odometria, se afasta de . O reparo é trocar por da sua decomposição em valores singulares , o que devolve os valores singulares a 1. A verificação é barata: e .
Exemplos Resolvidos
Todos os comprimentos estão em metros, e os valores são supostos, para ilustrar.
Exemplo 1: onde está o objeto, no referencial da base do robô?
Uma câmera está montada 1,2 m acima da origem da base e 0,5 m ao longo de , olhando para baixo: , então aponta para baixo. Um detector informa um objeto em nas coordenadas da câmera, com . Então
O objeto está em , girado em torno da vertical, com para cima. A conferência é física: 0,9 m abaixo de uma câmera a 1,2 m dá altura de 0,3 m. Multiplicar na ordem errada, , dá uma transformação rígida válida com translação , abaixo do plano da base. Os índices ( e depois , com ) denunciam o erro antes de qualquer conta.
Exemplo 2: invertendo poses
Pela fórmula, tem rotação e translação : vista da câmera, a origem da base está 1,2 m bem à frente, ao longo de , e 0,5 m ao longo de . Ela concorda com numpy.linalg.inv até em float64, e exatamente.
Para o objeto, tem rotação e translação . Inverter cada fator e inverter a ordem dá a mesma matriz, , até , e numpy.linalg.inv concorda até . Os dois atalhos errados, aplicados a :
textnaive 4x4 transpose, times T_so "-p" shortcut, times T_so [ 1 0 0 0.5446] [ 1 0 0 -0.0554] [ 0 1 0 -0.2567] [ 0 1 0 -0.3067] [ 0 0 1 0.3 ] [ 0 0 1 0 ] [ 0.5446 -0.2567 0.3 1.4525] [ 0 0 0 1 ]
Nenhum dos produtos é a identidade. O segundo é o mais perigoso, porque mantém o formato de uma pose: a rotação está certa e a posição erra por 31 cm.
Exemplo 3: uma pegada ao longo da cadeia
Uma pose de pré-pegada põe a garra 10 cm acima do objeto ao longo de , com o eixo de aproximação apontando para baixo: . Então
a garra a 0,4 m de altura, apontando para baixo. Um canto do objeto em em fica em em e em em . Este último valor sai igual calculado como aplicado em ou como aplicado em , que é a regra da cadeia conferida numericamente.
Exemplo 4: o mesmo deslocamento de cada lado
Sejam e o deslocamento :
Em a origem gira em torno do fixo até e sobe 0,3 m ao longo de . Em a origem anda 0,3 m ao longo do do corpo, que aponta para , até , e o referencial gira em torno de sem sair do lugar. Mesmo , referenciais diferentes, resultados diferentes.
Exemplo 5: onde o atalho quebra, e onde o arredondamento quebra R
Tome , uma model matrix com escala. Montar "" a partir dos blocos e multiplicar por dá , não ; o bloco não é ortogonal ().
Agora componha um milhão de vezes, a partir de :
textprecision max|R^T R - I| after 1e3 after 1e5 after 1e6 det after 1e6 float32 2.5e-05 1.9e-03 2.0e-02 0.9946 float64 7.4e-14 7.6e-12 7.6e-11 1.0000000000 (error 7.6e-11)
Em float32 a "rotação" encolhe volumes em meio por cento, e a inversa por erra por cerca de 2%. Trocar por da SVD traz o erro de volta para menos de nos dois casos. Em float64 o erro cresce de forma aproximadamente linear com o número de produtos, então um estimador de longa duração em float64 ainda precisa do reparo, só que com menos frequência.
Equívocos Comuns e Armadilhas
- "A inversa de uma pose é a transposta." Só o bloco de rotação é transposto. O Exemplo 2 mostra a transposta da matriz inteira falhando.
- "Inverter uma pose troca o sinal da posição." A nova posição é , não ; o erro no Exemplo 2 foi de 31 cm.
- " leva pontos de para ." Ela leva coordenadas em para coordenadas em . Leia os índices da direita para a esquerda.
- "Toda transformação se inverte com o atalho." Só as rígidas. A matriz com escala do Exemplo 5 devolveu .
- "Se cada fator está certo, o produto está certo." O produto invertido do Exemplo 1 era uma transformação rígida válida que punha o objeto abaixo da mesa.
- "Matrizes de rotação continuam rotações." Em ponto flutuante elas derivam: depois de um milhão de produtos em float32 no Exemplo 5.
Resumo
Uma transformação homogênea é a pose de em e o conversor de coordenadas em para coordenadas em . Poses se compõem ao longo de uma cadeia cancelando os índices internos, , e um produto cujos índices não se cancelam está errado mesmo sendo uma matriz válida. Como é ortogonal, a inversa é , exata e barata; a transposta da matriz inteira e o atalho estão errados, e a fórmula falha para matrizes com escala. Um deslocamento aplicado à esquerda usa eixos fixos, e à direita usa eixos do corpo. Produtos longos se afastam de , de forma mensurável em float32, e uma SVD restaura a rotação.