로봇공학전공의 캡스톤 디자인(졸업 작품) 후기!👨‍🎓

김민제·2024년 6월 11일
0

회고 및 후기🤔

목록 보기
5/12
post-thumbnail

캡스톤 사전 준비

주제 선정

  • 저희 조의 주제 선정은 비교적 빨리 끝났었습니다. 다 같이 모여 아이디어 회의를 했었는데 처음에는 지금 생각해보면 조금 허황된 얘기들(로봇이 2개로 분리되었다가 다시 결합하는 로봇 등..)도 많이 했었지만 최종적으로 결정이 난 것은 이동 로봇팔이었습니다!!
  • 이동은 4족 보행, 6족 보행, 바퀴 등을 많이 고민했지만 저희 수준에서 근 2달 반만에 4족 또는 6족 보행과 로봇팔을 함께 설계하고 구현하는 것이 어려움이 크다고 생각했고 4륜 바퀴를 사용하는 대신 메카넘 휠을 사용하여 기동성을 높이는 방향으로 아이디어를 채택하였습니다.

메카넘 휠 : 여러 개의 롤러들이 45° 각도로 기울어진 방향으로 휠 테두리를 돌아가며 장착된 바퀴이며 차체의 각 휠의 중심에서 발생하는 힘 벡터들을 합한 방향으로 이동하게 되어 방향을 유지한 채 전방향 이동이 가능한 바퀴입니다

  • 로봇팔은 6개의 관절을 사용한 6자유도를 채택하였고 그리퍼(집게)에 1개의 모터를 더 사용하여 총 7개의 모터와 4륜 자동차에 들어갈 4개의 모터를 합쳐 총 11개의 모터를 사용하기로 했습니다.
  • 제어는 PS4 콘솔로 하기로 했고 라즈베리파이 4를 쓰기로 했으며 모터는 다이나믹셀을 쓰기로 하였습니다!
  • 차체는 Python의 dynamixel SDK를 사용해 모터 제어를 이용하여 구동하기로 하였고 로봇팔은 역기구학 식을 세워 ROS를 사용하여 구동하기로 했습니다.

역할 분담

  • 팀원 A : 차체 설계 및 조립
  • 팀원 B : 로봇팔 설계 및 조립
  • 팀원 C : 로봇팔 역기구학 계산식 설계
  • 저 : 소프트웨어 전반 환경 구성과 제어 코딩
  • 역할 분담에서 소프트웨어 및 제어에 자신있는 사람이 저뿐이었고 나머지 팀원들은 다 하드웨어 설계 쪽이 맞는 것 같다고 하여 위와 같이 역할을 분담하게 되었습니다.
  • 로봇팔 구성의 난이도가 높을 것으로 예상되어 저도 위와 같은 역할 분담을 원했고 차체와 역기구학 설계가 로봇팔보다 일찍 끝날 것으로 예상되어 팀원 A와 C의 작업이 끝나면 완성물을 저에게 넘겨주고 팀원B의 작업을 돕기로 했습니다!

캡스톤 시작

라즈베리파이4 환경 설정

  • 필요한 모든 물품이 오고 캡스톤 전시회가 2달 남았을 시점에 시작하여 라즈베리파이4의 환경을 구성하는 것부터 시작하였습니다.
  • 라즈베리파이를 들고다니면서 팀원들과 협업할 일이 있을 것 같아 별도의 모니터와 키보드를 사용하여 라즈베리파이를 사용하는 것이 아니라 노트북에 가상환경을 구축하여 노트북에서 라즈베리파이의 IP로 접속을 하여 사용하는 방식으로 구현하였습니다.
  • 처음에는 Raspbian OS를 사용하였지만 ROS와의 호환성때문에 추후 Ubuntu 20.04버전으로 OS를 재설치 하였습니다. Ubuntu 환경에서 가상 환경을 만드는 것이 레퍼런스가 많지 않고 오류가 많아 이 부분에서 가장 고생을 많이 한 것 같고 간략한 흐름을 말씀드리자면 Angry IP Scanner로 라즈베리파이 IP 찾기 → putty로 IP 터미널에 접속하여 Ubuntu Desktop 설치 → 윈도우 원격 데스크톱 연결로 접속의 흐름이었는데 이 부분에서 오류가 너무 많았었습니다.
  • 추후 이 과정을 진행하시는 분들이 있을까 싶어 아래처럼 기록을 하며 과정을 진행했지만 좀 우당탕탕된 부분도 없지않아 있어서 원하시는 분이 있다면 정리를 해서 올리도록 하겠습니다!!

