Nesta postagem eu desenvolvo um braço robótico utilizando a biblioteca JavaScript Fabric.js (http://fabricjs.com/). A biblioteca funciona sobre o canvas do HTML5 e facilita o desenho de vários tipos de objetos, como círculos, retângulos, imagens, etc.
Estrutura do Braço Robótico

Sistema de Coordenadas
Quando o segumento número 1 se rotaciona em torno da junta 1, esse movimento leva consigo todo restante do braço robótico, isto é, os segumentos 2, 3 e o end effector e assim sucessivamente. Uma forma representar o estado do braço robótico é utilizar ângulos. É um mecanismo bastante intuitivo e, de certa forma, facilita a matemática necessária.
Cada segmento, então, possui um ângulo de rotação. Para esta implementação, preferi considerar que cada junta é a origem de um sistemas de coordenadas. Assim, se o segmento 2 está em um ângulo de 30°, este valor é em relação ao segmento 1. Para sabermos o ângulo do segmento 2 em relação ao mundo, precisamos somar o ângulo do segmento 1 em relação ao mundo ao ângulo do segmento 2.
A imagem abaixo ilustra esse pensamento. Os árgulos em vermlho são relativos à cada junto com o segmento anterior na qual ela está fixada. Note que o ângulo da junta inicial, que está posicioanda na origem do sistema de coordenadas, será sempre o mesmo ângulo em relação mundo.
O segundo segmento, que possui um ângulo de valor b em relação à primeira junta, estará em uma inclinação de a+b em relação ao mundo. Esse pensamento permanece para todas as outras juntas.

Usando alguns métodos iterativos de programação, podemos encontrar a posição x e y de cada junta dentro do plano cartesiano.

Implementação
A implementação foi feita com HTML e JavaScript, além do framework CSS Bootstrap.
Movimentação
A movimentação é baseada na escolha de qual junta mover e o apertar das setas para cima e para baixo (acho que não funciona em celulares). A velocidade angular é de 120° por segundo. Daí eu jogo essas regras em um loop e calculo quanto tempo se passou desde a última vez que os cálculos foram feitos. Uma regra de três é aplicada para saber a quantidade de movimento angular a ser realizado nesse intervalo de tempo. Por último, realizo os cálculos de todas as juntas baseado nesse ângulo movimentado, propagando o movimento para as juntas posteriores.
function gameLoop(timeDetalMillis) {
let incrementalAngle = (angularVelocity * timeDetalMillis) / 1000.0
if(eventInspector.isArrowUpKeyPressed()) {
incrementalAngle = incrementalAngle * -1
} else if(!eventInspector.isArrowDownKeyPressed()) {
incrementalAngle = 0
}
robotArm.addSegmentAngleDegrees(
parseInt($(SEGMENTS_SELECT_ID).find(":selected").val() || "0"),
{
segmentDeltaAngleDegrees: incrementalAngle
}
)
}
Resultado
O resultado final pode ser observado abaixo.

O código fonte está disponível no git: https://github.com/welyab/robot-arm-2d
Referências
Robot Pose: https://github.com/welyab/robot-arm-2d/tree/main/robot-arm-2d-model