Section 2.3: Action types: discrete, continuous, symbolic, motor-level, chunked

"Choosing an action space is how you tell a robot what kinds of mistakes it is allowed to make."

A Cautious Policy Interface
Technical illustration for Section 2.3: Action types: discrete, continuous, symbolic, motor-level, chunked.
Figure 2.3A: A taxonomy of action types arranged from discrete (button press, symbolic pick) through continuous joint torque to chunked multi-step action sequences, with a robot arm example for each tier.

This section assumes familiarity with the observation/state distinction introduced in section 2.2. The choice of action type directly shapes how rewards and constraints are specified, which is the subject of section 2.4. The discrete-versus-continuous tradeoff resurfaces in section 2.5 when action sequences are composed into trajectories and discounted over a horizon.

Big Picture

A robot hand squeezing a ripe peach can crush it in milliseconds if its fingers receive raw torque commands with no abstraction above them. The same task succeeds reliably when the controller operates on a "gentle grasp" skill that already encodes force limits. That gap, between commanding joints and commanding intentions, is the action-type problem. Embodied AI systems today fail or succeed largely on this single design choice, yet most practitioners inherit an action space without asking why it exists. Here you will map the full spectrum from motor-level signals to chunked multi-step primitives, understand the tradeoffs each tier imposes on learning and safety, and gain a principled vocabulary for choosing the right abstraction for any physical task.

Figure 2.3

The action type sits in the Decision box: it is the only place the system chooses what to change. Coarse symbolic actions commit more of the Consequence before the next Evidence arrives, so the choice of action type sets how long the closed loop runs blind before it can correct. This is the same diagram introduced as Figure 1.3.

Two robots run the identical fetch-the-mug task, but one is told to navigate_to(kitchen) while the other is handed raw joint torques: the first reuses its command after the sofa shifts three centimeters, the second has to relearn the whole motion from scratch. That single difference, the level at which you let a policy speak to the body, is the action-type problem, and it quietly decides controllability, safety, latency, data requirements, transfer difficulty, and how fast an agent recovers from a mistake. Figure 2.3A lays out the full taxonomy from discrete and symbolic actions through continuous joint torque to chunked multi-step sequences, and Figure 2.3 frames each choice as a closed-loop pattern in which the next observation depends on the last action. Action spaces are not interchangeable wrappers around a model.

Discrete actions are easy to enumerate, symbolic actions are useful for planning, continuous actions match motors and physics, motor-level actions expose control detail, and chunked actions reduce inference frequency while increasing commitment. OpenVLA-style systems add another pattern: map image and language context to action tokens or continuous control heads that must still respect robot limits.

Action Space Is Architecture

The action representation decides which layer owns intelligence. A symbolic action delegates execution to skills. A motor command delegates almost nothing. A chunked action delegates timing to the policy for several future steps.

Algorithm: Action Representation Selection Checklist

Input: task description, embodiment spec (actuators, controller rate \(f_c\)), latency budget \(\tau\), safety monitor \(\mathcal{S}\)

Output: action space \(\mathcal{A}\) with level, units, frame, bounds \(\mathbf{b}\), rate \(f_a\), chunk length \(H\), and clipping rule

  1. Identify the lowest safe actuator level (torque \(\tau_j\), joint velocity \(\dot{q}\), end-effector delta \(\Delta \mathbf{x}\), skill \(\pi_k\)) that the hardware controller can execute at rate \(f_c\).
  2. Choose the coarsest action level \(\ell\) such that recovery from an error is possible within the task's tolerance window \(\tau\). If \(\tau < 0.5\) s, prefer end-effector or joint level; if \(\tau > 2\) s, symbolic or skill level may suffice.
  3. Assign units, coordinate frame, and sign convention to every action dimension. Record these as executable constants, not comments.

Checkpoint

