학부연구생

문제 해결을 위한 시뮬레이션 제작 및 Tracing source 추출-2

Beige00 2024. 3. 14. 14:45

이전 구현에서 구한 결과 csv 파일을 검토하던 중, 이상한 점을 발견했다.

일정 시간 이후에는 각 노드들의 Remaining energy가 반복되었던 것이다.

C열이 remaining energy이며, 특정 값들이 반복되고 있다.

하여, 어떤 점이 문제일까 생각해보았는데, 각 노드들의 초기 에너지 세팅 값과 반복되는 energy 패턴에 연관성이 있음을 발견했다.

초기 에너지 세팅을 해준 값이 너무 작은 점, Trans&Recv 절차에 소모되는 에너지 양을 지나치게 크고, 통일 시킨 점이 문제로 생각된다.

따라서 에너지 소모 부분을 랜덤하게 세팅해주고,  코드를 재구성 하였다.

또한 전체적으로 다양한 랜덤 값을 가지게 코드를 변형하였다.

#include <sstream>
#include <fstream>
#include <ns3/network-module.h>
#include <ns3/core-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/energy-module.h"
#include "ns3/wifi-radio-energy-model-helper.h"
#include "ns3/device-energy-model.h"
#include "ns3/olsr-helper.h"
#include <vector>
#include <string>

using namespace ns3;

std::vector<std::vector<std::string>> Data;

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

Vector 
Normalize(const Vector& velocity){
     double magnitude = std::sqrt(velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z);
    // 크기가 0인 벡터는 정규화할 수 없으므로, 원본 벡터를 반환
    if (magnitude == 0)
    {
        return velocity;
    }
    return ns3::Vector(velocity.x / magnitude, velocity.y / magnitude, velocity.z / magnitude);
}

