Configure and Run an Embodied Task Program#
This tutorial deploys Task Program’s built-in Semantic Calls through explicit environment, integration, embodiment, and execution-policy configuration. The calls are declarative language instructions, not an independent execution API.
This page is for integration authors who bind scenes, robot profiles and execution policies. To customize an existing task by editing only its program, start with Customize your first expert trajectory.
The optional Authoring a Task Program in Python introduces the typed language without starting simulation; it is not a prerequisite for the Quickstart.
Use Atomic Skills instead when Python code should construct and execute
typed ActionInvocation values directly. The architecture and ownership
rules are described in Task Program architecture.
What you will configure#
A supported configuration-defined Task Program has six core owners. A task that also collects augmented trajectories may add a separate expansion declaration:
program.yamlowns the embodiment-independent task flow and targets;integration.yamlowns task-specific semantic requirements, its nestedscene_binding, resource defaults, action options, effect monitors, and runtime services;a reusable environment component (for example
envs/default.yamlandenvs/newton.yaml) owns the physical scene and ordinary Gym environment values;an embodiment component owns one robot, its sensors, and optional semantic skill profile;
an execution-policy component owns motion, recovery, runner, and effect assurance settings; and
task.<embodiment>.yamlselects those reusable owners for one runnable Gym ID.
There is no separate physical scene.yaml or task component. In particular,
the reusable environment component contains no id or task_program
field, so the same physical environment can also be selected by a
handwritten-trajectory deployment.
The shared EmbodiedEnv and Task Program adapter then lower Semantic Calls
to Atomic Skills while retaining the normal stepping, recording, and reset
lifecycle.
In a source checkout, the official repeated Pick/Place example is a complete
reference. Its physical backends live under envs/; the UR5 deployment additionally
references expansion/repeated_pick_place.yaml through expansion.config:
extensions/embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/envs/default.yamlandenvs/newton.yaml;extensions/embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/task_program/;extensions/embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/task.ur5.yaml;extensions/embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/task.franka.yaml;extensions/embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/expansion/repeated_pick_place.yaml;extensions/embodichain_tasks/configs/components/embodiments/ur5_dh_pgi_140_80.yaml;extensions/embodichain_tasks/configs/components/execution_policies/trajectory_open_loop.yaml.
These files have explicit ownership rather than generic deep-merge semantics. The deployment must select components that satisfy the task’s scene and embodiment contracts.
Declare object-centric intent#
The program names semantic scene entities and robot resources. It contains no joint names, planners, controller commands, simulator objects, or Python callables:
program_id: repeated_cube_pick_place
targets:
drop_pose:
kind: cyclic_pose
values:
- position: [-0.40, 0.48, 0.10]
quaternion_xyzw: [0.0, 0.0, 0.0, 1.0]
- position: [-0.42, -0.08, 0.10]
quaternion_xyzw: [0.0, 0.0, 0.0, 1.0]
program:
kind: repeat
count: 3
body:
kind: segment
name: move_cube
steps:
kind: sequence
items:
- kind: invoke
call:
kind: pick
object: cube
- kind: invoke
call:
kind: place
object: cube
at: {kind: target_ref, target: drop_pose}
cube is a canonical semantic object rather than a simulator UID. The
program deliberately contains no integration selection or robot-specific
resource ID. The task integration supplies the logical Pick and Place resource
defaults, and the selected embodiment supplies compatible concrete endpoints.
Compose the deployment#
The reusable environment owns physical simulation entities and ordinary environment values, including its explicit physics backend. Here is the complete Default environment used by the Quickstart:
environment_id: repeated_pick_place
physics: default
max_episodes: 1
max_episode_steps: 1200
num_envs: 1
arena_space: 2.5
simulation:
light:
direct:
- uid: main_light
light_type: sun
color: [0.6, 0.6, 0.6]
intensity: 5.0
direction: [0.0, 0.0, -1.0]
- uid: rect_light
light_type: rect
color: [1.0, 1.0, 1.0]
intensity: 8.0
init_pos: [-0.42, 0.08, 0.8]
direction: [0.0, 0.0, -1.0]
rect_width: 0.5
rect_height: 0.5
background: []
rigid_object:
- uid: cube
shape:
shape_type: Cube
size: [0.05, 0.05, 0.05]
body_type: dynamic
init_pos: [-0.42, -0.08, 0.025]
attrs:
mass_props:
mass: 0.05
rigid_props:
linear_damping: 0.2
angular_damping: 0.2
material_props:
dynamic_friction: 0.97
static_friction: 0.99
rigid_object_group: []
articulation: []
env:
sim_steps_per_control: 4
events: {}
dataset:
lerobot:
func: LeRobotRecorder
mode: save
params:
# Structured dataset output; robot_type comes from the selected embodiment.
save_path: /tmp/repeated-pick-place/datasets
extra:
scene_type: tabletop
task_description: repeated_pick_place_combined
data_type: sim
use_videos: true
The complete Franka deployment selects environment variants, Task Program components and an embodiment. It does not enable expansion:
id: TaskProgramRepeatedPickPlace-Franka-v1
environment:
default: envs/default.yaml
newton: envs/newton.yaml
task_program:
program: task_program/program.yaml
integration: task_program/integration.yaml
execution_policy: ../../../components/execution_policies/trajectory_open_loop.yaml
embodiment:
component: ../../../components/embodiments/franka_panda.yaml
overrides:
init_rot: [0.0, 0.0, 180.0]
During config_to_cfg(), the component resolver expands these selections,
checks that every semantic simulation_uid exists in the physical scene,
validates the scene and embodiment contracts, binds the exact scene-registry,
robot-profile, and policy-preset IDs into the otherwise unbound program, and
registers the common EmbodiedEnv. Component references resolve relative to
the runnable deployment file.
Select effect assurance explicitly#
Every execution policy must declare how semantic state is authorized to advance. The trajectory-only component selects projected assurance:
policy_id: trajectory_open_loop_v1
preset_id: trajectory
effect_assurance: projected
projected applies the action plan’s expected symbolic effect after command
completion. The matching task integration must declare an empty
effect_monitors mapping, and successful completion is not proof that the
physical grasp or release occurred.
For a physically verified curated call, select verified in the execution
policy and map every used Pick, Place, or HandOver call to an explicit monitor
in the task integration:
profile:
effect_monitors:
hand_over:
monitor_id: builtin.composite_effect
revision: "1"
params: {consecutive_samples: 10}
The integration must also install the evidence providers required by that monitor. Command acknowledgement alone is not physical evidence.
Load and validate without simulation#
From the source checkout root, the provider-independent API performs strict
file decoding before any live environment is constructed. Unlike the CLI,
load_task_program() takes a filesystem path, not a package-resource reference:
from embodichain.lab.task_program import (
TaskProgramIntegrationCfg,
load_task_program,
)
program = load_task_program(
"extensions/embodichain_tasks/configs/tasks/manipulation/"
"repeated_pick_place/task_program/program.yaml",
integration=TaskProgramIntegrationCfg(
robot_profile="ur5_dh_pgi_140_80",
scene_registry="task_program_repeated_pick_place",
runtime_preset="trajectory",
),
)
print(program.program_id)
The explicit integration argument represents the trusted deployment
selection that config_to_cfg() normally derives from the selected
embodiment, scene binding, and execution policy. A configured program.yaml
must not declare those IDs itself.
Unknown fields, duplicate YAML keys, invalid references, executable payloads,
and bounded-expansion violations raise a Task Program config error. Static
compilation additionally checks the program against a provider-free
SceneManifest; it does not observe simulation state or generate controller
actions.
Run through the environment entry point#
Run the complete configuration with the normal environment CLI:
embodichain run-task \
--gym_config \
embodichain_tasks/configs/tasks/manipulation/repeated_pick_place/task.ur5.yaml \
--headless
To select another compatible program while keeping the trusted integration:
embodichain run-task \
--gym_config path/to/task.ur5.yaml \
--task-program path/to/program.yaml \
--headless
The adapter produces lazy DemoSegment actions. The normal demo executor,
not the semantic package, calls env.step() and owns recording and reset.
Add settling and task validation#
A segment can distinguish physical-call verification from task acceptance:
program:
kind: segment
name: deliver_can
steps:
kind: invoke
call:
kind: hand_over
object: can
final_target: {kind: target_ref, target: delivery_pose}
post:
- kind: wait_stable
entity: can
preset: rigid_object
validators:
- kind: object_near_target
object: can
target: delivery_pose
position_tolerance: 0.12
The effect monitor verifies the semantic HandOver transition. wait_stable
advances environment behavior after motion. object_near_target decides
whether the final task segment is acceptable. These are intentionally separate
boundaries.
Use registered semantic calls carefully#
Use RegisteredSemanticCallCfg only when a task needs an allowlisted shared
lowering that is not one of Pick, Place, or HandOver. Its arguments remain
declarative. The trusted simulation registration owns the matching lowerer
factory and fingerprints its call ID, revision, and target atomic descriptor.
Do not place a callable, dotted import, simulator object, or task-local motion generator in the program. If a reusable behavior is fundamentally a new motion primitive, add it to Atomic Actions first and then expose a declarative registered call through Task Program.
Next steps#
Scene registry — canonical IDs, affordances, and live providers;
Robot skill profiles — resource graphs, command presets, and effect assurance;
Task Program — schema, compilation, parallel safety, and adapter lifecycle;
Built-in atomic actions — the atomic primitives reached after lowering.