구현

IRSML 시뮬레이션 직접 구성하기 - 3

Beige00 2024. 2. 14. 16:10

최근에 개인적인 사정으로 정신이 없었던 것 같다.

그 와중 모각코 활동과 병행하느라 정말로 오랜만에 포스팅을 하게된 거 같다.

따라서 이전 내용을 정리해보면

 

1. ns-3로 논문에 제시된 토폴로지가 아닌 간소화된 토폴로지를 짤 것임.

2. Adhoc network 토폴로지를 구성할 것이며, 3개의 AP, 12개의 MH를 구성하였음.

더보기

자세한 파라미터

 

1. 총 시뮬레이션 시간 : 250초

2. 500x500 m^2 정사각형 스테이지

3. 각 MH의 Speed는 0~20 m/s 까지 분포

4. 각 MH의 Pause time은 0~2초까지 분포

5. RandomWayPoint model 사용

6. wifi standard = 802.11ac

7. MaxPropagationLossModel을 사용, MaxRange = 250m

8. 나머지 설정 값은 Constant model들의 default 사용

9. TcpBulkSend <-> PacketSink application 사용

구현한 시뮬레이터의 결과 Xml file을 NetAnim으로 돌리면 다음과 같다.

 

여기까지 완료가 되면 이제 고려해야할 점은 어떻게 데이터들을 정리할 것인가이다.

 

IRSML 논문을 읽어보면 Supervised Learning Phase에서는 Queue Length와 Traffic load를 파라미터로 사용한다.

더보기

For each hop hij in the WMN, the PBP on this hop depends on two main components, the traffic load offers
to it (ρij) and queue length at the node i (L).

By using the regression technique of the SL method, we determine the
Bhði,jÞ as a function of the ρij and L.

그 이상 자세한 설명을 하지는 않는 것 같다. 따라서 나의 생각을 반영해야하는 부분인데, 일단 Queue Length 부터 생각해보자.

ns-3에서 직접적으로 QueueLength를 가져오는 법은 없어보여서 여러가지 방안을 생각해봤다.

그리고 다음의 방법으로 접근해보았다.

 

1. Mac 계층에서 QoS를 설정해준다.

2. Mobile Host에 설치될 BulkSend Application의 InetSocketAddress의 Type Of Service를 전부 AC_BE로 설정해준다.

3. 시뮬레이션 시작 4초 뒤 매 1초마다 각 node들의 QoS Txop Queue Length를 확인하는 함수를 실행한다.

 

더보기
#include <sstream>
#include <fstream>
#include <ns3/core-module.h>
#include <ns3/network-module.h>
#include <ns3/applications-module.h>
#include <ns3/netanim-module.h>
#include <ns3/mobility-module.h>
#include <ns3/internet-module.h>
#include <ns3/flow-monitor-module.h>
#include <ns3/yans-wifi-helper.h>
#include <ns3/aodv-helper.h>
#include <ns3/traffic-control-helper.h>
#include <ns3/adhoc-wifi-mac.h>
#include <ns3/wifi-mac-queue.h>
#include <ns3/qos-txop.h>

using namespace ns3;

std::ofstream file("QueueLength.txt");

void TracingQueueLength(NetDeviceContainer n){
    for(uint32_t i=0; i<n.GetN(); i++){
        PointerValue ptr;
        n.Get(i)->GetAttribute("Mac",ptr);
        Ptr<AdhocWifiMac> mac = ptr.Get<AdhocWifiMac>();
        Ptr<WifiMacQueue> txop = mac->GetTxopQueue(AC_BE);
        file<<Simulator::Now().GetSeconds()<<"s:"<<i<<" node Length : "<<txop->GetNPackets()<<std::endl;
    }
    file<<std::endl;
    Simulator::Schedule(Seconds(1.0),&TracingQueueLength,n);
}