Dinamixel SDK, ROS 설치 및 모터, 콘솔 제어

  • ROS는 Ubuntu 20.04버전에 맞는 ROS1 Noetic을 설치했고 파이썬에서 Dinamixel SDK를 설치하여 다이나믹셀 모터를 구동할 준비를 마쳤습니다.

  • 파이썬을 이용하여 모터 1개 제어, 모터 3개 병렬 제어, 모터 3개 조건 제어, 콘솔로 모터 제어 순서로 테스트를 해보았고 이러한 작동을 확인한 것이 캡스톤 전시회 한달 전이었습니다.

  • 모터 1개 제어

  • 모터 3개 병렬 제어 영상

  • 콘솔로 모터 3개 조건 제어 영상

이슈 발생 1 : 배터리 문제

  • 저희가 크게 문제에 맞닥뜨린 부분이 있었습니다. 라즈베리파이에 연결할 배터리를 잘못 구매했다는 점이고 구매할 때는 라즈베리파이 전용 배터리는 따로 없어 전압만 맞는 배터리를 구매했었는데 이는 다른 로봇 전용의 배터리였다는 부분이었습니다.
  • 이 문제는 제가 라즈베리파이 환경 설정과 모터 제어 단위테스트를 해보고 찾은 문제인데 라즈베리파이는 3.3V의 전압 레벨을 지원하고 저희가 구매한 배터리는 11.1V의 배터리라서 결국 배터리와 배터리 커버를 재구매하고 라즈베리파이에 직접 연결하는 형식으로 해결하였습니다.

이슈 발생 2 : U2D2 허브 배터리 문제

  • 저희가 예상하지 못했던 부분이 하나 있습니다. 바로 라즈베리파이 본체와 다이나믹셀을 이어 다이나믹셀을 구동시켜주는 U2D2허브 보드에도 배터리를 연결해주어야한다는 사실이었습니다. 이는 12V를 연결해주어야했고 원래는 SMPS를 통해서 다이나믹셀을 구동시켜주었습니다.

  • 그래서 이전 구매했던 11.1v짜리 배터리를 U2D2 보드에 연결할 생각을 해보았고 배터리의 선을 자르고 연결을 해보았을 때 배터리 전선이 너무 굵어 U2D2 보드에 들어가지 않는 문제가 또 발생하였습니다.
  • 이를 해결하기 위해 새로운 배터리를 구매하는 방법, 그냥 전원선을 연결하여 사용하는 방법 등을 생각하고 찾아보았지만 답이 안나왔고 자포자기하는 심정으로 위 11.1V의 배터리 선들을 라즈베리파이 기본 구성품인 GPIO 케이블과 연결하여 U2D2 허브에 연결하는 기가 막힌 방법을 시도해보았습니다.
  • 이 방법이 성공했고 저는 이번 졸업작품에서 가장 뿌듯하고 쾌감이 느껴진 부분이었습니다. (제어 파트를 담당했지만 배터리를 연결하고 가장 큰 뿌듯함을 느껴버리는…)
  • 그래서 이 모든 것이 완성되고 하드웨어 완성을 기다리게 된 순간이 캡스톤 전시회 약 3주 전이었습니다.
  • 최종 결합 사진
  • 위 파란색 보드과 파란색 배터리가 U2D2 보드와 11.1V배터리이고 아래 초록색 보드는 라즈베리파이인데 배터리는 아래에 결합해놓았습니다!!

이슈 3 : 하드웨어 완성이 안돼요…

  • 이렇게 3주를 남긴 시점에서 하드웨어 담당 친구들한테 완성도를 물어보고 아직 설계가 덜 되었다는 답을 듣고 난뒤 “6월 7일이 캡스톤 전시회이니 5월 27일까지 완성해서 줄 수 있겠냐 차체랑 로봇팔이랑 결합하고 제어하고 수정할 부분이 있으면 3D 프린팅을 또 해야하니 최소 10일은 잡아야할 것 같다.”라고 하여 저는 5월 27일까지 기다리고 있었습니다.
  • 하지만 모든 팀원의 연락이 오지 않았고 제가 따로 물었을 때는 차체는 6월 1일까지 가능할 것 같고 로봇팔은 담당하는 친구가 다리를 다쳐 입원해야한다고 “프린팅을 다 해서 5월 27일에 역기구학 설계를 하는 팀원C에게 전달해놓을테니 조립한 것을 받아라”라는 답변을 받았습니다.
  • 그래서 팀원 C에게 로봇팔을 5월 28일에 받기로 하고 연락을 기다렸습니다…

