c++simulationmodelingpulse

C++ Simulate sequence of pulse trains


I'm trying to model a pulse waveform in my application and I need a way to keep track of the pulses so that I can repeat their sequence. From the figure shown below, what I'd like to do is simulate the first three pulses (pulse 1-3), then simulate pulse 4 immediately after pulse 3, and simulate pulse 5 immediately after 4. Then repeat the whole sequence N times.

As shown in the diagram, I have the interval in seconds, the start time of the first pulse in seconds, and the duration of each pulse also in seconds. My application will be running real time in a run loop where it will be executing at 1 Hz.

My question is, how do I keep track of all the pulses and make sure they are all simulated with respect to each other? What I mean by simulated is, for example I'd like to print a simple statement during the duration of the 1st three pulses, and the same for pulse 4 and 5. Can someone suggest a pseudo algorithm at the very least for this operation?

enter image description here


Solution

  • Defining the class sequence as follows, we can simply check activity of each pulse by sequence::isActive. 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();
        }
    };