So far: pick the coarsest actuator level that still recovers in time, then lock down its units, frame, and sign convention before touching bounds, chunking, or clipping.

  1. Set per-dimension bounds \(\mathbf{b} = (b_1, \dots, b_d)\) derived from actuator limits and safety monitor \(\mathcal{S}\). Verify \(\|\alpha\|_\infty \leq \mathbf{b}\) for all sampled policy outputs \(\alpha \sim \pi(\cdot \mid o)\).
  2. If policy inference rate \(f_\pi < f_c\), select chunk length \(H = \lfloor f_c / f_\pi \rfloor\) and enable temporal ensemble (defined below: overlapping chunks predicted at successive timesteps are blended with exponentially decaying weights so the executed command is an average rather than one stale prediction) with weight \(w_t = \exp(-\lambda t)\) where \(\lambda \approx 1/H\).
  3. Define the clipping rule (clip-and-log, reject-and-hold, or scale) and confirm it produces a valid command even when \(\pi\) saturates all dimensions simultaneously.
  4. Enumerate invalid-command conditions (stale timestamp, out-of-frame, NaN) and specify the fallback action \(\alpha_\varnothing\) (hold position, zero velocity, or safe pose \(q^*\)).
  5. Inject synthetic saturation (\(\alpha = \mathbf{b}\)), delay (\(\Delta t = 2/f_a\)), and mid-chunk observation shift; confirm \(\mathcal{S}\) halts execution before joint limits are violated.
  6. Log raw policy output \(\alpha\), executed command \(\hat{\alpha} = \mathrm{clip}(\alpha, \mathbf{b})\), and clip magnitude \(\|\alpha - \hat{\alpha}\|\) separately from task reward \(r\).
  7. If action validity failures exceed 1% of steps during evaluation, revisit bounds or switch to a finer action level before continuing training.

Before reading on: if you had to pick a single field from the checklist above that practitioners most often leave undefined, which would it be? In practice, coordinate frame is a common candidate, because an action expressed in the wrong frame looks valid until the arm moves the wrong direction on hardware.

Theory

Let the action space be \(\mathcal{A}\). A discrete \(\mathcal{A}\) might contain actions such as open, close, or move-left. A continuous \(\mathcal{A}\) might be a vector of joint torques, velocities, or end-effector pose deltas. A symbolic \(\mathcal{A}\) might contain calls such as pick(red_block). Motor-level actions are the continuous tier taken down to its most literal form: a per-joint torque, current, or velocity command sent straight to an actuator, with no controller layer between the number and the motor. A chunked \(\mathcal{A}\) contains sequences of low-level actions, motor-level or continuous, emitted at once rather than one at a time.

The right action space depends on embodiment and timing. A high-level action can be easier to learn but hides safety-critical details. A low-level action can be precise but makes long-horizon reasoning harder. A chunked action can smooth robot motion and reduce model calls, but it delays correction if the world changes mid-chunk.

Of the tiers just contrasted, the symbolic end of the spectrum is the one that most directly buys back the long-horizon reasoning that low-level control gives up, so it is worth examining on its own. Symbolic actions matter in embodied AI because physical robots must plan across many steps in unpredictable environments. A policy operating on raw joint angles must relearn an entire motion sequence if a chair moves three centimeters. A policy operating on navigate_to(kitchen) reuses that symbol regardless of the exact floor plan, because a lower-level navigation stack resolves the physical details. This split between what to do and how to do it gives symbolic actions their data efficiency on long-horizon tasks. In practice the gap can be dramatic: as an illustrative order of magnitude, a policy trained on raw joint angles for a multi-room fetch task may need on the order of 40,000 episodes to converge, while an equivalent policy operating on symbolic navigation and grasp primitives can reach the same success rate in roughly 500 episodes, because the planner never has to rediscover that "go to kitchen" still works when the sofa moved three centimeters.

A policy that reasons over raw joint angles is not reasoning about the task; it is reasoning about the machinery that might accomplish the task.

Under the symbol: the skill contract

If the symbol is to carry that much abstraction, something underneath has to make it real, which is where the mechanics come in. Mechanically, a symbolic action is a function call into a library of executable skills. The planner selects a symbol; a skill controller beneath it runs a closed-loop policy that handles contact, timing, and recovery for that specific primitive. The boundary between layers is an API contract: the planner need not know whether grasp(mug) uses force control or position control, but it must know preconditions (the arm is near the mug) and expected postconditions (the mug is held). Violation of either at runtime triggers a replanning event rather than a raw motor fault.

A chunked action is like a ten-pin bowling delivery: the moment the ball leaves your hand you have committed to an entire trajectory covering several meters and roughly two seconds of flight. You cannot steer it mid-lane. What you can do is read the lane conditions carefully before releasing, then release a motion that is smooth and internally consistent enough to handle small surprises on its own. A single-step action, by contrast, is like steering a shopping trolley down a supermarket aisle: you adjust the direction every half-metre as new obstacles appear. Chunking trades mid-course steering for the smoothness and momentum that comes from committing to a well-planned arc.