이슈 4 : 팀원 C의 잠수 (로봇팔 하드웨어 결합 문제)

  • 약속했던 5월 28일이 되고 팀원 C에게 연락을 해보았지만 팀원 C가 잠수를 탔고 5일동안 연락을 받지 않았습니다. 카톡을 읽고도 대답을 하지 않았고 로봇팔 재료들을 다 들고 잠수를 탄거라서 초조하기 그지없었습니다..
  • 잠수가 오래될수록 초조한 팀원들의 분노(모자이크는 이름입니다..욕아닙니다..모두 화는 났지만 그렇다고 무차별적으로 욕하고 그런 나쁜 친구들은 아닙니다...)
  • 저포함 모든 팀원들은 팀원 C의 잠수가 길어질수록 초조해졌고 팀원들은 그라데이션 분노를 하기 시작합니다..(모자이크는 이름입니다..욕아닙니다..)
  • 팀원 C가 6월 2일 저녁 쯤 드디어 연락이 와서 미안하다는 말도 없이 “이정도 조립했는데 이거 안되고 저거 안되고 로봇팔 설계 문제가 어떻고해서… 이거 해야할거같아요“라고 하며 학교 근처 자취하는 저에게 주겠다고 하여 받은 결과물이 아래입니다.
  • 완성된 하드웨어가 아니라 조금 막막하고 받은 역기구학 식도 없어서 저는 일단 있는 로봇팔 모터제어만 따로 해보기로 했습니다.
  • 6월 3일에 차체 담당 팀원과 만나서 나머지를 조립해보기로 하고 차체와 연결도 해보기로 했습니다.

이슈 5 : 로봇팔이 달달달...

  • 받은 로봇팔 부분이라도 조금 더 결합해서 테스트해보고 이 부분에서는 다이나믹셀 위치 제어 모드를 사용하였습니다.
  • 하지만 콘솔의 버튼을 한 번만 눌러도 매우 짧게 누르는 것이 아닌 이상 여러번 눌린 것으로 감지되는 문제가 생겼고 이 친구가 초기 각도와 작동 각도 사이에서 인덱스가 버튼이 감지될 때마다 바뀌어 정신을 못차리는 상황이 발생했습니다.
  • 로봇팔 모터 제어 영상
  • 그래서 모터의 작동 앞에 로봇이 구동 중인지 체크하는 motor_speed_set이라는 boolean값을 한 개 두었고 작동이 시작될 때 True, 작동이 끝날 때 False로 변경하여 한 번 작동을 시작하면 끝까지 되도록 설정하여 해결하였습니다.
# 버튼이 인식되고 motor_speed_set이 False일 때 작동
if joystick.get_button(2):
	if not motor_speed_set:
    	for id in range(len(ARM_DXL_ID)):
        	dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, ARM_DXL_ID[id], ADDR_TORQUE_ENABLE, TORQUE_ENABLE)
            
           	...
            
         	index = 1 if index == 0 else 0 
        motor_speed_set = True
        
...


else:
	# 더 이상 입력이 없고, 작동을 마쳤을 떄 motor_speed_set를 다시 True로 변환
	if motor_speed_set:
		for id in CAR_DXL_ID:
			dxl_car_result, dxl_car_error = packetHandler.write4ByteTxRx(portHandler, id, ADDR_GOAL_VELOCITY, DXL_STOP_SPEED)
            
	...
    
	motor_speed_set = False

이슈 6 : 차체 크기와 로봇팔 아래 판 크기가 맞지 않아서 결합이 안됨

  • 6월 3일 차체 담당 팀원과 만나서 차체를 받아서 같이 결합해보고 로봇팔을 차체와 결합해보려 했습니다. 하지만 차체에서 로봇팔과 결합하는 판 부분이 너무 작아서 끼워지지가 않는 문제가 있었습니다.
  • 하지만 3D 프린팅을 다시 할 시간은 없어서 차체 윗 판을 갈아서 크기를 넓히기로 했습니다.
  • 영혼의 갈갈이 쇼
  • 이후 어찌저찌 크기가 맞아 결합을 했고 차체의 움직임까지 제어를 해보았습니다.

차체 제어

  • 차체는 상하좌우 이동, 대각선 이동, 차체 회전을 할 수 있도록 제어하였고 좌우 이동과 대각선 이동은 메카넘 휠의 원리로 모터를 제어하여 가능하게 하였습니다.
  • 모터는 다이나믹셀의 속도 제어를 이용하였습니다.
  • 차량 회전도 합니다!

