ns3

네트워크 시뮬레이터 ns3 :: 설치부터 구현까지

crystal bang 2020. 11. 16. 14:28

1. ns3 설치와 초반 스터디

졸업 프로젝트에서 설계한 V2P 네트워크 구조의 성능을 평가하기 위해 네트워크 시뮬레이션을 수행해야 했다.

많은 네트워크 시뮬레이션 중 오픈소스인 ns3(network simulator)을 사용하기로 결정했다.


ns3를 설치하기 위해 가상머신으로 Oracle VirtualBox를 사용했다. 

내가 사용한 버전은 ns-3.31로 ns3를 최초 설치한 날(대략 2020년 8월?) 기준 가장 최신 버전이었다.

지금 확인하니 ns-3.32가 2020년 10월 7일에 새로 릴리즈되었다!

VirtualBox를 설치하는 과정은 이미 많은 블로거가 작성해두어서 어렵지 않았고, ns3를 설치하는 과정은 블로그보다 유튜브에 검색하여 보이는 영상을 따라하니 금방 설치가 됐다. 


+ 추가로 공동 프로젝트를 하는 경우라면 팀원 간 버전을 일치 시키는 것이 좋을 것 같다. 

우리 팀의 경우 버전이 서로 다른데 웬만한 기능에서는 거의 유사하나 가끔씩..? 아예 같은 코드인데도 터미널 결과 출력이 다르다거나(로그가 출력되지 않는 문제), 혹은 이전 버전에서는 잘 빌드가 되는 코드도 최신 버전에서는 안되는 경우가 종종 있었다. 


우리 팀은 플젝 코드를 작성하기 전, ns3 페이지인 nsnam페이지에서 플젝에서 사용할만한 모듈을 미리 확인하고 시작했다. 

https://www.nsnam.org/

예를 들어, 보행자와 차량 노드의 경우 이동성을 가지기 때문에 mobility를 설정할 때 사용할 수 있는 모듈을 학습하거나 혹은 통신에서 사용할 WiFi, LTE, WAVE등의 채널을 어떻게 설정할 수 있는지를 가볍게 살펴봤다.

이후 각자 ns3에서 제공하는 tutorial(1~7)을 학습한 뒤 함께 스터디를 통해 전반적인 ns3 코드에 익숙해졌다.

ns3는 C++로 스크립트를 작성하기 때문에 언어 자체가 어렵지는 않았으나 ns3 모듈 사용법을 익히는 과정이 상당히 오래걸렸다.


2. SUMO(Simulation of Urban MObility)

위에서 간단히 이야기 했 듯, 우리 팀의 주제는 V2P(Vehicle to Pedestrian)이다. 

즉 차량과 보행자 간 통신을 통하여 충돌이 예상되는 경우 보행자와 차량에게 warning message를 전송하여 사고를 방지하는 기술이다. 우리는 이 V2P를 엣지 컴퓨팅 구조를 도입하여 서비스를 제공하고자 했다.


이 실험을 ns3에서 하기 위해서는 시뮬레이션 상에 배치된 보행자 노드와 차량 노드가 mobility를 가져야하는데, 처음에는 ns3에서 제공하는 MobilityModel에 DoWalk()와 같은 함수가 다 정의되어있어 그런 것들을 사용하려 했다.

그러나 샘플 코드를 수행하보니, 실제 보행자 차량의 움직임과 다르게 정말 랜덤하게 움직이는 것을 볼 수 있었다.


그래서 더 찾아보니, Vehicular network에서 mobility를 설정해야 될 때 SUMO를 통해 trace file을 생성하고 ns3에서 불러와 사용한다는 것을 확인하여 SUMO를 사용하기로 결정했다. 그리고 우분투에 SUMO를 설치했다.

https://www.eclipse.org/sumo/


SUMO를 설치하고 내가 해본 방식은 두 가지인데, 간단하게 소개하자면 아래와 같다.

1. Open Street Map(osm)을 이용해 실제 도로의 형상을 그대로 가져오기

우리는 스쿨존을 중심으로 300m반경의 구역을 실험해야 했기 때문에 네이버 지도에서 미리 선택할 구역을 확인한 뒤, osm에서 select area에 해당 구역을 선택했다. 

선택한 구역에 대해 Generate하면 오른쪽 우분투의 초록 화면과 같이 해당 지역의 지도가 SUMO에 뜨게 된다. 오른쪽 파란색 탭에서는 내가 지도에 추가하고자 하는 요소(자동차, 보행자, 자전거 등)을 선택할 수 있고, through traffic factor과 count를 조정하여 시뮬레이션에 추가 될 노드 수를 설정할 수 있다. 

OSM을 사용한 방법의 경우, 실제 도로를 스크랩해서 시뮬레이션을 할 수 있다는 것이 가장 큰 장점인 것 같다. 

