본문 바로가기

ubuntu/ROS

AR마커를 이용한 ROS 드론 코딩

사용한 개발환경은 다음과 같다.

===========================

ubuntu 16.0.4

ROS Kinetic

Python 2.7

Parrot bebop2

===========================

 

ROS를 이용해 드론을 코딩하는 프로젝트를 하면서 AR마커를 활용했던 부분을 정리하려고 합니다.

 

AR마커를 인식해 Subscribe하면서 받아오는 정보를 이용해 AR마커 앞에 놓인 물건을 픽업해오는 드론을 설계하였습니다.

먼저 드론을 GPS를 이용해 원하는 위치로 이동시킨 후, 제자리에서 회전시키면서 AR마커를 탐색합니다.

마커가 아주 조금만 가려지거나 카메라에서 사라지면 인식이 안되는 특성을 이용하여

드론이 회전하며 AR마커를 처음 찾았을 때, 놓쳤을 때 AR마커에서 발행되는 Position값을 활용하여 

AR마커의 정 중앙을 찾고, 드론이 바라보게 회전시킨 다음

AR마커가 바라보는 정면과, 드론이 AR마커를 바라보는 직선사이의 세타값을 이용하여 

드론이 AR마커 앞에 정렬하도록 한다.

 

AR마커 정보해석, 이용하는 기본원리에 대해 공부해 볼 수 있습니다.

가르쳐 주신 강사님 깃허브주소입니다.

https://github.com/greattoe/ros_tutorial_kr/blob/master/rospy/ar_2_analysis_marker.md

 

greattoe/ros_tutorial_kr

ROS Tutorial which translated into Korean. Contribute to greattoe/ros_tutorial_kr development by creating an account on GitHub.

github.com

다음과 같이 코드를 구현하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def get_marker(self, msg):
        n = len(msg.markers)
        if self.second_found_marker == False:
            if( n != 0 ):
                for tag in msg.markers:
                    if(tag.id == TARGET_ID):
                        self.msg = tag
                        #'''
                        
                        # '''
                        if self.cnt >= 1 and self.is_start == True:    
                            if self.first_found_marker is False:
                                self.first_found_marker = True
                                self.th_odom_1 = self.th_odom
                                print("marker First_found")
 
                #self.id = msg.markers[0].id
                #self.p  = msg.markers[0].pose
 
 
            else:
                if self.first_found_marker is True:
                    self.second_found_marker = True
                    self.th_odom_2 = self.th_odom
                    print("marker Second_found")
 
        else:
            for tag in msg.markers:
                if(tag.id == TARGET_ID):
                    self.msg_tmp = tag
 
        self.is_mark_checked = True
cs

 

함수의 매개변수인 msg는 

 

1
rospy.Subscriber('/ar_pose_marker', AlvarMarkers, self.get_marker )
cs

위와같이 AR마커가 발행하는 토픽을 받아오는 Subscriber를 작성할때 쓰는 콜백함수의 매개변수로 AR마커의 정보가 들어가게됩니다.

매번 콜백할때마다 마커가 인식되었는지 확인하며 사용자가 입력한 마커의 번호와 카메라가 인식한 마커의 번호가 일치한지 확인 한 후 정보를 활용하게 됩니다.

그와 동시에 드론자체의 주행기록(Odometry)를 변수로 따로 저장하여 AR마커에서 필요한 정보를 모두 얻은 후

드론이 어떻게 이동해야 할지를 계산하게 됩니다.

반응형

많은 시행착오를 거치면서 결국 육안으로 볼때 거의 정확한 결과를 이끌어 내었으나, 여러가지 변수에 의해 항상 일정한 결과를 얻어내는 것이 힘들었습니다.

바람으로 드론 기체가 흔들리면서 카메라가 흔들리는 것의 영향, 카메라가 광각이라 육안으로 확인할때와의 오차 등등 해결해야할 고비가 많았습니다. 

아쉬운 점은 프로젝트기간이 여유가 있었다면 자세를 교정하는 코드를 만들어 좀 더 정교하게 드론을 제어하고 싶었는데 못한 것이 아쉬웠습니다.

 

전체 코드는 이곳에서 확인할 수 있습니다.

https://github.com/aprkal12/ROS_Bebop2_Parrot

 

aprkal12/ROS_Bebop2_Parrot

Contribute to aprkal12/ROS_Bebop2_Parrot development by creating an account on GitHub.

github.com