이슈 7 : 팀원 C의 잠수 2 (로봇팔 제어 문제)

  • 이후 6월 4일에 로봇팔 역기구학 계산식을 받아 테스트해보기 위해 또 연락을 해보았고 또 다시 팀원 C는 잠수를 탔습니다..
  • 그래서 어쩔 수 없이 다이나믹셀 위저드를 이용하여 로봇팔의 초기 위치에 대한 모터의 각도와 로봇팔이 작동했을 때의 모터 각도를 기록하여 코드를 구성해보았고 모터 위치 제어를 이용하여 로봇팔을 제어하였습니다.

이슈 8 : 3축 모터의 사망

  • 로봇을 완성하여 제어해볼 때 2축 모터는 로봇팔의 무게를 고려하여 좋은 모터를 썼지만 3축 모터에서는 예산 부족으로 다른 모터와 같은 모터를 사용하였습니다.
  • 이를 작동시켜보았을 때 로봇팔 4,5,6축과 그리퍼의 무게를 3축 모터가 버티지 못해 죽는 상황이 발생했고 이를 해결하기위해 팀원들이 머리를 모아 “고무줄로 2축 모터와 3축 모터를 연결하여 3축 모터에 텐션을 주어 해결하자”라는 방법으로 이를 해결하였습니다.
  • 3축 모터가 죽을 수도 있다고 예상은 했지만 실제로 죽어버리니 생각보다 더 당황했었고 그래도 나름 잘 해결한 것 같습니다!!

이슈 9 : 로봇팔 회전 부분 전선 꼬임..

  • 마지막으로 또 하나의 이슈가 발생했습니다..
  • 모터와 모터끼리 연결된 전선이 각 모터가 회전할 때 꼬인다는 문제인데요..
  • 이 부분은 차체 위 로봇팔 회전, 로봇 팔꿈치 회전, 로봇 손목 회전 부분에서 발생한 문제였습니다.
  • 이는 전선의 길이를 늘려도 어차피 회전 각의 한계는 생기기 때문에 각도 제한을 주거나 원하는 각도로 위치 제어 값을 하나하나 지정해주어 문제를 해결했습니다.
  • 우선 차체 위 로봇팔 회전은 원하는 정확한 위치로 제어가 가능해야했기 떄문에 속도 제어를 유지하되 로봇팔이 이동할 때마다 각도를 읽어와 회전각의 제한을 주었습니다. 로봇팔 회전 한계 각도가 오른쪽으로는 270도, 왼쪽으로는 30도 였기 때문에 조건문으로 한계 각도에 대한 제한을 주었습니다!!
  • 로봇팔 회전 제어 코드
elif joystick.get_button(4):
    if not motor_speed_set: 
        if packetHandler.read4ByteTxRx(portHandler, ARM_ROT_DXL_ID, 132)[0] < int(4095/360*270):
            dxl_comm_arm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, ARM_ROT_DXL_ID, ADDR_GOAL_VELOCITY, ARM_DXL_MOVING_SPEED)
            if dxl_comm_arm_result != COMM_SUCCESS:
                print(f"ID {ARM_ROT_DXL_ID}: {packetHandler.getTxRxResult(dxl_comm_arm_result)}")
            elif dxl_error != 0:
                print(f"ID {ARM_ROT_DXL_ID}: {packetHandler.getRxPacketError(dxl_error)}")
            motor_speed_set = True
  • 위 코드는 로봇팔의 오른쪽 회전 제어입니다. int(4095/360*270)이라고 되어있는데 다이나믹셀 모터의 한바퀴 회전 단위가 4095여서 이를 360도로 나눠주고 제가 원하는 제한 값인 270도를 곱해준 것입니다!
  • 로봇 팔꿈치 회전, 로봇 손목 회전 부분은 초기각도와 작동 각도를 배열에 담아 버튼을 누르면 인덱스를 증가/감소 시키고 배열 내 인덱스의 각도로 위치 제어하는 방식을 사용하였습니다.
  • 로봇 팔꿈치 회전, 로봇 손목 회전 제어 코드
GRIPPER_POSITION = [45, 60, 75, 90, 105, 120, 135]
GRIPPER_INDEX = 0
ELBOW_POSITION = [270, 180, 90, 0]
ELBOW_INDEX = 2

...

