본문 바로가기

[패스트캠퍼스 11월 환급 챌린지]

패스트캠퍼스 환급챌린지 7일차 : callback 함수 동작 문제

[ 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다. ]

https://fastcampus.info/4oKQD6b

 

커리어 성장을 위한 최고의 실무교육 아카데미 | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

fastcampus.co.kr

 

 

 

 

 

https://fastcampus.co.kr/data_online_selfdriving

 

자율주행 로봇을 위한 ROS 2 & SLAM & Nav2 한번에 끝내기 | 패스트캠퍼스

로봇 입문 시작점 ROS 2부터 자율주행 로봇을 위한 SLAM & Navigation2 와 시뮬레이터를 활용한 자율주행 로봇 실습까지 한번에

fastcampus.co.kr

본 글은 위 강의를 참고하여 작성되었습니다

 

 

 

[강의시작 | 강의종료]

 

 

 

 

[완강 인증]

 

 

[학습 내용]

 

 

 

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

 

 

 

[강의 후기]

 

'odomentry(기준점에서 얼마나 떨어져 있는지를 나타내는 타입)' 정보를 사용해 벽과의 거리를 측정하고 일정 거리 이내 벽과 가까워졌다면 회전후 다른 벽까지 이동하는 실습 코드를 작성하고 문제점을 파악할 수 있었습니다.

 

-odomentry-

subscriber의 위치를 기준점을 기준으로 나타냅니다. publisher, subscriber 생성 방법은 아래와 같습니다.

from nav_msgs.msg import Odometry

class RobotControl(Node):
    def __init__(self):
        super().__init__('problem_node')

        self.seconds_sleeping = 10 # 회전할 시간을 10초로 설정

        # Publisher
        self.vel_pub = self.create_publisher(Twist, 'cmd_vel', 10)
        self.cmd_msg = Twist()

        # Subscriber
        self.odom_sub = self.create_subscription(
            Odometry, 'mobile_base_controller/odom', self.odom_callback, 10)
        self.scan_sub = self.create_subscription(
            LaserScan, 'scan_raw', self.scan_callback,
            QoSProfile(depth=10, reliability=ReliabilityPolicy.BEST_EFFORT))

위 코드에서 odom_callback, scan_callback 함수를 사용했습니다.

 

-odom_callback-

odomentry의 좌표값을 최신화하는 기능을 수행합니다.

    def odom_callback(self, msg: Odometry):
        self.get_logger().info("Odom CallBack")
        orientation_q = msg.pose.pose.orientation
        orientation_list = [orientation_q.x, orientation_q.y, orientation_q.z, orientation_q.w]
        self.roll, self.pitch, self.yaw = quat2euler(orientation_list)

 

-scan_callback-

전방 스캔값(거리)을 최신화하는 기능을 수행합니다.

    def scan_callback(self, msg: LaserScan):
        self.get_logger().info("Scan CallBack")
        self.front_laser = msg.ranges[359] # 전방 레이저 거리

 

-rotate-

벽과의 거리가 가까워졌을 때 회전하는 기능을 수행합니다.

    def rotate(self):
        self.cmd_msg.angular.z = -0.4 # 초기값 설정
        self.cmd_msg.linear.x = 0.0 # 초기값 설정

        rotation_start_time = self.get_clock().now() # 회전 시작 시간 기록
        rotation_duration = Duration(seconds=self.seconds_sleeping) # 

        while self.get_clock().now() - rotation_start_time < rotation_duration:
            self.vel_pub.publish(self.cmd_msg)

        self.get_logger().info("Rotation complete")
        self.stop_robot()

 

 

-문제점-

의도대로라면 벽과의 거리를 odom_callback(), scan_callback() 함수를 사용해 측정하고 일정 수치 이상 가까워지면 10초간 회전 후 벗어나야 합니다. 하지만 위 실습 영상을 보면 알 수 있듯이, 10초간 회전을 한번 더 실행하는 문제가 있습니다. 화면에 remaining 로그를 보면 0.4xxxxxxxxx로 같은 값이 2번 출력되는걸 확인 할 수 있습니다. 그 이유는 rotate() 함수 속의 while문 때문에 odom_callback 함수와 scan_callback 함수가 제대로 동작하지 않는 것 때문입니다. 이를 해결하는 방법은 다음 강의에서 다룰 예정입니다. 

 

 

-생각해볼 점-

이전 ROS 2 통신 방식 챕터를 마치고 심화 programming에 들어왔습니다. 심화 programming 챕터에서는 개발을 하며 생기는 문제들과 그 해결 방법을 다룹니다. 이번 강의에서는 odometry를 사용한 실습으로, 잘못된 while문 사용으로 다른 callback 함수가 동작하지 않는 문제를 다뤘습니다. 위 실습 코드를 보면, odom_callback(), scan_callback, rotate 등 여러 callback 함수를 사용하는 것을 확인할 수 있습니다. 이때 rotate() 함수의 while문 때문에 다른 callback 함수들이 동작하지 않는것을 확인했습니다. 지금은 단순하게 하나의 publisher, subscriber를 생성해 간단한 명령을 수행하는 로봇을 만들어보았으나, 실제로 프로젝트를 진행하면 여러가지 동작을 동시에 수행해야 합니다. 이때 지금과 같이 while문 때문에 다른 callback 함수들이 동작하지 못한다면, 큰 오류가 될 것입니다. 이를 위해 미리 일어날 수 있는 문제들을 확인하고 해결 방안을 찾는것이 앞으로의 개발에 도움이 될 것입니다. 지금은 실습 환경을 조성하고 그 환경 안에서만 공부를 진행했지만, 더 나아가 실제 프로젝트를 진행 할 때에도 강의에서 학습 한 내용들을 제대로 사용할 수 있을 때 까지 반복하여 수강하겠습니다.