.. Cover Letter

ㅇ 일상/대외활동 후기

(부트캠프 자체 해커톤) PinkLab 주관 로봇팔 활용 경진대회 진행과정 및 후기

BrainKimDu 2023. 2. 13. 10:29

PinkLab의 강사님께서 어떤 기업의 해커톤에 사용했던 로봇팔을 가지고 부트캠프 사람들과 자체해커톤을 열고싶다는 계획을 세우고 계셨습니다.
 
 
부상
강사님께서 사용하시는 MS사의 사무용 마우스와 등등

 
그래서 3일간의 사전교육을 듣고,
2월 16일 ( 오전 9시 30분 ~ 오후 9시) 
2월 17일 (오전 9시 30분 ~ 오후 6시) 
2월 20일 (오전 9시 30분 ~ 오후 9시) 
2월 21일 (오전 9시 30분 ~ 오후 4시)
까지 2인 1조로 대회를 진행했습니다.
 
처음에는 진행하는 과정을 적는 글이며
후기가 궁금하면 걍 맨 마지막으로..
 
 


로봇팔 초기세팅하기


이번 대회에서 사용할 DOBOT MG400 
가격이 무려 400만..이라고 합니다.
 

 

전원선 연결하기
렌선, 비상전원스위치, 등등을 연결함.

 
 
우분투 22.04에서 네트워크 설정하기
허브가 필요함

세팅 -> 네트워크 -> Wired 에 톱니바퀴 클릭 -> IPv4 들어가면 위의 화면이 나옴
 

다음처럼 입력하고, Apply 그리고 인터넷 연결을 해제하고 다시 연결하면 설정한대로 연결됩니다.
그러면 로봇팔을 사용할 준비가 끝납니다.
 


 DOBOT MG400  사용하기


다음의 dobot_api 라는 파일이 필요하고 다음의 사이트에서 구할 수 있습니다.
https://github.com/Dobot-Arm/TCP-IP-4Axis-Python-CMD/blob/main/dobot_api.py

 

GitHub - Dobot-Arm/TCP-IP-4Axis-Python-CMD: Demo of MG400/M1Pro, Python package based on TCP/IP protocol, command line operation

Demo of MG400/M1Pro, Python package based on TCP/IP protocol, command line operation mode - GitHub - Dobot-Arm/TCP-IP-4Axis-Python-CMD: Demo of MG400/M1Pro, Python package based on TCP/IP protocol,...

github.com

 

# 라이브러리 불러오기
import threading
from dobot_api import DobotApiDashboard, DobotApi, DobotApiMove, MyType
from time import sleep
import numpy as np

라이브러리를 불러옵니다. 
dobot_api 는 위에서 다운로드 받을 수 있습니다.
 

# PC-로봇 연결 함수 (TCP/IP 통신)
def connect_robot(ip):
    try:
        dashboard_p = 29999
        move_p = 30003
        feed_p = 30004
        print("연결 설정 중...")

        dashboard = DobotApiDashboard(ip, dashboard_p)
        move = DobotApiMove(ip, move_p)
        feed = DobotApi(ip, feed_p)
        print("연결 성공!!")

        return dashboard, move, feed

    except Exception as e:
        print(":연결 실패ㅜㅜ")
        raise e

PC와 로봇을 연결하는 함수입니다. 

# 로봇 에러 메시지 초기화 함수
def robot_clear(dashboard : DobotApiDashboard):
    dashboard.ClearError()

# 로봇 속도 조절 함수 (speed_value : 1~100)
def robot_speed(dashboard : DobotApiDashboard, speed_value):
    dashboard.SpeedFactor(speed_value)

# 그리퍼 구동 함수 (status 0 -> OFF, 1-> ON)
def gripper_DO(dashboard : DobotApiDashboard, index, status):
    dashboard.ToolDO(index, status)

# 현재 로봇 위치 받아오기 (로봇 베이스 좌표계 기준)
def get_Pose(dashboard : DobotApiDashboard):
    dashboard.GetPose()

로봇의 에러 메시지를 초기화하는 함수, 속도를 조절하는 함수, 그리퍼를 구동하는 함수, 현재 로봇의 위치를 받아오는 함수를 작성합니다.
 
다시 로봇팔을 보면

 
 

이부분은 전자석이기 때문에

def gripper_DO(dashboard : DobotApiDashboard, index, status):
    dashboard.ToolDO(index, status)

해당 함수를 사용해서 자석을 사용하거나 안하거나 할 수 있습니다.
활용은 밑에서 보도록 하자.
 

