google / google/brax

Issue with bodies flying apart in simulation [Question]

Open
#208 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Jupyter Notebook
Stars
3.2k
Forks
349
PR merge metrics
No merged PRs in 30d

Description

I am trying to implement my own simulation of a robot claw. I have an issue where for some reason all the bodies are exploding. This is odd to me because it only happens when I include all bodies together, pictured below. If I only include one claw it works just fine and all the joints work as expected. But for some reason I don't understand including both claws will cause the bodies to spontaneously explode away from each other at high speed. Additionally I have found that I can include both claws if I don't include a link to the ground plane. Is this a problem with my approach or is this a bug? I am unsure how investigate further and would appreciate any advice.

![Screenshot from 2022-07-03 13-14-59](https://user-images.githubusercontent.com/9042283/177056011-41b0db5c-4173-45da-9552-26d4664a64bc.png)

```
import functools
import time

from IPython.display import HTML, Image
import gym

try:
import brax
except ImportError:
from IPython.display import clear_output
!pip install git+https://github.com/google/brax.git@main
clear_output()
import brax

from brax import envs
from brax import jumpy as jp
from brax.envs import to_torch
from brax.io import html
from brax.io import image

import numpy as np

right_claw = True
left_claw = True

conf = brax.Config(dt=0.05, substeps=20, angular_damping=-0.05, dynamics_mode='pbd')
conf.gravity.z = -9.8

ground = conf.bodies.add(name='floor', mass=1)
ground.frozen.all = True
ground.inertia.x = 1
ground.inertia.y = 1
ground.inertia.z = 1
plane = ground.colliders.add().plane
plane.SetInParent()

link1 = conf.bodies.add(name='link1', mass=1)
cap = link1.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link2 = conf.bodies.add(name='link2', mass=1)
cap = link2.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.3
cap.SetInParent()

cap = link2.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

cap = link2.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link2.colliders[0].rotation.y = 90.0
link2.colliders[1].rotation.x = 90.0
link2.colliders[2].rotation.x = 90

link2.colliders[1].position.x = 0.1
link2.colliders[2].position.x = -0.1

if (right_claw):
link3 = conf.bodies.add(name='link3', mass=1)
cap = link3.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link3.colliders[0].rotation.y = 90.0

link4 = conf.bodies.add(name='link4', mass=1)
cap = link4.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link4.colliders[0].rotation.y = 90.0

link5 = conf.bodies.add(name='link5', mass=1)
cap = link5.colliders.add().capsule
cap.radius = 0.05
cap.length = 1
cap.SetInParent()

cap = link5.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

cap = link5.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link5.colliders[0].rotation.x = 90.0
link5.colliders[1].rotation.x = 90.0
link5.colliders[1].rotation.y = 45
link5.colliders[1].position.x = -0.15
link5.colliders[1].position.y = 0.6
link5.colliders[2].rotation.x = 90.0
link5.colliders[2].position.x = -0.30
link5.colliders[2].position.y = 0.5 + 0.28 + 0.15

if(left_claw):
link6 = conf.bodies.add(name='link6', mass=1)
cap = link6.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link6.colliders[0].rotation.y = 90.0

link7 = conf.bodies.add(name='link7', mass=1)
cap = link7.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link7.colliders[0].rotation.y = 90.0

link8 = conf.bodies.add(name='link8', mass=1)
cap = link8.colliders.add().capsule
cap.radius = 0.05
cap.length = 1
cap.SetInParent()

cap = link8.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

cap = link8.colliders.add().capsule
cap.radius = 0.05
cap.length = 0.5
cap.SetInParent()

link8.colliders[0].rotation.x = 90.0
link8.colliders[1].rotation.x = 90.0
link8.colliders[1].rotation.y = -45
link8.colliders[1].position.x = 0.15
link8.colliders[1].position.y = 0.6
link8.colliders[2].rotation.x = 90.0
link8.colliders[2].position.x = 0.30
link8.colliders[2].position.y = 0.5 + 0.28 + 0.15

joint1 = conf.joints.add(name='joint1', parent='floor', child='link1', angular_damping=50.0)
joint1.angle_limit.add(min=-360, max=360)
joint1.parent_offset.z = 0.25
joint1.rotation.y=90

joint2 = conf.joints.add(name='joint2', parent='link1', child='link2', angular_damping = 50.0)
joint2.angle_limit.add(min=-360, max=360)
joint2.parent_offset.z = 0.2
joint2.rotation.x = 90

if(right_claw):
joint3 = conf.joints.add(name='joint3', parent='link2', child='link3', angular_damping=50.0)
joint3.angle_limit.add(min=-75, max=75)
joint3.parent_offset.y = -0.2
joint3.parent_offset.x = 0.1
joint3.child_offset.x = -0.2
joint3.rotation.y = -90

joint4 = conf.joints.add(name='joint4', parent='link2', child='link4', angular_damping=50.0)
joint4.angle_limit.add(min=-360, max=360)
joint4.parent_offset.y = 0.2
joint4.parent_offset.x = 0.1
joint4.child_offset.x = -0.2
joint4.rotation.y = -90

joint5 = conf.joints.add(name='joint5', parent='link3', child='link5', angular_damping=50.0)
joint5.angle_limit.add(min=-360, max=360)
joint5.parent_offset.x = 0.2
joint5.child_offset.y = -0.45
joint5.rotation.y = -90

joint6 = conf.joints.add(name='joint6', parent='link4', child='link5', angular_damping=50.0)
joint6.angle_limit.add(min=-360, max=360)
joint6.parent_offset.x = 0.2
joint6.child_offset.y = -0.05
joint6.rotation.y = -90

if(left_claw):
joint7 = conf.joints.add(name='joint7', parent='link2', child='link6', angular_damping=50.0)
joint7.angle_limit.add(min=-75, max=75)
joint7.parent_offset.y = -0.2
joint7.parent_offset.x = -0.1
joint7.child_offset.x = 0.2
joint7.rotation.y = 90

joint8 = conf.joints.add(name='joint8', parent='link2', child='link7', angular_damping=50.0)
joint8.angle_limit.add(min=-360, max=360)
joint8.parent_offset.y = 0.2
joint8.parent_offset.x = -0.1
joint8.child_offset.x = 0.2
joint8.rotation.y = 90

joint9 = conf.joints.add(name='joint9', parent='link6', child='link8', angular_damping=50.0)
joint9.angle_limit.add(min=-360, max=360)
joint9.parent_offset.x = -0.2
joint9.child_offset.y = -0.45
joint9.rotation.y = 90

joint10 = conf.joints.add(name='joint10', parent='link7', child='link8', angular_damping=50.0)
joint10.angle_limit.add(min=-360, max=360)
joint10.parent_offset.x = -0.2
joint10.child_offset.y = -0.05
joint10.rotation.y = 90

actuator1 = conf.actuators.add(name='joint1', joint='joint1', strength=100.).torque
actuator1.SetInParent()

actuator2 = conf.actuators.add(name='joint2', joint='joint2', strength=100.).torque
actuator2.SetInParent()

if(right_claw):
actuator3 = conf.actuators.add(name='joint3', joint='joint3', strength=100.).torque
actuator3.SetInParent()

if(left_claw):
actuator4 = conf.actuators.add(name='joint7', joint='joint7', strength=100.).torque
actuator4.SetInParent()

sys = brax.System(conf)
qps = [sys.default_qp()]

for i in range(100):
qps.append(sys.step(qps[-1], [0, 0, 1, 1])[0])
HTML(html.render(sys, qps))
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.