如何用.cc源文件修改Omnet++/INET模块行为实现定向天线扇区搜索
解决Omnet++定向天线扇区扫描与连接检测的方案
核心修改思路
无需修改adhocHost核心代码,通过扩展移动性模块和添加自定义天线检测模块实现需求,避免破坏INET原有模型的兼容性。
1. 自定义扇区扫描移动性模块
替换LinearMobility,编写SectorScanMobility.cc/.h实现定时切换航向角的逻辑:
- 头文件定义核心参数:扇区数
M、单扇区停留时间scanDuration、初始航向角initialHeading、扇区角度间隔sectorAngle = 360/M initialize()中启动定时器,首次触发延迟设为0- 定时器触发时,顺时针计算下一扇区航向角(超过360取模),直接修改
heading变量后重置定时器 - 保持速度为0,确保主机位置固定,仅切换天线指向
示例代码片段(.cc):
#include "inet/mobility/base/MovingMobilityBase.h" using namespace inet; class SectorScanMobility : public MovingMobilityBase { protected: int numSectors; simtime_t scanTime; double sectorAngle; int currentSector = 0; cMessage *scanTimer = nullptr; virtual void initialize(int stage) override { MovingMobilityBase::initialize(stage); if (stage == INITSTAGE_LOCAL) { numSectors = par("numSectors"); scanTime = par("scanTime"); sectorAngle = 360.0 / numSectors; scanTimer = new cMessage("scanTimer"); scheduleAt(simTime(), scanTimer); } } virtual void handleSelfMessage(cMessage *msg) override { if (msg == scanTimer) { currentSector = (currentSector + 1) % numSectors; heading = initialHeading + currentSector * sectorAngle; emit(headingChangedSignal, heading); scheduleAt(simTime() + scanTime, scanTimer); } else MovingMobilityBase::handleSelfMessage(msg); } virtual void finish() override { cancelAndDelete(scanTimer); MovingMobilityBase::finish(); } }; Define_Module(SectorScanMobility);
在NED文件注册模块并替换原移动性组件:
module SectorScanMobility extends inet.mobility.base.MovingMobilityBase { parameters: int numSectors = default(8); simtime_t scanTime = default(1s); @class(SectorScanMobility); }
2. 天线检测与信息存储
在主机内添加AntennaScanner.cc/.h模块,绑定定向天线信号监听邻居:
- 依赖INET的
IRadioListener接口,订阅receptionStarted信号 - 检测到其他天线信号时,获取发送方主机名、自身当前航向角,存储到本地
std::map结构 - 检测信息可通过
EV输出,或传递给上层MAC模块为后续扩展做准备
示例代码片段:
#include "inet/physicallayer/wireless/common/contract/packetlevel/IRadio.h" #include "inet/physicallayer/wireless/common/radio/Radio.h" using namespace inet; class AntennaScanner : public cSimpleModule, public IRadioListener { protected: Radio *radio = nullptr; std::map<std::string, double> detectedAntennas; virtual void initialize(int stage) override { cSimpleModule::initialize(stage); if (stage == INITSTAGE_LOCAL) { radio = getModuleFromPar<Radio>(par("radioModule"), this); radio->addListener(this); } } virtual void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override { if (signalID == IRadio::receptionStartedSignal) { auto radioSignal = check_and_cast<RadioSignal *>(obj); auto senderHost = findContainingNode(radioSignal->getTransmitter()->getOwner()); std::string hostName = senderHost->getName(); auto mobility = getModuleFromPar<IMobility>(par("mobilityModule"), this); double currentHeading = mobility->getHeading(); detectedAntennas[hostName] = currentHeading; EV_INFO << "Detected antenna from " << hostName << " at heading " << currentHeading << endl; } } }; Define_Module(AntennaScanner);
在adhocHost的NED定义中添加该模块:
module ExtendedAdhocHost extends inet.node.adhoc.AdhocHost { submodules: antennaScanner: AntennaScanner { parameters: radioModule = "^.wlan[0].radio"; mobilityModule = "^.mobility"; } }
3. .ini文件配置
- 使用自定义
ExtendedAdhocHost替代原生adhocHost - 配置扇区扫描参数:
*.host*.mobility.type = "SectorScanMobility" *.host*.mobility.numSectors = 6 *.host*.mobility.scanTime = 2s *.host*.mobility.initialHeading = 0deg *.host*.mobility.speed = 0m/s
4. 状态机集成
将现有状态机逻辑整合到AntennaScanner或单独模块中:
- 用
cFSM类管理扫描、检测、握手等状态切换 - 检测到目标天线后,触发自定义控制报文实现握手逻辑
注意事项
- 确保定向天线
beamWidth参数设置为360/M,使单扇区匹配波束范围 - 测试阶段可关闭MAC层自动连接,先验证扫描与检测逻辑
- 后续扩展MAC层时,直接读取
AntennaScanner存储的天线信息即可
内容的提问来源于stack exchange,提问作者Drew.Lam
相关产品推荐
相关产品推荐

