> ## Documentation Index
> Fetch the complete documentation index at: https://innateinc-theo-docs-skills-authoring-api.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Full-Body Examples

Complete examples of skills that combine navigation, manipulation, and sensor data to create full-body robot behaviors.

For a real production example, read `pick_any_object` (shipped in `~/innate-os/workspace/innate_skills/pick_any_object.py`): it localizes an object described in natural language with the head camera, drives above it, visual-servos the wrist, grasps with `gripper_open()` / `gripper_close()`, and verifies the grasp before folding to rest.

## ScanAndWave

Rotate to find a person, then wave:

```innatepy theme={"languages":{"custom":["/languages/python-typed.json"]}}
import math
from innate import MainImage, Manipulation, Mobility, Head, Skill, SkillReturn

class ScanAndWave(Skill):
    mobility: Mobility
    manipulation: Manipulation
    head: Head
    image: MainImage

    def guidelines(self) -> str:
        return "Use when greeting someone in the room."

    def execute(self) -> SkillReturn:
        # Look up to see faces
        self.head.set_position(10)

        # Scan 360 degrees
        for i in range(8):
            self.feedback(f"Scanning direction {i + 1}/8")

            # Check for person (simplified - use vision API in practice)
            if self._detect_person(self.image):
                self._wave()
                return "Found person and waved"

            self.mobility.rotate(math.pi / 4)
            self.sleep(0.2)

        return "No person found"

    def _detect_person(self, image):
        # Intentionally stubbed for this example — swap in your own detector
        # (a local model or a cloud vision API call on the base64 image).
        return False

    def _wave(self):
        wave_left = [0.5, -0.3, 1.0, -0.5, 0.5, 0]
        wave_right = [0.5, -0.3, 1.0, -0.5, -0.5, 0]

        for _ in range(3):
            self.manipulation.move_joints(wave_left, duration=0.5)
            self.manipulation.move_joints(wave_right, duration=0.5)
```

## PickupRoutine

Position, look down, and prepare arm for pickup:

```innatepy theme={"languages":{"custom":["/languages/python-typed.json"]}}
from innate import Manipulation, Mobility, Head, Skill, SkillReturn

class PickupRoutine(Skill):
    mobility: Mobility
    manipulation: Manipulation
    head: Head

    # Safe arm positions
    HOME_POSE = [0, -0.5, 1.5, -1.0, 0, 0]
    READY_POSE = [0, -0.3, 1.0, -0.8, 0, 0]

    def guidelines(self) -> str:
        return "Use to prepare for picking up an object in front of the robot."

    def execute(self, approach_distance: float = 0.3) -> SkillReturn:
        # Step 1: Safe starting position
        self.feedback("Moving arm to safe position")
        self.manipulation.move_joints(self.HOME_POSE)

        # Step 2: Look down at target area
        self.feedback("Looking at target area")
        self.head.set_position(-20)

        # Step 3: Approach slowly
        self.feedback("Approaching target")
        self.mobility.send_cmd_vel(linear_x=0.05, angular_z=0, duration=approach_distance / 0.05)

        # Step 4: Move arm to ready position
        self.feedback("Preparing arm")
        self.manipulation.move_joints(self.READY_POSE)

        return "Ready for pickup"
```

## PatrolAndMonitor

Patrol between positions while monitoring camera:

```innatepy theme={"languages":{"custom":["/languages/python-typed.json"]}}
import math
import time
from innate import MainImage, Mobility, Head, Skill, SkillReturn

class PatrolAndMonitor(Skill):
    mobility: Mobility
    head: Head
    image: MainImage

    def guidelines(self) -> str:
        return "Use for surveillance - rotates and captures images at each position."

    def execute(self, positions: int = 4, duration: float = 30.0) -> SkillReturn:
        images = []
        rotation_per_position = (2 * math.pi) / positions
        start_time = time.time()

        while time.time() - start_time < duration:
            for i in range(positions):
                # Scan head up and down at each position
                for angle in [-15, 0, 10]:
                    self.head.set_position(angle)
                    self.sleep(0.5)   # not time.sleep — this one is interruptible

                    images.append(self.image)
                    self.feedback(f"Captured image {len(images)}")

                # Rotate to next position
                self.mobility.rotate(rotation_per_position)

        return f"Patrol complete. Captured {len(images)} images."
```

## InspectObject

Approach an object and examine it from multiple angles:

```innatepy theme={"languages":{"custom":["/languages/python-typed.json"]}}
import math
from innate import MainImage, Mobility, Head, Skill, SkillReturn

class InspectObject(Skill):
    mobility: Mobility
    head: Head
    image: MainImage

    def guidelines(self) -> str:
        return "Use to examine an object from multiple angles. Robot should be near the object."

    def execute(self, angles: int = 4) -> SkillReturn:
        images = []
        rotation_per_angle = (2 * math.pi) / angles

        # Look down at object
        self.head.set_position(-15)

        for i in range(angles):
            self.feedback(f"Capturing angle {i + 1}/{angles}")

            # Capture from current angle
            images.append(self.image)

            # Orbit around (rotate, then strafe)
            self.mobility.rotate(rotation_per_angle)

        return f"Inspection complete - {len(images)} views captured"
```

## GoHomePosition

Return to a safe home configuration:

```innatepy theme={"languages":{"custom":["/languages/python-typed.json"]}}
from innate import Manipulation, Head, Skill, SkillReturn

class GoHomePosition(Skill):
    manipulation: Manipulation
    head: Head

    HOME_ARM = [0, -0.5, 1.5, -1.0, 0, 0]

    def guidelines(self) -> str:
        return ("Use to return the robot's arm and head to safe home positions. "
                "Do not use if carrying something.")

    def execute(self) -> SkillReturn:
        # Arm first (priority for safety)
        self.feedback("Moving arm to home")
        self.manipulation.move_joints(self.HOME_ARM)

        # Then head
        self.feedback("Centering head")
        self.head.set_position(0)

        return "Home position reached"
```