int
main(int argc, char* argv[]){

    static unsigned int seed = 5323;

    seed = 8253729*seed + 2396403;

    int runN = seed%3;

    seed %= 32768;


    uint32_t APnum = 3;
    double TotalTime = 250.0;
    SeedManager::SetSeed(seed);
    SeedManager::SetRun(runN);

    NodeContainer ApNodes;
    ApNodes.Create(APnum);
    NodeContainer mobileNodes;
    mobileNodes.Create(12);

    NodeContainer adhocNodes;
    adhocNodes.Add(ApNodes);
    adhocNodes.Add(mobileNodes);
    
    NetDeviceContainer mobileDevices;
    NetDeviceContainer APDevices;


    //RTS&CTS setting
    Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",StringValue("0"));


    MobilityHelper mobility;
    Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
    positionAlloc->Add(Vector(250,350,0));
    positionAlloc->Add(Vector(125,150,0));
    positionAlloc->Add(Vector(375,150,0));
    mobility.SetPositionAllocator(positionAlloc);
    mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
    mobility.Install(ApNodes);

    ObjectFactory points;
    points.SetTypeId("ns3::RandomRectanglePositionAllocator");
    points.Set("X",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=500.0]"));
    points.Set("Y",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=500.0]"));
    Ptr<PositionAllocator> waypos = points.Create()->GetObject<PositionAllocator>();
    mobility.SetMobilityModel("ns3::RandomWaypointMobilityModel",
    "Speed",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=20.0]"),
    "Pause",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=2.0]"),
    "PositionAllocator",PointerValue(waypos));
    mobility.Install(mobileNodes);

    WifiHelper wifi;
    wifi.SetStandard(WIFI_STANDARD_80211ac);
    YansWifiPhyHelper wifiPhy;
    YansWifiChannelHelper wifiChannel;
    wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
    wifiChannel.AddPropagationLoss("ns3::RangePropagationLossModel","MaxRange",DoubleValue(250.0));
    wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel");
    wifiPhy.SetChannel(wifiChannel.Create());
    WifiMacHelper mac;
    wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
    mac.SetType("ns3::AdhocWifiMac","QosSupported",BooleanValue(true));
    mobileDevices = wifi.Install(wifiPhy,mac,mobileNodes);
    APDevices = wifi.Install(wifiPhy,mac,ApNodes);
    NetDeviceContainer allDevices = NetDeviceContainer(APDevices,mobileDevices);


    InternetStackHelper internet;
    AodvHelper aodv;
    internet.SetRoutingHelper(aodv);
    internet.Install(adhocNodes);
    Ipv4AddressHelper address;
    address.SetBase("10.1.1.0","255.255.255.0");
    Ipv4InterfaceContainer allInterfaces;
    allInterfaces = address.Assign(allDevices);

    ApplicationContainer sources;

    for(uint32_t i=0; i<12; i++){
        uint32_t port = 9;
        for(uint32_t j=0; j<APnum; j++){
            auto ipv4 = ApNodes.Get(j)->GetObject<Ipv4>();
            const auto address = ipv4->GetAddress(1,0).GetLocal();
            InetSocketAddress sinkSocket (address, port++);
            sinkSocket.SetTos(0x70);
            BulkSendHelper sourceHelper ("ns3::TcpSocketFactory",sinkSocket);
            sources.Add(sourceHelper.Install(mobileNodes.Get(i)));
        }
      }
    sources.Start(Seconds(2.0));
    sources.Stop(Seconds(TotalTime-2.0));


    
    PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 9));
    ApplicationContainer sinkApp1 = sinkHelper1.Install(ApNodes.Get(0));
    sinkApp1.Start(Seconds(0.0));
    sinkApp1.Stop(Seconds(TotalTime));

    PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 10));
    ApplicationContainer sinkApp2 = sinkHelper2.Install(ApNodes.Get(1));
    sinkApp2.Start(Seconds(0.0));
    sinkApp2.Stop(Seconds(TotalTime));

    PacketSinkHelper sinkHelper3 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 11));
    ApplicationContainer sinkApp3 = sinkHelper3.Install(ApNodes.Get(2));
    sinkApp3.Start(Seconds(0.0));
    sinkApp3.Stop(Seconds(TotalTime));



    Ptr<FlowMonitor> flowmon;
    FlowMonitorHelper flow;
    flowmon = flow.InstallAll();
    AnimationInterface anim ("IRSML_demo.xml");
    anim.EnablePacketMetadata();
    anim.SetMaxPktsPerTraceFile(100000000);
    anim.UpdateNodeDescription(0,"AP-1");
    anim.UpdateNodeColor(0,126,126,126);
    anim.UpdateNodeSize(0,250,250);
    anim.UpdateNodeDescription(1,"AP-2");
    anim.UpdateNodeColor(1,126,126,126);
    anim.UpdateNodeSize(1,250,250);
    anim.UpdateNodeDescription(2,"AP-3");
    anim.UpdateNodeColor(2,126,126,126);
    anim.UpdateNodeSize(2,250,250);
    anim.EnableIpv4RouteTracking("IRSML_routes.xml",Seconds(1),Seconds(TotalTime-1),Seconds(TotalTime/2));
    anim.EnableIpv4L3ProtocolCounters(Seconds(0),Seconds(TotalTime-1));
    anim.EnableQueueCounters(Seconds(0),Seconds(TotalTime-1));
    
    wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
    wifiPhy.EnablePcap("IRSML",allDevices.Get(0));
    wifiPhy.EnablePcap("IRSML-Mobile",allDevices.Get(6));

    Simulator::Schedule(Seconds(4.0),&TracingQueueLength,allDevices);
    Simulator::Stop(Seconds(TotalTime));

    Simulator::Run();
    flowmon->SerializeToXmlFile("IRSML_flowmetrics.xml",true,true);
    Simulator::Destroy();
    file.close();
}

QueueLen.txt 결과

이렇게 도출해낸 결과가 유효한지는 교수님과 면담을 할 때 질문을 해봐야겠다.

 

다음은 i,j 간 traffic load를 측정해야한다.

https://groups.google.com/g/ns-3-users/c/OYS2LaXfyxc

 

how to get the traffic load and Packet loss rate of link on NS3

 hello,recently I'm doing a simulation about load balance on NS3. So I need some parameters of wireless network : the traffic load and Packet loss rate of every link between two wireless node. Unfortunately, now I don't know how to get the t

groups.google.com

이 링크에서도 알 수 있듯이 traffic load를 어떻게 정의할 것인지가 첫번째 관건이다.

IRSML 논문에서는 따로 구체적인 정의를 하지 않았다.

따라서 Throughput으로 traffic load를 처리하는 걸로 하고 link 간 Throughput을 한번에 추출해보겠다.

 

그러나 추출 이전에 문득 든 생각이 있었는데, 바로 Throughput과 QueueLength를 개별로 측정해도 될 것인가이다.

한 함수에서 동시에 측정을 하면 문제가 없겠지만, Throughput과 QueueLength를 개별로 측정을 할 시 "타이밍"의 문제가 발생할 것만 같다.

따라서 위에 작성해둔 Tracing Schedule 함수에서 동시에 Throughput과 QueueLength를 측정하기로 하였다.

우선 ns-3.40 all attribute documentation을 확인하자.