Consider a specific case. ACT (Action Chunking with Transformers, Zhao et al. 2023) uses chunk lengths of 100 steps at 50 Hz on a bimanual robot, committing 2 seconds of motion before the next policy query. Single-step prediction on the same insertion tasks needed roughly 5 times as many demonstrations to reach the same success rate (as reported in Zhao et al. 2023). Chunking compressed that data requirement by smoothing out the compounding errors that accumulate across 100 individual decisions. The system still required a temporal ensemble strategy, where overlapping chunks predicted at successive timesteps are blended with exponentially decaying weights so the executed command is an average rather than a single stale prediction, to recover when the object shifted mid-chunk. By contrast, RT-2 (Brohan et al. 2023) maps image and language tokens to 256 discrete action bins per dimension at 3 Hz, trading motor precision for broad semantic generalization across seen and unseen object categories. The difference is stark: ACT closes the loop 50 times per second, RT-2 closes it 3 times, yet both ship useful robots because they target different failure modes. This tradeoff is called the action-rate versus generality frontier, and every action-space decision lives somewhere on it.

When using ACT-style action chunking, set the temporal ensemble parameter k in the exponential weight formula exp(-k * t) to match your chunk length: a chunk of 100 steps at 50 Hz typically uses k = 0.01, while shorter chunks of 10-20 steps need k values around 0.1 to prevent stale early-chunk predictions from dominating. If you skip this tuning and leave the default k from the reference ACT implementation, you will see jerky transitions at chunk boundaries when deploying on hardware running at a different control rate than the training setup. The LeRobot library exposes this as temporal_ensemble_coeff in the ACT policy config and logs the effective ensemble weight per timestep, which makes mismatches immediately visible.

Mechanism

Every action needs units, limits, rate, coordinate frame, validity checks, and execution semantics. A delta pose in the end-effector frame is different from a target pose in the world frame. A gripper command can mean binary open-close, continuous width, or force-controlled closure.

Step-Through: Action Representation Selection

Trace the selection checklist with one task: nudge a mug 2 cm to the right on a tabletop, controller rate \(f_c = 20\) Hz, policy inference rate \(f_\pi = 5\) Hz, latency budget \(\tau = 0.4\) s. Step 1, lowest safe actuator level the controller can run at 20 Hz: end-effector delta \(\Delta\mathbf{x}\). Step 2, recovery must fit inside \(\tau = 0.4\) s < 0.5 s, so we stay at end-effector level rather than going symbolic. Step 3, units and frame: \(\Delta x\) in metres, frame tool0, +x to the robot's right. Step 4, bounds from actuator limits: \(\mathbf{b} = (b_x, b_y, b_z) = (0.02, 0.02, 0.015)\) m; a single 2 cm nudge needs \(b_x = 0.02\), exactly at the cap. Step 5, since \(f_\pi = 5 < f_c = 20\), set chunk length \(H = \lfloor 20/5 \rfloor = 4\) and temporal-ensemble weight \(w_t = \exp(-\lambda t)\) with \(\lambda \approx 1/H = 0.25\). Step 6, clipping rule clip-and-log: a policy output of \(\alpha_x = 0.035\) becomes \(\hat\alpha_x = 0.020\), logging a clip magnitude of \(0.015\). The result: a 4-step chunk of 0.5 cm end-effector deltas at 20 Hz, committing \(4/20 = 0.2\) s of motion per query, well inside the 0.4 s recovery window.

Worked Example

Code Fragment 2.3.1 compares four action representations for the same tabletop instruction. Notice that each representation shifts responsibility to a different layer of the system.

# Section 2.3: runnable checkpoint for Action types: discrete, continuous, symbolic, motor-level,
# chunked.
# Keep the output small so the evidence record can be inspected directly.
action_spaces = {
    "discrete_skill": ["find_object", "grasp", "place"],
    "symbolic_call": "place(red_block, tray)",
    "continuous_delta": {"dx_m": 0.01, "dy_m": -0.02, "dz_m": 0.00, "grip": 0.7},
    "chunked_delta": [
        {"dx_m": 0.01, "grip": 0.5},
        {"dx_m": 0.01, "grip": 0.7},
        {"dx_m": 0.00, "grip": 0.9},
    ],
}
for name, action in action_spaces.items():
    print(name, action)
Code Fragment 2.3.1 contrasts skill, symbolic, continuous, and chunked actions for one manipulation task.
Library Shortcut