# 로봇 속도 조절 함수 (speed_value : 1~100)
def robot_speed(dashboard : DobotApiDashboard, speed_value):
    dashboard.SpeedFactor(speed_value)

속도를 조절하는 함수가 없다면 최고속도로 다니게 되고, 이는 안전사고 발생우려가 있다. 그러므로 적절한 속도를 지정하거나 비상정지버튼을 항상 휴대해야합니다.
 

# 현재 로봇 위치 받아오기 (로봇 베이스 좌표계 기준)
def get_Pose(dashboard : DobotApiDashboard):
    dashboard.GetPose()

하얀색 버튼을 누르면 로봇팔을 자유자재로 움직일 수 있습니다.. 이때 해당 함수를 부르면 x, y, z, 그리퍼각도 를 얻을 수 있습니다.
 
 
다음 코드로 넘어가자.

# 로봇 구동 함수 (현재 위치 -> 목표 위치(point_list))
def run_point(move: DobotApiMove, point_list: list):
    move.MovL(point_list[0], point_list[1], point_list[2], point_list[3])

def get_feed(feed: DobotApi):
    global current_actual
    hasRead = 0

    while True:
        data = bytes()
        while hasRead < 1440:
            temp = feed.socket_dobot.recv(1440 - hasRead)
            if len(temp) > 0:
                hasRead += len(temp)
                data += temp
        hasRead = 0
        a = np.frombuffer(data, dtype=MyType)

        if hex((a['test_value'][0])) == '0x123456789abcdef':
            current_actual = a["tool_vector_actual"][0]     # Refresh Properties
        sleep(0.001)

# 로봇이 목표 위치로 도달할 때 까지 기다리는 함수
def wait_arrive(point_list):
    global current_actual
    while True:
        is_arrive = True
        if current_actual is not None:
            for index in range(4):
                if (abs(current_actual[index] - point_list[index]) > 1):
                    is_arrive = False
            if is_arrive:
                return
        sleep(0.001)

run_point는 로봇팔의 매니퓰레이터를 목표한 위치로 이동시키고, 자동으로 역기구학을 풀어 관절각도로 이동시키는 동작을 api에서 수행합니다.
그 외 두 개는 자주 사용은 안한거 같아서 뭔지 잘 모릅니다.
 

# 입력 파라미터
ip = "192.168.1.6"              # Robot의 IP 주소
gripper_port = 1                # 그리퍼 포트 번호
speed_value = 10                # 로봇 속도 (1~100 사이의 값 입력)

# 로봇이 이동하고자 하는 좌표 (x, y, z, yaw) unit : mm, degree
point_home = [245, 5, 50, 115]
point_grip = [304, 19, -56.5, 16]
point_parse = [255, -54, -5, 115]

이동하고자 하는 좌표를 run_point 함수에 넣어주면 로봇이 동작합니다.
 
 
이제 로봇을 동작시키자.

# 로봇 연결
dashboard, move, feed = connect_robot(ip)
dashboard.EnableRobot()
print("이제 로봇을 사용할 수 있습니다!")

# 쓰레드 설정
feed_thread = threading.Thread(target=get_feed, args=(feed,))
feed_thread.setDaemon(True)
feed_thread.start()

다음의 코드를 실행하면
연결이 완료되었다 출력한 후 로봇을 사용할 수 있다는 것을 리턴합니다.
 

# 로봇 상태 초기화 1 : 로봇 에러 메시지 초기화
robot_clear(dashboard) 

# 로봇 상태 초기화 2 : 로봇 속도 조절
robot_speed(dashboard, speed_value)

함수를 불러와 초기 설정을 하고 로봇을 구동합니다.
 

# 로봇 구동 1 (point_init)
run_point(move, point_home)
# wait_arrive(point_home)
sleep(5)

# # 로봇 구동 2 (Grip)
run_point(move, point_grip)
# wait_arrive(point_grip)
sleep(5)

해당 코드를 사용하면 홈좌표로 이동하고 그립자세를 취합니다.
 

# 그리퍼 구동
gripper_DO(dashboard, gripper_port, 1)
sleep(0.1)

다음처럼 그리퍼를 구동시켜서 물건을 집게할 수 있습니다.
 
 
그래서 함수를 응용하면 다음의 일을 하게할 수 있습니다.

# 로봇 구동 1 (point_init)
run_point(move, point_home)
# wait_arrive(point_home)
sleep(1)

#  로봇 구동 2 (Grip)
run_point(move, point_grip)
# wait_arrive(point_grip)
sleep(1)

# 그리퍼 켜기
gripper_DO(dashboard, gripper_port, 1)
sleep(0.1)

# 홈으로
run_point(move, point_home)
# wait_arrive(point_home)
sleep(1)

