C++ 模拟脉冲串序列

C++ Simulate sequence of pulse trains

我正在尝试在我的应用程序中模拟脉冲波形 我需要一种方法来跟踪脉搏以便我可以重复 他们的顺序。从下图中,我想做的是 模拟前三个脉冲(脉冲 1-3),然后模拟脉冲 4 在脉冲 3 之后立即模拟,并在脉冲 4 之后立即模拟脉冲 5。 然后重复整个序列N次。

如图所示,我有以秒为单位的间隔, 以秒为单位的第一个脉冲的开始时间,以及持续时间 每个脉冲也以秒为单位。我的应用程序将 运行ning 实时 在 运行 循环中,它将以 1 Hz 的频率执行。

我的问题是,如何跟踪所有脉冲并确保 它们都是相对于彼此模拟的吗?我所说的模拟的意思是, 例如,我想在 第一个三个脉冲,脉冲 4 和脉冲 5 相同。有人可以建议一个伪 算法至少用于此操作?

假设我正确地理解了这个问题,我会这样做的方法是使用模算术,并将每个脉冲序列表征为一个布尔函数,并将时间戳作为函数的参数,例如:

// Returns true iff the pulse is present at the specified time
bool IsPulseActiveAtTime(long int theTime);

这样做的好处是您可以模拟无限系列的脉冲,同时只使用少量固定的内存。如果您需要,它还允许您在任何 past/future 时间(即不仅仅是当前时间)有效地查询每个脉冲序列 was/will-be 的预期状态。

这是一个简单的演示程序,它在 100 个模拟过程中打印出四个脉冲的自动收报机磁带 "seconds":

#include <stdio.h>

class PulseSequence
{
public:
   PulseSequence(long int startTime, long int duration, long int interval)
      : _startTime(startTime)
      , _duration(duration)
      , _interval(interval)
   {
      // empty
   }

   bool IsPulseActiveAtTime(long int theTime) const
   {
      if (theTime < _startTime) return false;
      return ((theTime-_startTime) % _interval) < _duration;
   }

private:
   const long int _startTime;  // time at which the first pulse starts
   const long int _duration;   // length of each pulse
   const long int _interval;   // difference between the start-time of one pulse and the start-time of the next
};

// Unit test/example
int main(int, char **)
{
   const int NUM_PULSE_SEQUENCES = 4;

   const PulseSequence sequences[NUM_PULSE_SEQUENCES] = {
      PulseSequence(0, 3, 5),
      PulseSequence(1, 2, 6),
      PulseSequence(3, 3, 4),
      PulseSequence(5, 1, 3),
   };

   for (long int curTime = 0; curTime < 100; curTime++)
   {
      printf("curTime=%02li: [", curTime);
      for (int i=0; i<NUM_PULSE_SEQUENCES; i++) putchar(sequences[i].IsPulseActiveAtTime(curTime)?('0'+i):' ');
      printf("]\n");
   }
   return 0;
}

输出如下所示:

$ ./a.out
curTime=00: [0   ]
curTime=01: [01  ]
curTime=02: [01  ]
curTime=03: [  2 ]
curTime=04: [  2 ]
curTime=05: [0 23]
curTime=06: [0   ]
curTime=07: [012 ]
curTime=08: [ 123]
curTime=09: [  2 ]
curTime=10: [0   ]
curTime=11: [0 23]
curTime=12: [0 2 ]
curTime=13: [ 12 ]
[...]

定义classsequence如下,我们可以简单的通过sequence::isActive检查每个脉冲的activity。 DEMO is here.

class sequence
{    
    int period_;
    int start_;
    int end_;
    std::array<std::pair<int,int>, 5> pulses;

public:
    sequence(int start, int duration, int interval, int repeat) 
        : period_(2*interval+3*duration),
          start_(start),
          end_(start+repeat*period_),
          pulses
          {{
              {0                    , duration             }, // pulse 1
              {interval             , interval  +  duration}, // pulse 2
              {2*interval           , 2*interval+  duration}, // pulse 3
              {2*interval+  duration, 2*interval+2*duration}, // pulse 4
              {2*interval+2*duration, period_              }  // pulse 5
          }}
    {
        if(duration <= 0){
            throw std::runtime_error("Duration must be positive integer.");
        }

        if(interval < 0){
            throw std::runtime_error("Interval must be non negative integer.");
        }
    }

    bool isActive(int time, std::size_t idx) const
    {
        const auto& pulse = pulses[idx];

        // 0 for each start time of sequence (pulse 1)
        const auto refTime = (time - start_)%period_;

        return (pulse.first <= refTime) && (refTime < pulse.second) && (time < end_);
    }

    int getPeriod() const{
        return period_;
    }

    int getStartTime() const{
        return start_;
    }

    int getEndTime() const{
        return end_;
    }

    std::size_t getPulseNum() const{
        return pulses.size();
    }
};