Skip to content

feat(serve): first-class quadcopter drone embodiment support#126

Closed
DsThakurRawat wants to merge 1 commit into
FastCrest:mainfrom
DsThakurRawat:feat/serve-drone-support
Closed

feat(serve): first-class quadcopter drone embodiment support#126
DsThakurRawat wants to merge 1 commit into
FastCrest:mainfrom
DsThakurRawat:feat/serve-drone-support

Conversation

@DsThakurRawat
Copy link
Copy Markdown
Collaborator

@DsThakurRawat DsThakurRawat commented May 14, 2026

Description

Introduces native aerial drone (quadcopter/UAV) support as a first-class embodiment in the Reflex VLA framework. Establishes the continuous 5-DOF flight action space, 50 Hz control loop configuration, and integrates it securely into the core deployment layer.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Infrastructure / CI update

How Has This Been Tested?

  • pytest tests/ passes locally
  • reflex doctor sanity check
  • Other (please specify): Validated continuous action space parity and presets loading successfully

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have kept the PR scoped to a single concern (one concern per PR)

@rylinjames
Copy link
Copy Markdown
Collaborator

Thanks @DsThakurRawat — closing this in favor of the consolidated PR which supersedes both this and #125. You're credited via Co-Authored-By on the new commit.

The main reason this didn't get merged on its own: it stuffs payload-release semantics into the gripper field. They're distinct concepts — a quadcopter dropping a package isn't a gripper closing. The new PR introduces payload_release as its own optional block, keeping gripper for what it actually is.

Closing — see the replacement PR for the full picture.

@rylinjames rylinjames closed this May 15, 2026
rylinjames added a commit that referenced this pull request May 15, 2026
…ease (#132)

Adds first-class quadcopter as a fourth shipped embodiment, and the
structural schema changes that drones (and future gripper-less robots)
need without special-casing every call site.

### Schema changes

- `gripper` moved from `required` to optional. Embodiments without a
  gripper (drones, future fixed-wing, AGVs) simply omit the block.
- `constraints.max_gripper_velocity` moved from required to optional —
  only meaningful when a gripper is present. Cross-field validation now
  enforces "gripper present implies max_gripper_velocity present" so
  arm presets can't accidentally drop it.
- New optional `payload_release` block with `component_idx` +
  `trigger_threshold`. Mutually exclusive with `gripper` in practice
  (an embodiment has one end-effector type).
- `quadcopter` added to the embodiment enum.

No reformatting of schema.json — only the lines that actually change.

### Runtime

- `EmbodimentConfig.gripper` and `EmbodimentConfig.payload_release` are
  now `default_factory=dict` so loading is order-insensitive.
- New `has_gripper` property — callers should use this instead of
  unconditionally accessing `gripper_idx`.
- `gripper_idx` still raises KeyError when no gripper is present (loud
  failure, not a silent -1 sentinel).
- `to_dict()` omits empty optional fields so round-trip output validates
  against the schema's `additionalProperties: false` constraint.
- `SafetyLimits.from_embodiment_config` handles gripper-less embodiments
  by broadcasting `max_ee_velocity` across all action dims. The
  existing arm path is unchanged — regression test added.

### Quadcopter preset

- 5-DOF action: body rates (roll/pitch/yaw, rad/s) + thrust [0,1] +
  payload release [0,1]. Action index 4 is the payload trigger.
- 10-DOF state: position (3) + orientation quat xyzw (4) + linear
  velocity (3). Matches PX4/MAVROS Odometry message shape, the
  canonical drone state. A 4-DOF "orientation only" state is unusable
  for real drone control (no damping, no drift correction).
- 50 Hz control loop (matches PX4 outer-loop rate), 20-action chunks.
- `max_ee_velocity: 5.0` (flight speed, ~11 mph) — fits within the
  existing schema cap of 10 m/s. The schema cap is intentionally NOT
  raised; if you need faster, override at the runtime layer or split
  per-embodiment in a future schema version.
- Single canonical location at `src/reflex/embodiments/presets/`
  (not duplicated in `configs/embodiments/`).

### Tests

- 200 passing across embodiments + safety + guard tests.
- New `TestGripperOptional` class with 8 cases: quadcopter omits gripper,
  validates clean, gripper_idx raises, arm presets unchanged, payload
  release idx bounds check, gripper-implies-velocity cross-check,
  SafetyLimits builds for both drone and arm.
- Split parameterised `test_max_ee_velocity_capped` into arm (≤ 2 m/s)
  and drone (≤ 6 m/s) variants.

Supersedes #125 and #126.

Co-authored-by: Divyansh Rawat <186957976+DsThakurRawat@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants