QualNet节点放置与移动

本文详细介绍了QualNet中节点的初始化位置、移动模型、放置方法和移动实现过程。重点解析了节点移动数据结构、预初始化、组移动模型以及移动实现的内部逻辑,强调了在仿真过程中无法动态修改节点移动参数,需要通过自定义代码实现。
摘要由CSDN通过智能技术生成

在原稿基础上添加部分:之前发这篇博客时只是粗略看了代码,并没有深入细究。经过这几天的开发,发现QualNet自带的移动模型,不论是随机路径点、组移动、文件设置路径点,都是在初始化阶段就已经把所有要经过的路径点和到达时刻计算好,存入目的地列表,然后在仿真中,根据相应时刻的到达,将节点移动到相应位置。在仿真过程中,无法添加新的路径点,即无法随心所欲地在中途修正节点的移动参数。 解决办法是,初始化设定节点都不移动,即不调用任何移动模型,然后在仿真过程中,如果需要移动节点时,自己设定目的地和到达时刻,把移动函数的代码复制过来,就可以实现。不需要插入目的地列表,也不需要从列表中取出目的地,当场设定、当场移动。

1 初始化节点位置

struct NodePositions {
    NodeAddress       nodeId;
    int               partitionId;
    NodePlacementType nodePlacementType;
    MobilityData*     mobilityData;
};

节点位置数据结构包含节点id、节点所在分区id、节点放置类型、节点移动数据。在main函数中调用 MOBILITY_AllocateNodePositions()函数分配节点位置内存,读取用户配置文件,设置每个节点放置类型,再调用MOBILITY_PreInitialize()函数预先初始化移动数据。

void MOBILITY_AllocateNodePositions(
        numNodes,
        nodeIdArray,
        &nodePositions,
        &nodePlacementTypeCounts,
        &nodeInput,
        seedVal);
{
    NodePositions* nodePositions =
        (NodePositions*)MEM_malloc(sizeof(NodePositions) * numNodes);
    int* nodePlacementTypeCounts =
        (int*)MEM_malloc(sizeof(int) * NUM_NODE_PLACEMENT_TYPES);

    for (i = 0; i < NUM_NODE_PLACEMENT_TYPES; i++) {
        nodePlacementTypeCounts[i] = 0;
    }

    for (i = 0; i < numNodes; i++) 
    {
        nodePositions[i].nodeId = nodeIdArray[i];
        nodePositions[i].partitionId = 0;

        //设置节点放置类型        
        IO_ReadString(
            nodeIdArray[i],
            ANY_ADDRESS,
            nodeInput,
            "NODE-PLACEMENT",
            &wasFound,
            buf);        

        if (strcmp(buf, "RANDOM") == 0) {
            nodePositions[i].nodePlacementType = RANDOM_PLACEMENT;
            nodePlacementTypeCounts[RANDOM_PLACEMENT]++;
        }
        else if (strcmp(buf, "UNIFORM") == 0) {
            nodePositions[i].nodePlacementType = UNIFORM_PLACEMENT;
            nodePlacementTypeCounts[UNIFORM_PLACEMENT]++;
        }
        else if (strcmp(buf, "GRID") == 0) {
            nodePositions[i].nodePlacementType = GRID_PLACEMENT;
            nodePlacementTypeCounts[GRID_PLACEMENT]++;
        }
        else if (strcmp(buf, "FILE") == 0) {
            nodePositions[i].nodePlacementType = FILE_BASED_PLACEMENT;
            nodePlacementTypeCounts[FILE_BASED_PLACEMENT]++;
        }
        else if (strcmp(buf, "GROUP") == 0) {
            nodePositions[i].nodePlacementType = GROUP_PLACEMENT;
            nodePlacementTypeCounts[GROUP_PLACEMENT]++;
        }
        else if (strcmp(buf, "EXTERNAL") == 0) {
            nodePositions[i].nodePlacementType = EXTERNAL_PLACEMENT;
            nodePlacementTypeCounts[EXTERNAL_PLACEMENT]++;
        }
        else {
            char errorMessage[MAX_STRING_LENGTH];

            sprintf(errorMessage, "Unknown NODE-PLACEMENT type: %s.\n", buf);
            ERROR_ReportError(errorMessage);
        }

        // 分配内存并初始化节点移动类型        
        nodePositions[i].mobilityData =
            (MobilityData*)MEM_malloc(sizeof(MobilityData));
        memset(nodePositions[i].mobilityData, 0, sizeof(MobilityData));

        MOBILITY_PreInitialize(
            nodeIdArray[i],
            nodePositions[i].mobilityData,
            nodeInput,
            seedVal);
    }		
}

 2 预先初始化节点移动数据

struct MobilityData 
{
    MobilityType mobilityType;
    D_Float32 distanceGranularity;
    D_BOOL groundNode;
    RandomSeed        seed;
    //组移动模型相关
    RandomSeed        groupSeed;
    int               groupIndex;
    Coordinates groupTerrainOrigin;
    Coordinates groupTerrainDimensions;
    double groupMaxSpeed;
    double groupMinSpeed;
    double internalMaxSpeed;
    double internalMinSpeed;
    clocktype internalMobilityPause;
    //序列号,未来、当前、过去位置
    int               sequenceNum;
    MobilityElement*  next;
    MobilityElement*  current;
    MobilityElement*  past[NUM_PAST_MOBILITY_EVENTS];
    //目的地数量、目的地列表
    int               numDests;
    MobilityElement*  destArray;
    MobilityRemainder remainder;
    void *mobilityVar;
};

节点移动数据结构主要包括移动类型、当前过去和未来位置、目的地列表等,组移动时还有组内组件最大最小移动速度等参数。MOBILITY_PreInitialize()函数读取用户配置文件,设置节点移动类型等参数,初始化节点当前过去和未来位置。

void MOBILITY_PreInitialize(
    NodeAddress nodeId,
    MobilityData* mobilityData,
    NodeInput* nodeInput,
    int seedVal)
{    
    // 设置节点移动类型.
    IO_ReadString(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值