1. Progress strategy
2. Algorithm
3. Source code
4. Data sheet of Humming bird
5. Author
6. License
- Using for editting python
- Guide
- Using for data file trasfer
- Guide
- Using for connect PC and Raspberry pi
- Guide
- Using for github update
- Guide
- Changing of Throttle, Roll, Pitch and Yaw for position control
def sendControlPosition(self, positionX, positionY, positionZ, velocity, heading, rotationalVelocity):
Variable name | form | range | unit | explain |
---|---|---|---|---|
position X | float | -10.0 ~ 10.0 | meter | forward(+), behind(-) |
position Y | float | -10.0 ~ 10.0 | meter | left(+), right(-) |
position Z | float | -10.0 ~ 10.0 | meter | up(+), down(-) |
velocity | float | 0.5 ~ 2.0 | meter | moving velocity |
heading | Int16 | -360 ~ 360 | degree | left turn(+), right turn(-) |
rotationalVelocity | Int16 | 10 ~ 360 | degree/s | rotational velocity |
- Fix rings below the ceiling and we can change heights of ring
- About the third ring, it can change right or left
- Have some patterns on the floor for stable hovering
Use sensor reset in controller for H.W problem
Setting trim for stable hovering
Check the whole manual
Go to "manual "
Used the try catch grammer for landing that you have any errors in flight
In mode3, if the circle color is red go back to mode 1
After in mode3, if the circle color is blue just Landing
- Pictures from contest map
lower_green = (60, 150, 55)
upper_green = (80, 255, 255)
lower_red1 = (150, 30, 30)
upper_red1 = (190, 255, 255)
lower_red2 = (-10, 100, 55)
upper_red2 = (10, 255, 255)
lower_blue = (90, 190, 75)
upper_blue = (110, 255, 255)
drone = Drone()
drone.open()
- The function of find the ring
- Return value is center of the ring
def detect_rect(img_hsv):
try:
img_mask_green = cv2.inRange(img_hsv, lower_green, upper_green)
dst3 = cv2.medianBlur(img_mask_green, 15)
_, contours, hierarchy = cv2.findContours(dst3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
area_temp = 640 * 480
area_temp2 = 0
for cnt in contours:
epsilon = 0.01 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
area = cv2.contourArea(approx)
mmt = cv2.moments(approx)
cx = int(mmt['m10'] / mmt['m00'])
cy = int(mmt['m01'] / mmt['m00'])
if (8000 < area) and (area < area_temp):
area_temp = area
pt_temp = (cx, cy)
if (8000 < area) and (area > area_temp2):
area_temp2 = area
approx_temp = approx
if len(approx_temp) == 4:
approx_list = [tuple(approx_temp[0, 0]), tuple(approx_temp[1, 0]), tuple(approx_temp[2, 0]),
tuple(approx_temp[3, 0])]
approx_list.sort()
left_length = abs(approx_list[0][1] - approx_list[1][1])
right_length = abs(approx_list[2][1] - approx_list[3][1])
else:
left_length = 0
right_length = 0
return pt_temp, left_length, right_length
except Exception as e:
return 'fail'
original | HSV |
---|---|
mask_green | morphology |
median | result |
- The function of find the color of circle
- Return value is color of circle
def detect_color(img_hsv):
img_mask_red1 = cv2.inRange(img_hsv, lower_red1, upper_red1)
img_mask_red2 = cv2.inRange(img_hsv, lower_red2, upper_red2)
img_mask_red = cv2.add(img_mask_red1, img_mask_red2)
img_mask_blue = cv2.inRange(img_hsv, lower_blue, upper_blue)
R = np.sum(img_mask_red == 255, axis=None)
B = np.sum(img_mask_blue == 255, axis=None)
if R > B: # red
circle_color = 'red'
else: # blue
circle_color = 'blue'
return circle_color
- The function of find the circle
- Return value is center of circle
def detect_circle(img_hsv, circle_color):
if circle_color == 'red':
img_mask_red1 = cv2.inRange(img_hsv, lower_red1, upper_red1)
img_mask_red2 = cv2.inRange(img_hsv, lower_red2, upper_red2)
img_mask_red = cv2.add(img_mask_red1, img_mask_red2)
dilation_red = cv2.morphologyEx(img_mask_red, cv2.MORPH_CLOSE, np.ones((15, 15), np.uint8))
dilation_red = cv2.dilate(dilation_red, np.ones((7, 7), np.uint8), iterations=1)
dst_red = cv2.medianBlur(dilation_red, 7)
circles = cv2.HoughCircles(dst_red, cv2.HOUGH_GRADIENT, 1, 50, param1=50, param2=10, minRadius=3, maxRadius=70)
elif circle_color == 'blue':
img_mask_blue = cv2.inRange(img_hsv, lower_blue, upper_blue)
dilation_blue = cv2.morphologyEx(img_mask_blue, cv2.MORPH_CLOSE, np.ones((15, 15), np.uint8))
dilation_blue = cv2.dilate(dilation_blue, np.ones((7, 7), np.uint8), iterations=1)
dst_blue = cv2.medianBlur(dilation_blue, 7)
circles = cv2.HoughCircles(dst_blue, cv2.HOUGH_GRADIENT, 1, 50, param1=50, param2=10, minRadius=3, maxRadius=70)
if circles is not None:
max_circle = max(circles[0, :, 2])
for j in circles[0]:
if int(max_circle) == int(j[2]):
return j[0], j[1]
else:
return 0, 0
img_mask_blue | morphology |
---|---|
dilate | medianBlur |
result |
- After take off, go forward for 0.7m & begin mode 2
try:
drone.sendTakeOff()
sleep(5)
camera = PiCamera()
camera.resolution = (640, 480) # (2592,1944)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
circle_color = 'red'
mode1 = False
mode2 = True
mode3 = False
ring_range = 40
i = 0
no_ring_cnt = 0
drone.sendControlPosition16(7, 0, 0, 5, 0, 0)
sleep(3)
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
img = frame.array
img = cv2.flip(img, 0)
img = cv2.flip(img, 1)
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imwrite("total_capture/{}.jpg".format(i), img)
i = i + 1
rawCapture.truncate(0)
- mode 1 : go forward for 1.3m & change to mode 2
if mode1: # 1.3m
drone.sendControlPosition16(13, 0, 0, 5, 0, 0)
sleep(5)
mode1 = False
mode2 = True
- mode 2 : Control left right and degree adjustment (watch the camera straight forward) & change to mode 3
elif mode2:
if 'fail' == detect_rect(img_hsv):
continue
else:
pt_temp, left_length, right_length = detect_rect(img_hsv)
if pt_temp[1] > 480 - 90+20:
drone.sendControlPosition16(0, 0, -7, 5, 0, 0)
sleep(3)
elif pt_temp[1] < 90+20:
drone.sendControlPosition16(0, 0, 7, 5, 0, 0)
sleep(3)
else:
if pt_temp[1] > 480 - 130+20:
drone.sendControlPosition16(0, 0, -3, 5, 0, 0)
sleep(1)
elif pt_temp[1] < 130+20:
drone.sendControlPosition16(0, 0, 3, 5, 0, 0)
sleep(1)
elif pt_temp[0] < 100:
drone.sendControlPosition16(0, 11, 0, 5, 0, 0)
sleep(5)
elif pt_temp[0] > 640 - 100:
drone.sendControlPosition16(0, -11, 0, 5, 0, 0)
sleep(5)
else:
if pt_temp[1] > 240 + ring_range + 30:
drone.sendControlPosition16(0, 0, -1, 5, 0, 0)
sleep(0.5)
elif pt_temp[1] < 240 - ring_range + 30:
drone.sendControlPosition16(0, 0, 1, 5, 0, 0)
sleep(0.5)
elif pt_temp[0] > 320 + ring_range:
drone.sendControlPosition16(0, -1, 0, 5, 0, 0)
sleep(0.5)
elif pt_temp[0] < 320 - ring_range:
drone.sendControlPosition16(0, 1, 0, 5, 0, 0)
sleep(0.5)
else: #각도 미세조정
if left_length - right_length > 25:
drone.sendControlPosition16(0, 0, 0, 0, 10, 20)
sleep(3)
elif right_length - left_length > 25:
drone.sendControlPosition16(0, 0, 0, 0, -10, 20)
sleep(3)
else:
drone.sendControlPosition16(8, 0, 0, 5, 0, 0)
sleep(3)
mode2 = False
mode3 = True
- mode 3 : go forward after find a color of the circle and find cirle (Blue color is Landing, Red color is rotate for 90 degrees to counter clockwise)
elif mode3:
circle_color = detect_color(img_hsv)
circle_x, circle_y = detect_circle(img_hsv, circle_color)
if circle_x == 0:
continue
else:
drone.sendControlPosition16(0, -1, 0, 5, 0, 0)
sleep(0.5)
elif circle_x < 320 - 40:
drone.sendControlPosition16(0, 1, 0, 5, 0, 0)
sleep(0.5)
else:
sleep(1)
drone.sendControlPosition16(10, 0, 0, 5, 0, 0)
sleep(6)
if circle_color == 'blue':
sleep(1)
drone.sendLanding()
drone.close()
break
elif circle_color == 'red':
drone.sendControlPosition16(0, 0, 0, 0, 90, 20)
sleep(6)
mode3 = False
mode1 = True
- If there is errors just landing (prevention of collision)
except Exception as e:
drone.sendLanding()
drone.close()
- Go to Details
Team leader: Seungjik Kim
Team members: Yeongin Kim, Soyoung Jung
This project is licensed under the MIT License - see the LICENSE file for details