симуляция — C ++ Имитация последовательности импульсов

Я пытаюсь смоделировать форму импульса в моем приложении
и мне нужен способ отслеживать импульсы, чтобы я мог повторить
их последовательность. Из рисунка, показанного ниже, я хотел бы сделать следующее:
смоделируйте первые три импульса (импульс 1-3), затем смоделируйте импульс 4
сразу после импульса 3 и имитировать импульс 5 сразу после 4.
Затем повторите всю последовательность N раз.

Как показано на диаграмме, у меня есть интервал в секундах,
время начала первого импульса в секундах и длительность
каждый импульс также в секундах. Мое приложение будет работать в режиме реального времени
в цикле выполнения, где он будет выполняться с частотой 1 Гц.

У меня вопрос, как я могу отслеживать все импульсы и убедиться,
они все симулированы по отношению друг к другу? Что я имею в виду под имитацией,
например, я хотел бы напечатать простое утверждение во время
Первые три импульса, и то же самое для импульсов 4 и 5. Может ли кто-то предложить псевдо
алгоритм по крайней мере для этой операции?

введите описание изображения здесь

1

Решение

Определение класса sequence следующим образом, мы можем просто проверить активность каждого импульса sequence::isActive,
ДЕМО здесь.

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();
}
};
1

Другие решения

Предполагая, что я правильно понял проблему, я бы использовал модульно-арифметику и охарактеризовал каждую последовательность импульсов как булеву функцию с меткой времени в качестве параметра функции, например:

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

Преимущество этого состоит в том, что вы можете моделировать бесконечную серию импульсов, используя только небольшой фиксированный объем памяти. Это также позволяет вам эффективно запрашивать, какое ожидаемое состояние каждой последовательности импульсов было / будет в любое прошлое / будущее время (т. Е. Не только как в текущее время), если вам нужно это сделать.

Вот простая демонстрационная программа, которая распечатывает тиккерную ленту из четырех импульсов в течение 100 смоделированных «секунд»:

#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 ]
[...]
0

По вопросам рекламы [email protected]