대신 위의 사진에서 볼 수 있듯이 내가 선택한 구역 외의 도로가 꽤 많이 포함이 되어서 정밀하게 실험을 하기에는 어려웠다.

또한 우리가 duration과 노드 수를 딱 입력할 수 없는 것이 개인적으로 불편했다. 예를 들어 duration을 60으로 두면 나는 대략 1분 동안 시뮬레이션이 진행 될 줄 알았지만 노드 생성을 60동안 하는거라 실제 종료 시간은 크게 달랐다. 



2. netedit을 이용해 내가 실험하고자 하는 도로 형상을 제작하기

두번째 방법은 netedit을 이용해 내가 원하는 형상을 직접 만드는 방법이다.

우리는 osm을 이용하여 진행하다가, 위에서 언급한 문제점들로 결국 이 방법으로 실험을 진행했다.

netedit은 GUI가 꽤 발달된 것 같아서 사용법을 익히는 데 크게 어렵지 않았다. 


우리는 400m*400m의 grid map을 실험에 사용할 도로 환경으로 netedit에서 생성했다. 저 도로를 가까이서 살펴보면 아래와 같다. 검은 부분은 차도이고 회색은 인도이다. 노란 선은 내가 설정한 루트이다. 

netedit에서 위의 이미지와 같이 원하는 형상으로 도로, 인도를 설정하고 vehicle과 pedestrian을 원하는 경로대로 추가한 뒤, 확장자 .sumocfg로 저장을 해야한다. (Edit에서 open in SUMO 한 다음 SUMO에서 다시 sumocfg파일로 저장해야 함)

이렇게 저장된 .sumocfg파일을 이제 많은 과정을 거쳐 ns3에서 사용할 tcl파일로 변환하는 과정을 거쳐야 하는데, 이 과정을 스스로 하려면 매우 어렵고, 유튜브에 잘 소개한 영상이 있기 때문에 그걸 보며 하나씩 따라하는게 좋다.

https://www.youtube.com/watch?v=9Tt5GNMuOpc


이 과정을 거치면 ns3에서 불러올 수 있는 mobility파일인 tcl파일이 저장이 되고, ns3에서 제공하는 ns2mobility 예제 코드를 살짝 변경하여 우리가 만든 파일을 불러오기만 하면 된다. 이 과정도 위의 영상에 포함되어있다.

참고로 tcl파일은 ns3의 이전 시뮬레이터인 ns2에서 사용하던 확장자이다. 그래서 tcl파일로 생성된 mobility파일을 ns2MobilityHelper를 이용해 ns3에서 불러오는 것 같다.


3. 본격 ns3 코드 작성 (WiFi, WAVE)

3.1 WiFi

tcl파일을 불러오는 것까지 성공한 뒤에, 우리는 그 파일 위에 코드를 작성했다. 

가장 먼저 시도했던 것은 노드 간 LTE 통신이었지만, 이 부분은 pgw, remote host, enb node등 추가 해야하는 디바이스가 많고 잔 에러가 많아 통신 구현이 어려웠다. 그래서 LTE통신 대신 WiFi 통신을 사용하는 것으로 방향을 변경했다.

우리 코드에서 WiFi를 구현한 순서를 크게 정리하자면 아래와 같다. 

1. WiFi channel 
2. WiFi phy layer 
3. WiFi mac layer
4. WiFi Internet stack, Ipv4 할당
5. 노드 간 패킷을 주고받기 위한 적당한 Application 정의 및 사용

여러 코드를 참고하며 각 순서에서 어떤 것을 셋팅해야 하는지, 또 어떤 값을 주어야 하는지를 배우며 우리 프로젝트에 맞는 코드를 작성했다.
개인적으로 어려웠던 부분은 WiFi 통신 반경을 넓히는 것이었는데, 아래의 코드를 추가하고 성공했다.


다른 과정들은 크게 어려움 없이 진행되었고, 5번 과정인 application 정의 및 사용에서 어느정도 고민을 하게 되었다.
보행자 노드는 1초마다 서버로 패킷을 전송하고, 서버는 보행자들로 부터 온 모든 패킷을 수신하는 기능을 위해 적합한 application을 생각해보았다.

결과로 1초마다 패킷을 전송하는 것에는 OnOff application을, 패킷을 수신하는 것에는 Packet Sink application을 사용했다.
보행자 노드가 1초를 주기로 패킷을 보내게 되었고, 엣지 서버는 본인에게 오는 모든 패킷을 수신했다.
 //보행자가 엣지에게 OnOff app을 통해 1초를 주기로 유니캐스트 하는 부분

//packetsink app을 통해 들어오는 패킷을 수신하는 부분


WiFi를 구현하는 과정에서 크고 작은 에러 발생했었는데, 그럴 땐  nsnam 공식 페이지, github, google ns3 user group을 통해 찾아보았고 많은 도움을 얻었다. 

