Noah SchwartzRyan UngerCharles Robson
Published © GPL3+

Drone on a Leash

A BeagleBone Blue powered drone that will follow you around on a leash.

AdvancedFull instructions provided20 hours9,463
Drone on a Leash

Things used in this project

Hardware components

BeagleBone Blue BeagleBone Blue
The autopilot and companion computer for the drone.
HobbyKing™ SMACK 300 Premium FPV Ready Folding Drone Frame (KIT)
Lightweight and small frame to mount everything on.
Emax 4pc RS2205 2600KV Brushless Motor
High powered motors that will provide more than enough thrust to fly our drone and the leash.
Night Flying Propeller 5x3 Clear (CW/CCW) (4pcs)
Cheap and light weight propellers that are compatible with the motors and the frame. Definitely get more than one set in case you break one.
Turnigy MultiStar 30A BLHeli-S Rev16 V3 ESC 2~4S (Opto)
Electronic speed controllers that drive the motors. The pwm input comes from the beaglebone.
1500 mAh 4S 100C Lipo Battery
Plenty of other battery options. Just make sure the capacity is high enough, without being too heavy. The motors/ESCs are meant to go with a 4S battery. We recommend getting more than one so it can charge while the other is flying.
LiPo voltage alarm
Very loud, but very important. We accidentally killed the capacity of one of our batteries by having it discharge too much. This item solves that.
2.4Ghz A-FHSS Compatible 8CH Receiver (Hitec Minima compatible)
PPM compatible receiver, the beaglebone blue uses PPM for the RC controller.
Aurora 9 - 9 Channel 2.4GHz Aircraft Computer Radio
Discontinued, but any transmitter receiver combo that outputs PPM should work fine.
Analog joystick (Generic)
We used one from Adafruit. While it is now out of stock, practically any 2 axis analog voltage divider joystick with a decent range of motion would work.
Dog Leash 26
The longest dog leash I could find online. Anything would work here, even strong rope.
Power Distribution Board
Battery output to the ESCs and Beaglebone Blue. As simple as some heavy gauge wire, or a power distribution board with all the wire soldered to it.
JST Jumper Bundle for the BeagleBone Blue
Renaissance Robotics JST Jumper Bundle for the BeagleBone Blue
We didn't have this, but it would have saved a lot of trouble. You need one 4 wire and one 6 wire.
Turnigy MultiStar 32Bit ESC Program Card
Technically optional, but it will be much easier to program the ESCs with this, rather than using timed RC commands.


Read more


This code samples the joystick position, runs it through a PID controller, and reacts to the position by trying to get it back to the setpoint.
#!/usr/bin/env python3

import sys
import time
import Adafruit_BBIO.ADC as ADC
import math
from dronekit import connect, VehicleMode

##Set up these values before flying!!!!
run = 1
setpoint_x = 50
setpoint_y = 0
setpoint = [setpoint_x, setpoint_y]
Kp = 0.1
Ki = 0
Kd = 0
integral = [0.0, 0.0]
error_prior = [0.0, 0.0]
iteration_time = .1
current = [0, 0]
bias = 0
hover_thrust = 0.5

	print("ADC Setup")

tcp_link = 'tcp:'

	vehicle = connect(tcp_link)
	print("mavlink connection successful! tcp link: " + tcp_link)
	run = 1
	print(" \n \nmavlink connection failed! \n \n")
	run = 0

# wait for vehicle attitude information to become available
while vehicle.attitude.yaw is None:
# save initial yaw to use as target
target_yaw = math.degrees(vehicle.attitude.yaw)

# convert euler angles to quaternion to send over mavlink
# credit dronekit example:
def to_quaternion(roll = 0.0, pitch = 0.0, yaw = 0.0):
	t0 = math.cos(math.radians(yaw * 0.5))
	t1 = math.sin(math.radians(yaw * 0.5))
	t2 = math.cos(math.radians(roll * 0.5))
	t3 = math.sin(math.radians(roll * 0.5))
	t4 = math.cos(math.radians(pitch * 0.5))
	t5 = math.sin(math.radians(pitch * 0.5))

	w = t0 * t2 * t4 + t1 * t3 * t5
	x = t0 * t3 * t4 - t1 * t2 * t5
	y = t0 * t2 * t5 + t1 * t3 * t4
	z = t1 * t2 * t4 - t0 * t3 * t5
	return [w, x, y, z]

	while run:
		# read joystick values 0-100
			x_val = 100*"AIN1")
			y_val = 100*"AIN3")
			current = [x_val, y_val]
			print("ADC Values not Found!")
		# calculate PID
		error = [a_i - b_i for a_i, b_i in zip(setpoint, current)]
		integral = [a_i + (b_i * iteration_time) for a_i, b_i in zip(integral, error)]
		derivative = [(a_i - b_i) / iteration_time for a_i, b_i in zip(error, error_prior)]
		output = [Kp*a_i + Ki*b_i + Kd*c_i + bias for a_i, b_i, c_i in zip(error, integral, derivative)]
		# generate mavlink message to send attitude setpoint
		new_quat = to_quaternion(output[0], output[1], target_yaw)
		msg = vehicle.message_factory.set_attitude_target_encode(
			0, # time_boot_ms
			1, # target system
			1, # target component
			new_quat, # attitude (quaternion)
			0, # roll rate
			0, # pitch rate
			0, # yaw rate
			hover_thrust  # thrust (0-1 where 0.5 is no vertical velocity)

except KeyboardInterrupt:



Noah Schwartz

Noah Schwartz

1 project • 1 follower
Ryan Unger

Ryan Unger

1 project • 1 follower
Charles Robson

Charles Robson

0 projects • 0 followers