В настоящее время я работаю над алгоритмом для Veins 4.7.1, где многие транспортные средства и RSU отправляют и получают сообщения.
Теперь я хочу, чтобы мой RSU выполнял периодические расчеты независимо от того, было ли отправлено или получено сообщение. Проблема в том, что я не знаю, как и где реализовать эти периодические вычисления в моем приложении RSU.
Моей первой попыткой было реализовать вычисления в одной из функций, представленных в BaseWaveApplLayer
. Я думал добавить их в handlePositionUpdate(cObject* obj)
с таймером, но я явно не могу использовать эту функцию в приложении RSU.
Любая помощь могла бы быть полезна.
Спасибо за ваш ответ, кажется, у меня были некоторые недоразумения по поводу обработки сообщений. Теперь стало ясно
Наконец-то я решил свою проблему благодаря комментарию Венту.
Я просто создал встроенный тип сообщения wsm в BaseApplLayer.h
и реализовал следующий код в TraCIDemoRSU11p.cc
void TraCIDemoRSU11p::initialize(int stage) {
MyBaseWaveApplLayer::initialize(stage);
if (stage == 0) { // Members and pointers initialization
}
else if (stage == 1) { // Members that require initialized other modules
// Message Scheduling
scheduleAt(simTime(), sendSelfMsgEvt);
}
}
void TraCIDemoRSU11p::handleSelfMsg(cMessage* msg) {
switch (msg->getKind()) {
case SELF_MSG_EVT: {
std::cout << "RSU Self Message received at " << simTime().dbl() << std::endl;
// Perform Calculations
// ...
// Self Message sending:
scheduleAt(simTime() + PERIOD, sendSelfMsgEvt);
break;
}
default: {
if (msg)
DBG_APP << "APP: Error: Got Self Message of unknown kind! Name: "
<< msg->getName() << endl;
break;
}
}
}
Использование собственных сообщений является типичным способом выполнения периодической задачи в модуле. Однако это может быть проблематично, если вам нужно выполнить несколько задач. Сначала вам нужно создать все сообщения, правильно их обработать и не забыть cancelAndDelete
их в деструкторе.
Вы можете добиться того же результата с меньшим количеством кода, используя утилиту Veins под названием TimerManager
(добавлена в Veins 4.7.). Вам нужно иметь члена TimerManager
в модуле и указывать задачи в initialize
. Преимущество в том, что если вы решите добавить новые периодические задачи позже, это так же просто, как добавить их в initialize
, а TimerManager
позаботится обо всем остальном. Это может выглядеть так:
class TraCIDemoRSU11p : public DemoBaseApplLayer {
public:
void initialize(int stage) override;
// ...
protected:
veins::TimerManager timerManager{this}; // define and instantiate the TimerManager
// ...
};
И initialize
void TraCIDemoRSU11p::initialize(int stage) {
if (stage == 0) { // Members and pointers initialization
}
else if (stage == 1) { // Members that require initialized other modules
// encode the reaction to the timer firing with a lambda
auto recurringCallback = [this](){
//Perform Calculations
};
// specify when and how ofthen a timer shall fire
auto recurringTimerSpec = veins::TimerSpecification(recurringCallback).interval(1);
// register the timer with the TimerManager instance
timerManager.create(recurringTimerSpec, "recurring timer");
}
}
Подробнее читайте в руководстве на Github: Руководство TimerManager. Код с комментариями взят оттуда.
Как насчет отправки собственного сообщения через определенные промежутки времени?