claudeDroneteam-docs
documentation · reference
Docs reference

Structured knowledge from collected_doc_media/claudedrone_docs/. Browse the tree on the left; the source of truth is markdown in the repo.

Setpoint vs Takeoff — 4 rules for ArduPilot GUIDED

Rules distilled after 5 iterations of the takeoff node: setpoints only for flying drones, strict phase ordering, state-not-tick checks, a single timer.

stablesimulationupdated 2026-05-11T00:00:00.000ZClaudeDroneSimulationArduPilotGUIDEDSetpointRules

A short summary after five iterations of debugging the takeoff node (full history: Takeoff node evolution). These four rules are short, but each was paid for in disarm-on-arm loops that took a day or two to diagnose. Save yourself the time.

Rule 1 — Setpoints are only for a flying drone

# ❌ setpoint from tick 0
def loop(self):
    self.sp_pub.publish(self.target)

# ✅ setpoint only after takeoff is confirmed
def loop(self):
    if self.phase == 'hover':
        self.sp_pub.publish(self.target)

/mavros/setpoint_position/local is a position-hold command for an already flying drone. On the ground, ArduPilot treats it as a conflict with NAV_TAKEOFF. Spamming setpoints before takeoff is one of the most reliable ways to disarm yourself.

Rule 2 — Strict command ordering

❌ arm → setpoint                       (conflict → DISARM)
✅ guided → arm → takeoff → setpoint    (phases separated)

In each phase, send only the tool that phase requires. Never two at once.

Rule 3 — One timer, explicit phases

# ❌ nested create_timer (loops forever)
self.create_timer(2.0, self.do_takeoff)     # inside a callback
# → do_takeoff is called every 2 seconds, forever

# ✅ one timer + a phase string
self.phase = 'wait'
self.create_timer(0.1, self.loop)
def loop(self):
    if self.phase == 'wait': ...
    elif self.phase == 'guided': ...

create_timer in ROS 2 is persistent, not one-shot. Use a phase field to separate steps, never nested timers.

Rule 4 — Check state, not just tick

# ❌ time-based transition
if self.tick > 70:
    self.do_takeoff()

# ✅ state-confirmed transition
if self.tick > 70 and self.state.armed and self.state.mode == 'GUIDED':
    self.do_takeoff()

Tick-based FSMs break when MAVROS / EKF settling is slow (15-25 s indoor). By the time tick > 70, the node may not even have state.connected yet. The full event-driven rewrite is in Takeoff node v7 event-driven.

Why these rules aren’t in the documentation

Every one of these came from a real ArduPilot SITL failure. The system explains its behavior through logs, not through docs. That’s the actual engineering pattern in robotics: write code → run it → read logs → revise the hypothesis. Documentation tells you what should work; logs tell you what does.

© 2026 claudeDrone Team · auto-pipeline · Nuxt 3 SSR