{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6e223bb8",
   "metadata": {},
   "source": [
    "# 1 - Getting started with Strands Robots\n",
    "\n",
    "The shortest path into the SDK: build a simulated robot, run a policy on it, and read its state back. No hardware, no GPU, no Hugging Face credentials.\n",
    "\n",
    "**Install:** `uv pip install -U \"strands-robots[sim-mujoco,lerobot]\"`\n",
    "\n",
    "Part of the [examples/notebooks](./README.md) getting-started series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "264b463c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-29T14:28:00.611589Z",
     "iopub.status.busy": "2026-06-29T14:28:00.611463Z",
     "iopub.status.idle": "2026-06-29T14:28:00.618031Z",
     "shell.execute_reply": "2026-06-29T14:28:00.617516Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "\n",
    "# macOS uses the 'cgl' offscreen GL backend; Linux headless uses 'egl'.\n",
    "os.environ.setdefault(\"MUJOCO_GL\", \"cgl\" if sys.platform == \"darwin\" else \"egl\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d984b1fd",
   "metadata": {},
   "source": [
    "## Build a robot\n",
    "\n",
    "`Robot(\"so100\")` returns a [MuJoCo](https://mujoco.org)-backed simulation by default (`mode=\"sim\"`), so nothing touches real hardware. The same call with `mode=\"real\"` returns a hardware-backed robot driven by LeRobot - the agent code is identical across both."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3207293e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-29T14:28:00.619860Z",
     "iopub.status.busy": "2026-06-29T14:28:00.619733Z",
     "iopub.status.idle": "2026-06-29T14:28:02.293270Z",
     "shell.execute_reply": "2026-06-29T14:28:02.292417Z"
    }
   },
   "outputs": [],
   "source": [
    "from strands_robots import MockPolicy, Robot, create_policy\n",
    "\n",
    "sim = Robot(\"so100\", mesh=False)\n",
    "print(\"sim ready:\", sim.tool_name)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0055d4e4",
   "metadata": {},
   "source": [
    "## Run a policy\n",
    "\n",
    "A policy turns observations into actions. `MockPolicy` is a sinusoidal stand-in that runs anywhere, so you can exercise the full loop before attaching a trained checkpoint."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d8b32c19",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-29T14:28:02.295436Z",
     "iopub.status.busy": "2026-06-29T14:28:02.295258Z",
     "iopub.status.idle": "2026-06-29T14:28:03.009758Z",
     "shell.execute_reply": "2026-06-29T14:28:03.009277Z"
    }
   },
   "outputs": [],
   "source": [
    "result = sim.run_policy(\n",
    "    robot_name=\"so100\",\n",
    "    policy_object=MockPolicy(),\n",
    "    instruction=\"wave the arm\",\n",
    "    n_steps=30,\n",
    ")\n",
    "print(\"run_policy status:\", result.get(\"status\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2c33eb7",
   "metadata": {},
   "source": [
    "## One entry point for every policy\n",
    "\n",
    "`create_policy()` is the universal constructor. The same call resolves a mock, a Hugging Face checkpoint (`create_policy(\"lerobot/act_aloha_sim\")`), a GR00T server (`create_policy(\"zmq://...\")`), or a local path - the provider is inferred from the argument."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a5e66f2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-29T14:28:03.011347Z",
     "iopub.status.busy": "2026-06-29T14:28:03.011244Z",
     "iopub.status.idle": "2026-06-29T14:28:03.015595Z",
     "shell.execute_reply": "2026-06-29T14:28:03.015203Z"
    }
   },
   "outputs": [],
   "source": [
    "policy = create_policy(\"mock\")\n",
    "print(\"created policy:\", type(policy).__name__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "864e498b",
   "metadata": {},
   "source": [
    "## Read the robot's state\n",
    "\n",
    "`get_observation()` returns the current joint state (and camera frames, if any cameras are attached)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87fd742a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-06-29T14:28:03.016841Z",
     "iopub.status.busy": "2026-06-29T14:28:03.016771Z",
     "iopub.status.idle": "2026-06-29T14:28:03.522033Z",
     "shell.execute_reply": "2026-06-29T14:28:03.521602Z"
    }
   },
   "outputs": [],
   "source": [
    "obs = sim.get_observation(robot_name=\"so100\")\n",
    "print(\"observation keys (first 5):\", sorted(obs.keys())[:5])\n",
    "sim.destroy()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a99431d7",
   "metadata": {},
   "source": [
    "## Next\n",
    "\n",
    "- **[2 - Record and stream](./02_record_and_stream.ipynb)** - capture a LeRobotDataset and read it back.\n",
    "- **[3 - Record, train, deploy](./03_record_train_deploy.ipynb)** - the full data loop, training included.\n",
    "- The numbered scripts in [`examples/`](../) cover the mesh, agents, and natural-language control."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