void 
TracingParameter(EnergySourceContainer e, NetDeviceContainer n){
    for(uint32_t i=0; i<n.GetN(); i++){
        //node들의 에너지 잔량,속도, 방향, 위치 정보 수집(Node x, Node y)
        Ptr<Node> node = n.Get(i)->GetNode();
        Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
        Ptr<BasicEnergySource> enPtr = DynamicCast<BasicEnergySource>(e.Get(i));
        ApplicationContainer app = node->GetApplication(0);
        Ptr<PacketSink> psink = StaticCast<PacketSink>(app.Get(0));

        Vector pos = mobility->GetPosition();
        Vector velocity = mobility->GetVelocity();
        Vector Direction = Normalize(velocity);

        uint32_t nodeID = node->GetId();
        double nodeX = pos.x;
        double nodeY = pos.y;
        double dirX = Direction.x;
        double dirY = Direction.y;
        double remainEn = enPtr->GetRemainingEnergy();
        double spdX = velocity.x;
        double spdY = velocity.y;
        double averageTL = ((psink->GetTotalRx()*8)/(1e6*Simulator::Now().GetSeconds()));

        //Second, nodeid, energy, posx, posy, dirx,diry
        Data.push_back({std::to_string(Simulator::Now().GetSeconds()),
        std::to_string(nodeID),
        std::to_string(remainEn),
        std::to_string(nodeX),
        std::to_string(nodeY),
        std::to_string(dirX),
        std::to_string(dirY),
        std::to_string(spdX),
        std::to_string(spdY),
        std::to_string(averageTL)
        });
    }
    std::cout<<Simulator::Now().GetSeconds()<<std::endl;
    Simulator::Schedule(Seconds(1),&TracingParameter,e,n);
}

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


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

    Data.push_back({"Second","NodeID","RemainingEnergy",
    "Node position x","Node position y",
    "Node Direction X","Node Direction Y",
    "Node Speed X","Node Speed Y", "averageTP"});
    
    double TotalTime = 300.0;
    int nodeNum = 50;

    NodeContainer AdhocNodes;
    AdhocNodes.Create(nodeNum);

    NetDeviceContainer AdhocDevices;

    MobilityHelper mobility;
    ObjectFactory points;
    points.SetTypeId("ns3::RandomRectanglePositionAllocator");
    points.Set("X",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"));
    points.Set("Y",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"));
    Ptr<PositionAllocator> waypos = points.Create() -> GetObject<PositionAllocator>();
    mobility.SetMobilityModel("ns3::RandomWaypointMobilityModel",
    "Speed",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=5.0]"),
    "Pause",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=3.0]"),
    "PositionAllocator",PointerValue(waypos));
    mobility.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
    "X",StringValue("ns3::UniformRandomVariable[Min=0|Max=1000]"),
    "Y",StringValue("ns3::UniformRandomVariable[Min=0|Max=1000]"));
    mobility.Install(AdhocNodes);
    //속도 pause time 방향 범위 내 랜덤.

    WifiHelper wifi;
    wifi.SetStandard(WIFI_STANDARD_80211ac);
    YansWifiPhyHelper phy;
    YansWifiChannelHelper channel;
    WifiMacHelper mac;
    mac.SetType("ns3::AdhocWifiMac");
    phy.SetErrorRateModel("ns3::YansErrorRateModel");
    channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
    wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
    channel.AddPropagationLoss("ns3::RangePropagationLossModel","MaxRange",DoubleValue(350));
    phy.SetChannel(channel.Create());
    AdhocDevices.Add(wifi.Install(phy,mac,AdhocNodes));

    InternetStackHelper internet;
    OlsrHelper olsr;
    internet.SetRoutingHelper(olsr);
    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 sink_app;

    PacketSinkHelper packetSink("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(),port));
    sink_app=packetSink.Install(AdhocNodes);
    sink_app.Start(Seconds(1.0));
    sink_app.Stop(Seconds(TotalTime));

    Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
    Ptr<UniformRandomVariable> y = CreateObject<UniformRandomVariable>();
    x->SetAttribute("Min",DoubleValue(0));
    x->SetAttribute("Max",DoubleValue(30));
    for(int i=0; i<nodeNum; i++){
        for(int j=0; j<nodeNum; j++){
            if(i==j) continue;
            OnOffHelper onoff("ns3::UdpSocketFactory",InetSocketAddress(ipv4Interface.GetAddress(j), port));
            onoff.SetAttribute("StartTime",TimeValue(Seconds(x->GetInteger())));
            onoff.SetAttribute("StopTime",TimeValue(Seconds(TotalTime)));
            onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]")); // 전송 지속 시간
            onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=1]")); // 전송 중단 시간
            onoff.SetAttribute("DataRate", DataRateValue(DataRate("54Mbps"))); // 데이터 전송률
            onoff.SetAttribute("PacketSize",UintegerValue(2048));
            onoff.Install(AdhocNodes.Get(i));
        }
    }


    BasicEnergySourceHelper basicSourceHelper;
    EnergySourceContainer sources;
    DeviceEnergyModelContainer energyDevices;
    x->SetAttribute("Min",DoubleValue(2000));
    x->SetAttribute("Max",DoubleValue(6000));
    for(int i=0; i<nodeNum; i++){
        basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ",ns3::DoubleValue(x->GetValue()));
        sources.Add(basicSourceHelper.Install(AdhocNodes.Get(i)));
    }//초기 에너지량 랜덤성 부여
    ns3::WifiRadioEnergyModelHelper radioHelper;
   
    file<<"Tx,Rx Energy"<<std::endl;
    x->SetAttribute("Min",DoubleValue(0.02));
    x->SetAttribute("Max",DoubleValue(0.04));
    for(int i=0; i<nodeNum; i++){
        double snd = x->GetValue();
        double rcv = x->GetValue();
        radioHelper.Set("TxCurrentA",ns3::DoubleValue(snd));//전송 전류 0.017A
        radioHelper.Set("RxCurrentA",ns3::DoubleValue(rcv));
        file<<i<<": "<<snd<<", "<<rcv<<std::endl;
        energyDevices.Add(radioHelper.Install(AdhocDevices.Get(i),sources.Get(i)));
    }
    Simulator::Schedule(Seconds(1),&TracingParameter,sources,AdhocDevices);
    Simulator::Stop(Seconds(TotalTime));
    
    file<<"Inital Energy"<<std::endl;
    for(int i=0; i<nodeNum; i++){
        file<<i<<": "<<sources.Get(i)->GetRemainingEnergy()<<std::endl;
    }

    Simulator::Run();
    Simulator::Destroy();
    makeCsvFile("Result.csv",Data);
    file.close();
}

 

그리고 이전 글에 다루지 않은 내용이 있었는데, AODV에서 OLSR로 라우팅 프로토콜을 바꿨다.

AODV는 내 시뮬레이션 환경 특성상 잦은 위치 변경이 존재하는데 데이터 전송이 필요할 떄만 경로를 설정하는 프로토콜이라 오버헤드가 높다.

따라서 자꾸 negative delay를 유발하는 원인같아 OLSR로 바꾸었다.

시뮬레이션이 오래걸리는 관계로 시간은 300초로 줄였다.

 

이제 여기서 추가로 생각할 점은

1. Result.csv에서 averageTP가 계속 0인 노드가 발생한다는 점이다. 결국 해당 노드로 어떠한 데이터도 가지 않았다는 것인데 프로토콜이나 노드에 LOG를 찍어서 알아봐야겠다. 지금 간단히 드는 생각은 mobility model에서 speed와 pause 타임을 조금 조절해주는 방향을 생각하고 있다.

=> 시뮬레이션 시간과 노드들의 speed 값을 조금 수정해주니 결국 모든 노드가 연결되었다. 이동성이 너무 적은 특이 개체에 대해 짧은 시뮬레이션 시간동안 찾아내지 못한 것 같다.

 

2. 얻어진 데이터 중 node의 속도, 방향과 위치를 이용해 구한 상대거리를 어떻게 점수로 변환할 지를 고민해야한다.

 

오늘은 여기까지 하고 후에 교수님과 이야기를 해보아야겠다.