BlenderProc icon indicating copy to clipboard operation
BlenderProc copied to clipboard

Physics Positioning: some objects don't fall onto the table completely

Open YorkWang-Go opened this issue 1 year ago • 4 comments
trafficstars

scene

I want to place three objects on a table, so I randomly release three objects onto the table. My code is as follows. However, I've noticed that the final positions of the objects are not logical; they haven't fully settled on the table, as shown in the image below. Ideally, the final positions of all objects should be stable under the influence of gravity.

Minimal code example

import blenderproc as bproc
import argparse
import numpy as np
import os
import bpy
import random
from scipy.spatial.transform import Rotation


def load_objects(obj_path, cat):
    small_obj = bproc.loader.load_obj(obj_path)[0]
    small_obj.set_cp("category_id", cat)
    small_obj.enable_rigidbody(True, mass=1.0, friction=100.0, linear_damping=0.99, angular_damping=0.99)
    return small_obj

def load_table(table_path):
    table = bproc.loader.load_obj(table_path)[0]
    table.set_cp("category_id", -1)
    table.enable_rigidbody(active=False, collision_shape="MESH")
    return table

parser = argparse.ArgumentParser()
parser.add_argument('cam_num', nargs='?', default=16, help='number of camera')
args = parser.parse_args()

bproc.init()

bproc.renderer.enable_normals_output()
bproc.renderer.enable_depth_output(activate_antialiasing=False)
bproc.renderer.set_max_amount_of_samples(50)

numbers = list(range(0, 1668))
# max_iter = 5000
max_iter = 1
current_iter = 0
# for i in range(5000):
while current_iter < max_iter:

    if current_iter >= 0:
        small_obj_a = load_objects('bowl.obj', 1)
        small_obj_b = load_objects('bottle.obj', 2)
        small_obj_c = load_objects('lightbulb.obj', 3)
        obj_list = [small_obj_a, small_obj_b, small_obj_c]

        ground = load_table(args.ground_obj)
        light = bproc.types.Light()

        bpy.context.scene.view_layers["ViewLayer"].pass_alpha_threshold = 0

        bproc.renderer.enable_segmentation_output(map_by=["category_id"])

        bproc.utility.reset_keyframes()

        poi = bproc.object.compute_poi(bproc.filter.all_with_type(obj_list, bproc.types.MeshObject))
        cam_poses = 0
        while cam_poses < args.cam_num:
            np.random.seed(cam_poses)
            location = bproc.sampler.shell(center=[0, 0, 0],
                                           radius_min=1,
                                           radius_max=1,
                                           elevation_min=40,
                                           elevation_max=89)
            rotation_matrix = bproc.camera.rotation_from_forward_vec(poi - location)

            euler_rotation = rotation_matrix_to_euler_angles(rotation_matrix)

            cam2world_matrix = bproc.math.build_transformation_mat(location, euler_rotation)
            bproc.camera.add_camera_pose(cam2world_matrix, frame=cam_poses)
            cam_poses += 1

        # Sample the poses of all spheres above the ground without any collisions in-between
        def sample_pose(obj: bproc.types.MeshObject):
            obj.set_location(np.random.uniform([-0.1, -0.1, 0.10], [0.1, 0.1, 0.14]))
            obj.set_rotation_euler(bproc.sampler.uniformSO3())
        bproc.object.sample_poses(
            obj_list,
            sample_pose_func=sample_pose
        )

        light.set_type("SUN")
        light.set_location([0, 0, 0.5])
        light.set_rotation_euler([-0.063, -0.2177, -0.1985])
        light.set_energy(1)
        light.set_color([1, 0.978, 0.407])

        # Run the simulation and fix the poses of the spheres at the end
        bproc.object.simulate_physics_and_fix_final_poses(min_simulation_time=100, max_simulation_time=200, check_object_interval=0.5, substeps_per_frame=20, solver_iters=30)
        # render the whole pipeline
        data = bproc.renderer.render()

        # write the data to a .hdf5 container
        i_idx = "%04d" % current_iter
        a_idx = "%04d" % a
        b_idx = "%04d" % b
        c_idx = "%04d" % c

        hdf5_out_path = os.path.join(args.output_dir, 'scene_{}'.format(i_idx))
        bproc.writer.write_hdf5(hdf5_out_path, data)
        # save my scene in .obj file
        bpy.ops.export_scene.obj(filepath="scene_{}.obj".format(i_idx), axis_forward='Y', axis_up='Z')
        bproc.clean_up()
        current_iter += 1

Files required to run the code

codes.zip

Expected behavior

actually happen: the final positions of the objects are not logical; they haven't fully settled on the table. expected: all objects naturally fall on the table.

BlenderProc version

v2.5.0

YorkWang-Go avatar Dec 05 '23 13:12 YorkWang-Go

@YorkWang-Go

I am interested to try your script but get an error. Would you please provide the necessary assets in order to run it? [email protected]

(blenderproc) mona@ada:~/BlenderProc/blenderproc/scripts$ blenderproc debug fall_on_table.py --custom-blender-path ~/Downloads/blender-3.5.1-linux-x64/
Using blender in /home/mona/Downloads/blender-3.5.1-linux-x64/
Using temporary directory: /dev/shm/blender_proc_036a1e9ae4c041b9bad4eb84a13a1940
/home/mona/Downloads/blender-3.5.1-linux-x64/3.5/python/lib/python3.10/site-packages/numpy/core/getlimits.py:500: UserWarning: The value of the smallest subnormal for <class 'numpy.float64'> type is zero.
  setattr(self, word, getattr(machar, word).flat[0])
/home/mona/Downloads/blender-3.5.1-linux-x64/3.5/python/lib/python3.10/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class 'numpy.float64'> type is zero.
  return self._float_to_str(self.smallest_subnormal)
/home/mona/Downloads/blender-3.5.1-linux-x64/3.5/python/lib/python3.10/site-packages/numpy/core/getlimits.py:500: UserWarning: The value of the smallest subnormal for <class 'numpy.float32'> type is zero.
  setattr(self, word, getattr(machar, word).flat[0])
/home/mona/Downloads/blender-3.5.1-linux-x64/3.5/python/lib/python3.10/site-packages/numpy/core/getlimits.py:89: UserWarning: The value of the smallest subnormal for <class 'numpy.float32'> type is zero.
  return self._float_to_str(self.smallest_subnormal)
Selecting render devices...
Device NVIDIA RTX 6000 Ada Generation of type OPTIX found and used.
Device Intel Xeon w5-3435X of type CPU found and used.
Error: Python: Traceback (most recent call last):
  File "/fall_on_table.py", line 38, in <module>
NameError: name 'remaining_idx' is not defined
Location: /home/mona/Downloads/blender-3.5.1-linux-x64/3.5/scripts/modules/bpy/ops.py:113

Screenshot from 2023-12-05 09-08-44

monajalal avatar Dec 05 '23 14:12 monajalal

@monajalal Thank you and I made a mistake. I have updated my codes and also send them to you.

YorkWang-Go avatar Dec 05 '23 15:12 YorkWang-Go

Hey @YorkWang-Go,

it seems that your bottle and your bowl mesh are corrupted. At least the normals are wrong (you can see that also by looking at the weird artifacts in the rendering). Due to this corruption, the origin cannot be set to the center of volume and this again causes the simulation to be erroneous.

cornerfarmer avatar Dec 06 '23 21:12 cornerfarmer

@cornerfarmer Hello, but when I use some other bowls and bottles which look normal, the problem still remains. scene codes.zip

YorkWang-Go avatar Dec 07 '23 01:12 YorkWang-Go