구현

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

Beige00 2024. 2. 26. 17:32

교수님과의 상담에서 많은 깨달음이 있었다.

우선 불투명하거나 모호하게 뜬 데이터나, ns3에서 제공하지 않는 부분을 최대한 걷어내고 다시 구현을 해야겠다.

 

1. 통상의 Adhoc Network를 가정할 것임. (AP들 제거)

2. 각 node 단에서의 데이터를 뽑아낼 것임.(flow x)

3. csv는 일단 COLAB 쪽으로 raw data만 정리해서 보내고 가공은 COLAB 쪽에서

4. 각 MH들의 Mobility 제거, 배치만 랜덤으로.

 

이를 기준으로 아예 새로 코드를 짜겠다.

 

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


using namespace ns3;

std::vector<std::vector<std::string>> QL;
std::vector<std::vector<std::string>> TP;
uint32_t APnum = 3;


void makeCsvFile(const std::string& filename, const std::vector<std::vector<std::string>>& data){
    std::ofstream file(filename);
    for(const auto& row : data){
        for(auto it = row.begin(); it!=row.end(); ++it){
            file<<*it;
            if(next(it)!=row.end()){
                file<<",";
            }
        }
        file<<std::endl;
    }
    file.close();
}

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);
        QL.push_back({std::to_string(Simulator::Now().GetSeconds()),std::to_string(i),std::to_string(txop->GetNPackets())});
    }
    for(uint32_t i=0; i<n.GetN(); 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()));
        TP.push_back({std::to_string(Simulator::Now().GetSeconds()),std::to_string(i),std::to_string(averageTL)});
    }
    Simulator::Schedule(Seconds(1.0),&TracingParameter,n);
}


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

    QL.push_back({"Second","NodeID","QueueLength"});
    TP.push_back({"Second","NodeID","ThroughPut"});
    
    double TotalTime = 2000.0;

    NodeContainer AdhocNodes;
    AdhocNodes.Create(30);

    NetDeviceContainer AdhocDevices;

    Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",StringValue("0"));

    MobilityHelper mobility;
    mobility.SetPositionAllocator("ns3::RandomRectanglePositionAllocator","X",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"),
    "Y",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"));
    mobility.Install(AdhocNodes);

    WifiHelper wifi;
    wifi.SetStandard(WIFI_STANDARD_80211ac);
    YansWifiPhyHelper phy;
    YansWifiChannelHelper channel;

    channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
    channel.AddPropagationLoss("ns3::RangePropagationLossModel","MaxRange",DoubleValue(250.0));
    phy.SetErrorRateModel("ns3::YansErrorRateModel");
    phy.SetChannel(channel.Create());
    WifiMacHelper mac;
    wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
    mac.SetType("ns3::AdhocWifiMac","QosSupported",BooleanValue(true));
    AdhocDevices = wifi.Install(phy,mac,AdhocNodes);

    InternetStackHelper internet;
    AodvHelper aodv;
    internet.SetRoutingHelper(aodv);
    internet.Install(AdhocNodes);
    Ipv4AddressHelper ipv4;
    ipv4.SetBase("10.1.1.0","255.255.255.0");
    Ipv4InterfaceContainer ipv4Interface = ipv4.Assign(AdhocDevices);

    uint64_t port = 9;
    ApplicationContainer sources;
    for(uint32_t i=0; i<AdhocDevices.GetN(); i++){
        for(uint32_t j=0; j<AdhocDevices.GetN();j++){
            if(i==j) continue;
            auto ipv4 = AdhocNodes.Get(j)->GetObject<Ipv4>();
            const auto address = ipv4->GetAddress(1,0).GetLocal();
            InetSocketAddress sinkSocket (address,port);
            sinkSocket.SetTos(0x70);
            BulkSendHelper bulk ("ns3::TcpSocketFactory",sinkSocket);
            sources.Add(bulk.Install(AdhocNodes.Get(i)));
        }
    }
    sources.Start(Seconds(1.0));
    sources.Stop(Seconds(TotalTime-1.0));

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

    Simulator::Run();

    Simulator::Destroy();
    makeCsvFile("QueueLength.csv",QL);
    makeCsvFile("ThroughPut.csv",TP);
}

//csv 파일을 결과로 출력해내는 최종 코드이다. 추후 데이터 소스의 문제가 있다고 판단될 시,
//데이터를 구하는 Tracing 부분만 수정해서 사용하면 될 것이다.

해당 코드로 작성된 csv 파일 결과를 살펴보니 Throughput은 거의 모든 노드가 일정하게 나왔고,

QueueLength는 늘어나는 구간이 없었다.

내가보기엔 시나리오를 간략화하며 Traffic load가 너무 줄어들어 안정된 네트워크 상태가 유지되는 것 같다.

Data rate 등을 건드려서 loss를 발생시키는 방향으로 구현을 바꾸어나가겠다.