# Source: https://internrobotics.github.io/InternDataEngine-Docs/custom/task.html # Creating a Custom Task [​](#creating-a-custom-task) This guide explains how to create a new task by combining your custom assets, robots, controllers, and skills into a complete task configuration. ## Overview [​](#overview) After creating custom components (assets, robots, controllers, skills), you can combine them into a task YAML configuration. The workflow will load this configuration to set up the simulation environment. ## Prerequisites [​](#prerequisites) Before creating a custom task, ensure you have: - **Custom Assets **- See [Assets Guide](/InternDataEngine-Docs/custom/assets.html) - **Custom Robot **- See [Robot Guide](/InternDataEngine-Docs/custom/robot.html) - **Custom Controller **- See [Controller Guide](/InternDataEngine-Docs/custom/controller.html) - **Custom Skill **- See [Skill Guide](/InternDataEngine-Docs/custom/skill.html) ## Prepare Asset Directory [​](#prepare-asset-directory) Organize your task assets following the structure: ``` new_task/ └── new_objs/ # Rigid objects directory ├── new_obj0/ # Object instance 0 │ ├── Aligned_obj.obj # Preprocessed mesh │ ├── Aligned.mtl # Material file │ ├── Aligned_obj.usd # USD with physics properties │ ├── Aligned_grasp_sparse.npy # Grasp poses (optional) │ └── textures/ # Texture files ├── new_obj1/ # Object instance 1 └── new_obj2/ # Object instance 2 ``` 1 2 3 4 5 6 7 8 9 10 Place this directory under your asset root (e.g., `workflows/simbox/assets/ `or `workflows/simbox/example_assets/ `). Note For rigid manipulation objects, objects of the **same category **should be placed in the **same parent folder **(e.g., `new_obj0 `, `new_obj1 `, `new_obj2 `all under `new_objs/ `). This organization enables **category-level domain randomization **. Inside each object subfolder, use consistent naming conventions: `Aligned_obj.obj `, `Aligned_obj.usd `, `Aligned_grasp_sparse.npy `, etc. ## Create Task YAML Configuration [​](#create-task-yaml-configuration) Create a new YAML file in `workflows/simbox/core/configs/tasks/ `: yaml ``` # ============================================================================= # New Task Configuration # ============================================================================= tasks: - name: new_task asset_root: workflows/simbox/assets task: BananaBaseTask task_id: 0 offset: null render: True # ========================================================================= # Arena Configuration # ========================================================================= arena_file: workflows/simbox/core/configs/arenas/example.yaml # ========================================================================= # Environment Map (Lighting) # ========================================================================= env_map: envmap_lib: envmap_lib apply_randomization: False intensity_range: [4000, 7000] rotation_range: [0, 180] # ========================================================================= # Robots # ========================================================================= robots: - name: "new_robot" robot_config_file: workflows/simbox/core/configs/robots/new_robot.yaml euler: [0.0, 0.0, 0.0] ignore_substring: ["material", "table", "floor"] # ========================================================================= # Objects # ========================================================================= objects: - name: obj0 path: new_task/new_objs/new_obj0/Aligned_obj.usd target_class: RigidObject dataset: custom category: new_object prim_path_child: Aligned translation: [0.3, 0.0, 0.0] euler: [0.0, 0.0, 0.0] scale: [1, 1, 1] apply_randomization: False - name: obj1 path: new_task/new_objs/new_obj1/Aligned_obj.usd target_class: RigidObject dataset: custom category: new_object prim_path_child: Aligned translation: [0.0, 0.2, 0.0] euler: [0.0, 0.0, 0.0] scale: [1, 1, 1] apply_randomization: False - name: obj2 path: new_task/new_objs/new_obj2/Aligned_obj.usd target_class: RigidObject dataset: custom category: new_object prim_path_child: Aligned translation: [0.0, -0.2, 0.0] euler: [0.0, 0.0, 0.0] scale: [1, 1, 1] apply_randomization: False # ========================================================================= # Regions (Object Placement) # ========================================================================= regions: - object: obj0 target: table random_type: A_on_B_region_sampler random_config: pos_range: [[0.2, -0.15, 0.0], [0.4, 0.15, 0.0]] yaw_rotation: [-30.0, 30.0] - object: obj1 target: table random_type: A_on_B_region_sampler random_config: pos_range: [[-0.4, -0.15, 0.0], [-0.2, 0.15, 0.0]] yaw_rotation: [-180.0, 180.0] - object: obj2 target: table random_type: A_on_B_region_sampler random_config: pos_range: [[-0.4, -0.15, 0.0], [-0.2, 0.15, 0.0]] yaw_rotation: [-180.0, 180.0] # ========================================================================= # Cameras # ========================================================================= cameras: - name: head_camera translation: [0.5, 0.0, 0.8] orientation: [0.924, 0.383, 0.0, 0.0] camera_axes: usd camera_file: workflows/simbox/core/configs/cameras/realsense_d455.yaml parent: "" apply_randomization: False - name: wrist_camera_left translation: [0.0, 0.05, 0.03] orientation: [0.0, 0.0, 0.0, 1.0] camera_axes: usd camera_file: workflows/simbox/core/configs/cameras/realsense_d435.yaml parent: "new_robot/path/to/fl_ee_link" apply_randomization: False - name: wrist_camera_right translation: [0.0, -0.05, 0.03] orientation: [0.0, 0.0, 0.0, 1.0] camera_axes: usd camera_file: workflows/simbox/core/configs/cameras/realsense_d435.yaml parent: "new_robot/path/to/fr_ee_link" apply_randomization: False # ========================================================================= # Data Settings # ========================================================================= data: task_dir: "new_task_demo" language_instruction: "New task." detailed_language_instruction: "New task." collect_info: "Custom task with new robot and skill" version: "v1.0" update: True max_episode_length: 500 # ========================================================================= # Skills # ========================================================================= # Dual-arm mode: left arm operates obj0, right arm operates obj1 and obj2 skills: - new_robot: - left: - name: skill0 objects: [obj0] - right: - name: skill1 objects: [obj1, obj2] ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 ## Task Modes [​](#task-modes) The task configuration supports multiple execution modes. Here are common patterns: ### Single-Arm Task [​](#single-arm-task) For single-arm robots, configure only one arm in the skills section. Skills execute sequentially — each skill starts only after the previous one completes. The task finishes when all skills are done. **Left Arm Example: ** yaml ``` skills: - new_robot: - left: - name: skill0 objects: [obj0] - name: skill1 objects: [obj1] - name: skill2 objects: [obj2] ``` 1 2 3 4 5 6 7 8 9 **Right Arm Example: ** yaml ``` skills: - new_robot: - right: - name: skill0 objects: [obj0] - name: skill1 objects: [obj1] - name: skill2 objects: [obj2] ``` 1 2 3 4 5 6 7 8 9 ### Dual-Arm Sequential Task [​](#dual-arm-sequential-task) For dual-arm robots operating sequentially. In this pattern, one arm completes all its skills before the other arm begins. The example below shows the left arm executing first, followed by the right arm. yaml ``` # Left arm skills execute first, then right arm skills skills: - new_robot: - left: - name: skill0 objects: [obj0] - name: skill1 objects: [obj1] - name: skill2 objects: [obj2] - right: - name: skill3 objects: [obj3] - name: skill4 objects: [obj4] - name: skill5 objects: [obj5] ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ### Dual-Arm Simultaneous Task [​](#dual-arm-simultaneous-task) For dual-arm robots operating simultaneously. Both arms start at the same time and execute their skills independently. Within each arm, skills still execute sequentially. The task finishes when all skills from both arms are complete. yaml ``` # Left and right arm skills start simultaneously skills: - new_robot: - left: - name: skill0 objects: [obj0] - name: skill1 objects: [obj1] - name: skill2 objects: [obj2] right: - name: skill3 objects: [obj3] - name: skill4 objects: [obj4] - name: skill5 objects: [obj5] ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ### Complex Task Example [​](#complex-task-example) You can freely combine single-arm, dual-arm sequential, and dual-arm simultaneous tasks in any order. This example demonstrates a tableware arrangement task: - **Phase 1 (Sequential) **: Right arm picks a plate, places it on the table, then returns home - **Phase 2 (Simultaneous) **: Left arm picks and places the fork while right arm picks and places the spoon yaml ``` # Source: workflows/simbox/core/configs/tasks/basic/lift2/arrange_the_tableware/ skills: - lift2: - right: - name: pick objects: [plate] filter_z_dir: ["forward", 80] filter_x_dir: ["downward", 130] pre_grasp_offset: 0.05 gripper_change_steps: 10 ignore_substring: ["plate_shelf"] post_grasp_offset_min: 0.075 post_grasp_offset_max: 0.125 - name: place objects: [plate, table] place_direction: vertical filter_z_dir: ["forward", 10] filter_y_dir: ["upward", 60, 30] filter_x_dir: ["downward", 120, 150] position_constraint: object x_ratio_range: [0.5, 0.5] y_ratio_range: [0.12, 0.20] pre_place_z_offset: 0.15 place_z_offset: 0.1 post_place_vector: [-0.05, 0.0, 0.0] success_mode: xybbox - name: heuristic__skill mode: home gripper_state: 1.0 - left: - name: pick objects: [fork] filter_z_dir: ["forward", 80] filter_x_dir: ["downward", 130] pre_grasp_offset: 0.05 gripper_change_steps: 10 post_grasp_offset_min: 0.125 post_grasp_offset_max: 0.175 - name: place objects: [fork, plate] place_direction: vertical filter_z_dir: ["forward", 20] filter_x_dir: ["downward", 150] x_ratio_range: [-0.25, -0.15] y_ratio_range: [0.30, 0.70] pre_place_z_offset: 0.175 place_z_offset: 0.125 success_mode: left threshold: 0.01 - name: heuristic__skill mode: home gripper_state: 1.0 right: - name: pick objects: [spoon] filter_z_dir: ["forward", 80] filter_x_dir: ["downward", 130] pre_grasp_offset: 0.05 gripper_change_steps: 10 post_grasp_offset_min: 0.125 post_grasp_offset_max: 0.175 - name: place objects: [spoon, plate] place_direction: vertical filter_z_dir: ["forward", 20] filter_x_dir: ["downward", 150] x_ratio_range: [1.15, 1.25] y_ratio_range: [0.30, 0.70] pre_place_z_offset: 0.175 place_z_offset: 0.125 success_mode: right threshold: 0.01 - name: heuristic__skill mode: home gripper_state: 1.0 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 ## Run the Task [​](#run-the-task) Run the simulation with your task configuration: bash ``` # Plan with render mode (suitable for debugging) bash scripts/simbox/simbox_plan_with_render.sh new_task [num_samples] [random_seed] # Plan and render mode bash scripts/simbox/simbox_plan_and_render.sh new_task [num_samples] [random_seed] # DE pipeline mode (suitable for data generation) bash scripts/simbox/simbox_pipe.sh new_task [num_samples] [random_seed] ``` 1 2 3 4 5 6 7 8