A single-page 3D visualization tool for robot end-effector poses and kinematic simulation. Built with Three.js in the browser and an optional Python IK server backed by cuMotion.
flowchart TD
subgraph Browser ["Browser (index.html)"]
UI["Sidebar UI\n(pose inputs, URDF loader,\njoint sliders)"]
THREE["Three.js Scene\n(WebGL renderer)"]
ORBIT["OrbitControls\n(orbit / zoom / pan)"]
IK_CLIENT["IK Client\n(fetch to port 7843)"]
UI -->|add pose / update joints| THREE
ORBIT --> THREE
UI -->|solve IK request| IK_CLIENT
IK_CLIENT -->|joint angles| UI
end
subgraph Server ["IK Server (ik_server.py)"]
HTTP["HTTP API\n:7843"]
PARSER["URDF Parser\n(xml.etree)"]
CCD["CCD Position Solver\n(Python / NumPy)"]
CUMOTION["cuMotion GPU IK\n(optional — NVIDIA RTX)"]
HTTP -->|/load_urdf| PARSER
HTTP -->|/solve_ik| CCD
HTTP -->|/solve_ik| CUMOTION
PARSER --> CCD
PARSER --> CUMOTION
end
subgraph Scene ["3D Scene"]
GRID["XY Grid\n(500mm, 50mm steps)"]
AXES["World Axes\n(X/Y/Z with cones)"]
POSES["Pose Quivers\n(XYZ arrows per pose)"]
PATH["Sequential Path Line"]
ROBOT["Robot Skeleton\n(cylinders + spheres)"]
EE_Q["EE Quiver\n(live from FK)"]
end
THREE --> GRID
THREE --> AXES
THREE --> POSES
THREE --> PATH
THREE --> ROBOT
ROBOT --> EE_Q
IK_CLIENT <-->|JSON REST| HTTP
- WebGL scene via Three.js — dark/light theme toggle
- World origin with X (red) / Y (green) / Z (blue) axis lines and cones
- XY floor grid, 50mm spacing
- Isometric camera start; orbit (left-drag), zoom (scroll), pan (right-drag)
- Add 6D poses: X, Y, Z (mm) + Rx, Ry, Rz (degrees, ZYX Euler)
- Each pose rendered as a color-coded quiver (local X/Y/Z arrows)
- Sequential path line connecting all poses in order
- Select a pose from the list to auto-populate inputs for IK targeting
- Clear All button
- Load any
.urdffile directly in the browser (no mesh files needed) - Auto-detects metres vs mm (scales accordingly)
- FK rendered as cylinder/sphere skeleton with end-effector quiver
- Joint sliders with live FK — values shown in degrees/mm, click to type
- Live EE pose readout: position inputs update as you jog joints
- Solve IK button targets whatever is in the X/Y/Z/Rx/Ry/Rz inputs
- With IK server running: uses Python CCD (position) or cuMotion GPU IK (6D, when kernels built)
- Without server: falls back to browser-side finite-difference solver
- Status bar shows position error, orientation error, backend used
Open index.html directly in Chrome or run a local server:
cd /path/to/robpos-3d-graph
python3 -m http.server 7842Then open http://localhost:7842.
cd server
python3 ik_server.pyRequires Python 3.10+ and NumPy (pip install numpy).
The viewer automatically detects the server at http://127.0.0.1:7843 and shows a green status indicator when connected.
Click Load Robot (URDF) in the sidebar and select a .urdf file. The robot skeleton appears in the scene. Tested with ABB GoFa CRB15000.
| Endpoint | Method | Description |
|---|---|---|
/status |
GET | Health check — returns backend and load state |
/load_urdf |
POST | Load robot from URDF content or file path |
/solve_ik |
POST | Solve IK for a 6D target pose |
{
"content": "<urdf xml string>"
}{
"target": { "x": 400, "y": 200, "z": 800, "rx": 0, "ry": 90, "rz": 0 },
"joint_names": ["joint_1", "joint_2", "joint_3", "joint_4", "joint_5", "joint_6"],
"current_angles": { "joint_1": 0.0, "joint_2": 0.0 }
}{
"status": "ok",
"solved": true,
"angles": { "joint_1": 0.49, "joint_2": -0.25, "joint_3": 0.69, "joint_4": -0.39, "joint_5": 1.02, "joint_6": 4.71 },
"pos_err": 7.1,
"ori_err": -1,
"backend": "fallback-ccd",
"ee": [403.7, 197.4, 805.5]
}cuMotion provides GPU-accelerated 6D IK with collision awareness. It requires an NVIDIA GPU with CUDA.
cd server
bash install_curobo.shOr manually:
cd server
git clone https://github.com/NVlabs/curobo.git
cd curobo
CUROBO_USE_PYBIND=1 /path/to/python3 -m pip install -e . --no-build-isolationNote: The current dev2 build has incomplete kernel sources. Once a stable release is available the GPU path will activate automatically — no code changes needed. The server falls back to Python CCD in the meantime.
When cuMotion is working, the server status will show:
✓ IK server • cumotion • 6 joints loaded
robpos-3d-graph/
├── index.html Single-page app (viewer + UI + browser IK)
├── README.md This file
└── server/
├── ik_server.py Python IK server (CCD + cuMotion)
├── install_curobo.sh cuMotion installation script
└── curobo/ cuMotion source (cloned by install script)
If started in a terminal: Ctrl+C
Kill the IK server (port 7843):
kill $(lsof -ti:7843)Kill by process name:
pkill -f ik_server.pyKill the viewer HTTP server (port 7842):
kill $(lsof -ti:7842)| Action | Control |
|---|---|
| Orbit | Left-drag |
| Zoom | Scroll wheel |
| Pan | Right-drag |
| Select pose | Click pose in list |
| Edit joint angle | Click the value label next to slider |
| Component | Dependency |
|---|---|
| Browser renderer | Three.js r128 (CDN) |
| Camera controls | Three.js OrbitControls (CDN) |
| IK server | Python 3.10+, NumPy |
| GPU IK | NVIDIA GPU, CUDA 12.x, PyTorch 2.x, cuMotion |
No build step required for the viewer. Everything runs from the single HTML file.