#  2번째 지점으로 이동하기
run_point(move, point_grip2)
# wait_arrive(point_grip2)
sleep(1)

# 그리퍼 끄기
gripper_DO(dashboard, gripper_port, 0)
sleep(0.1)

다음의 동작을 한 번 GIF로 확인해보자.
 

 
동작을 잘 하는 모습..
 
 
 


대회 당일 아침


대회 당일 문제를 풀기위해 초기세팅을 했습니다.

다음과 같이 카메라와 로봇팔을 위치하게 하고 
판위에 놓여있는 블록들을 주어진 문제에 맞게 옮기는 것이 주제입니다.
 
그래서 문제는 다음과 같습니다.

(이 과정을 그대로 하시는 분들이 있으시기 때문에 지워졌습니다.) 

 
 


후기


2번은 9개의 팀중에서 가장 빨랐습니다. 18초..
 
그러나 1번을 푸는 과정에서
막바지에 1층을 옮기는 작업만 남기고 로봇팔이 도달할 수 없다는 오류가 발생했습니다.
코드가 문제인지 확인을 해보니
코드가 문제는 아니였여서

그래서 YOLO의 결과를 보니(디버깅을 위해서 계속 출력을 하게 두었음)
YOLO 이놈이 작업영역 밖에 있는 무언가를 circle이라고 인식해버리는 바람에 실패했습니다.
 
다행히도
강사님께서 측정시간 5분안에 완주하면 된다고 하셔서
코드는 건들지 않고 세팅을 다시하고 다시 측정해서
4분 48초가 걸렸습니다.
 
뭔가 억울하지만, 그런 부분이 있었다는게 대회의 재미가 아닐까..
 
여튼 최종 결과는
9개의 팀중에서 3등
 
1등팀은 우리와 같이 욜로를 사용하면서, 알고리즘도 잘 짰고, 모든 부분에서 손발이 잘맞았고
2등팀은 처음에 포기했던 OpenCV를 끝가지 사용해서 결국 완주하고 2등을 했습니다. 대단한 분들
 
 
대회를 마치면서 
전공지식으로만 배웠고, 졸작으로 했던 로봇팔은
전공지식만 살려서 구현해본 것이라 실전에서 어떻게 쓰이는지 이해하기 어려웠습니다.
 
실제로 이렇게 로봇팔을 직접 코드로 움직여보면서 로봇팔을 움직여보면서
로봇팔을 코딩할때는 어떻게 해야하는지, 어떻게 움직여야 하는지를 이해하게 되었습니다.
 
 
 
아쉬웠던 점이라면, 
내가 아는 방식대로만 하려는 버릇을 고치기 위해, 초반에는 OpenCV로도 접근을 해봤지만 실패했습니다.
아무도 성공을 못했더라면 시도는 좋았네라고 볼 수 있지만, 2등팀이 있기 때문에 조금 더 깊게 알아볼 걸이라는 아쉬움이 생깁니다.
빠르게 포기하고 정석으로 가는 사람과 가능성이 있다 판단된걸 끝까지 완성시키는 사람 중에 누가 맞다고 하긴 어렵지만,
지금은 취업한 상태가 아니고 공부를 하는 상태인데, 너무 빠른길만 찾지 말고, 
다양한 분야를 접해보고, 조사해보는 식으로 공부를 해야겠다 생각합니다.
 
 
추가로 항상 알고리즘을 짤때, 쓸데없는 다양한 환경까지 고려하려고 하는 것 같습니다.
어떻게 보면 꼼꼼할 수도 있는데, 누가보면 쓸데없는거에 시간을 잡아먹는 일을 하고 있을 수도 있습니다.
그래서 알고리즘을 짤때, 복잡한 것보다, 조금이라도 덜 복잡한 알고리즘을 생각할 수 있는 힘을 길러야할 것 같습니다.
 
 
여튼 이런 기회를 만들어주신 PinkLab의 PinkWink 강사님 감사합니다.
PinkWink

 

PinkWink

한 변두리 공학도의 블로그입니다. 재미있어 보이는 것들을 모두 기초스럽게 접근하는 블로그이며... 그보다 더욱 소중한 우리 아가 미바뤼의 발자취를 남겨두는 블로그이기도 합니다.

pinkwink.kr

 
깃헙에서 코드를 보실 수 있습니다.
brainKimDu/PinkLab-RobotArm-hackathon (github.com)

 

GitHub - brainKimDu/PinkLab-RobotArm-hackathon

Contribute to brainKimDu/PinkLab-RobotArm-hackathon development by creating an account on GitHub.

github.com