Forward and inverse: two directions of the same problem
Forward kinematics starts with joint values. An angular joint rotates; a sliding joint translates. MyModelRobot combines those motions with the joint origins defined in URDF, following the parent–child hierarchy to calculate each link’s position and orientation.
Write the selected point’s position as p(q), where q is the list of joint values. Forward kinematics evaluates p(q). Inverse kinematics asks for q that brings this point close to a target t:
min e = ‖t − p(q)‖
The error e is the straight-line distance to the target. Different joint configurations may produce the same position, and some targets have no solution. MyModelRobot searches iteratively from the current pose.
What are you moving?
Double-click a segment, or enable the pose tool and select one. A ray from the camera through the pointer identifies the visible mesh and its owning robot link.
The point being positioned is the centre of the selected link’s visual bounding box, calculated in that link’s coordinates. This geometric handle ties placement to the segment’s shape rather than an arbitrary surface detail; it is not a centre of mass. Your click may be elsewhere on the surface, so the tool retains a fixed world-space offset between your click and this centre. The segment follows without suddenly snapping its centre under the pointer.
A screen pointer supplies two coordinates; the target needs three. Initially, pointer rays intersect a plane through the click, facing the camera. The intersection plus the retained offset gives the centre target; moving the pointer moves this target in a parallel plane. The wheel or depth buttons move the plane nearer or farther. The camera pauses during placement so this mapping stays stable.
Which joints take part?
The solver walks from the selected link towards its ancestors. It treats links connected by fixed joints as one rigid assembly, preventing rigid decorations from creating false branch boundaries. It includes movable joints until it reaches a branching assembly, then stops before moving that shared anchor.
Thus, selecting one arm generally adjusts that arm’s chain while its branching anchor stays steady. Joints farther down the tree than the selected link keep their values: their links follow the segment with the existing bends. Choosing a forearm and choosing a hand can therefore produce different motions.
One joint at a time: axis-constrained CCD
MyModelRobot uses cyclic coordinate descent (CCD). Each sweep visits the chosen joints from the selected segment towards the anchor. For each joint, it recalculates the current point and the joint’s axis in world coordinates, using the parent’s current transform and the URDF joint origin.
For a revolute or continuous joint, the allowed motion is rotation around that axis. Imagine looking straight down it. The solver projects the vectors from the joint origin to the selected point and to the target onto the plane perpendicular to the axis. Call those projected vectors u and v, and the unit axis a. The signed correction is:
Δq = atan2(a · (u × v), u · v)
This turns the point’s projected direction towards the target’s. Ordinary sweeps cap each correction at 0.25 radians. If the point lies on the rotation axis, rotation cannot change its position, so that joint is skipped.
A prismatic joint instead slides along its axis:
Δq = (t − p) · a
This extracts the part of the position error that sliding can correct. Each ordinary update is capped at 4% of the robot’s overall scale. After every joint adjustment, forward kinematics updates the link transforms before the next joint is considered.
Repeating, respecting limits, and learning from the result
Revolute and prismatic values stay within their joint limits. Continuous angles wrap to an equivalent value between −π and π. Angles use radians; translations use metres.
Short batches across animation frames keep the browser responsive, normally allowing up to 20 sweeps and about 4 milliseconds per call. It keeps the best pose found. Its reach tolerance is 0.1% of the robot’s bounding-box diagonal at selection time, with a minimum of one micrometre. When progress stops, deterministic trial offsets can help a straight or awkward configuration begin moving; unsuccessful trials are discarded.
Try selecting a forearm, moving the target sideways, and then changing its depth. Watch which sliders respond and which remain steady. Place the pose to keep it, or cancel to restore the starting values.
This is a local position solver: orientation is free, collision warnings are advisory, and “Best pose” means the best configuration found by this search. A remaining gap may reflect reach, limits, or a local stall. Try another starting bend or select a different segment to explore why.
Kinematyka prosta i odwrotna
Kinematyka prosta zaczyna od wartości przegubów. Przegub obrotowy wykonuje obrót, a przesuwny — przesunięcie. MyModelRobot łączy te ruchy z położeniami i orientacjami początkowymi przegubów zapisanymi w URDF. Następnie, zgodnie z hierarchią rodzic–dziecko, wyznacza położenie i orientację każdego segmentu.
Położenie wybranego punktu zapiszmy jako p(q), gdzie q oznacza zestaw wartości przegubów. Kinematyka prosta oblicza p(q). Kinematyka odwrotna szuka takich wartości q, aby punkt znalazł się blisko celu t:
min e = ‖t − p(q)‖
Błąd e jest odległością od celu w linii prostej. Różne konfiguracje mogą dawać to samo położenie, a niektóre cele są nieosiągalne. MyModelRobot prowadzi obliczenia iteracyjne od bieżącej konfiguracji, zamiast wyznaczać wszystkie możliwe rozwiązania.
Co właściwie przesuwasz?
Kliknij segment dwukrotnie albo włącz narzędzie ustawiania pozycji i wybierz segment. Promień biegnący od kamery przez wskaźnik wskazuje widoczną geometrię i segment robota, do którego ona należy.
Przesuwanym punktem jest środek prostopadłościanu obejmującego geometrię wizualną wybranego segmentu, obliczony w jego lokalnym układzie współrzędnych. Ten uchwyt geometryczny wiąże ustawianie pozycji z kształtem segmentu zamiast z przypadkowym szczegółem powierzchni; nie jest środkiem masy. Ponieważ możesz kliknąć w innym miejscu powierzchni, narzędzie zachowuje stałe przesunięcie w układzie świata między kliknięciem a tym środkiem. Segment podąża za wskaźnikiem bez nagłego przeskoku środka pod kursor.
Wskaźnik na ekranie ma dwie współrzędne, a cel w przestrzeni potrzebuje trzech. Początkowo promień wskaźnika przecina płaszczyznę przechodzącą przez kliknięty punkt i zwróconą do kamery. Punkt przecięcia powiększony o zachowane przesunięcie wyznacza cel środka; ruch wskaźnika przesuwa ten cel po płaszczyźnie równoległej. Kółko myszy lub przyciski głębokości przesuwają płaszczyznę bliżej albo dalej. Podczas ustawiania kamera pozostaje nieruchoma, co stabilizuje to odwzorowanie.
Które przeguby biorą udział?
Algorytm przechodzi od wybranego segmentu w stronę jego przodków w hierarchii. Segmenty połączone przegubami stałymi traktuje jak jeden sztywny zespół, dzięki czemu nieruchome elementy dekoracyjne nie tworzą pozornych granic rozgałęzień. Dodaje do łańcucha przeguby ruchome aż do rozgałęzienia, po czym zatrzymuje się przed poruszeniem wspólnego punktu oparcia.
Wybranie segmentu ręki zwykle uruchamia więc przeguby tej ręki, pozostawiając nieruchomy zespół, z którego wychodzą gałęzie. Przeguby leżące dalej w hierarchii niż wybrany segment zachowują swoje wartości. Ich segmenty podążają za nim z dotychczasowymi zgięciami. Wybór przedramienia może zatem wywołać inny ruch niż wybór dłoni.
Po jednym przegubie: CCD z uwzględnieniem osi
MyModelRobot stosuje cykliczny spadek po współrzędnych, czyli CCD. Jeden przebieg odwiedza wybrane przeguby od przesuwanego segmentu w stronę punktu oparcia. Dla każdego z nich algorytm ponownie oblicza położenie punktu oraz oś przegubu w układzie świata, korzystając z aktualnej transformacji rodzica i początku przegubu z URDF.
Przegub obrotowy lub obrotowy bez ograniczeń pozwala obracać tylko wokół swojej osi. Wyobraź sobie widok wzdłuż niej. Algorytm rzutuje wektory prowadzące od początku przegubu do przesuwanego punktu i do celu na płaszczyznę prostopadłą do osi. Oznaczmy te rzuty jako u i v, a jednostkowy wektor osi jako a. Poprawka kąta ze znakiem wynosi:
Δq = atan2(a · (u × v), u · v)
Poprawka obraca kierunek punktu w stronę kierunku celu. W zwykłym przebiegu jej wartość bezwzględna nie przekracza 0,25 radiana. Jeśli punkt leży na osi, obrót nie zmieni jego położenia, więc ten przegub zostaje pominięty.
Przegub przesuwny działa inaczej:
Δq = (t − p) · a
Iloczyn skalarny wybiera część błędu, którą można usunąć ruchem wzdłuż osi. Pojedyncza zwykła poprawka nie przekracza 4% skali całego robota. Po każdej zmianie kinematyka prosta aktualizuje transformacje segmentów, zanim algorytm przejdzie do następnego przegubu.
Kolejne przybliżenia i obserwacja wyniku
Wartości przegubów obrotowych i przesuwnych pozostają w granicach ich ograniczeń. Kąty przegubów ciągłych są sprowadzane do równoważnych wartości między −π a π. Kąty podaje się w radianach, a przesunięcia w metrach.
Aby przeglądarka zachowała płynność działania, obliczenia odbywają się w krótkich seriach rozłożonych na klatki animacji: zwykle do 20 przebiegów i około 4 milisekund na wywołanie. Program zachowuje najlepszą znalezioną konfigurację. Tolerancja osiągnięcia celu wynosi 0,1% przekątnej prostopadłościanu obejmującego robota w chwili wyboru segmentu, lecz co najmniej jeden mikrometr. Gdy poprawa ustaje, ustalone poprawki próbne pomagają czasem ruszyć z wyprostowanej lub niekorzystnej konfiguracji. Nieudane próby są odrzucane.
Wybierz przedramię, przesuń cel w bok, a następnie zmień jego głębokość. Obserwuj, które suwaki reagują. Zatwierdź konfigurację lub anuluj, aby przywrócić wartości początkowe.
To lokalne rozwiązywanie zadania położenia: orientacja jest swobodna, a ostrzeżenia o kolizjach nie blokują ruchu. „Najlepsza pozycja” oznacza najlepszy wynik tego wyszukiwania. Pozostała odległość może wynikać z zasięgu, ograniczeń lub lokalnego zastoju. Zmień początkowe zgięcie albo wybrany segment i porównaj efekt.