robosim.entities
entites.py Helpers to make various entities, like cubes, robots, meshes Import level: 3
1""" 2entites.py Helpers to make various entities, like cubes, robots, meshes 3Import level: 3 4""" 5from pathlib import Path 6import raylib as rl 7import numpy as np 8from microecs import World, EntityId 9from robosim.constants import FPV_HEIGHT, FPV_WIDTH 10from robosim.utils import RlModelWithTexture, get_project_root, Pose4x4, Point3D, make_radius, FPVData, make_arr 11from robosim.components import (ColliderKinds, HasModel, HasPose, HasTypeAndArgs, 12 HasCollision, HasFPV, HasVelocity6DoF, HasAcceleration6DoF, 13 HasMotionInput, HasPhysicsLevel1, HasPhysicsLevel2) 14from robosim.camera import Camera 15 16def make_cube(world: World, pose: Pose4x4, size: Point3D, scale: float, 17 texture_path: Path | None = None) -> EntityId: 18 """helper function to create a cube in the ECS world""" 19 20 mesh = rl.GenMeshCube(size[0], size[1], size[2]) 21 rl_model = rl.LoadModelFromMesh(mesh) 22 rel_texture_path = str(texture_path.relative_to(get_project_root())) if texture_path is not None else None 23 rl_texture = rl.LoadTexture(str(rel_texture_path).encode()) if texture_path is not None else None 24 model = RlModelWithTexture(rl_model, rl_texture) 25 components = [HasModel, HasPose, HasTypeAndArgs, HasCollision] 26 top_left, bottom_right = model.bbox 27 28 return world.add_entity( 29 components=components, 30 _type=np.array([{"type": "cube"}], "object"), 31 _args=np.array([{"size": size.tolist(), "texture_path": rel_texture_path, "scale": scale}], "object"), 32 model=np.array([model], "object"), 33 scale=np.float32([scale]), 34 model_bbox=np.float32([top_left, bottom_right]), 35 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 36 pose=pose, 37 collider_kind=np.int32([ColliderKinds.AABB]), 38 candidate_pose=pose, 39 ) 40 41def make_mesh(world: World, model_path: Path, pose: Pose4x4, scale: float, 42 texture_path: Path | None = None, collidable: bool = False) -> EntityId: 43 """helper function to create a mesh in the ECS world""" 44 rel_model_path = model_path.relative_to(get_project_root()) 45 rel_texture_path = str(texture_path.relative_to(get_project_root())) if texture_path is not None else None 46 model = RlModelWithTexture.from_path(rel_model_path, rel_texture_path) 47 top_left, bottom_right = model.bbox 48 components = [HasModel, HasPose, HasTypeAndArgs] 49 kwargs = {} 50 if collidable: 51 components.append(HasCollision) 52 kwargs = { 53 "collider_kind": np.array([ColliderKinds.AABB], "int32"), 54 "candidate_pose": pose, 55 } 56 57 return world.add_entity( 58 components=components, 59 model=np.array([model], "object"), 60 scale=np.float32([scale]), 61 model_bbox=np.float32([top_left, bottom_right]), 62 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 63 pose=pose, 64 _type=np.array([{"type": "mesh"}], "object"), 65 _args=np.array([ 66 {"model_path": str(rel_model_path), "texture_path": rel_texture_path, "scale": scale}], "object"), 67 **kwargs, 68 ) 69 70def make_robot(world: World, model_path: Path, pose: Pose4x4, scale: float, physics_type: str, 71 velocity: np.ndarray | None = None, acceleration: np.ndarray | None = None, **kwargs) -> EntityId: 72 """helper function to create a robot in the ECS world""" 73 fpv_camera = Camera(make_arr(0, 0, 0), make_arr(0, 0, 0), make_arr(0, 0, 0), 60.0, rl.CAMERA_PERSPECTIVE) 74 fpv_data = FPVData(frame=np.zeros((FPV_HEIGHT * FPV_WIDTH * 4, ), "uint8"), frame_shape=(FPV_HEIGHT, FPV_WIDTH, 4)) 75 fpv_texture = rl.LoadRenderTexture(FPV_WIDTH, FPV_HEIGHT) # TODO: how do we deallocate? 76 77 rel_model_path = model_path.relative_to(get_project_root()) 78 model = RlModelWithTexture.from_path(rel_model_path) # TODO: how do we deallocate? 79 top_left, bottom_right = model.bbox 80 velocity = velocity if velocity is not None else np.zeros((6, ), "float32") 81 acceleration = acceleration if acceleration is not None else np.zeros((6, ), "float32") 82 83 components = [HasTypeAndArgs, HasModel, HasPose, HasFPV, HasVelocity6DoF, 84 HasAcceleration6DoF, HasMotionInput, HasCollision] 85 if physics_type == "level1": 86 components.append(HasPhysicsLevel1) 87 else: 88 components.append(HasPhysicsLevel2) 89 90 return world.add_entity( 91 components=components, 92 _type=np.array([{"type": "robot"}], "object"), 93 _args=np.array([{"model_path": str(rel_model_path), "scale": scale}], "object"), 94 model=np.array([model], "object"), 95 scale=np.float32([scale]), 96 model_bbox=np.float32([top_left, bottom_right]), 97 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 98 pose=pose, 99 velocity=velocity, 100 acceleration=acceleration, 101 fpv_camera=np.array([fpv_camera], "object"), 102 fpv_data=np.array([fpv_data], "object"), 103 fpv_texture=np.array([fpv_texture], "object"), 104 candidate_pose=pose, 105 collider_kind=np.array([ColliderKinds.SPHERE], "int32"), 106 **kwargs 107 )
def
make_cube( world: microecs.world.World, pose: numpy.ndarray, size: numpy.ndarray, scale: float, texture_path: pathlib.Path | None = None) -> int:
17def make_cube(world: World, pose: Pose4x4, size: Point3D, scale: float, 18 texture_path: Path | None = None) -> EntityId: 19 """helper function to create a cube in the ECS world""" 20 21 mesh = rl.GenMeshCube(size[0], size[1], size[2]) 22 rl_model = rl.LoadModelFromMesh(mesh) 23 rel_texture_path = str(texture_path.relative_to(get_project_root())) if texture_path is not None else None 24 rl_texture = rl.LoadTexture(str(rel_texture_path).encode()) if texture_path is not None else None 25 model = RlModelWithTexture(rl_model, rl_texture) 26 components = [HasModel, HasPose, HasTypeAndArgs, HasCollision] 27 top_left, bottom_right = model.bbox 28 29 return world.add_entity( 30 components=components, 31 _type=np.array([{"type": "cube"}], "object"), 32 _args=np.array([{"size": size.tolist(), "texture_path": rel_texture_path, "scale": scale}], "object"), 33 model=np.array([model], "object"), 34 scale=np.float32([scale]), 35 model_bbox=np.float32([top_left, bottom_right]), 36 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 37 pose=pose, 38 collider_kind=np.int32([ColliderKinds.AABB]), 39 candidate_pose=pose, 40 )
helper function to create a cube in the ECS world
def
make_mesh( world: microecs.world.World, model_path: pathlib.Path, pose: numpy.ndarray, scale: float, texture_path: pathlib.Path | None = None, collidable: bool = False) -> int:
42def make_mesh(world: World, model_path: Path, pose: Pose4x4, scale: float, 43 texture_path: Path | None = None, collidable: bool = False) -> EntityId: 44 """helper function to create a mesh in the ECS world""" 45 rel_model_path = model_path.relative_to(get_project_root()) 46 rel_texture_path = str(texture_path.relative_to(get_project_root())) if texture_path is not None else None 47 model = RlModelWithTexture.from_path(rel_model_path, rel_texture_path) 48 top_left, bottom_right = model.bbox 49 components = [HasModel, HasPose, HasTypeAndArgs] 50 kwargs = {} 51 if collidable: 52 components.append(HasCollision) 53 kwargs = { 54 "collider_kind": np.array([ColliderKinds.AABB], "int32"), 55 "candidate_pose": pose, 56 } 57 58 return world.add_entity( 59 components=components, 60 model=np.array([model], "object"), 61 scale=np.float32([scale]), 62 model_bbox=np.float32([top_left, bottom_right]), 63 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 64 pose=pose, 65 _type=np.array([{"type": "mesh"}], "object"), 66 _args=np.array([ 67 {"model_path": str(rel_model_path), "texture_path": rel_texture_path, "scale": scale}], "object"), 68 **kwargs, 69 )
helper function to create a mesh in the ECS world
def
make_robot( world: microecs.world.World, model_path: pathlib.Path, pose: numpy.ndarray, scale: float, physics_type: str, velocity: numpy.ndarray | None = None, acceleration: numpy.ndarray | None = None, **kwargs) -> int:
71def make_robot(world: World, model_path: Path, pose: Pose4x4, scale: float, physics_type: str, 72 velocity: np.ndarray | None = None, acceleration: np.ndarray | None = None, **kwargs) -> EntityId: 73 """helper function to create a robot in the ECS world""" 74 fpv_camera = Camera(make_arr(0, 0, 0), make_arr(0, 0, 0), make_arr(0, 0, 0), 60.0, rl.CAMERA_PERSPECTIVE) 75 fpv_data = FPVData(frame=np.zeros((FPV_HEIGHT * FPV_WIDTH * 4, ), "uint8"), frame_shape=(FPV_HEIGHT, FPV_WIDTH, 4)) 76 fpv_texture = rl.LoadRenderTexture(FPV_WIDTH, FPV_HEIGHT) # TODO: how do we deallocate? 77 78 rel_model_path = model_path.relative_to(get_project_root()) 79 model = RlModelWithTexture.from_path(rel_model_path) # TODO: how do we deallocate? 80 top_left, bottom_right = model.bbox 81 velocity = velocity if velocity is not None else np.zeros((6, ), "float32") 82 acceleration = acceleration if acceleration is not None else np.zeros((6, ), "float32") 83 84 components = [HasTypeAndArgs, HasModel, HasPose, HasFPV, HasVelocity6DoF, 85 HasAcceleration6DoF, HasMotionInput, HasCollision] 86 if physics_type == "level1": 87 components.append(HasPhysicsLevel1) 88 else: 89 components.append(HasPhysicsLevel2) 90 91 return world.add_entity( 92 components=components, 93 _type=np.array([{"type": "robot"}], "object"), 94 _args=np.array([{"model_path": str(rel_model_path), "scale": scale}], "object"), 95 model=np.array([model], "object"), 96 scale=np.float32([scale]), 97 model_bbox=np.float32([top_left, bottom_right]), 98 model_radius=np.float32([make_radius(size=bottom_right - top_left)]), 99 pose=pose, 100 velocity=velocity, 101 acceleration=acceleration, 102 fpv_camera=np.array([fpv_camera], "object"), 103 fpv_data=np.array([fpv_data], "object"), 104 fpv_texture=np.array([fpv_texture], "object"), 105 candidate_pose=pose, 106 collider_kind=np.array([ColliderKinds.SPHERE], "int32"), 107 **kwargs 108 )
helper function to create a robot in the ECS world