Skip to content

Commit 200dad0

Browse files
committed
finalize 03 arm tutorial
1 parent cd36588 commit 200dad0

1 file changed

Lines changed: 45 additions & 58 deletions

File tree

docs/tutorials/03_arm.md

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This tutorial demonstrates fundamental drone safety and control operations using
3030
- **Automatic Transitions**: How requesting a takeoff can modify the vehicle's flight mode.
3131
- **DroneController**: Our automatic utility that reads `DroneStateModel` and forwards ROS service calls based on our desired results.
3232
- **ROS param sets**: Each ROS node can have specific service calls to set configuration parameters on it. we use this to configure heartbeat signal frequency and type on the mavros node.
33+
- **initializeDroneControl**: This is our connection utility imported from `src/lib/drone_utils.js`. This helps us avoid some of the intialization boilerplate code we had in the previous examples.
3334

3435
## Prerequisites
3536

@@ -146,6 +147,49 @@ async disarm(): Promise<void> {
146147

147148
**Automatic Arming**: You set your requested state. The `DroneController` internals will take care of any ongoing issues to arm or disarm the drone
148149

150+
## Manual arm/disarm
151+
In here we can see that we call the `.arm()` function if needed. And we keep monitoring the drone state till we observe an armed state
152+
153+
<Tabs groupId="language">
154+
<TabItem value="js" label="JavaScript" default>
155+
156+
```javascript
157+
{
158+
const st = await droneState.getState();
159+
console.log(`[STEP 1] Current state before arming: armed=${st.vehicle?.armed}, mode=${st.vehicle?.mode}`);
160+
if (!st.vehicle?.armed) {
161+
console.log("[STEP 1] Arming drone...");
162+
await droneController.arm();
163+
console.log("[STEP 1] Arm command sent successfully");
164+
} else {
165+
console.log("[STEP 1] Drone already armed - skipping arm command");
166+
}
167+
}
168+
169+
// Step 2: Wait to observe the armed state
170+
console.log("[STEP 2] Waiting 6 seconds to observe armed state...");
171+
await sleep(6000);
172+
let armedState = await droneState.getState();
173+
174+
while(!armedState.vehicle?.armed) {
175+
console.log("[STEP 2] Retrying. drone not armed...");
176+
await droneController.arm();
177+
await sleep(1000);
178+
armedState = await droneState.getState();
179+
}
180+
```
181+
182+
</TabItem>
183+
<TabItem value="python" label="Python">
184+
185+
```bash
186+
# Coming soon...
187+
```
188+
</TabItem>
189+
</Tabs>
190+
191+
## Automatic arm/disarm
192+
149193
<Tabs groupId="language">
150194
<TabItem value="js" label="JavaScript" default>
151195
@@ -195,65 +239,8 @@ Flight controllers include multiple safety features:
195239
- **Pre-Arm Checks**: Validates GPS, battery, sensors before arming. Even ground control connection will be validated here. We use mavros so we already configure mavros to act as the ground control for our drone. Had we not done that then the arm would fail. We do this by using ros param sets
196240
- setting `/mavros/sys.heartbeat_mav_type` to `GCS`
197241
- setting `/mavros/sys.heartbeat_rate` to `2.0`
198-
199-
- **Emergency Protocols**: Automatic failsafe responses
200-
201-
## Code Walkthrough
202-
203-
### Setup Phase
204-
205-
```javascript
206-
// Connect to ROS Bridge
207-
const bridge = new ROSLibBridgeWrapper();
208-
await bridge.waitForConnection();
209-
210-
// Monitor drone state
211-
const droneState = new DroneStateModel();
212-
droneState.connect(bridge);
213-
214-
// Control the drone
215-
const droneController = new DroneController(droneState, bridge);
216-
```
217-
218-
### Arming Operation
219-
220-
```javascript
221-
// Check current state
222-
const state = droneState.getState();
223-
if (!state.vehicle?.armed) {
224-
// Arm the drone
225-
await droneController.arm();
226-
227-
// Wait for confirmation using low-latency listener
228-
await new Promise((resolve, reject) => {
229-
const timeout = setTimeout(() => reject(new Error("Timeout")), 5000);
230-
231-
// Listen for vehicle state changes (armed, mode, etc.)
232-
const unsubscribe = droneState.onSectionChange('vehicle', (oldVal, newVal) => {
233-
if (newVal.armed && !oldVal.armed) {
234-
clearTimeout(timeout);
235-
unsubscribe();
236-
resolve();
237-
}
238-
});
239-
});
240-
}
241-
```
242-
243-
### Low-Latency State Monitoring
244-
245-
Instead of polling every 100ms, this tutorial uses the new `onSectionChange()` API:
246-
247-
- **`onSectionChange(section, listener)`**: Registers a listener for changes in a specific state section
248-
- **Immediate notifications**: Fires when ROS messages update state, not on a timer
249-
- **Selective listening**: Only listens to relevant state sections (excludes time updates)
250-
- **Automatic cleanup**: Listeners are unsubscribed when no longer needed
242+
Keep in mind that our map panel and anything utility that we have that interacts with the mavros node will do this just to ensure that things are setup properly. As long as the mavros node is up these configurations will remain.
251243
252-
The code waits for state confirmation because:
253-
- Commands are sent asynchronously
254-
- Network delays may occur
255-
- Verifies the flight controller accepted the command
256-
- Provides immediate feedback when we receive new states from mavros.
257244
258245
## Next Steps
259246

0 commit comments

Comments
 (0)