(https://www.nsnam.org/docs/release/3.40/doxygen/d3/d79/_attribute_list.html)

이것들을 활용해서 hop hij에 대한 Traffic load ρij를 알아내야하는 것이다.

ρij는 정확히 hop i,j 의 연결에서 발생하는 Traffic load를 의미할 것이다.

 

더보기
#include <sstream>
#include <fstream>
#include <ns3/core-module.h>
#include <ns3/network-module.h>
#include <ns3/applications-module.h>
#include <ns3/netanim-module.h>
#include <ns3/mobility-module.h>
#include <ns3/internet-module.h>
#include <ns3/flow-monitor-module.h>
#include <ns3/yans-wifi-helper.h>
#include <ns3/aodv-helper.h>
#include <ns3/traffic-control-helper.h>
#include <ns3/adhoc-wifi-mac.h>
#include <ns3/wifi-mac-queue.h>
#include <ns3/qos-txop.h>

using namespace ns3;

std::ofstream file("QueueLength.txt");
std::ofstream file1("ThroughPut.txt");
uint32_t APnum = 3;


void TracingParameter(NetDeviceContainer n){
    for(uint32_t i=0; i<n.GetN(); i++){
        PointerValue ptr;
        
        n.Get(i)->GetAttribute("Mac",ptr);
        Ptr<AdhocWifiMac> mac = ptr.Get<AdhocWifiMac>();
        Ptr<WifiMacQueue> txop = mac->GetTxopQueue(AC_BE);
        file<<Simulator::Now().GetSeconds()<<"s : "<<i<<" node Length : "<<txop->GetNPackets()<<std::endl;
    }
    for(uint32_t i=0; i<APnum; i++){
        Ptr<PacketSink> psink;
        ApplicationContainer app = n.Get(i)->GetNode()->GetApplication(0);
        psink = StaticCast<PacketSink>(app.Get(0));
        double averageTL = ((psink->GetTotalRx()*8)/(1e6*Simulator::Now().GetSeconds()));
        file1<<Simulator::Now().GetSeconds()<<"s : "<<i<<" AP ThroughPut: "<<averageTL<<std::endl;
    }
    file<<std::endl;
    file1<<std::endl;
    Simulator::Schedule(Seconds(1.0),&TracingParameter,n);
}


int
main(int argc, char* argv[]){

    static unsigned int seed = 5323;

    seed = 8253729*seed + 2396403;

    int runN = seed%3;
    double TotalTime = 250.0;
    seed %= 32768;


    SeedManager::SetSeed(seed);
    SeedManager::SetRun(runN);

    NodeContainer ApNodes;
    ApNodes.Create(APnum);
    NodeContainer mobileNodes;
    mobileNodes.Create(12);

    NodeContainer adhocNodes;
    adhocNodes.Add(ApNodes);
    adhocNodes.Add(mobileNodes);
    
    NetDeviceContainer mobileDevices;
    NetDeviceContainer APDevices;


    //RTS&CTS setting
    Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",StringValue("0"));


    MobilityHelper mobility;
    Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
    positionAlloc->Add(Vector(250,350,0));
    positionAlloc->Add(Vector(125,150,0));
    positionAlloc->Add(Vector(375,150,0));
    mobility.SetPositionAllocator(positionAlloc);
    mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
    mobility.Install(ApNodes);

    ObjectFactory points;
    points.SetTypeId("ns3::RandomRectanglePositionAllocator");
    points.Set("X",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=500.0]"));
    points.Set("Y",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=500.0]"));
    Ptr<PositionAllocator> waypos = points.Create()->GetObject<PositionAllocator>();
    mobility.SetMobilityModel("ns3::RandomWaypointMobilityModel",
    "Speed",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=20.0]"),
    "Pause",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=2.0]"),
    "PositionAllocator",PointerValue(waypos));
    mobility.Install(mobileNodes);

    WifiHelper wifi;
    wifi.SetStandard(WIFI_STANDARD_80211ac);
    YansWifiPhyHelper wifiPhy;
    YansWifiChannelHelper wifiChannel;
    wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
    wifiChannel.AddPropagationLoss("ns3::RangePropagationLossModel","MaxRange",DoubleValue(250.0));
    wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel");
    wifiPhy.SetChannel(wifiChannel.Create());
    WifiMacHelper mac;
    wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
    mac.SetType("ns3::AdhocWifiMac","QosSupported",BooleanValue(true));
    mobileDevices = wifi.Install(wifiPhy,mac,mobileNodes);
    APDevices = wifi.Install(wifiPhy,mac,ApNodes);
    NetDeviceContainer allDevices = NetDeviceContainer(APDevices,mobileDevices);


    InternetStackHelper internet;
    AodvHelper aodv;
    internet.SetRoutingHelper(aodv);
    internet.Install(adhocNodes);
    Ipv4AddressHelper address;
    address.SetBase("10.1.1.0","255.255.255.0");
    Ipv4InterfaceContainer allInterfaces;
    allInterfaces = address.Assign(allDevices);

    ApplicationContainer sources;

    for(uint32_t i=0; i<12; i++){
        uint32_t port = 9;
        for(uint32_t j=0; j<APnum; j++){
            auto ipv4 = ApNodes.Get(j)->GetObject<Ipv4>();
            const auto address = ipv4->GetAddress(1,0).GetLocal();
            InetSocketAddress sinkSocket (address, port++);
            sinkSocket.SetTos(0x70);
            BulkSendHelper sourceHelper ("ns3::TcpSocketFactory",sinkSocket);
            sources.Add(sourceHelper.Install(mobileNodes.Get(i)));
        }
      }
    sources.Start(Seconds(2.0));
    sources.Stop(Seconds(TotalTime-2.0));


    
    PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 9));
    ApplicationContainer sinkApp1 = sinkHelper1.Install(ApNodes.Get(0));
    sinkApp1.Start(Seconds(0.0));
    sinkApp1.Stop(Seconds(TotalTime));

    PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 10));
    ApplicationContainer sinkApp2 = sinkHelper2.Install(ApNodes.Get(1));
    sinkApp2.Start(Seconds(0.0));
    sinkApp2.Stop(Seconds(TotalTime));

    PacketSinkHelper sinkHelper3 ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 11));
    ApplicationContainer sinkApp3 = sinkHelper3.Install(ApNodes.Get(2));
    sinkApp3.Start(Seconds(0.0));
    sinkApp3.Stop(Seconds(TotalTime));



    Ptr<FlowMonitor> flowmon;
    FlowMonitorHelper flow;
    flowmon = flow.InstallAll();
    AnimationInterface anim ("IRSML_demo.xml");
    anim.EnablePacketMetadata();
    anim.SetMaxPktsPerTraceFile(100000000);
    anim.UpdateNodeDescription(0,"AP-1");
    anim.UpdateNodeColor(0,126,126,126);
    anim.UpdateNodeSize(0,250,250);
    anim.UpdateNodeDescription(1,"AP-2");
    anim.UpdateNodeColor(1,126,126,126);
    anim.UpdateNodeSize(1,250,250);
    anim.UpdateNodeDescription(2,"AP-3");
    anim.UpdateNodeColor(2,126,126,126);
    anim.UpdateNodeSize(2,250,250);
    anim.EnableIpv4RouteTracking("IRSML_routes.xml",Seconds(1),Seconds(TotalTime-1),Seconds(TotalTime/2));
    anim.EnableIpv4L3ProtocolCounters(Seconds(0),Seconds(TotalTime-1));
    anim.EnableQueueCounters(Seconds(0),Seconds(TotalTime-1));
    
    wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
    wifiPhy.EnablePcap("IRSML",allDevices.Get(0));
    wifiPhy.EnablePcap("IRSML-Mobile",allDevices.Get(6));

    Simulator::Schedule(Seconds(4.0),&TracingParameter,allDevices);
    Simulator::Stop(Seconds(TotalTime));

    Simulator::Run();
    flowmon->SerializeToXmlFile("IRSML_flowmetrics.xml",true,true);
    Simulator::Destroy();
    file.close();
    file1.close();
}

 

여기까지를 생각하고 더 이상 진전이 없었다.

정확히 이야기하면 구현은 마무리 하였는데 이렇게 접근해서 얻어낸 데이터가 올바른 과정을 거쳐 얻어낸 데이터인지에 대한 확신이 없어서 더 이상 진행을 하지 못하였다.

QueueLength는 QosTxop로 돌려서 측정하고, Traffic load는 각 AP의 Average ThroughPut으로 일단 수집을 하긴 했다.

 

여기까지 수집한 데이터를 교수님과 상의 후, 틀린 점 혹은 개선점을 찾아봐야겠다.