diff --git a/package-lock.json b/package-lock.json
index 3e375af..d60cf07 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"bun": "^1.1.38",
"clsx": "^2.1.1",
"depcheck": "^1.4.7",
+ "framer-motion": "^11.18.0",
"lenis": "^1.1.18",
"motion": "^11.14.1",
"next": "15.1.2",
@@ -3547,13 +3548,12 @@
}
},
"node_modules/framer-motion": {
- "version": "11.14.1",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.14.1.tgz",
- "integrity": "sha512-6B7jC54zgnefmUSa2l4gkc/2CrqclHL9AUbDxxRfbFyWKLd+4guUYtEabzoYMU8G5ICZ6CdJdydOLy74Ekd7ag==",
- "license": "MIT",
+ "version": "11.18.2",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
+ "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==",
"dependencies": {
- "motion-dom": "^11.14.1",
- "motion-utils": "^11.14.1",
+ "motion-dom": "^11.18.1",
+ "motion-utils": "^11.18.1",
"tslib": "^2.4.0"
},
"peerDependencies": {
@@ -4800,16 +4800,17 @@
}
},
"node_modules/motion-dom": {
- "version": "11.14.1",
- "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.14.1.tgz",
- "integrity": "sha512-Y68tHWR0d2HxHDskNxpeY3pzUdz7L/m5A8TV7VSE6Sq4XUNJdZV8zXco1aeAQ44o48u0i8UKjt8TGIqkZSQ8ew==",
- "license": "MIT"
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
+ "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==",
+ "dependencies": {
+ "motion-utils": "^11.18.1"
+ }
},
"node_modules/motion-utils": {
- "version": "11.14.1",
- "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.14.1.tgz",
- "integrity": "sha512-R6SsehArpkEBUHydkcwQ/8ij8k2PyKWAJ7Y8PN3ztnFwq5RBU3zIamYH6esTp09OgsbwB57mBEZ9DORaN1WTxQ==",
- "license": "MIT"
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz",
+ "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="
},
"node_modules/ms": {
"version": "2.1.3",
diff --git a/public/cad/decimate_mesh.py b/public/cad/decimate_mesh.py
new file mode 100644
index 0000000..b746bbe
--- /dev/null
+++ b/public/cad/decimate_mesh.py
@@ -0,0 +1,39 @@
+import open3d as o3d
+import shutil
+from pathlib import Path
+
+
+def decimate_mesh(input_path, output_path, target_faces=7500):
+ try:
+ mesh = o3d.io.read_triangle_mesh(str(input_path))
+ if len(mesh.triangles) > target_faces:
+ mesh = mesh.simplify_quadric_decimation(target_faces)
+ o3d.io.write_triangle_mesh(str(output_path), mesh)
+ print(f"Decimated {input_path.name}: {len(mesh.triangles)} faces")
+ return True
+ except Exception as e:
+ print(f"Could not decimate {input_path.name}, copying original: {e}")
+ return False
+ return False
+
+
+def process_folder(folder_path, output_folder):
+ folder_path = Path(folder_path)
+ output_folder = Path(output_folder)
+ output_folder.mkdir(exist_ok=True)
+
+ mesh_files = list(folder_path.glob("*.stl")) + list(folder_path.glob("*.obj"))
+
+ for mesh_path in mesh_files:
+ output_path = output_folder / mesh_path.name
+ if not decimate_mesh(mesh_path, output_path):
+ shutil.copy2(mesh_path, output_path)
+ print(f"Copied original {mesh_path.name}")
+
+
+if __name__ == "__main__":
+ zbot_path = Path("zbot")
+ mesh_folder = zbot_path / "meshes"
+ output_folder = zbot_path / "meshes_decimated"
+
+ process_folder(mesh_folder, output_folder)
diff --git a/public/cad/z-bot2_fe_urdf.mjcf b/public/cad/z-bot2_fe_urdf.mjcf
new file mode 100644
index 0000000..126af9c
--- /dev/null
+++ b/public/cad/z-bot2_fe_urdf.mjcf
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/cad/z-bot2_fe_urdf.urdf b/public/cad/z-bot2_fe_urdf.urdf
new file mode 100644
index 0000000..f28119c
--- /dev/null
+++ b/public/cad/z-bot2_fe_urdf.urdf
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/cad/zbot 2/meshes/3215_1Flange.stl b/public/cad/zbot 2/meshes/3215_1Flange.stl
new file mode 100644
index 0000000..ca8d695
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_1Flange.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_1Flange_2.stl b/public/cad/zbot 2/meshes/3215_1Flange_2.stl
new file mode 100644
index 0000000..461e553
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_1Flange_2.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange.stl b/public/cad/zbot 2/meshes/3215_BothFlange.stl
new file mode 100644
index 0000000..9d55058
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange_2.stl b/public/cad/zbot 2/meshes/3215_BothFlange_2.stl
new file mode 100644
index 0000000..849abec
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange_2.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange_3.stl b/public/cad/zbot 2/meshes/3215_BothFlange_3.stl
new file mode 100644
index 0000000..4eed15d
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange_3.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange_4.stl b/public/cad/zbot 2/meshes/3215_BothFlange_4.stl
new file mode 100644
index 0000000..33adf2b
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange_4.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange_5.stl b/public/cad/zbot 2/meshes/3215_BothFlange_5.stl
new file mode 100644
index 0000000..8b4dcca
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange_5.stl differ
diff --git a/public/cad/zbot 2/meshes/3215_BothFlange_6.stl b/public/cad/zbot 2/meshes/3215_BothFlange_6.stl
new file mode 100644
index 0000000..5169612
Binary files /dev/null and b/public/cad/zbot 2/meshes/3215_BothFlange_6.stl differ
diff --git a/public/cad/zbot 2/meshes/FINGER_1.stl b/public/cad/zbot 2/meshes/FINGER_1.stl
new file mode 100644
index 0000000..4343fed
Binary files /dev/null and b/public/cad/zbot 2/meshes/FINGER_1.stl differ
diff --git a/public/cad/zbot 2/meshes/FINGER_1_2.stl b/public/cad/zbot 2/meshes/FINGER_1_2.stl
new file mode 100644
index 0000000..db85507
Binary files /dev/null and b/public/cad/zbot 2/meshes/FINGER_1_2.stl differ
diff --git a/public/cad/zbot 2/meshes/FOOT.stl b/public/cad/zbot 2/meshes/FOOT.stl
new file mode 100644
index 0000000..64b3983
Binary files /dev/null and b/public/cad/zbot 2/meshes/FOOT.stl differ
diff --git a/public/cad/zbot 2/meshes/FOOT_2.stl b/public/cad/zbot 2/meshes/FOOT_2.stl
new file mode 100644
index 0000000..8603566
Binary files /dev/null and b/public/cad/zbot 2/meshes/FOOT_2.stl differ
diff --git a/public/cad/zbot 2/meshes/L-ARM-MIRROR_1.stl b/public/cad/zbot 2/meshes/L-ARM-MIRROR_1.stl
new file mode 100644
index 0000000..0d3f432
Binary files /dev/null and b/public/cad/zbot 2/meshes/L-ARM-MIRROR_1.stl differ
diff --git a/public/cad/zbot 2/meshes/R-ARM-MIRROR-1.stl b/public/cad/zbot 2/meshes/R-ARM-MIRROR-1.stl
new file mode 100644
index 0000000..fb31089
Binary files /dev/null and b/public/cad/zbot 2/meshes/R-ARM-MIRROR-1.stl differ
diff --git a/public/cad/zbot 2/meshes/U-HIP-L.stl b/public/cad/zbot 2/meshes/U-HIP-L.stl
new file mode 100644
index 0000000..ef0beac
Binary files /dev/null and b/public/cad/zbot 2/meshes/U-HIP-L.stl differ
diff --git a/public/cad/zbot 2/meshes/U-HIP-R.stl b/public/cad/zbot 2/meshes/U-HIP-R.stl
new file mode 100644
index 0000000..87f45b1
Binary files /dev/null and b/public/cad/zbot 2/meshes/U-HIP-R.stl differ
diff --git a/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2.stl b/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2.stl
new file mode 100644
index 0000000..bf3fc57
Binary files /dev/null and b/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2.stl differ
diff --git a/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl b/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl
new file mode 100644
index 0000000..f6e73e6
Binary files /dev/null and b/public/cad/zbot 2/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl differ
diff --git a/public/cad/zbot 2/meshes/Z-BOT2_MASTER-BODY-SKELETON.stl b/public/cad/zbot 2/meshes/Z-BOT2_MASTER-BODY-SKELETON.stl
new file mode 100644
index 0000000..c82ff53
Binary files /dev/null and b/public/cad/zbot 2/meshes/Z-BOT2_MASTER-BODY-SKELETON.stl differ
diff --git a/public/cad/zbot 2/z-bot2_fe_urdf.mjcf b/public/cad/zbot 2/z-bot2_fe_urdf.mjcf
new file mode 100644
index 0000000..126af9c
--- /dev/null
+++ b/public/cad/zbot 2/z-bot2_fe_urdf.mjcf
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/cad/zbot 2/z-bot2_fe_urdf.urdf b/public/cad/zbot 2/z-bot2_fe_urdf.urdf
new file mode 100644
index 0000000..8a97726
--- /dev/null
+++ b/public/cad/zbot 2/z-bot2_fe_urdf.urdf
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/cad/zbot.tgz b/public/cad/zbot.tgz
new file mode 100644
index 0000000..10e56bd
Binary files /dev/null and b/public/cad/zbot.tgz differ
diff --git a/public/cad/zbot/meshes/3215_1Flange.stl b/public/cad/zbot/meshes/3215_1Flange.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_1Flange_2.stl b/public/cad/zbot/meshes/3215_1Flange_2.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange.stl b/public/cad/zbot/meshes/3215_BothFlange.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange_2.stl b/public/cad/zbot/meshes/3215_BothFlange_2.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange_3.stl b/public/cad/zbot/meshes/3215_BothFlange_3.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange_4.stl b/public/cad/zbot/meshes/3215_BothFlange_4.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange_5.stl b/public/cad/zbot/meshes/3215_BothFlange_5.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/3215_BothFlange_6.stl b/public/cad/zbot/meshes/3215_BothFlange_6.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/FINGER_1.stl b/public/cad/zbot/meshes/FINGER_1.stl
new file mode 100644
index 0000000..4343fed
Binary files /dev/null and b/public/cad/zbot/meshes/FINGER_1.stl differ
diff --git a/public/cad/zbot/meshes/FINGER_1_2.stl b/public/cad/zbot/meshes/FINGER_1_2.stl
new file mode 100644
index 0000000..db85507
Binary files /dev/null and b/public/cad/zbot/meshes/FINGER_1_2.stl differ
diff --git a/public/cad/zbot/meshes/FOOT.stl b/public/cad/zbot/meshes/FOOT.stl
new file mode 100644
index 0000000..64b3983
Binary files /dev/null and b/public/cad/zbot/meshes/FOOT.stl differ
diff --git a/public/cad/zbot/meshes/FOOT_2.stl b/public/cad/zbot/meshes/FOOT_2.stl
new file mode 100644
index 0000000..8603566
Binary files /dev/null and b/public/cad/zbot/meshes/FOOT_2.stl differ
diff --git a/public/cad/zbot/meshes/L-ARM-MIRROR_1.stl b/public/cad/zbot/meshes/L-ARM-MIRROR_1.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/R-ARM-MIRROR-1.stl b/public/cad/zbot/meshes/R-ARM-MIRROR-1.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/meshes/U-HIP-L.stl b/public/cad/zbot/meshes/U-HIP-L.stl
new file mode 100644
index 0000000..ef0beac
Binary files /dev/null and b/public/cad/zbot/meshes/U-HIP-L.stl differ
diff --git a/public/cad/zbot/meshes/U-HIP-R.stl b/public/cad/zbot/meshes/U-HIP-R.stl
new file mode 100644
index 0000000..87f45b1
Binary files /dev/null and b/public/cad/zbot/meshes/U-HIP-R.stl differ
diff --git a/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2.stl b/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2.stl
new file mode 100644
index 0000000..bf3fc57
Binary files /dev/null and b/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2.stl differ
diff --git a/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl b/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl
new file mode 100644
index 0000000..f6e73e6
Binary files /dev/null and b/public/cad/zbot/meshes/Z-BOT2-MASTER-SHOULDER2_2.stl differ
diff --git a/public/cad/zbot/meshes/Z-BOT2_MASTER-BODY-SKELETON.stl b/public/cad/zbot/meshes/Z-BOT2_MASTER-BODY-SKELETON.stl
new file mode 100644
index 0000000..e69de29
diff --git a/public/cad/zbot/z-bot2_fe_urdf.mjcf b/public/cad/zbot/z-bot2_fe_urdf.mjcf
new file mode 100644
index 0000000..126af9c
--- /dev/null
+++ b/public/cad/zbot/z-bot2_fe_urdf.mjcf
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/cad/zbot/z-bot2_fe_urdf.urdf b/public/cad/zbot/z-bot2_fe_urdf.urdf
new file mode 100644
index 0000000..8a97726
--- /dev/null
+++ b/public/cad/zbot/z-bot2_fe_urdf.urdf
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/cad/zbotmeshes/3215_1Flange.stl b/public/cad/zbotmeshes/3215_1Flange.stl
new file mode 100644
index 0000000..ca8d695
Binary files /dev/null and b/public/cad/zbotmeshes/3215_1Flange.stl differ
diff --git a/public/cad/zbotmeshes/3215_1Flange_2.stl b/public/cad/zbotmeshes/3215_1Flange_2.stl
new file mode 100644
index 0000000..461e553
Binary files /dev/null and b/public/cad/zbotmeshes/3215_1Flange_2.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange.stl b/public/cad/zbotmeshes/3215_BothFlange.stl
new file mode 100644
index 0000000..9d55058
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange_2.stl b/public/cad/zbotmeshes/3215_BothFlange_2.stl
new file mode 100644
index 0000000..849abec
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange_2.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange_3.stl b/public/cad/zbotmeshes/3215_BothFlange_3.stl
new file mode 100644
index 0000000..4eed15d
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange_3.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange_4.stl b/public/cad/zbotmeshes/3215_BothFlange_4.stl
new file mode 100644
index 0000000..33adf2b
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange_4.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange_5.stl b/public/cad/zbotmeshes/3215_BothFlange_5.stl
new file mode 100644
index 0000000..8b4dcca
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange_5.stl differ
diff --git a/public/cad/zbotmeshes/3215_BothFlange_6.stl b/public/cad/zbotmeshes/3215_BothFlange_6.stl
new file mode 100644
index 0000000..5169612
Binary files /dev/null and b/public/cad/zbotmeshes/3215_BothFlange_6.stl differ
diff --git a/public/cad/zbotmeshes/FINGER_1.stl b/public/cad/zbotmeshes/FINGER_1.stl
new file mode 100644
index 0000000..4343fed
Binary files /dev/null and b/public/cad/zbotmeshes/FINGER_1.stl differ
diff --git a/public/cad/zbotmeshes/FINGER_1_2.stl b/public/cad/zbotmeshes/FINGER_1_2.stl
new file mode 100644
index 0000000..db85507
Binary files /dev/null and b/public/cad/zbotmeshes/FINGER_1_2.stl differ
diff --git a/public/cad/zbotmeshes/FOOT.stl b/public/cad/zbotmeshes/FOOT.stl
new file mode 100644
index 0000000..64b3983
Binary files /dev/null and b/public/cad/zbotmeshes/FOOT.stl differ
diff --git a/public/cad/zbotmeshes/FOOT_2.stl b/public/cad/zbotmeshes/FOOT_2.stl
new file mode 100644
index 0000000..8603566
Binary files /dev/null and b/public/cad/zbotmeshes/FOOT_2.stl differ
diff --git a/public/cad/zbotmeshes/L-ARM-MIRROR_1.stl b/public/cad/zbotmeshes/L-ARM-MIRROR_1.stl
new file mode 100644
index 0000000..0d3f432
Binary files /dev/null and b/public/cad/zbotmeshes/L-ARM-MIRROR_1.stl differ
diff --git a/public/cad/zbotmeshes/R-ARM-MIRROR-1.stl b/public/cad/zbotmeshes/R-ARM-MIRROR-1.stl
new file mode 100644
index 0000000..fb31089
Binary files /dev/null and b/public/cad/zbotmeshes/R-ARM-MIRROR-1.stl differ
diff --git a/public/cad/zbotmeshes/U-HIP-L.stl b/public/cad/zbotmeshes/U-HIP-L.stl
new file mode 100644
index 0000000..ef0beac
Binary files /dev/null and b/public/cad/zbotmeshes/U-HIP-L.stl differ
diff --git a/public/cad/zbotmeshes/U-HIP-R.stl b/public/cad/zbotmeshes/U-HIP-R.stl
new file mode 100644
index 0000000..87f45b1
Binary files /dev/null and b/public/cad/zbotmeshes/U-HIP-R.stl differ
diff --git a/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2.stl b/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2.stl
new file mode 100644
index 0000000..bf3fc57
Binary files /dev/null and b/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2.stl differ
diff --git a/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2_2.stl b/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2_2.stl
new file mode 100644
index 0000000..f6e73e6
Binary files /dev/null and b/public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2_2.stl differ
diff --git a/public/cad/zbotmeshes/Z-BOT2_MASTER-BODY-SKELETON.stl b/public/cad/zbotmeshes/Z-BOT2_MASTER-BODY-SKELETON.stl
new file mode 100644
index 0000000..c82ff53
Binary files /dev/null and b/public/cad/zbotmeshes/Z-BOT2_MASTER-BODY-SKELETON.stl differ
diff --git a/src/components/navbar/burgerMenu.tsx b/src/components/navbar/burgerMenu.tsx
deleted file mode 100644
index ea1a337..0000000
--- a/src/components/navbar/burgerMenu.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { ExpressiveArrow } from "@/components/iconography/Iconography";
-import { navigationConfig, transitionEaseLinearDuration300 } from "@/components/util/constants";
-import { motion } from "motion/react";
-import Link from "next/link";
-
-const BurgerMenu = (isOpen: boolean) => {
- return isOpen ? (
-
- {navigationConfig.map((navItem, index) => {
- return (
-
-
- {navItem.name}
-
- {navItem.isExternal ? : <>>}
-
- );
- })}
-
- ) : (
- <>>
- );
-};
-
-export default BurgerMenu;
diff --git a/src/components/navbar/burgerOpenButton.tsx b/src/components/navbar/burgerOpenButton.tsx
deleted file mode 100644
index df763f1..0000000
--- a/src/components/navbar/burgerOpenButton.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { BurgerOpenButtonProps } from "@/components/util/interfaces";
-import clsx from "clsx";
-import { motion } from "motion/react";
-
-const BurgerOpenButton = ({ atTop = true, ...props }: BurgerOpenButtonProps) => {
- return (
- {
- props.onClick(!props.isOpen);
- }}
- >
-
-
-
-
-
-
- );
-};
-
-export default BurgerOpenButton;
diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx
deleted file mode 100644
index 303177f..0000000
--- a/src/components/navbar/navbar.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import Logotype from "@/components/logos/logotype";
-import BurgerMenu from "@/components/navbar/burgerMenu";
-import BurgerOpenButton from "@/components/navbar/burgerOpenButton";
-import { navigationConfig } from "@/components/util/constants";
-import { useWindowSize } from "@/components/util/functions";
-import clsx from "clsx";
-import { useLenis } from "lenis/dist/lenis-react";
-import { AnimatePresence, motion, useMotionValueEvent, useScroll } from "motion/react";
-import { useEffect, useState } from "react";
-
-export default function NavBar({ href = "/" }: { href?: string } = {}) {
- const { scrollY } = useScroll();
- const lenis = useLenis();
- const [, setDesktopNavHidden] = useState(false);
- const [desktopPreviousScroll, setPrevScroll] = useState(scrollY.get());
- const [mobileShouldOpenBurger, setMobileShouldOpenBurger] = useState(false);
-
- function update(current: number, previous: number): void {
- if (current < previous) {
- setDesktopNavHidden(false);
- } else if (current > 100 && current > previous) {
- setDesktopNavHidden(true);
- }
- }
-
- useMotionValueEvent(scrollY, "change", (current: number) => {
- update(current, desktopPreviousScroll);
- setPrevScroll(current);
- });
- const width = useWindowSize().width;
-
- const navBasedOnWidth = (isDesktop: boolean) => {
- return isDesktop ? desktopNavBar() : mobileNavBar();
- };
-
- const atTop = scrollY.get() < 100;
-
- const mobileNavBar = () => {
- return (
- <>
-
-
-
-
- {BurgerMenu(mobileShouldOpenBurger)}
- >
- );
- };
-
- const desktopNavBar = () => {
- return (
- <>
-
-
- {navigationConfig.map((navItem, index) => {
- return (
-
- {navItem.name}
- {navItem.isExternal && (
-
-
-
-
- )}
-
- );
- })}
-
- >
- );
- };
- useEffect(() => {
- setMobileShouldOpenBurger(false);
- lenis?.start();
- }, [width, lenis]);
-
- useEffect(() => {
- if (lenis) {
- if (mobileShouldOpenBurger) {
- lenis.stop();
- } else {
- lenis.start();
- }
- }
- }, [mobileShouldOpenBurger, lenis]);
-
- return (
- = 768
- ? atTop
- ? "var(--background-0)"
- : "var(--background)"
- : mobileShouldOpenBurger
- ? "var(--background)"
- : "var(--background-0)",
- }}
- >
- {navBasedOnWidth(width >= 768)}
-
- );
-}
diff --git a/src/components/robot/RobotWrapper.tsx b/src/components/robot/RobotWrapper.tsx
index 989b6f8..a7423bd 100644
--- a/src/components/robot/RobotWrapper.tsx
+++ b/src/components/robot/RobotWrapper.tsx
@@ -6,7 +6,13 @@ import dynamic from "next/dynamic";
// Dynamically import the RobotRenderer component
const RobotRenderer = dynamic(() => import("./robotRenderer"), { ssr: false });
-const RobotRendererWrapper: React.FC = () => {
+interface RobotWrapperProps {
+ urdfPath: string;
+ scale?: number;
+ translateY?: number;
+}
+
+const RobotRendererWrapper: React.FC = ({ urdfPath, scale, translateY }) => {
const [isVisible, setIsVisible] = useState(false);
const mountRef = useRef(null);
@@ -30,7 +36,7 @@ const RobotRendererWrapper: React.FC = () => {
return (
- {isVisible && }
+ {isVisible && }
);
};
diff --git a/src/components/robot/robotRenderer.tsx b/src/components/robot/robotRenderer.tsx
index 3b1f173..72519bd 100644
--- a/src/components/robot/robotRenderer.tsx
+++ b/src/components/robot/robotRenderer.tsx
@@ -12,9 +12,12 @@ import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js";
import { LuminosityShader } from "three/examples/jsm/shaders/LuminosityShader.js";
import { SobelOperatorShader } from "three/examples/jsm/shaders/SobelOperatorShader.js";
-const URDF_URL = "/cad/gpr-20241204.urdf";
-const SCALE = 3;
-const TRANSLATE_Y = 1.2;
+export interface RobotRendererProps {
+ urdfPath: string;
+ scale?: number;
+ translateY?: number;
+ waypoints?: { [key: string]: { start: number; end: number } };
+}
interface Waypoint {
start: number;
@@ -48,16 +51,46 @@ const WAYPOINTS: { [key: string]: Waypoint } = {
const DURATION_S = 5;
-const RobotRenderer: React.FC = () => {
+const Z_BOT_WAYPOINTS: { [key: string]: Waypoint } = {
+ right_shoulder_yaw: { start: -0.5, end: 0.5 },
+ left_shoulder_pitch: { start: -0.5, end: 0.5 },
+ right_shoulder_pitch: { start: -0.5, end: 0.5 },
+ left_hip_yaw: { start: -0.3, end: 0.3 },
+ right_hip_yaw: { start: 0, end: 0 },
+ left_hip_roll: { start: 0, end: 0 },
+ right_hip_roll: { start: -0.3, end: 0 },
+ left_hip_pitch: { start: -0.3, end: 0.3 },
+ right_hip_pitch: { start: -0.3, end: 0.3 },
+ left_knee: { start: 0, end: 0.3 },
+ right_knee: { start: 0, end: 0.3 },
+ left_ankle: { start: -0.2, end: 0.2 },
+ right_ankle: { start: -0.2, end: 0.2 },
+};
+
+const RobotRenderer: React.FC = ({
+ urdfPath,
+ scale = 2.5,
+ translateY = 1.0,
+ waypoints = WAYPOINTS,
+}) => {
const mountRef = useRef(null);
let effectSobel: ShaderPass;
+ let composer: EffectComposer | null = null;
+
useEffect(() => {
+ console.log("Attempting to load URDF from:", urdfPath);
+
+ if (!urdfPath) {
+ console.error("URDF path is required");
+ return;
+ }
+
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
- 13,
+ 20,
window.innerWidth / window.innerHeight,
- 0.1,
- 1000
+ 0.01,
+ 2000
);
const renderer = new THREE.WebGLRenderer({
antialias: true,
@@ -66,124 +99,139 @@ const RobotRenderer: React.FC = () => {
});
const currentMount = mountRef.current;
- if (currentMount) {
- const { clientWidth, clientHeight } = currentMount;
- camera.aspect = clientWidth / clientHeight;
- camera.updateProjectionMatrix();
- renderer.setSize(clientWidth, clientHeight);
+ if (!currentMount) {
+ console.error("Mount ref is not available");
+ return;
}
+
+ const { clientWidth, clientHeight } = currentMount;
+ camera.aspect = clientWidth / clientHeight;
+ camera.updateProjectionMatrix();
+ renderer.setSize(clientWidth, clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000, 0);
-
- if (currentMount) {
- currentMount.appendChild(renderer.domElement);
- }
+ currentMount.appendChild(renderer.domElement);
const loader = new URDFLoader();
- loader.load(URDF_URL, (robot: THREE.Object3D) => {
- const updateMaterials = () => {
- robot.traverse((child) => {
- if (child instanceof THREE.Mesh) {
- const originalColor =
- child.material instanceof THREE.Material
- ? (child.material as THREE.MeshPhysicalMaterial).color
- : new THREE.Color(0x808080);
- child.material = new THREE.MeshPhysicalMaterial({
- metalness: 0.4,
- roughness: 0.5,
- color: originalColor,
- });
- }
- });
- };
-
- scene.add(robot);
- updateMaterials();
-
- // Correcting for the robot initial size and position.
- robot.rotateY(Math.PI / 2);
- robot.translateY(TRANSLATE_Y);
- robot.scale.set(SCALE, SCALE, SCALE);
-
- const controls = new OrbitControls(camera, renderer.domElement);
- controls.enableDamping = true;
- controls.dampingFactor = 0.25;
- controls.screenSpacePanning = false;
- controls.maxPolarAngle = Math.PI / 2;
- controls.enableZoom = false;
- controls.enablePan = false;
-
- const startTime = Date.now();
-
- const animate = () => {
- requestAnimationFrame(animate);
- controls.update();
-
- // Update joint positions with a sinusoidal pattern
- const time = (Date.now() - startTime) / 1000;
- robot.traverse((child) => {
- const joint = child as URDFJoint;
- if (joint.isURDFJoint) {
- if (WAYPOINTS[joint.name]) {
- const { start, end } = WAYPOINTS[joint.name];
+ try {
+ console.log("Starting URDF load...");
+ loader.load(urdfPath, (robot: THREE.Object3D) => {
+ console.log("URDF loaded successfully");
+ const updateMaterials = () => {
+ robot.traverse((child) => {
+ if (child instanceof THREE.Mesh) {
+ const originalColor =
+ child.material instanceof THREE.Material
+ ? (child.material as THREE.MeshPhysicalMaterial).color
+ : new THREE.Color(0x808080);
+ child.material = new THREE.MeshPhysicalMaterial({
+ metalness: 0.4,
+ roughness: 0.5,
+ color: originalColor,
+ });
+ }
+ });
+ };
+
+ scene.add(robot);
+ updateMaterials();
+
+ // Correcting for the robot initial size and position.
+ const isZBot = urdfPath.includes("z-bot");
+ if (isZBot) {
+ robot.rotateX(-Math.PI / 2);
+ robot.rotateZ(Math.PI / 4);
+ } else {
+ robot.rotateY(Math.PI / 2);
+ }
+ robot.translateY(translateY);
+ robot.scale.set(scale, scale, scale);
+
+ const controls = new OrbitControls(camera, renderer.domElement);
+ controls.enableDamping = true;
+ controls.dampingFactor = 0.25;
+ controls.screenSpacePanning = false;
+ controls.maxPolarAngle = Math.PI / 2;
+ controls.enableZoom = false;
+ controls.enablePan = false;
+
+ // Set camera position and controls
+ if (isZBot) {
+ camera.position.z = 0;
+ camera.position.y = 0;
+ camera.position.x = 80;
+ controls.target.set(0, -8, 0);
+ } else {
+ camera.position.z = 16;
+ camera.position.y = 9;
+ camera.position.x = 9;
+ }
+
+ const mainLight = new THREE.DirectionalLight(0xffffff, 2);
+ mainLight.position.set(100, 0, -20);
+ camera.add(mainLight);
+
+ const fill1Light = new THREE.DirectionalLight(0xffffff, 2);
+ fill1Light.position.set(-100, 0, -200);
+ camera.add(fill1Light);
+
+ const fill2Light = new THREE.DirectionalLight(0xffffff, 0.2);
+ fill2Light.position.set(0, 0, 20);
+ camera.add(fill2Light);
+
+ scene.add(camera);
+
+ composer = new EffectComposer(renderer);
+ const renderPass = new RenderPass(scene, camera);
+ composer!.addPass(renderPass);
+
+ const shaderPass = new ShaderPass(LuminosityShader);
+ composer!.addPass(shaderPass);
+
+ // color to grayscale conversion
+ const effectGrayScale = new ShaderPass(LuminosityShader);
+ composer!.addPass(effectGrayScale);
+
+ // Sobel operator
+ effectSobel = new ShaderPass(SobelOperatorShader);
+ effectSobel.uniforms["resolution"].value.x = window.innerWidth * window.devicePixelRatio;
+ effectSobel.uniforms["resolution"].value.y = window.innerHeight * window.devicePixelRatio;
+ composer!.addPass(effectSobel);
+
+ const outputPass = new OutputPass();
+ composer!.addPass(outputPass);
+
+ const startTime = Date.now();
+ const activeWaypoints = isZBot ? Z_BOT_WAYPOINTS : WAYPOINTS;
+
+ const animate = () => {
+ requestAnimationFrame(animate);
+ controls.update();
+
+ // Update joint positions with a sinusoidal pattern
+ const time = (Date.now() - startTime) / 1000;
+ robot.traverse((child) => {
+ const joint = child as URDFJoint;
+ if (joint.isURDFJoint && activeWaypoints[joint.name]) {
+ const { start, end } = activeWaypoints[joint.name];
const value =
start + (end - start) * ((Math.sin((time * Math.PI) / DURATION_S) + 1) / 2);
joint.setJointValue(value);
}
- }
- });
-
- composer.render();
- };
-
- animate();
- });
+ });
- const mainLight = new THREE.DirectionalLight(0xffffff, 2);
- mainLight.position.set(100, 0, -20);
- camera.add(mainLight);
+ composer!.render();
+ };
- const fill1Light = new THREE.DirectionalLight(0xffffff, 2);
- fill1Light.position.set(-100, 0, -200);
- camera.add(fill1Light);
-
- const fill2Light = new THREE.DirectionalLight(0xffffff, 0.2);
- fill2Light.position.set(0, 0, 20);
- camera.add(fill2Light);
-
- scene.add(camera);
-
- camera.position.z = 16;
- camera.position.y = 9;
- camera.position.x = 9;
-
- const composer = new EffectComposer(renderer);
- const renderPass = new RenderPass(scene, camera);
- composer.addPass(renderPass);
-
- const shaderPass = new ShaderPass(LuminosityShader);
- composer.addPass(shaderPass);
-
- // color to grayscale conversion
-
- const effectGrayScale = new ShaderPass(LuminosityShader);
- composer.addPass(effectGrayScale);
-
- // you might want to use a gaussian blur filter before
- // the next pass to improve the result of the Sobel operator
-
- // Sobel operator
-
- effectSobel = new ShaderPass(SobelOperatorShader);
- effectSobel.uniforms["resolution"].value.x = window.innerWidth * window.devicePixelRatio;
- effectSobel.uniforms["resolution"].value.y = window.innerHeight * window.devicePixelRatio;
- composer.addPass(effectSobel);
-
- const outputPass = new OutputPass();
- composer.addPass(outputPass);
+ animate();
+ });
+ } catch (error) {
+ console.error("Error loading URDF:", error);
+ return;
+ }
const handleResize = () => {
- if (currentMount) {
+ if (currentMount && composer) {
const { clientWidth, clientHeight } = currentMount;
camera.aspect = clientWidth / clientHeight;
camera.updateProjectionMatrix();
@@ -203,7 +251,7 @@ const RobotRenderer: React.FC = () => {
}
window.removeEventListener("resize", handleResize);
};
- }, []);
+ }, [urdfPath, scale, translateY, waypoints]);
return
;
};
diff --git a/src/landing/CommunitySection.tsx b/src/landing/CommunitySection.tsx
deleted file mode 100644
index b45cb2b..0000000
--- a/src/landing/CommunitySection.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-import { CTAButton, InlineCTA } from "@/components/buttons/CTAButtons";
-import { Discord } from "@/components/footer/socialMediaSvgs";
-import { ExpressiveArrow } from "@/components/iconography/Iconography";
-import {
- ColorVariant,
- FillMode,
- IconMode,
- Size,
- TeamCol1,
- TeamCol2,
-} from "@/components/util/constants";
-import { photoPathAltText, photoPaths } from "@/components/util/photoPaths";
-import Image from "next/image";
-
-const TeamColumn = ({ members, styling }: { members: string[]; styling: string }) => (
-
- {members.map((member, index) => (
-
- {member}
-
- ))}
-
-);
-const CommunitySection = () => {
- return (
-
-
- Community
- Take ownership of how we keep building.
-
- Get rapid-fire support during your development process through our Discord—home to
- 2000+ active members who have collaborated on 6 humanoid robots and counting.
-
-
-
- We are actively publishing papers and collectively exploring the frontier of embodied
- intelligence.
-
-
-
-
- Join the Discord
-
-
- Send feedback
-
-
-
-
-
-
- About us
-
- We're hackers, engineers, and researchers that believe in a world where robots are
- made for everyone.
-
-
- We're from Tesla AI, Google, Meta FAIR, Tencent, and Xiaomi building opportunities
- for robots to be more than workers.
-
-
-
-
-
- );
-};
-
-export default CommunitySection;
diff --git a/src/landing/DataSection.tsx b/src/landing/DataSection.tsx
deleted file mode 100644
index d105836..0000000
--- a/src/landing/DataSection.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { InlineCTA } from "@/components/buttons/CTAButtons";
-import { ExpressiveArrow } from "@/components/iconography/Iconography";
-
-const DataSection = () => {
- return (
-
-
-
-
- Data buy-back
-
- Get refunded each month that you send us data.
-
- If you collect at least 100 hours of telemetry over the course of a month we'll pay
- you back the month's payment.
-
-
-
- See privacy policy
-
-
-
- );
-};
-
-export default DataSection;
diff --git a/src/landing/GallerySection.tsx b/src/landing/GallerySection.tsx
deleted file mode 100644
index e8b78fd..0000000
--- a/src/landing/GallerySection.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { motion, useTransform, useScroll, MotionValue } from "motion/react";
-import { useContext } from "react";
-import { createContext } from "react";
-import { useRef } from "react";
-import Image from "next/image";
-import { photoPathAltText, photoPaths } from "@/components/util/photoPaths";
-
-const Images = [
- {
- src: photoPaths.GALLERY_1,
- alt: photoPathAltText.GALLERY_1_ALT,
- },
- {
- src: photoPaths.GALLERY_2,
- alt: photoPathAltText.GALLERY_2_ALT,
- },
- {
- src: photoPaths.GALLERY_3,
- alt: photoPathAltText.GALLERY_3_ALT,
- },
- {
- src: photoPaths.GALLERY_4,
- alt: photoPathAltText.GALLERY_4_ALT,
- },
- {
- src: photoPaths.GALLERY_5,
- alt: photoPathAltText.GALLERY_5_ALT,
- },
- {
- src: photoPaths.GALLERY_6,
- alt: photoPathAltText.GALLERY_6_ALT,
- },
-];
-
-const GalleryItem = ({ src, alt, index }: { src: string; alt: string; index: number }) => {
- const scrollYProgress = useContext(ScrollContext);
- return (
-
-
-
- );
-};
-
-const ScrollContext = createContext(new MotionValue());
-
-const GallerySection = () => {
- const scrollRef = useRef(null);
- const { scrollYProgress } = useScroll({
- target: scrollRef,
- offset: ["start start", "end start"],
- });
-
- return (
-
-
- {Images.map((image, index) => (
-
- ))}
-
-
- );
-};
-
-export default GallerySection;
diff --git a/src/landing/PricingSection.tsx b/src/landing/PricingSection.tsx
deleted file mode 100644
index bbfd3aa..0000000
--- a/src/landing/PricingSection.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { CTASubtitleButton } from "@/components/buttons/CTAButtons";
-import { FillMode } from "@/components/util/constants";
-
-const PricingSection = () => {
- return (
-
-
-
-
- Limited edition — 20 units total
-
-
- Get free yearly hardware upgrades as a founder
-
-
-
- Priority delivery and yearly service on new parts and hardware, for the rest of your life.
-
-
- Order K-Bot FE
-
-
-
-
-
- Available for all engineers
-
- Our plug and play robotics solution, at an accessible price.
-
-
-
- {`Invest in yourself and your engineering potential with K-Bot's embodied AI ecosystem.`}
-
-
- Order K-Bot
-
-
-
- );
-};
-
-export default PricingSection;
diff --git a/src/landing/ResearchSection.tsx b/src/landing/ResearchSection.tsx
deleted file mode 100644
index 9232e47..0000000
--- a/src/landing/ResearchSection.tsx
+++ /dev/null
@@ -1,301 +0,0 @@
-import { CTAButton } from "@/components/buttons/CTAButtons";
-import { Github } from "@/components/footer/socialMediaSvgs";
-import {
- EVLAIcon,
- KOSIcon,
- KRECIcon,
- KSIMIcon,
- KLANGIcon,
-} from "@/components/iconography/ResearchIcons";
-import { useWindowSize } from "@/components/util/functions";
-import { motion, useMotionValue } from "motion/react";
-import { useState, useEffect, useMemo } from "react";
-import clsx from "clsx";
-import { IconMode } from "@/components/util/constants";
-import { ColorVariant, FillMode, Size } from "@/components/util/constants";
-
-const RESEARCH_ITEMS = [
- {
- title: "Edge VLA",
- description:
- "We’re collaboratively training a foundation for general purpose robots, that gets faster with more contributions from the open-source community",
- image: "/images/research/edge-vla.png",
- link: "https://github.com/kscalelabs/evla",
- icon: ,
- variant: ColorVariant.METHYL,
- },
- {
- title: "K-OS",
- description: "Work with reliable real-time ML inference using our Rust-based operating system.",
- image: "/images/research/edge-vla.png",
- link: "https://github.com/kscalelabs/kos",
- icon: ,
- variant: ColorVariant.PLASMA,
- },
- {
- title: "Klang",
- description:
- "Skip writing ROS nodes with our domain-specific language for interfacing with neural interpretation.",
- image: "/images/research/edge-vla.png",
- link: "https://github.com/kscalelabs/klang",
- icon: ,
- variant: ColorVariant.OXIDE,
- },
- {
- title: "kRec",
- description:
- "Our compact serialization format for robotics telemetry, with efficient decoding to avoid bottlenecks in training neutral networks.",
- image: "/images/research/edge-vla.png",
- link: "https://github.com/kscalelabs/krec",
- icon: ,
- variant: ColorVariant.RUST,
- },
- {
- title: "kSim",
- description:
- "Define any RL objectives for your robot with our open-source repository for policy simulation.",
- image: "/images/research/edge-vla.png",
- link: "https://github.com/kscalelabs/ksim",
- icon: ,
- variant: ColorVariant.MOLTEN,
- },
-];
-
-interface ResearchItem {
- title: string;
- description: string;
- image: string;
- link: string;
- index: number;
- icon: React.ReactNode;
- variant: ColorVariant;
-}
-
-const ResearchCard = ({ title, description, link, index, icon, variant }: ResearchItem) => {
- const bg = (variant: ColorVariant): string => {
- switch (variant) {
- case ColorVariant.METHYL:
- return "bg-methyl ";
- case ColorVariant.PLASMA:
- return "bg-plasma ";
- case ColorVariant.OXIDE:
- return "bg-oxide ";
- case ColorVariant.RUST:
- return "bg-rust ";
- case ColorVariant.MOLTEN:
- return "bg-molten ";
- case ColorVariant.SOL:
- return "bg-sol ";
- case ColorVariant.FILAMENT:
- return "bg-filament ";
- case ColorVariant.CARBON:
- return "bg-carbon ";
- default:
- return "bg-foreground ";
- }
- };
- return (
-
-
- {icon}
-
-
{title}
-
{description}
-
- View on Github
-
-
-
-
- );
-};
-
-const DRAG_BUFFER = 50;
-
-const SPRING_OPTIONS = {
- type: "spring",
- mass: 1,
- stiffness: 100,
- damping: 20,
-};
-
-export const SwipeCarousel = () => {
- const [imgIndex, setImgIndex] = useState(0);
- const width = useWindowSize().width;
-
- const dimensions = useMemo(() => {
- if (width < 480) {
- return {
- card: 80,
- gap: 5,
- max: RESEARCH_ITEMS.length - 1,
- offset: 0,
- };
- }
- if (width < 640) {
- return {
- card: 70,
- gap: 5,
- max: RESEARCH_ITEMS.length - 1,
- };
- }
- if (width < 768) {
- return {
- card: 60,
- gap: 2.5,
- max: RESEARCH_ITEMS.length - 1,
- };
- }
- if (width < 1440) {
- return {
- card: 40,
- gap: 2.5,
- max: RESEARCH_ITEMS.length - 2,
- };
- }
- if (width < 1920) {
- return {
- card: 30,
- gap: 1.25,
- max: RESEARCH_ITEMS.length - 3,
- };
- }
- return {
- card: 21.25,
- gap: 1.25,
- max: RESEARCH_ITEMS.length - 4,
- };
- }, [width]);
-
- const dragX = useMotionValue(0);
-
- const onDragEnd = () => {
- const x = dragX.get();
- if (x <= -(width < 768 ? dimensions.card / 2 : DRAG_BUFFER) && imgIndex < dimensions.max) {
- setImgIndex((pv) => Math.min(pv + Math.round(x / -DRAG_BUFFER), dimensions.max));
- } else if (x >= (width < 768 ? dimensions.card / 2 : DRAG_BUFFER) && imgIndex > 0) {
- setImgIndex((pv) => Math.max(pv - Math.round(x / DRAG_BUFFER), 0));
- }
- };
-
- const decrement = () => {
- if (imgIndex > 0) {
- setImgIndex((pv) => pv - 1);
- }
- };
-
- const increment = () => {
- if (imgIndex < dimensions.max) {
- setImgIndex((pv) => pv + 1);
- }
- };
-
- useEffect(() => {
- setImgIndex(0);
- }, [width]);
-
- return (
-
-
- 0 ? 1 : 0.5 }}
- transition={{ duration: 0.2 }}
- >
- ←
-
-
- →
-
-
-
- {/*
- {imgIndex} {dimensions.card} {dimensions.gap}
-
*/}
-
0 ? dimensions.gap : 0)}vw`,
- }}
- transition={SPRING_OPTIONS}
- onDragEnd={onDragEnd}
- className="flex flex-none cursor-grab gap-x-[5vw] sm:gap-x-[2.5vw] 2xl:gap-x-[1.25vw]"
- >
-
-
-
-
- );
-};
-
-const Images = () => {
- return (
- <>
- {RESEARCH_ITEMS.map((item, i) => (
-
- ))}
- >
- );
-};
-
-// const Dots = ({ imgIndex, setImgIndex }) => {
-// return (
-//
-// {imgs.map((_, idx) => {
-// return (
-// setImgIndex(idx)}
-// className={`h-3 w-3 rounded-full transition-colors ${
-// idx === imgIndex ? "bg-neutral-50" : "bg-neutral-500"
-// }`}
-// />
-// );
-// })}
-//
-// );
-// };
-
-const ResearchSection = () => {
- return (
-
-
- Research
- The humanoid robot is as strong as its brain.
-
-
- {/* */}
-
-
- );
-};
-
-export default ResearchSection;
diff --git a/src/landing/RobotSection.tsx b/src/landing/RobotSection.tsx
deleted file mode 100644
index 826edaf..0000000
--- a/src/landing/RobotSection.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import RobotWrapper from "@/components/robot/RobotWrapper";
-import { useWindowSize } from "@/components/util/functions";
-import { motion, useInView } from "motion/react";
-import { useRef } from "react";
-
-const RobotSection = () => {
- const ref = useRef(null);
- const isInView = useInView(ref, { once: true });
- const width = useWindowSize().width;
-
- return (
-
- = 768 ? "text-filament" : " text-foreground")
- }
- >
-
- The best humanoid robot platform for the K-Scale software ecosystem
-
-
- Bringing high-performance, real-time teleoperation and machine learning into every robot
-
-
-
-
-
-
-
-
- Drag to orbit
-
-
-
-
-
- );
-};
-
-export default RobotSection;
diff --git a/src/landing/SpecSection.tsx b/src/landing/SpecSection.tsx
deleted file mode 100644
index 940fa97..0000000
--- a/src/landing/SpecSection.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { InlineCTA } from "@/components/buttons/CTAButtons";
-import { ExpressiveArrow } from "@/components/iconography/Iconography";
-import { photoPathAltText, photoPaths } from "@/components/util/photoPaths";
-import { motion } from "motion/react";
-import Image from "next/image";
-
-const SpecSection = () => {
- return (
-
-
-
-
- What is K-Bot?
-
- A general-purpose humanoid robot optimized for the K-Scale software stack.
-
-
-
- Read tech specs
-
-
-
-
-
- We built K-Bot with an aerospace-grade aluminium body, anodized in a protective matte
- black finish.
-
-
-
-
-
-
-
- Equipped with high-torque quasi-direct drive electric actuators running high-frequency
- closed-loop control.
-
-
-
-
-
-
-
- Dependable, blazing-fast end-to-end neural network inference with our custom
- high-performance operating system.
-
-
-
-
-
-
- );
-};
-
-export default SpecSection;
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 313e9fd..243fa45 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,17 +1,16 @@
import Footer from "@/components/footer/footer";
import NavBar from "@/components/navbar/navbar";
-import CommunitySection from "@/landing/CommunitySection";
-import GallerySection from "@/landing/GallerySection";
-import HeaderSection from "@/landing/HeaderSection";
-import ResearchSection from "@/landing/ResearchSection";
-import RobotSection from "@/landing/RobotSection";
-import SpecSection from "@/landing/SpecSection";
-import Sponsors from "@/landing/Sponsors";
-import WhatCanItDoSection from "@/landing/WhatCanItDoSection";
+import Script from "next/script";
+import CommunitySection from "@/zbot/CommunitySection";
+import GallerySection from "@/zbot/GallerySection";
+import HeaderSection from "@/zbot/HeaderSection";
+import ResearchSection from "@/zbot/ResearchSection";
+import SpecSection from "@/zbot/SpecSection";
+import RobotSection from "@/zbot/RobotSection";
import { useLenis } from "lenis/dist/lenis-react";
import { useEffect } from "react";
-export default function Home() {
+export default function ZBot() {
const lenis = useLenis();
useEffect(() => {
@@ -35,16 +34,28 @@ export default function Home() {
return (
-
+