프로젝트 명 : 딥러닝을 활용한 스마트 자율주행 시스템
목적 : 캡스톤 디자인 & LINK+ 경진대회 & 한미르 경진대회 & 공학혁신센터 경진대회
참여 인원 : 3 명
참여 기간 : 2020. 9 ~ 2021. 6
기관 : 부경대학교 공과대학, 산학협력단, 공학혁신센터
담당 업무
사용 언어 및 프레임워크 : Python, Pytorch
MEC 서버 흐름도
출처 : 딥러닝을 활용한 스마트 자율주행 시스템
특정 신호에 반응하는 자율 주행체 서버 흐름도
한정된 자원을 통해 Road_Following + Collision_Avodiance 가 동시에 가능한 모델 구현 및 성능 유지 보수
YOLOv5 Custom 데이터 셋을 통해 Object_Following
자율주행체 동작제어
#코드의 가장 핵심인 excute 부분. change에 맞추어 값이 변화한다.
def execute(change):
global angle_last, count, left, right
image = change['new']
xy = model_trt(preprocess(image)).detach().float().cpu().numpy().flatten()
x = round(xy[0], 3)
y = round((0.5 - xy[1]), 3)
x_slider.value = x
y_slider.value = y
angle = round(np.arctan2(x, y),3) #radian
if botLine.botLineObject.isStop is False:
#gpio.output(7, gpio.HIGH)
#gpio.output(11, gpio.LOW)
if( y <= 0.001) and ( abs(x) <= 0.2 ) :
count = count + 1
left = max(left - (left * (count * 0.03)), 0)
right = max(right - (right * (count * 0.03)), 0)
if( count >= 15 ):
robot.stop()
left = 0
right = 0
else: # 장애물 x
count = 0
if ( (abs(angle - angle_last) > abs(angle_last)) and ( angle_last != 0) and (abs(angle) > pid_value.value)) :
angle = angle_last + ( angle * diff_slider.value )
pid = round(angle ,2)
if pid > 0 :
left = round(pid * add_motor.value * speed_slider.value + speed_slider.value , 2)
right = round(-pid * dec_motor.value * speed_slider.value + speed_slider.value, 2)
else:
left = round(pid * dec_motor.value * speed_slider.value + speed_slider.value , 2)
right = round(-pid * add_motor.value * speed_slider.value + speed_slider.value, 2)
else:
pid = round(angle ,2) #0.95 etc..
left = round(max(pid, 0)* add_motor.value * speed_slider.value + speed_slider.value , 2)
right = round(max(-pid, 0)* add_motor.value * speed_slider.value + speed_slider.value, 2)
speed_slider.value = speed_gain_slider.value
steering_slider.value = pid
#전역변수 설정
angle_last = angle
robot.left_motor.value = left
robot.right_motor.value = right
else:
robot.stop()
#gpio.output(7, gpio.LOW)
#gpio.output(11, gpio.HIGH)
botLine.onUpdate()
execute({'new': camera.value})
데이터 전처리 및 수집, 유지보수
그림 1
그림 2
그림 3
그림 3
def get_x(path, width):
"""Gets the x value from the image filename"""
return (float(int(path.split("_")[1])) - width/2) / (width/2)
def get_y(path, height):
"""Gets the y value from the image filename"""
return (float(int(path.split("_")[2])) - height/2) / (height/2)
class XYDataset(torch.utils.data.Dataset):
def __init__(self, directory, random_hflips=False):
self.directory = directory
self.random_hflips = random_hflips
self.image_paths = glob.glob(os.path.join(self.directory, '*.jpg'))
self.color_jitter = transforms.ColorJitter(0.3, 0.3, 0.3, 0.3)
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
image_path = self.image_paths[idx]
image = PIL.Image.open(image_path)
width, height = image.size
x = float(get_x(os.path.basename(image_path), width))
y = float(get_y(os.path.basename(image_path), height))
if float(np.random.rand(1)) > 0.5:
image = transforms.functional.hflip(image)
x = -x
image = self.color_jitter(image)
image = transforms.functional.resize(image, (224, 224))
image = transforms.functional.to_tensor(image)
image = image.numpy()[::-1].copy()
image = torch.from_numpy(image)
image = transforms.functional.normalize(image, [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
return image, torch.tensor([x, y]).float()