[ROS2] Global Localization 실습, neuronbot2 활용

TaerinLog·2025년 11월 10일

가상환경 시작

  • ros2 launch neuronbot2_gazebo neuronbot2_world.launch.py
  • ros2 launch neuronbot2_nav localization_launch.py use_sim_time:=true
  • rviz2 -d nav2_default_view.rviz

1) AMCL 노드 실행 확인

  • ros2 node list
    출력에 /amcl 또는 AMCL 노드가 보여야 함

2) 서비스 확인

  • ros2 service list
    AMCL 노드가 실행되면 서비스가 등록됐는지 확인

    reinitialize_global_localization가 서비스에 존재하므로 해당 서비스 사용

3) 서비스 호출

  • 서비스 타입 확인

  • 서비스 호출
    ros2 service call /reinitialize_global_localization std_srvs/srv/Empty

  • Global Localization 실행 후

  • ros2 run teleop_twist_keyboard teleop_twist_keyboard로 로봇을 움직인 후

    Global Localization 이 잘 수행되지 않는 모습

대응방안

  • 파티클 수 조정 (AMCL 파라미터)
  1. tf-transformations 라이브러리 다운 및 새로운 패키지 생성
  • tf-transformations는 수학적 계산을 도와주는 라이브러리
  • 좌표 변환(회전, 쿼터니언, 행렬 등) 계산할 때 필요
sudo apt install ros-humble-tf-transformations 

ros2 pkg create --build-type ament_python localizer_server --dependencies rclpy geometry_msgs tf-transformations
  1. global_localization.py 생성 및 작성
import rclpy
from rclpy.node import Node
from std_srvs.srv import Empty
from rcl_interfaces.srv import SetParameters
from rcl_interfaces.msg import Parameter, ParameterValue, ParameterType
from time import sleep

class GlobalLocalizationManager(Node):
    def __init__(self):
        super().__init__('global_localization_manager')

        # 기본 파티클 수
        self.default_min_particles = 500
        self.default_max_particles = 2000

        # 글로벌 로컬라이제이션 시 파티클 수
        self.global_min_particles = 1000
        self.global_max_particles = 20000

        # 서비스 클라이언트
        self.relocalization_client = self.create_client(Empty, '/reinitialize_global_localization')
        self.param_client = self.create_client(SetParameters, '/amcl/set_parameters')

        if not self.relocalization_client.wait_for_service(timeout_sec=1.0) \
                and not self.param_client.wait_for_service(timeout_sec=1.0):
            self.get_logger().error('AMCL set_parameters 서비스 없음!')
            return
        
    def set_amcl_particles(self, min_particles, max_particles):
        params = [
            Parameter(name='max_particles', value=ParameterValue(type=ParameterType.PARAMETER_INTEGER, integer_value=max_particles)),
            Parameter(name='min_particles', value=ParameterValue(type=ParameterType.PARAMETER_INTEGER, integer_value=min_particles))
        ]

        request = SetParameters.Request()
        request.parameters = params

        future = self.param_client.call_async(request)
        rclpy.spin_until_future_complete(self, future)
        self.get_logger().info(f'AMCL 파티클 수 설정: min={min_particles}, max={max_particles}')

    def call_global_localization(self):
        # 글로벌용 파티클 수로 증가
        self.set_amcl_particles(self.global_min_particles, self.global_max_particles)

        # 글로벌 로컬라이제이션 수행
        if not self.relocalization_client.wait_for_service(timeout_sec=2.0):
            self.get_logger().error('reinitialize_global_localization 서비스 없음!')
            return

        req = Empty.Request()
        future = self.relocalization_client.call_async(req)
        rclpy.spin_until_future_complete(self, future)
        self.get_logger().info('Global Localization 수행 완료')
        sleep(10)
        
        # 완료 후 기본 파티클 수로 복원
        self.set_amcl_particles(self.default_min_particles, self.default_max_particles)
        self.get_logger().info('파티클 수 기본값으로 복원 완료')

def main(args=None):
    rclpy.init(args=args)
    node = GlobalLocalizationManager()

    # 글로벌 로컬라이제이션 수행
    node.call_global_localization()

    rclpy.shutdown()

if __name__ == '__main__':
    main()
  1. setup.py에 entry_points 추가
  • 'global_localization = localizer_server.global_localization:main'
  1. 패키지 빌드
  • colcon build --symlink-install --packages-select localizer_server
  • source ~/nav2_ws/install/local_setup.bash
  1. 서비스 호출
    ros2 run localizer_server global_localization
  • ros2 run teleop_twist_keyboard teleop_twist_keyboard로 로봇을 움직인 후

Global Localization 이 잘 수행된 것을 확인

profile
taerin

0개의 댓글