Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create a stable pile of cylindrical objects in a tray? #525

Open
onishu opened this issue Jan 10, 2025 · 4 comments
Open

How to create a stable pile of cylindrical objects in a tray? #525

onishu opened this issue Jan 10, 2025 · 4 comments

Comments

@onishu
Copy link

onishu commented Jan 10, 2025

First of all, I want to express my admiration for your fantastic work. I'm eager to use your simulator to develop robotic algorithms.
I'm trying to create a simulation of bin picking using a Franka Panda robot.
Specifically, I want to create a scene with cylindrical parts randomly piled in a tray.
However, I'm encountering an issue: when I execute scene.step(), the pile of parts in the tray explodes or scatters.
Could you please provide guidance on how to create a stable pile of parts in the tray?
What settings or techniques should I use to prevent the parts from scattering when the simulation starts?
Thank you in advance for your help. I'm looking forward to using your simulator for developing robotic algorithms.

import genesis as gs
import numpy as np

gs.init(backend=gs.gpu)


scene = gs.Scene(
    viewer_options=gs.options.ViewerOptions(
        camera_pos=(3, -1, 1.5),
        camera_lookat=(0.0, 0.0, 0.5),
        camera_fov=30,
        res=(960, 640),
        max_FPS=60,
    ),
    sim_options=gs.options.SimOptions(
        dt=0.01,
    ),
    show_viewer=True,
    rigid_options=gs.options.RigidOptions(
        enable_joint_limit=True,
        enable_collision=True,
        gravity=(0, 0, -9.8),
    ),
)

plane = scene.add_entity(
    gs.morphs.Plane(),
)


tray_material = gs.materials.Rigid(rho=1000)
tray_surface = gs.surfaces.Default(color=(0.8, 0.8, 0.8))


entities = {}

entities["tray_bottom"] = scene.add_entity(
    material=tray_material,
    morph=gs.morphs.Box(
        pos=(0, 0.50, 0.005),
        size=(0.3, 0.3, 0.01),
        fixed=True,
    ),
    surface=tray_surface,
)

# トレイの側面
side_positions = [
    (0, 0.00 - 0.15, 0.025),
    (0, 0.00 + 0.15, 0.025),
    (-0.15, 0.00, 0.025),
    (0.15, 0.00, 0.025),
]
side_sizes = [
    (0.28, 0.02, 0.04),
    (0.28, 0.02, 0.04),
    (0.02, 0.28, 0.04),
    (0.02, 0.28, 0.04),
]
for i, (pos, size) in enumerate(zip(side_positions, side_sizes)):
    side_name = f"tray_side{i + 1}"
    entities[side_name] = scene.add_entity(
        material=tray_material,
        morph=gs.morphs.Box(
            pos=pos,
            size=size,
            fixed=True,
        ),
        surface=tray_surface,
    )
    scene.link_entities(entities["tray_bottom"], entities[side_name], "box_baselink", "box_baselink")

num_cylinders = 40
cylinders = []
for i in range(num_cylinders):
    cylinder = scene.add_entity(gs.morphs.Cylinder(radius=0.02, height=0.05, pos=(np.random.uniform(-0.13, 0.13), 0.50 + np.random.uniform(-0.13, 0.13), 0.03 + np.random.uniform(0, 0.04))))
    cylinders.append(cylinder)

cam = scene.add_camera(pos=(3, -1, 1.5), lookat=(0.0, 0.0, 0.5), fov=30, res=(960, 640), GUI=False)


########################## build ##########################
scene.build()

cam.start_recording()
for i in range(100):
    print("hold", i)
    scene.step()

    cam.render()
cam.stop_recording(save_to_filename="video.mp4", fps=60)
video.mp4
@wangyian-me
Copy link
Collaborator

They are expected to be scattered if they are in collision from the beginning. You can tune the damping of the dofs to let it solve the collision and in the meantime won't explode.

@onishu
Copy link
Author

onishu commented Feb 3, 2025

Thank you for your comment.
I understand the first setting to avoid bumping into each other, but I don't know how to set the damping of the dofs setting.
What should I do?

@onishu
Copy link
Author

onishu commented Feb 12, 2025

Dear @wangyian-me

As per your advice, I first arranged the cylinders so they wouldn't collide with each other. Then, I simulated them falling freely due to gravity and hitting the tray below. However, when I defined the material using Rigid(), the bounce was too high, and they disappeared from the top of the tray. I tried using MPM.ElastoPlastic(), but they remained suspended without hitting the tray. Is this MPM method correct for implementing the damping you advised? Below is the code I created. I would appreciate your advice.

import genesis as gs
import numpy as np

gs.init(backend=gs.gpu)

scene = gs.Scene(
    viewer_options=gs.options.ViewerOptions(
        camera_pos=(3, -1, 1.5),
        camera_lookat=(0.0, 0.0, 0.5),
        camera_fov=30,
        res=(960, 640),
        max_FPS=60,
    ),
    sim_options=gs.options.SimOptions(
        dt=0.00001,
        gravity=(0, 0, -9.8),
    ),
    mpm_options=gs.options.MPMOptions(
        dt=0.00001,
        lower_bound=(-0.3, -0.3, -0.1),
        upper_bound=(0.3, 0.8, 0.3),
        particle_size=0.002,
        gravity=(0, 0, -9.8),
    ),
    # fem_options=gs.options.FEMOptions(
    #     dt=0.00001,
    #     damping=1.0,
    # ),
    show_viewer=True,
)

# plane tray
tray = scene.add_entity(
    gs.morphs.Box(
        pos=(0, 0, 0.02),
        size=(0.5, 0.5, 0.04),
        fixed=True,
    ),
    material=gs.materials.Rigid(),
)

num_cylinders = 10
for i in range(num_cylinders):
    cylinder = scene.add_entity(
        gs.morphs.Cylinder(
            radius=0.01,
            height=0.03,
            pos=(np.random.uniform(-0.2, 0.2), np.random.uniform(-0.2, 0.2), np.random.uniform(0.05, 0.1)),
            euler=(np.random.uniform(0, 2 * np.pi), np.random.uniform(0, 2 * np.pi), np.random.uniform(0, 2 * np.pi)),
        ),
        material=gs.materials.MPM.ElastoPlastic(),
    )

scene.build()

for i in range(20000):
    scene.step()

@wangyian-me
Copy link
Collaborator

when I defined the material using Rigid(), the bounce was too high, and they disappeared from the top of the tray

Can I see the video?

but I don't know how to set the damping of the dofs setting

set the mass of the cylinders so they are not too light

for link in cylinder.links:
        link._inertial_mass = 1.0

...
scene.build()

...

for dof in range(cylinder.dof_start, cylinder.dof_end, 1):
        cylinder.solver.dofs_info[dof].damping = 0.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants