본문

OMNeT++ Signals #3. Signal-Based Statistics Recording-2

통계 목적으로 시그널을 호출(emit)하는 것은 다른 목적을 위해 시그널을 호출하는 것과 크게 다른점이 없다. 통계적 시그널에는 수량적(numeric)값을 사용하며, 따라서 오버로드된 emit() 함수는 long, double, simtime_t을 허용하며 더욱 효율적인 작업을 가능하게 한다. 


* timestamp 와 함꼐 호출하기

호출된 값은 현재 시뮬레이션 시간과 연관되어 있다. 다른 timestamp를 사용하기 원하는 경우, cOutVector의 recordWithTimestamp()를 사용할 수 있다. 예를 들어, 무선 프레임 수신이 성공할 때마다 시그널을 호출하고자 하는 경우를 생각해 보자.하지만, 패킷 수신이 성공하는지 여부는 수신이 끝난 이후에 판별할 수 있다. 따라서, 시간이 수신 완료를 기점으로 설정되므로, 이전의 시간에 맞춰 조정되어야 한다.


원하는 시간정보와 함께 값(신호)를 호출하고자 할때, cTimestampedValue 클래스(public 멤버변수로 simtime_t time, double value값만 존재한다)에 (timestamp, value)쌍이 채워진 후, 이를 emit(simsignal_t, cObject*) 메소드를 통해 호출해야 한다. 참고할 것은, cTimestampedValue는 시그널 메커니즘의 일부가 아니라는 것이다. 대신,  OMNeT++에서 제공하는 결과 기록 리스너가 정의되어 cTimestampedValue를 받아들일 수 있는 것이다. 또한 만약 성능에 민감한 경우라면, cTimestampedValue 객체는 클래스 멤버 혹은 정적 변수로 생성되어, 객체 생성,소멸에 드는 시간을 절약할 수 있다. 


simtime_t frameReceptionStartTime = ...;

double receivePower = ...;

cTimestampedValue tmp(frameReceptionStartTime, receivePower);

emit(recvPowerSignal, &tmp);


* 비수량적 값과함께 호출하기

가끔은 다양한 목적을 갖는 시그널을 사용할 필요가 있다. 혹은 기존에 있던 통계와 관련없는 시그널을 사용하여 결과값 계산에 도움을 줄 수 있다. 이러한 요구에 맞추어, const char* 혹은 cObject*와 같은 비수량적(non-numeric) 타입을 갖는 시그널이 사용될 수 있다. 이러한 값들이 숫자로 사용되는 어디서든지, 다음과 같은 규칙이 내장된 결과 기록 리스너에서 사용된다.

* 문자열은 1.0으로, NULL은 0.0으로 기록된다. CITimestampedValue로 캐스팅될 수 있는 객체들은 getSignalTime()과 getSignalValue()메소드를 사용하여 기록될 수 있다. 다른 객체들은 NULL을 제외하면 모두 1.0으로 기록된다.


CITimestampedValue는 c++ 인터페이스로서, 다른 클래스의 base 클래스로 사용될 수 있다. 또한 아래와 같이 선언되어 있다.

class cITimestampedValue {

     public:

          virtual ~cITimestampedValue() {}

          virtual double getSignalValue(simsignal_t signalID) = 0;

          virtual simtime_t getSignalTime(simsignal_t signalID);

};


getSignalValue()는 순수 가상함수이지만, getSignalTIme()은 현재 시뮬레이션 시간을 반환하는 기능이 기본적으로 구현되어 있다. signalID인자는 동일한 클래스가 서로다른 여러개의 시그널을 받을 수 있도록 해준다. 



기본적으로 제공되는 result filter, recorder에 더하여 사용자는 직접 이들을 정의할 수 있다. 모듈을 정의하고 새로운 NED 함수를 만드는것 처럼, c++ 언어를 기반으로 구현체를 만들어야 하고, 이것을 OMNeT++가 인지할 수 있도록 매크로를 등록해야 한다. 새로운 resuilt filter/recorder는 source=와 record= 속성에서 사용될 수 있다.


result filter를 만들고자 한다면, 반드시 cResultFilter을,더욱 상세하게 말하자면 cNumbericResultFielter 혹은 cObjectResultFilter를 서브클래스 해야 한다. 새로운 result filter  클래스는 Register_ResultFilter(NAME, CLASSNAME) 매크로를 사용하여 등록되어야 한다. 이와 비슷하게, result recorder를 만들기 위해서는 cResultRecorder, 더 자세하게 말하자면 cNumericResultRecorder 클래스를 서브클래스 해야 하며 역시 Register_ResultRecorder(NAME, CLASSNAME) 매크로를 사용하여 등록시켜야 한다.


/**

*Filter that outputs the sum of signal values divided by the measurement

*interval (simtime minus warmup period).

*/

class SumPerDurationFilter : public cNumericResultFilter {

     protected:

          double sum;

          virtual bool process(simtime_t& t, double& value);

     public:

          SumPerDurationFilter() {sum = 0;}

};

Register_ResultFilter("sumPerDuration", SumPerDurationFilter);


bool SumPerDurationFilter::process(simtime_t& t, double& value)

{

     sum += value;

     value = sum / (simTime() - simulation.getWarmupPeriod());

     return true;

}





[그림] result filter와 result recorder 클래스의 상속관계



원문출처 : OMNeT++ User Manual Version 4.2.2 : 4.15 Signal-Based Statistics Recording

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.