The 14-line comparison becomes one action-space declaration in Gymnasium, one policy configuration in LeRobot, or one action adapter in an OpenVLA-style inference service. The tools handle validation, normalization, batching, and model I/O. The hand-built version remains useful because it exposes units, frames, limits, and chunk length.

Practical Recipe

  1. Start from the actuator, safety monitor, and controller rate, then move upward to skills.
  2. Choose the coarsest action that still allows timely recovery.
  3. Record units, bounds, coordinate frame, rate, and clipping behavior.
  4. Test action latency by injecting delay and measuring recovery.
  5. Report action validity failures separately from task failures.
When to Switch Action Levels

Use symbolic or skill-level actions when task horizons exceed 10 seconds and the skill library is reliable: planning over skills scales better than planning over torques. Switch to end-effector deltas when contact geometry matters but full joint control is unnecessary: most manipulation benchmarks (RLBench, LIBERO) use 6-DoF (six degrees of freedom) end-effector deltas at 10-20 Hz for this reason. Drop to joint or torque level only when compliance, force control, or dynamic tasks (catching, throwing, legged locomotion) require it, because the feedback bandwidth justifies the added policy complexity. Add chunking when policy inference is slower than the control rate: a 3 Hz vision-language model cannot close the loop at 20 Hz, so committing a 7-step chunk bridges the gap.

Failure Mode

A high-level action such as pick can hide dangerous low-level motion. A motor-level action can be safe but too hard for long-horizon planning. A chunked action can improve smoothness while delaying correction after a slip, occlusion, or human interruption.

Treating action types as interchangeable wrappers you can swap late in a project is a costly mistake. The action type fixes which stack layer owns timing, recovery, safety checking, and contact resolution. Switch from symbolic actions to joint-level commands and the learned policy must absorb every contact and timing detail the skill library once handled, which demands different training data, a different controller, and a rebuilt safety monitor. The action type is an architectural boundary between the policy, the controller, and the skill library. Change it and you restructure all three layers at once.

Practical Example

