CVAD

2. CARLA튜토리얼 본문

CARLA

2. CARLA튜토리얼

_DK_Kim 2023. 10. 17. 16:22

지난 번에 CARLA를 설치 했으니, 본격적으로 사용해보도록하자. 

본 포스팅은 CARLA document에서 제공하는 튜토리얼 예제를 참고하여 진행하였습니다.
예제 링크 : (https://carla.readthedocs.io/en/latest/tuto_first_steps/#loading-a-map)

 

 

본 포스팅에서는 다룰 내용은 아래와 같다.

  • Pyhton 코드로 CARLA 조작하는 방법
  • Loading Map : CARLA에서 기본적으로 제공하는 MAP을 불러오는 방법
  • Spectator navigation : CARLA simulator의 spectator를 조작하는 방법
  • Adding Vehicles : CARLA simulator 환경에서 차량을 소환하는 방법
  • Adding Camera : 소환된 차량에 Camera를 부착하는 방법
  • Animate vehicles with traffic manager : CARLA의 traffic manager를 이용하여 소환된 차량을 조작하는 방법

Python 코드로 CARLA 조작하는 방법

학습된 모델을 CARLA simulator에 적용해보거나, simulator에 다양한 옵션들을 손쉽게 바꾸고 싶다면 Python 코드를 이용하는 것이 좋다. 특히 나의 경우, 전자의 이유가 가장 컸다. 

 

여기서 가장 중요한 것은 carla모듈을 import 하는 것인데, numpy나 torch와 같이 그냥 import하면 인식을 못한다.

때문에, 추가적으로 코드를 작성해야한다. 아래의 코드를 작성하고자 하는 코드 제일 상단에 적어주자.

 

import glob
import os
import sys

try:
    sys.path.append(glob.glob('[carla 설치 위치]/carla/PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass

 

여기서 [carla 설치 위치]에 본인이 설치한 carla 위치를 적어주면 된다. 만약, 오류가 발생한다면 직접 egg파일이 존재하는 위치로 이동해서 path를 확인한 뒤 수정하면 된다. 참고로 egg 파일 위치로 가면 아래와 같은 화면을 볼 수 있다.

 

 

이제 아래의 예제 코드들을 적용해보면, 정상적으로 작동할 것이다.

다만, 이 방식의 경우 문제점이 있다. 바로 carla내에 존재하는 function들이 자동완성이 안되는 문제인데... 아직까지 이를 해결할 방법을 못 찾았다. 만약 찾는다면 이에 대해 바로 포스팅하겠다.

 

아무튼, 실행하고자 하는 코드마다 저 코드를 적어주면 된다는 것이 핵심이다.

 

한 가지 더 적자면, 코드를 적용하기 앞서서 꼭 Simulator의 Play버튼을 눌러준 뒤 코드를 실행하자.

안그러면 python에서 CARLA simulator의 client를 인식하지 못한다.

그리고 코드 동작을 멈추고 싶다면 simulator를 먼저 멈추고(stop 누르기) 코드를 중지시키자.
경험상 그냥 끄면 CARLA가 항상 렉걸리면서 팅겼었다.


Loading Map

CARLA에서는 기본적으로 Town01-12까지 map을 제공한다. 참고로, simulator를 키면 자동으로 Town10이 불러와진다.

하지만, document에 적힌 것과 달리 나의 경우 특정 map들은 불러와지지 않았는데 아마 버전마다 차이가 있는 것 같다.

각 map에 대한 설명은 document에 자세하게 나와있다.

 

제공된 Map들은 아래의 코드를 통해 불러와 볼 수 있다. 아래는 Town04를 불러오는 코드이다.

 

import glob
import os
import sys

try:
    sys.path.append(glob.glob('[carla 설치 위치]/carla/PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass
    
import carla
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # seconds
world = client.get_world()
client.load_world('Town04')

 

실행에 앞서 알아둬야할 것이 있는데, 아마 처음 코드를 실행하면 바로 안불러와지거나, 불러와졌다가 오류가 뜨면서 튕길 것이다.

 

추측하건데, Town asset을 추가적으로 다운로드 받으면서 충돌이 일어나 강제적으로 튕기는 것 같다.

그래서 한 Town 당 여러 번 실행하여 asset을 완벽히 다운받으면 그 뒤로 해당 오류는 발생하지 않는다.

아래는 위에서 언급한 오류다.

 

이 오류가 아마 계속 뜨며 simulator가 꺼질 것이다. 인내심을 갖고 반복해서 asset을 전부 다운 받으면 해당 map을 사용할 수 있다.

 

Map asset을 완전히 다운받고 위의 코드를 그대로 실행한다면, 아래와 같이 Town04의 화면을 볼 수 있을 것이다.

 

Town10(기본 화면)에서 Town04로 바뀌는 것


Spectator Navigation

다음은 Simulator에서 Perspective camera를 조작하는 방법을 알아보자.

Perspective camera는 Simulator에서 화면을 보여주는 기본적인 camera로 simulator를 처음키면 보이는 화면을 의미한다.

CARLA에서는 이 카메라를 Spectator 라고 부른다.

 

기본적으로 Simulator 상에서는 W,A,S,D를 통한 이동과 마우스 휠을 통한 이동속도 조절이 가능하다.

Play버튼을 누른 뒤 Simulator에서 조작을 해보자. 

 

그러나 경우에 따라 코드가 실행됨과 동시에 특정 위치를 봐야할 경우가 있다. 이럴 때는 아래의 코드를 이용하여 자신이 원하는 위치와 각도로 spectator를 옮길 수 있다.

 

import glob
import os
import sys

try:
    sys.path.append(glob.glob('[carla 설치 위치]/carla/PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass
    
import carla

client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # seconds
world = client.get_world()

spectator = world.get_spectator()
new_loc = carla.Location(x=-100, y=160, z=25)
new_rot = carla.Rotation(pitch=-5.0, yaw=-30.0, roll=0.0)
new_transform = carla.Transform(new_loc, new_rot)
spectator.set_transform(new_transform)

 

위 코드에서 carla.Location의 x, y, z값과 carla.Rotation의 pitch, yaw, roll 값을 수정하여 spector의 위치와 각도를

정할 수 있다. 아래는 코드를 실행했을 때의 화면이다.

 

 

만일 Location과 Rotation 둘 중 하나만 바꾸고 싶다면, 아래의 코드를 사용하면 된다.

# 위치만 바꾸고 싶을 경우,
new_loc = carla.Location(x=-100, y=100, z=25)
spectator.set_location(new_loc)

# 각도만 바꾸고 싶을 경우,
new_rot = carla.Rotation(pitch=20.0, yaw=20.0, roll=20.0)
spectator.set_rotation(new_rot)

Adding Vehicles

이제 본격적으로 Vehicle을 Simulator에 불러와보자.

CARLA는 차량과 보행자, 카메라와 같은 object들을 blueprint 라는 개념으로 library화 하여 저장하고 있다. 때문에, 이 파트에서는 Vehicle만을 다뤘지만, 비슷한 방식으로 보행자나 다른 object를 소환할 수 있다.

 

아무튼, 이 blueprint들을 가져와서 Map에 소환하는 것이 가장 큰 골자이다. 아래의 코드를 실행하면 소환 가능한 random 위치에 50개의 차량이 소환될 것이다. (그리고, 이 파트부터는 carla를 import 하기 위한 코드를 생략하겠다.)

 

import carla
import random
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # seconds
world = client.get_world()

client.load_world('Town04')

####################
### Adding NPC #####
####################

# vehicle에 대한 library를 import하는 코드
vehicle_bp = world.get_blueprint_library().filter('*vehicle*')

# 차(혹은 물체)를 소환할 수 있는 point들을 지정
spawn_loc = world.get_map().get_spawn_points()

# 50개 random한 위치에서 소환
for i in range(0,50):
    world.try_spawn_actor(random.choice(vehicle_bp), random.choice(spawn_loc))

 

위 코드를 보면 알겠지만, world.get_map().get_spawn_points()를 통해서 사전에 정의된 소환 가능 지역을 불러올 수 있다. 추후  커스텀 맵을 제작한다면 이 부분에 대한 정의도 필요할 것 같다.

아래는 코드를 실행한 화면이다.

 

 


Adding Camera

 

앞선 파트에서 자동차를 소환했다면, 이제는 차량에 camera를 부착해보자. 먼저 부착할 특정 차를 정의해줘야한다.

그리고 자동차를 불러온 방법과 동일하게 camera도 blueprint를 통해 가져온다.

아래의 코드는 ego_vehicle이라는 특정 차량을 정의하고, 이 차량에 camera를 부착한 뒤 프레임마다 camera 데이터를 받아오는 코드다.

 

import carla
import random
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # seconds
world = client.get_world()

client.load_world('Town04')

vehicle_bp = world.get_blueprint_library().filter('*vehicle*')
spawn_loc = world.get_map().get_spawn_points()
ego_vehicle = world.spawn_actor(random.choice(vehicle_bp), random.choice(spawn_loc))

# Camera transform을 정의
camera_init_trans = carla.Transform(carla.Location(z=1.5))

# Camera bluprint를 가져옴. 그리고, rgb 카메라로 가져올 수 있도록 property 값을 설정
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
# Camera를 소환 후 ego vehicle에 부착 
camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=ego_vehicle)

# Camera에서 받는 데이터를 저장하기 위해서는 listen() method를 사용해야한다.
# listen method를 arguemnt를 callback로 저장하는 기능을 제공해준다.

# lambda 함수를 이용해서 callback을 저장하는 코드
camera.listen(lambda image: image.save_to_disk('out/%06d.png' % image.frame))

 

위 코드를 실행하면 out이라는 폴더에 camera에서 얻은 이미지가 저장된 것을 볼 수 있다. 아래는 그 이미지 중 하나다.

 

z 값을 1.5로 잡아서 이상한 위치로 camera가 잡힌 것 같다.


Animate vehicles with traffic manager

카메라도 붙여보았고, 자동차도 소환해보았으니 움직여볼 차례다. CARLA에서는 Traffic Manager라는 기능을 통해 차량이 자율적으로 움직일 수 있도록 기능을 제공하고 있다. 물론, 사용자가 만든 모델 혹은 로직을 이용해서도 움직일 수 있다.

 

본 포스팅에서는 autopilot()을 이용하여 차량을 자율적으로 움직여보겠다.

단, document에 있는 코드를 실행하면 차량만 소환되고 움직이지 않는 문제가 발생하여 코드를 일부 수정하였다.

(추측하건데, get_actors() 함수로 받아온 vehicle list에서 문제가 발생한 것 같다.)

 

코드는 다음과 같다.

import carla
import random
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)  # seconds
world = client.get_world()

spectator = world.get_spectator()
new_loc = carla.Location(x=-100, y=160, z=25)
new_rot = carla.Rotation(pitch=-5.0, yaw=-30.0, roll=0.0)
new_transform = carla.Transform(new_loc, new_rot)
spectator.set_transform(new_transform)


vehicle_blueprints = world.get_blueprint_library().filter('*vehicle*')
spawn_points = world.get_map().get_spawn_points()


for i in range(0, 50):
    vehicle = world.try_spawn_actor(random.choice(vehicle_blueprints), random.choice(spawn_points))
    if i == 49:
        ego_vehicle = vehicle

    if vehicle:
        vehicle.set_autopilot(True)


camera_init_trans = carla.Transform(carla.Location(z=1.5))
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=ego_vehicle)
camera.listen(lambda image: image.save_to_disk('out/%06d.png' % image.frame))

 

spectactor의 경우는 차량이 움직이는 것을 조금 더 잘 보기 위해 작성한 것이며, camera는 ego_vehicle이 움직일 때 잘 붙어서 움직이는지 보기위해 작성한 코드다. 따라서, spectator와 camera 관련 코드는 생략해도 좋다.

코드를 실행하면 아래와 같이 동작함을 확인할 수 있다.

 

중간에 차가 서로 부딪히고 난리났다

참고로, 차끼리 충돌하고 이상하게 동작해도 성공한 거 맞으니 무시하자

728x90

'CARLA' 카테고리의 다른 글

3. CARLA 0.9.12 버전으로 재설치  (1) 2024.05.27
1. Ubuntu 20.04 CARLA install  (0) 2023.08.12