nsnam: 어떤 클래스가 있고 그 안에서 어떤 함수가 있는지, 파라미터는 무엇인지 등을 확인할 때 주로 참고함
github: 사용하고 싶은 클래스, 함수가 어떻게 사용되는지 예제 코드 확인할 때 주로 참고함
ns3 user group: 원인을 알기 어려운 문제에 대해 같은 상황이 있었는지? 물어보고 확인할 때 주로 참고함


사실 이렇게 확인하긴 했지만 그냥 이것 저것 고쳐보다 보면 어떤 문장이 채널에서 어떤 것을 설정하는 지 감을 잡는것에 가장 큰 도움이 됐던 것 같다.



3.2 WAVE

차량과 서버의 통신에는 WAVE를 이용했다. WAVE 코드 구현은 WiFi와 다른 부분이 많지 않았다. 
그래서 WiFi를 끝내고 WAVE로 넘어갔을 땐 큰 어려움 없이 성공했던 것 같다.

대신 한가지 달랐던 점은 이번엔 Broadcast 통신을 했다는 점인데, 그 부분도 처음엔 조금 어려웠지만 아래와 같이 작성하니 성공했다.

10.1.2의 베이스를 가진 노드들에게 모두 전송하도록 했고, Broadcast를 Allow했더니 원하는대로 실험이 되었다.




4. 실험 결과 확인 툴 (NetAnim, Wireshark, terminal)

4.1 터미널 로그 출력

가장 즉각적으로 결과를 확인할 수 있는 방법이다. ./waf --run을 통해 실행해보면 터미널에 결과가 바로 쭉 출력되기 때문에 내가 설정한 코드가 잘 적용이 되고 있는지, 예를 들어 패킷 전송과 수신이 잘 되고 있는지를 확인하기에 좋다. 

로그를 추가하고 싶은 부분에 내가 원하는 정보로 로그를 터미널에 출력하도록 설정해도 되고, 

혹은 내가 설정한 Application에 대해 노드들이 잘 받고 있는지, 전송과 수신 Ip는 어떻게 할당이 되었는지, 언제 패킷을 보내고 언제 받았는지를 확인하고 싶을 때에는 아래와 같이 추가하여 터미널에서 확인했다.


위의 방법과 같이 로그를 출력하는 코드를 설정하고 코드를 실행해보면 터미널에 아래와 같이 쭉 로그가 뜨면서 결과를 확인 할 수 있었고, 잘못 작성한 부분을 비교적 쉽게 파악할 수 있었다. 

그래서 ns3코드를 작성한다면 정상적으로 빌드가 되고 실행이 되더라도 log를 꼭 확인하며 원하는대로 정말 잘되고 있는 것인지 확인하는 과정이 중요한 것 같다!! 



4.2 Netanim

netanim은 시뮬레이션 코드에서 설정한 노드의 이동성, 패킷 송수신 과정, 할당된 IP와 MAC주소 등을 시각화하여 볼 수 있는 툴이다.

사용법도 간단하다. 코드에 netanim 헤더파일을 추가하고, 코드의 마지막에 netanim 파일 생성하는 코드를 한줄만 추가하면 알아서 생성이된다. 그 xml파일을 netnaim에서 열기만 하면 쉽게 확인할 수 있다. 


코드에서 설정한 위치에(위에서는 sumo를 통해 설정한 루트 상에 노드가 존재함) 빨간 노드가 있고 파란선으로 패킷이 흐르는 방향, 시간을 볼 수 있다. 코드를 시각화하여 보기 좋아서 코드 작성 중 확인하면 좋았다.


4.3 wireshark

네트워크 상에서 어떤 패킷이 흐르는 지 캡쳐하여 구체적으로 확인할 수 있는 툴이다. 

우리는 pedestrian과 edge device의 phy layer에 pcap파일을 생성하도록 설정하여 어떤 패킷들이 각 노드에게 들어오고 나가는지를 확인했다. 

실험 결과를 도출하고, 또 우리가 설정한 것과 다른 패킷이 이동할 때 원인 분석을 하는데 큰 도움이 됐다.


이 역시도 아래와 같이 pcap파일 생성 코드를 추가만 하면 자동으로 wireshark에서 확인할 수 있는 pcap파일이 생성된다.

wireshark는 우분투 소프트웨어 설치하는 곳에서 쉽게 install 할 수 있었다.





5. 마무리

ns3로 한 첫 번째 프로젝트인데, 자료가 부족해서 너무 힘들었다 ;-(
원인을 전혀 모르겠는 에러도 많았고 잘 동작은 되지만 결과가 이상한 적도 너무 많았다..

그래도 그냥 계속 붙잡고 이것 저것 고쳐보고 공부하고 검색하다 보니 다 해결이 되긴 했다ㅎ
빨리 코드 작성 마무리하고 실험 결과 도출까지 짠 끝내고 싶다!