The Toyota Research Institute home-robot stack and the Everyday Robots project (Google X, wound down 2023 with its fleet folded into DeepMind's RT-2 work) both converged on the same split: a symbolic task planner picks the order of subtasks like wipe(counter) or move_to(sink), while a continuous Cartesian velocity controller handles the centimeters around chair legs and human feet where a fixed skill cannot anticipate the geometry. The safety layer sits underneath both, clipping end-effector speed to roughly 0.25 m/s whenever a person is detected inside the workspace, a limit drawn directly from ISO/TS 15066 collaborative-robot guidance rather than chosen by the policy.

Real-World Application: Warehouse Manipulation

Amazon's robotic stowing system (the Sparrow and DRT arms in fulfillment centers) layers action types exactly as this section describes: a symbolic planner picks stow(item, bin), a learned grasp head emits end-effector pose deltas to seat the suction cup, and a low-level impedance controller, where the controller regulates the relationship between contact force and displacement so the arm yields softly instead of pushing rigidly through resistance, closes the loop on contact force. The symbolic layer never sees torque, and the torque layer never sees the order plan, which is what lets one fleet handle millions of distinct item shapes without retraining the planner.

Memorable Shortcut

An action space is like a steering wheel: too small and you cannot maneuver, too large and the learner spends half the drive discovering the curb.

Research Frontier

Three active directions define where action representation research stands in 2024-2026. First, flow-matching action heads (where the model learns a continuous velocity field that transports noise to an action chunk in one smooth pass, rather than iteratively denoising) (Physical Intelligence, pi0, Black et al. 2024) replace diffusion denoising chains with a single-pass ODE (ordinary differential equation) integration, cutting chunk inference from roughly 100 ms to 10 ms on Franka Panda hardware; this makes 20 Hz closed-loop control viable with a full vision-language backbone and is, as of this writing, one of the more widely adopted architectures for generalist robot policies, though the field is moving quickly enough that this could change. Second, action tokenization at scale (OpenVLA-OFT, Kim et al. 2024; subsequent fine-tuning studies, 2025) shows that discretizing each of 7 DoF into 256 bins and decoding them autoregressively from a 7B-parameter vision-language model (VLM) reaches 56.5% success on BridgeV2 (a standard multi-task manipulation benchmark of tabletop pick-and-place episodes) without task-specific pretraining, but the 6 Hz output rate still requires a compliant impedance controller underneath; 2025 work on parallel decoding and speculative action tokens aims to close this rate gap without sacrificing semantic grounding. Third, hierarchical chunking with adaptive commit length (He et al. 2024, GROOT; concurrent work at CMU's PerAct research group) (GROOT and PerAct are both research systems for adaptive-length action chunking, not products) lets the policy decide at runtime whether to commit a 4-step or 20-step chunk based on predicted uncertainty, outperforming fixed-length chunking on contact-rich tasks where the optimal commit length varies by subtask phase. Open problem suitable for a PhD thesis: none of these systems has a principled method for estimating the minimum safe commit length online, given current contact state and controller bandwidth. A student who formalizes this as a recovery-time lower bound, verifiable from the impedance controller's stiffness and the policy's output uncertainty, could unify the flow-matching, diffusion, and token-autoregressive families under a single deployability criterion.

Mini Lab

Take a simple pick-and-place task and write three action interfaces: symbolic skill, end-effector delta, and chunked delta. For each, define the controller that must sit below it.

Self Check

Can you state your action units, coordinate frame, update rate, action bounds, and clipping behavior without inspecting the policy code?

Action representation is an architectural boundary. A symbolic skill shifts burden to a planner and skill library. An end-effector delta shifts burden to a controller and calibration stack. A joint command shifts burden to the learned policy and safety monitor. A chunked action shifts burden to prediction because the policy commits before seeing every intermediate consequence.

The practical question is not which action type is most elegant. It is which layer should own timing, contact, validity checking, and recovery for the task at hand.

Tool or LibraryRole in This TopicBuilder Advice
Gymnasium spacesdeclares discrete, continuous, multi-discrete, dictionary, and bounded action structuresUse spaces as executable documentation for units, bounds, shapes, and clipping behavior.
ROS 2 controllersexecute velocity, position, effort, and trajectory commands under real timing constraintsUse them to check whether the action representation can be executed safely at deployment rate.
LeRobot and VLA action adaptersnormalize robot actions, action chunks, and policy outputs into deployable commandsUse them when learned action heads must be mapped back to body-specific controllers.

Audit an action interface before training. The audit should fail if units, frames, rates, bounds, or chunk semantics are absent.

  1. Name the action level: symbolic, skill, end-effector, joint, torque, velocity, or chunked sequence.
  2. Record units, coordinate frame, bounds, update rate, controller below the action, and clipping behavior.
  3. Define what happens when a command is invalid or stale.
  4. Inject saturation, delay, and mid-chunk observation changes.
  5. Report action validity failures separately from policy-task failures.
# Audit an action interface for fields needed by a real controller.
action_interface = {
    "level": "end_effector_delta",
    "units": {"dx": "m", "dy": "m", "dz": "m", "yaw": "rad"},
    "frame": "tool0",
    "rate_hz": 20,
    "bounds": {"dx": 0.02, "dy": 0.02, "dz": 0.015, "yaw": 0.10},
    "clip_behavior": "clip_and_log",
    "controller_below": "cartesian_impedance",
}

def missing_action_contract(interface: dict[str, object]) -> list[str]:
    required = ["level", "units", "frame", "rate_hz", "bounds", "clip_behavior", "controller_below"]
    return [key for key in required if key not in interface]

print(missing_action_contract(action_interface))
Code Fragment 2.3.2 audits whether an action interface contains the fields required for safe execution.

When an action interface fails, ask whether the command was invalid, clipped, stale, in the wrong frame, too coarse, too low-level, or too committed through chunking. Those are different failures and should not be collapsed into "bad policy."

Hands-On Lab: Audit An Action Interface

Duration: ~65 minutesDifficulty: Intermediate

Objective

Build an action-interface contract for one task and test how clipping, delay, or chunking would change recovery.

What You'll Practice

  • Define action units, bounds, frames, and update rate
  • Detect missing execution fields before policy training
  • Log raw commands, executed commands, and clipping
  • Compare correction delay for single-step and chunked actions

Setup

pip install numpy pandas
Code Fragment 2.3.L1 installs NumPy and pandas for the section lab trace.

Steps

Step 1: Define the action contract

Write the execution fields before choosing a policy.

contract = {
    "level": "end_effector_delta",
    "units": {"dx": "m", "dy": "m", "dz": "m", "grip": "fraction"},
    "frame": "tool0",
    "rate_hz": 20,
    "bounds": {"dx": 0.02, "dy": 0.02, "dz": 0.015, "grip": 1.0},
    "clip_behavior": "clip_and_log",
}
print(contract["frame"], contract["rate_hz"])
Code Fragment 2.3.L1.1 defines an action contract with units, frame, rate, bounds, and clipping behavior.

Hint

If a controller cannot execute the command, the action representation is not finished.

Step 2: Check for missing execution fields

Audit the contract before running a policy.

required = {"level", "units", "frame", "rate_hz", "bounds", "clip_behavior"}
missing = sorted(required - contract.keys())
assert not missing, f"Action contract missing fields: {missing}"
print({"contract_ready": True, "rate_hz": contract["rate_hz"], "bounds": contract["bounds"]})
Code Fragment 2.3.L1.2 reports whether the action contract is executable enough to test.

Hint

Most action bugs hide in units, frames, bounds, and silent clipping.

Step 3: Simulate clipping

Test whether out-of-bounds commands are visible in the log.

command = {"dx": 0.05, "dy": 0.00, "dz": 0.00, "grip": 0.6}
clipped = {**command, "dx": min(command["dx"], contract["bounds"]["dx"])}
clip_amount = command["dx"] - clipped["dx"]
assert clip_amount >= 0.0
print({"raw_dx": command["dx"], "executed_dx": clipped["dx"], "clip_amount": round(clip_amount, 3)})
Code Fragment 2.3.L1.3 records the raw command, executed command, and clipping flag.

Hint

A clipped command is not the action the policy selected. Log both.

Step 4: Compare commitment length

Record how long the system must continue before it can correct a bad command.

interfaces = [
    {"name": "single_delta", "chunk_len": 1, "rate_hz": 20},
    {"name": "five_step_chunk", "chunk_len": 5, "rate_hz": 20},
]
for item in interfaces:
    item["commitment_ms"] = 1000 * item["chunk_len"] / item["rate_hz"]
print(interfaces)
Code Fragment 2.3.L1.4 compares correction delay for single-step and chunked actions.

Hint

Chunking can smooth control, but it also delays recovery when observations change.

Expected Output

The completed lab produces a compact action-interface audit showing whether the contract is complete, whether clipping is visible, and how long a chunked command delays correction.

Stretch Goals

  • Add a joint-level version and compare its bounds against the end-effector version.
  • Add a stale-command rule that holds position when the command age exceeds the control budget.

Complete Solution

Code Fragment 2.3.L2 creates a compact action-interface audit table.
Key Takeaway

The action space is a design commitment. It decides how intelligence, safety, timing, and recovery are divided across the embodied stack.

Exercise 2.3.1

Design three action spaces for opening a drawer: one symbolic, one end-effector-level, and one joint-level. State one advantage and one risk for each.

What's Next?

Section 2.4 connects those action choices to reward functions, task specifications, and constraints.

Project Ideas

Beginner (weekend): Action-space comparison in Gymnasium CartPole. Implement the same task with a discrete action space (left/right) and a continuous torque action space using Gymnasium, and measure how many training steps each needs to reach a target return; the key challenge is writing a fair comparison that holds all hyperparameters constant except the action space definition itself. Intermediate (1-2 weeks): Chunked vs. single-step pick-and-place in PyBullet. Build a tabletop pick-and-place environment in PyBullet, train a policy using LeRobot with single-step end-effector deltas and again with a 10-step action chunk at the same control rate, then measure success rate and correction latency after mid-task object perturbations; the key challenge is tuning the temporal ensemble coefficient so chunk boundaries do not produce jerky motion on the physical-rate replay. Intermediate (1-2 weeks): Symbolic-to-motor skill bridge in ROS2. Build a two-layer stack in ROS2 where a high-level planner issues symbolic actions such as grasp(cup) and a MoveIt2 skill controller resolves each symbol into joint trajectories, then log precondition failures and replanning events across 50 trials; the key challenge is defining the API contract between layers so a skill failure triggers replanning rather than a raw motor fault.

Bibliography & Further Reading

Farama Foundation. "Gymnasium Documentation." (2024). https://gymnasium.farama.org/

The maintained reference for reset, step, spaces, termination, truncation, wrappers, and reproducible environments.

Kaelbling, L. P., Littman, M. L., and Cassandra, A. R.. "Planning and acting in partially observable stochastic domains." (1998). https://www.sciencedirect.com/science/article/pii/S000437029800023X

A foundational POMDP reference for belief-state reasoning under partial observability.

Bellman, R.. "A Markovian Decision Process." (1957). https://doi.org/10.1515/9781400835386-007

The mathematical origin of the state, action, transition, and reward framing.