패스트캠퍼스 환급챌린지 22일차 : 자율주행 로봇을 위한 ROS2 & Nav2 한번에 끝내기 강의 후기
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
오늘은 프로그래밍을 진행할 때
마주할 수 있는 문제에 대해서 실습해보았다.
어떤 문제인지는 차근차근 설명하면서
얘기해보도록 하겠다.
[오늘의 수강 영상]
[오늘의 실습]
오늘은 PAL Robotics에서 제공하는 TIAGo 밑에 달려있던 로봇인
PMB2를 사용하여 실습을 진행했다.
로봇 시뮬레이션 환경을 구성하기 위해 아래 명령어를 입력했다.
$ sudo apt install ros-humble-pmb2-simulation
$ pip install transforms3d
설치가 완료되면 시뮬레이션 환경을 열어준다.
$ ros2 launch pmb2_gazebo pmb2_gazebo.launch.py is_public_sim:=True world_name:=simple_office_with_people
간단하게 로봇을 키보드로 조종하고 싶다면
아래 명령어를 사용해보면 된다.
$ ros2 run teleop_twist_keyboard teleop_twist_keyboard
앞으로 계속 이 로봇을 사용하는지는 명확히 알 수 없지만
또 새로운 로봇을 사용해서 실습을 진행한니
다시 리프레쉬 되는 기분이다.
이 로봇을 사용하여 프로그래밍을 진행할 때
자주 발생할 수 있는 문제점을 알아보기 위해
아래와 같은 시나리오로 코드를 구현했다.
1. 로봇이 0.5m 이내에 가까이 있는 장애물을 감지할 때까지 앞으로 이동
2. 로봇이 장애물과 0.5m 보다 가까워지면 로봇은 정지하고 방향을 바꾸기 위해 회전
여기서 우리는 3가지 Callback을 사용한다.
1.odom_callback : 로봇의 현재 회전량
2. scan_callback : 로봇 기준으로 전방 거리를 측정하기 위한 용도
3. timer_callback : 로봇 제어하기 위한 용도
이를 구현하기 위해 아래 명령어를 사용하여 패키지를 생성한다.
$ ros2 pkg create --build-type ament_python node_exercise --dependencies rclpy std_msgs sensor_msgs geometry_msgs nav_msgs
다음으로 주신 코드에서 init부분부터 보면
self.seconds_sleeping = 10
→회전할 시간을 10초로 설정
self.vel_pub = self.create_publisher(Twist, 'cmd_vel', 10)
→cmd_vel 토픽으로 Twist 메시지를 퍼블리시하여
로봇의 속도를 제어하는 publisher 생성
self.odom_sub = self.create_subscription( Odometry, 'mobile_base_controller/odom', self.odom_callback, 10)
→ 'mobile_base_controller/odom' 토픽을 구독하여
로봇의 위치/자세(오도메트리) 정보를 받는 subscription 생성
→odometry값인 'obile_base_controller/odom'값이 들어왔을 때
odom_callback이 돈다.
self.scan_sub = self.create_subscription( LaserScan, 'scan_raw', self.scan_callback, QoSProfile(depth=10, reliability=ReliabilityPolicy.BEST_EFFORT))
→ 'scan_raw' 토픽을 구독하여
레이저 거리 센서(LiDAR) 데이터를 받는 subscription 생성
→ Laser값인 scan_raw가 들어왔을 때 scan_callback이 동작한다.
self.timer = self.create_timer(0.3, self.timer_callback)
→ 0.3초마다 timer_callback 함수를 실행하여 주기적으로 로봇 동작을 제어한다.
→ orientation에서 쿼터니언으로 값을 받은 후
→ quat2euler를 사용하여 roll, pitch, yaw로 값을 변경한다.
→ 레이저 거리 데이터 중 359번째 값(로봇 전방거리)을 가져온다.
→ 가져온 값을 self.front_laser에 저장하여 장애물 감지에 활용한다.
def scan_callback(self, msg: LaserScan):
→ 여기에서 msg뒤에 :를 하고 LaserScan과 같이
타입을 기술해주면 함수 내에서 msg뒤에 .을 붙였을 때
자동완성 기능을 사용할 수 있다.
→이걸 안하면 자동완성 기능을 사용할 수 없다.
→로봇에 정지신호를 보내는 함수
→로봇에 직진신호를 보내는 함수
→ 10초 동안 반시계방향으로 회전하는 함수
→while문을 사용하여 10초 동안 회전을 유지한다.
→10초는 아까 self.seconds_sleeping으로
설정한 것이다.
rotation_duration = Duration(seconds=self.seconds_sleeping)
→ 여기 있는 Duration함수를 사용해서
우리가 사용하는 단위인 second로 단위를 변경한다.
→ 왜냐하면 ros에서 기본적으로 사용하는
시간 단위는 ㎱이기 때문이다.
→ 0.3초마다 front_laser값을 가져와서
거리를 측정하고 그 값에 따라 구동 명령을 수행한다.
모든 코드 설명은 완료하였고 이제 실행해보면
아래와 같은 결과들이 나온다.
이 동영상을 보면 직진하며 Lader 거리가
0.5m이상일 때는 Odom Callback과 Scan Callback이
잘 작동하며 거리값의 최신화가 잘되는 반면
0.5m이내로 들어오고 나서 10초동안 회전할 때는
while문에 갇혀 거리값의 최신화가
잘되지 않고 회전하기 직전의 값을 한번 더 사용해서
계속 회전을 하는 걸 볼 수 있다.
이런 문제가 오늘 수업을 통해 전해주시고 싶었던 부분이다.
"While문에 갇혀서 하나의 callback만 돌고
나머지 두개의 callback이 제대로 동작하지 못한다."
이 문제를 잘 해결할 수 있는 방법에 대해서
다음 시간을 통해 알려주신다고 말씀해주셨다.
이 문제는 실제로 내가 학교에서 프로젝트를
진행하면서 겪었던 문제들이며
그때마다 그냥 하나의 변수를 설정하여
어떤 상황에서는 while문을
빠져나오도록 문제를 해결했었는데
이번에 강의를 통해 이런 문제를 해결할 수 있는 방법이
따로 있다는걸 보니 내일이랑 내일 모레 들을 강의가
기대가 된다.
이것도 잘 기억해서 두고두고 써먹어야겠다!!
#패스트캠퍼스 #직장인자기계발 #직장인공부 #환급챌린지 #패스트캠퍼스후기 #오공완
🔥누적 수강 9백만 시간 돌파 기념 100% 페이백 (03.22 - 03.27) | 패스트캠퍼스
단 6일 한정! 지금 수강 시작하면 수강료 100% 돌려드려요!
fastcampus.co.kr