Skip to content

Commit

Permalink
Add z-bot urdf
Browse files Browse the repository at this point in the history
  • Loading branch information
verdakode committed Jan 23, 2025
1 parent 5c71bf7 commit c5bf4fa
Show file tree
Hide file tree
Showing 48 changed files with 1,776 additions and 118 deletions.
242 changes: 242 additions & 0 deletions public/cad/z-bot2_fe_urdf.mjcf

Large diffs are not rendered by default.

559 changes: 559 additions & 0 deletions public/cad/z-bot2_fe_urdf.urdf

Large diffs are not rendered by default.

Binary file added public/cad/zbot.tgz
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_1Flange.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_1Flange_2.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange_2.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange_3.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange_4.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange_5.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/3215_BothFlange_6.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/FINGER_1.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/FINGER_1_2.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/FOOT.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/FOOT_2.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/L-ARM-MIRROR_1.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/R-ARM-MIRROR-1.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/U-HIP-L.stl
Binary file not shown.
Binary file added public/cad/zbot/meshes/U-HIP-R.stl
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
242 changes: 242 additions & 0 deletions public/cad/zbot/z-bot2_fe_urdf.mjcf

Large diffs are not rendered by default.

559 changes: 559 additions & 0 deletions public/cad/zbot/z-bot2_fe_urdf.urdf

Large diffs are not rendered by default.

Binary file added public/cad/zbotmeshes/3215_1Flange.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_1Flange_2.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_BothFlange.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_BothFlange_2.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_BothFlange_3.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_BothFlange_4.stl
Binary file not shown.
Binary file added public/cad/zbotmeshes/3215_BothFlange_5.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/3215_BothFlange_6.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/FINGER_1.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/FINGER_1_2.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/FOOT.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/FOOT_2.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/L-ARM-MIRROR_1.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/R-ARM-MIRROR-1.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/U-HIP-L.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/U-HIP-R.stl
Diff not rendered.
Binary file added public/cad/zbotmeshes/Z-BOT2-MASTER-SHOULDER2.stl
Diff not rendered.
Diff not rendered.
Diff not rendered.
10 changes: 8 additions & 2 deletions src/components/robot/RobotWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<RobotWrapperProps> = ({ urdfPath, scale, translateY }) => {
const [isVisible, setIsVisible] = useState(false);
const mountRef = useRef<HTMLDivElement | null>(null);

Expand All @@ -30,7 +36,7 @@ const RobotRendererWrapper: React.FC = () => {

return (
<div ref={mountRef} className="w-full h-full overflow-hidden rounded-lg">
{isVisible && <RobotRenderer />}
{isVisible && <RobotRenderer urdfPath={urdfPath} scale={scale} translateY={translateY} />}
</div>
);
};
Expand Down
275 changes: 162 additions & 113 deletions src/components/robot/robotRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<RobotRendererProps> = ({
urdfPath,
scale = 2.5,
translateY = 1.0,
waypoints = WAYPOINTS,
}) => {
const mountRef = useRef<HTMLDivElement | null>(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,
Expand All @@ -66,124 +99,140 @@ 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.rotateY(Math.PI); // Face forwardo
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, -7, 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();
Expand All @@ -203,7 +252,7 @@ const RobotRenderer: React.FC = () => {
}
window.removeEventListener("resize", handleResize);
};
}, []);
}, [urdfPath, scale, translateY, waypoints]);

return <div ref={mountRef} className="w-full h-full overflow-hidden rounded-lg" />;
};
Expand Down
3 changes: 1 addition & 2 deletions src/landing/RobotSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const RobotSection = () => {
}}
animate={{
backgroundColor: isInView ? "var(--carbon-0)" : "var(--carbon-50)",

pointerEvents: isInView ? "none" : "auto",
}}
style={{
Expand Down Expand Up @@ -73,7 +72,7 @@ const RobotSection = () => {
<h3 className="text-filament text-body">Drag to orbit</h3>
</motion.hgroup>
</motion.aside>
<RobotWrapper />
<RobotWrapper urdfPath="/cad/gpr-20241204.urdf" scale={5.0} translateY={1.2} />
</div>
</section>
);
Expand Down
2 changes: 2 additions & 0 deletions src/pages/zbot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ 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";

Expand Down Expand Up @@ -52,6 +53,7 @@ export default function ZBot() {
<HeaderSection />
<ResearchSection />
<SpecSection />
<RobotSection />
<GallerySection />
<CommunitySection />
</main>
Expand Down
2 changes: 1 addition & 1 deletion src/zbot/RobotSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const RobotSection = () => {
<h3 className="text-filament text-body">Drag to orbit</h3>
</motion.hgroup>
</motion.aside>
<RobotWrapper />
<RobotWrapper urdfPath="/cad/z-bot2_fe_urdf.urdf" scale={40} translateY={0.5} />
</div>
</section>
);
Expand Down

0 comments on commit c5bf4fa

Please sign in to comment.