ami-iit / jaxsim

A differentiable physics engine and multibody dynamics library for control and robot learning.
https://jaxsim.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
66 stars 9 forks source link

Port on notebooks the existing GPU simulations of model #60

Closed traversaro closed 8 months ago

traversaro commented 9 months ago

First step (cartpole):

Second step (ergocub):

I would keep the two in two different notebooks as the second one requires a separate dependency.

flferretti commented 9 months ago

Check out the Development section for the related working branch

traversaro commented 8 months ago

I tried to add a visualization based on iDynTree, but I forgot that in iDynTree on PyPI I disabled the irrlicht deps in https://github.com/robotology/idyntree/pull/1068, so I get as error:

[ERROR] ModelLoader :: loadModelFromFile : Error in parsing model from URDF.
[ERROR] Visualizer :: init : Impossible to use iDynTree::Visualizer, as iDynTree has been compiled without Irrlicht.
[ERROR] Visualizer :: addModel : Impossible to use iDynTree::Visualizer, as iDynTree has been compiled without Irrlicht.
[ERROR] Visualizer :: drawToFile : Impossible to call drawToFile in a not initialized visualizer
traversaro commented 8 months ago

For reference, this was the code:

import requests

url = "https://raw.githubusercontent.com/flferretti/jaxsim/example/notebook/examples/assets/cartpole.urdf"

response = requests.get(url)
if response.status_code == 200:
    model_urdf_path = response.text
else:
    logging.error("Failed to fetch data")

import idyntree.bindings as idyntree
import numpy as np

viz_options = idyntree.VisualizerOptions()
viz_options.winHeight = 600
viz_options.winWidth = 800

viz = idyntree.Visualizer()
viz.init(viz_options)
viz.camera()

class Visualizer:
    def __init__(self, model_path, joint_list) -> None:
        robot_idyn = idyntree.ModelLoader()
        robot_idyn.loadReducedModelFromFile(model_path, joint_list)

        viz_options = idyntree.VisualizerOptions()
        viz_options.winHeight = 600
        viz_options.winWidth = 800

        self.viz = idyntree.Visualizer()
        self.viz.init(viz_options)
        self.viz.addModel(robot_idyn.model(), "robot")

        self.set_environment()
        self.set_light()
        self.set_camera()

        # idyntree viz quantities
        self.H = idyntree.Transform.Identity()
        self.R = idyntree.Rotation()
        self.p = idyntree.Position()
        self.s = idyntree.VectorDynSize(robot_idyn.model().getNrOfDOFs())

    def set_environment(self):
        self.viz.enviroment().setElementVisibility("floor_grid", True)
        self.viz.enviroment().setElementVisibility("world_frame", True)

    def set_camera(self):
        camera_pos_idyn = idyntree.Position()
        camera_pos = [1.5, 0.5, 0.4]
        camera_pos_idyn.FromPython(np.array(camera_pos))
        self.viz.camera().setPosition(idyntree.Position.FromPython(camera_pos))
        target_pos_idyn = idyntree.Position()
        target_pos = [0, 0.0, 0.8]
        target_pos_idyn.FromPython(target_pos)
        self.viz.camera().setTarget(target_pos_idyn)

    def set_light(self):
        # additional lights
        self.viz.enviroment().addLight("sun1")
        self.viz.enviroment().lightViz("sun1").setType(idyntree.DIRECTIONAL_LIGHT)
        self.viz.enviroment().lightViz("sun1").setDirection(
            idyntree.Direction(-5, 0, 0)
        )
        self.viz.enviroment().addLight("sun2")
        self.viz.enviroment().lightViz("sun2").setType(idyntree.DIRECTIONAL_LIGHT)
        self.viz.enviroment().lightViz("sun2").setDirection(idyntree.Direction(5, 0, 0))

    def update(self, H, s, T, f) -> bool:
        self.R = idyntree.Rotation.FromPython(H[:3, :3])
        self.p = idyntree.Position.FromPython(H[:3, 3])
        self.H.setRotation(self.R)
        self.H.setPosition(self.p)
        self.s = idyntree.VectorDynSize.FromPython(s)
        self.viz.modelViz("robot").setPositions(self.H, self.s)
        self.viz.draw()
        return True

    def drawToFile(self, filename) -> bool:
        return self.viz.drawToFile(filename)

viz = Visualizer(model_path=model_urdf_path, joint_list=["linear", "pivot"])
viz.drawToFile("frame1.png")
flferretti commented 8 months ago

We could try to use the conda version of IDynTree using condacolab. Otherwise, tomorrow I will work on the use of pixi to make the example easier to use

flferretti commented 8 months ago

In https://github.com/ami-iit/jaxsim/commit/856d06e4a6a58e6e08fdf12d7fde83c50b804485 I added pixi support for linux-64 and osx-64, where the latter uses JAX Metal for GPU support on Apple Silicon. As it is still in experimental phase, we can think of dropping support for the examples on OSX, for the time being

flferretti commented 8 months ago

Notebook added in #63. I'll open a different issue for ErgoCub simulation. Closing