# 손목 회전 코드
if hat[0] == -1 and GRIPPER_INDEX > 0:
    if not motor_speed_set:
        GRIPPER_INDEX -=1
        dxl_gripper_rot_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, GRIPPER_DXL_ROT_ID, ADDR_TORQUE_ENABLE, TORQUE_ENABLE)
        if dxl_gripper_rot_result != COMM_SUCCESS:
            print("%s" % packetHandler.getTxRxResult(dxl_gripper_rot_result))
        elif dxl_error != 0:
            print("%s" % packetHandler.getRxPacketError(dxl_error))
        else:
            print("Dynamixel has been successfully moved")
        dxl_gripper_rot_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, GRIPPER_DXL_ROT_ID, PROFILE_VELOCITY, ARM_DXL_MOVING_SPEED)
        dxl_gripper_rot_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, GRIPPER_DXL_ROT_ID, POSITION_CONTROL_MODE, int(4095/360*GRIPPER_POSITION[GRIPPER_INDEX]))
        if dxl_comm_result != COMM_SUCCESS:
            print("ID %d: %s" % (GRIPPER_DXL_ROT_ID, packetHandler.getTxRxResult(dxl_gripper_rot_result)))
        elif dxl_error != 0:
            print("ID %d: %s" % (GRIPPER_DXL_ROT_ID, packetHandler.getRxPacketError(dxl_error)))
        motor_speed_set = True
  • 작동 각도를 배열에 담아두고 초기 각도를 인덱스로 두어 손목은 초기 각도가 45도, 팔꿈치는 초기각도가 90도가 되도록 하였습니다!
  • 그 아래에는 예시로 손목 작동 코드를 넣었는데 버튼이 입력되고 손목 인덱스가 0보다 크다면 손목 인덱스를 1 감소시키고 손목회전각도[손목_인덱스]로 모터 위치 제어를 하였습니다.

로봇 완성

  • 로봇팔 설계 및 조립 담당 팀원 B가 6월 4일 퇴원을 했고 6월 5일에 로봇팔 설계가 잘못된 부분을 해결해서 다시 프린팅해보겠다고 하여 기다리고 있었습니다.
  • 허나 6월 6일까지 완성이 안됐고 6월 6일에 팀원들이 모여 로봇팔 조립을 도와줌으로써 오후 7시쯤 완성하였습니다.
  • 로봇팔을 모터 제어하는 코드를 미리 다 짜놓은 상황이었기에 새로 조립한 모터 3개롸 그리퍼를 제어하는 코드만 추가하면 되었고 이를 제가 완성하고 오류들을 모두 해결한 시점이 11시정도였습니다.

시연 영상

  • 물체 잡기
  • 물체 옮기기

캡스톤 끝…!!!

  • 이로써 캡스톤 전시회까지 무사히 마쳤습니다. 다른 팀은 사족 보행 로봇, 교통 사고 시 주의판을 자동으로 설치하는 로봇 등을 만들었고 로봇 공학 전공의 7팀 중 시연이 가능할 정도로 작동을 하는 팀이 저희 팀 포함 2팀밖에 없었기 때문에 좋은 점수를 받았을거라 예상합니다!!
  • 캡스톤 전시회 하드웨어의 늦은 완성, 소프트웨어의 잦은 문제 발생, 역기구학 포기 등의 많은 이슈가 있었지만 그래도 잘 해결되어 다행이고 그래도 로봇 공학 전공에서의 마무리를 잘한 것 같습니다!!
  • 졸업하려면 1학기가 남았지만 남은 학점이 없어 2학기에는 학교를 가지 않아도 되어서 실질적으로 막학기였는데 뭔가 시원섭섭한 것 같습니다!!
  • 진로가 개발자여서 소프트웨어 파트 전반을 담당했고 프로젝트를 진행하며 재밌다는 생각이 많이 들어 이쪽 길로 더 열심히 가야할 것 같습니다!!
  • 제가 선택한 길이 맞는 것인지 불안한 취준 시기라고 생각하지만 제가 더 재밌어하고 열정이 생기는 개발을 더 열심히 하는 것이 불안함을 떨쳐내는 길이라고 생각합니다!!
  • 웹 개발 프로젝트도 화이팅…!!!

비슷한 프로젝트를 하시는데 제가 했던 내용과 비슷한 부분에서 의문점이 드시는 분들은 댓글을 남겨주세요!! 알고있는 부분이면 자세히 알려드리겠습니다!!

profile
블로그 이전했습니다!! 👉 https://alswp006.github.io/

0개의 댓글

관련 채용 정보