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

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

Open
YorkWang-Go opened this issue Dec 5, 2023 · 4 comments
Open
Labels
question Question, not yet a bug ;)

Comments

@YorkWang-Go
Copy link

YorkWang-Go commented Dec 5, 2023

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 YorkWang-Go added the question Question, not yet a bug ;) label Dec 5, 2023
@monajalal
Copy link

monajalal commented Dec 5, 2023

@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?
mona.jalal.tmh@gmail.com

(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

@YorkWang-Go
Copy link
Author

YorkWang-Go commented Dec 5, 2023

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

@cornerfarmer
Copy link
Member

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.

@YorkWang-Go
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question, not yet a bug ;)
Projects
None yet
Development

No branches or pull requests

3 participants