양삼렬-자율주행 RC카 제작 결과 보고서
활동 보고서
양*렬
2024-07-26
[프로젝트 개요] - 자율주행 RC카를 만든다 [설계 및 계획] - 외형은 스타크래프트의 벌처 외형을 따 만든다 [제작 과정] - 먼저 모델링을 한다 아두이노의 회로를 이용하여 RC카를 제작한다 RC카의 코드를 작성한다 RC주행을 시험한다 코드작성과 주행 시험을 반복한다 [코드 구조 및 설명] - import cv2 import urllib.request import numpy as np import time IP_ADDR = '192.168.0.64' def go_backward(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=a') time.sleep(0.05) def turn_left(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=c') time.sleep(0.1) def turn_right(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=b') time.sleep(0.1) def calibrate_left(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=c') time.sleep(0.04) def calibrate_right(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=b') time.sleep(0.04) def go_forward(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=d') time.sleep(0.1) def stop(): urllib.request.urlopen('http://'+IP_ADDR+':80/command?cmd=e') def onMouse(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print(x, y) cv2.namedWindow("live transmission", cv2.WINDOW_AUTOSIZE) stop_cnt = 0 while True: img_resp = urllib.request.urlopen('http://'+IP_ADDR+'/cam-hi.jpg') imgnp = np.array(bytearray(img_resp.read()), dtype=np.uint8) frame = cv2.imdecode(imgnp, -1) (h1, w1) = frame.shape[:2] frame = frame[600:h1, :] (h, w) = frame.shape[:2] topLeft = (350, 0) # x+y가 가장 값이 좌상단 좌표 topRight = (1335, 0) # x+y가 가장 큰 값이 우하단 좌표 bottomLeft = (0, 590) # x-y가 가장 작은 것이 우상단 좌표 bottomRight = (1600, 600) pts1 = np.float32([topLeft, topRight, bottomRight, bottomLeft]) w1 = abs(bottomRight[0] - bottomLeft[0]) w2 = abs(topRight[0] - topLeft[0]) h1 = abs(topRight[1] - bottomRight[1])+600 h2 = abs(topLeft[1] - bottomLeft[1])+600 width = int(max([w1, w2])) # 두 좌우 거리간의 최대값이 서류의 폭 height = int(max([h1, h2])) # 두 상하 거리간의 최대값이 서류의 높이 pts2 = np.float32([[0, 0], [width - 1, 0], [width - 1, height - 1], [0, height - 1]]) # 변환 행렬 계산 mtrx = cv2.getPerspectiveTransform(pts1, pts2) # 원근 변환 적용 frame = cv2.warpPerspective(frame, mtrx, (width, height)) # 파란색, 빨간색, 초록색 채널 추출 blue_channel = frame[:, :, 0] green_channel = frame[:, :, 1] red_channel = frame[:, :, 2] # 조건에 맞는 픽셀 필터링 blue_filtered = np.zeros_like(blue_channel, dtype=np.uint8) blue_mask = np.logical_and(blue_channel >= 130, np.logical_and(red_channel <= 130, green_channel <= 200)) blue_filtered[blue_mask] = 255 # 이진화를 위해 255로 설정 kernel = np.ones((5, 5), np.uint8) blue_filtered = cv2.morphologyEx(blue_filtered, cv2.MORPH_OPEN, kernel) edges = cv2.Canny(blue_filtered, 10, 100, apertureSize=3) (w, h) = blue_filtered.shape[:2] points = cv2.findNonZero(blue_filtered) if points is not None: meaned_point = np.mean(points, axis=0)[0] meaned_point_x = int(meaned_point[0]) meaned_point_y = int(meaned_point[1]) cv2.circle(frame, (meaned_point_x, meaned_point_y), 5, (255, 255, 255), -1) cv2.line(frame, (h//3, 0), (h//3, w), (255, 255,255), 5) cv2.line(frame, (h//3*2, 0), (h//3*2, w), (255, 255,255), 5) if meaned_point_x < (h//3): calibrate_left() elif meaned_point_x > (h//3*2): calibrate_right() else: go_forward() else: go_backward() frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA) cv2.imshow("live transmission", frame) cv2.setMouseCallback("live transmission", onMouse) key = cv2.waitKey(5) if key == ord('q'): stop() break stop() cv2.destroyAllWindows() 설명은 따로 하지 않는다 [성능 테스트 및 평가] -되게 잘 안간다 그래서 수동 컨트롤 하는 코드를 짜서 조종하는 RC카를 제작하였다 [결과 및 결론] -잘만 하면 제대로 된 자율주행 RC카를 만들수 있었을거 같은데 되지 않아 좀 안타까웠다 시간이 좀 많았다면 제대로 된 자율주행 RC카를 만들어보고 싶다