Can i load a urdf model that uses .STL files as meshes using three.js and then use DAT GUI for the controlling the robot joints ?
Yes - all loaders parse to Three.Mesh, and Three.Mesh can in turn be controlled by Dat.GUI. Youâll need to code that controlling part though.
hey, thanks for the reply !
I got your point but for the controlling part of robot can i get some resources for coding that part
Thank you
I believe you can take that models ânodesâ or âchildren meshesâ by traversing the model. Just ask chat gpt to help you understand traversing 3d objects in three js. Let me know if you cannot still figure it out, and Iâll leave the code below.
Hey thanks for the reply mate ,
I want you tp please send me the code , it will be very helpful for me , also i am making the GUI that looks like below , i want to connect the slider of a PyQt5 GUI with the three.js application made with react , How can i achieve it .
thanks
Iâll see what I can doâŚI canât work on the code till the weekend, and even then Iâm busy with my own project. HoweverâŚhere is the basic code to take a model(in my case gltf) and traverse through its nodes:
// Import Three.js library
import * as THREE from âthreeâ;
// Import GLTF loader
import { GLTFLoader } from âthree/examples/jsm/loaders/GLTFLoader.jsâ;
// Create a new Three.js scene
const scene = new THREE.Scene();
// Create a camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// Create a renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Add lights to the scene
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 1, 0);
scene.add(directionalLight);
// Load GLTF model
const loader = new GLTFLoader();
loader.load(
âpath/to/your/model.gltfâ,
function (gltf) {
// Add the loaded model to the scene
scene.add(gltf.scene);
// Traverse through the nodes of the GLTF model
gltf.scene.traverse(node => {
// Check if the node has a name
if (node.name) {
// Console log the name of the node
console.log(node.name);
}
});
},
undefined,
function (error) {
console.error(error);
}
);
// Function to update the scene
function animate() {
requestAnimationFrame(animate);
// Rotate the model
if (scene.children.length > 0) {
scene.children[0].rotation.y += 0.01;
}
renderer.render(scene, camera);
}
// Call the animate function
animate();
Hey , thank you for the help and sending me the code , I wanted to ask something out of context , that is if i have an application that is a GUI sending the slider data to the server and i have an application that is react based in which we load an URDF Model using THREE.JS and visualizing it and also loading the model in PyQt5 GUI .
so can we make two clients at the same time and one server ,the two clients will be react application and PYQT5 Application that will send slider data and i want the same data to get send to the react application too. and server will act as a communication medium . How can we do this task and also if u get time , please look into this project , will be very helpful
Thank You Again
Thatâs a good questionâŚhowever I havenât done any work with making my own database/server. I have worked with firebase(a database by google) and have used it to make multiplayer before.
I also havenât used the gui before, but I can say that what your talking about seems reasonable; the way I would do it is send the id and the info to firebase and on the client recieve it.
Also, why do you want more than one instance of this. You could make it all one thing and just use the export and imports to get and set data across the application.
Maybe I donât understand, but thatâs the best I got. Thanks! -Jackson
This urdf three.js project provides tools and examples on how to load an manipulate a URDF model as well as a drag-and-drop viewer:
How can we do this task and also if u get time , please look into this project , will be very helpful
If youâre having a specific problem you should post code showing the problem youâre having so people can help. But simply asking people to do work for you is generally frowned upon when asking questions. Itâs your project, not ours.
Hey thanks for the reply
Can u please tell me what do u mean by more than one instance
Do u mean about the workflow I am following?
Thanks
Rohan
YesâŚI wasnât quite sure what you were meaning.(as far as your workflow)
Did my reply earlier help or no? I can reread this stuff too
import React, { Component } from âreactâ;
import * as THREE from âthreeâ;
import OrbitControls from âthree-orbitcontrolsâ;
import URDFLoader from âurdf-loaderâ;
//import io from âsocket.io-clientâ;
import * as dat from âdat.guiâ;
const gui = new dat.GUI();
const controls = {
BJ: 0, // Joint angles for each joint
SJ: 0,
EJ: 0,
W1J: 0,
W2J: 0,
W3J: 0
};
gui.add(controls, âBJâ, -180, 180).name(âBase Jointâ); // Adjust range as needed
gui.add(controls, âSJâ, -180, 180).name(âShoulder Jointâ);
gui.add(controls, âEJâ, -180, 180).name(âElbow Jointâ);
gui.add(controls, âW1Jâ, -180, 180).name(âW1 Jointâ);
gui.add(controls, âW2Jâ, -180, 180).name(âW2 Jointâ);
gui.add(controls, âW3Jâ, -180, 180).name(âW3 Jointâ);
class RobotScene extends Component {
constructor(props) {
super(props);
this.state = {
sliderData: {}
};
// Setting up the initial state and references
this.scene = new THREE.Scene();
this.camera = null;
this.renderer = null;
this.robotBase = null; // Reference to the robotâs base
// Connect to the Socket.IO server
//this.socket = io("http://localhost/4000"); // Adjust server address and port as needed
// Bind event listener to handle incoming slider data
//this.socket.on("sliderData", this.handleSliderData);
this.initScene();
this.addRobot();
this.addControls();
this.startAnimationLoop();
window.addEventListener('resize', this.handleWindowResize);
}
// componentDidMount() {
// // Clean up Socket.IO connection on component unmount
// // window.addEventListener("beforeunload", () => {
// // this.socket.disconnect();
// // });
// }
// handleSliderData = (data) => {
// // Update state with received slider data
// //this.setState({ sliderData: data });
// // Log received slider data
// //console.log("Received slider data:", data);
// // You can update your URDF visualization based on the received data here
// };
initScene() {
// Set up camera
this.camera = new THREE.PerspectiveCamera(
75, // fov = field of view
window.innerWidth / window.innerHeight, // aspect ratio
0.1, // near plane
1000 // far plane
);
this.camera.position.z = 5; // Move the camera back
// Set up renderer
this.renderer = new THREE.WebGLRenderer();
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement); // Append to the document body
// Set up orbit controls
new OrbitControls(this.camera, this.renderer.domElement);
// Set up lighting
const ambientLight = new THREE.AmbientLight(0x404040);
this.scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1);
this.scene.add(directionalLight);
}
addRobot() {
const loader = new URDFLoader();
loader.load("/robot_active.urdf", (robot) => {
this.robotBase = robot; // Assuming the robot base is the root of the loaded URDF model
this.scene.add(robot);
});
}
updateRobotJoints() {
if (this.robotBase) {
// Replace these names with the actual joint names from your URDF file
const BJ = this.robotBase.getObjectByName('BJ');
// const SJ = this.robotBase.getObjectByName('SJ');
// const EJ = this.robotBase.getObjectByName('EJ');
// const W1J = this.robotBase.getObjectByName('W1J');
// const W2J = this.robotBase.getObjectByName('W2J');
// const W3J = this.robotBase.getObjectByName('W3J');
if (BJ) {
const BJRotationRadians = THREE.MathUtils.degToRad(controls.BJ);
BJ.rotation.z = THREE.MathUtils.clamp(BJRotationRadians, -2.0944, 2.0944);
}
// if (SJ) SJ.rotation.y = THREE.MathUtils.degToRad(controls.SJ);
// if (EJ) EJ.rotation.y = THREE.MathUtils.degToRad(controls.EJ);
// if (W1J) W1J.rotation.y = THREE.MathUtils.degToRad(controls.W1J);
// if (W2J) W2J.rotation.y = THREE.MathUtils.degToRad(controls.W2J);
// if (W3J) W3J.rotation.y = THREE.MathUtils.degToRad(controls.W3J);
}
}
startAnimationLoop = () => {
this.updateRobotJoints(); // Update the robot joints in each frame
// Animation loop
this.renderer.render(this.scene, this.camera);
// Update any animations or rendering operations here
// Keep looping
this.frameId = window.requestAnimationFrame(this.startAnimationLoop);
};
handleWindowResize = () => {
// Update camera and renderer on window resize
const width = window.innerWidth;
const height = window.innerHeight;
this.renderer.setSize(width, height);
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
};
render() {
return null; // No need to render anything in this component
}
}
export default RobotScene;
This is my code where i am using Dat.GUI for the control of the robot urdf model and i want to connect each slider with the 6 joints respectively , so can anyone please check what is missing in the code as i am not been able to connect the slider with the robot joints
BJ.rotation.z = THREE.MathUtils.clamp(BJRotationRadians, -2.0944, 2.0944);
This is not the correct way to set joint rotations. I recommend reading the urdf-loader documentation.
can you please tell me what is wrong and i have looked the documentation also but didnât find anything related to it , can you please help me
Joint angles and positions are set using the URDFJoint.setJointValue function or the URDFRobot.setJointValue function. There is no need, and in fact it may provide incorrect results, to set a joint via three.jsâ rotation object.
i have looked the documentation also but didnât find anything related to it
I accept that thereâs always room for improvement in documentation but if you take even a cursory look at the documentation page or the simple loader example youâll see that there are other classes and member functions for a robot class that should cue you to at least look a little deeper or ask more specific questions.
So is there any other solution that we could work on so as to rotate the joints of the urdf model
using three.js (DAT.GUI for controls )
how do i get the logic for controlling the robot urdf , if u could provide me some resource that will be helpful