Files
templates/tools/dsview/tests/scope_demo_test.cpp
T

32 lines
5.7 KiB
C++

#include "scope_demo.h" // Проверяем тот же переносимый источник, который подключён к настоящему DSView.
#include <cassert> // Ошибка физической модели должна завершать нативную проверку ненулевым кодом.
#include <limits> // Нечисловые значения воспроизводят повреждённые входные параметры.
int main() { // Проверка не требует Qt, аппаратного анализатора или платы Zynq.
const double epsilon = 1e-9; // Допуск 1 нВ учитывает погрешность вычисления sin, сохраняя проверку амплитуды в вольтах.
for (unsigned channel = 0; channel < 4; ++channel) { // Все каналы проверяются независимо, включая две разные формы сигнала.
const double period = 1 / set_scope::hz[channel]; // Период в секундах рассчитывается из частоты исходного эмулятора Zynq.
assert(std::abs(set_scope::value(channel, period / 4) - set_scope::peak[channel]) < epsilon); // Четверть периода даёт положительный пик у обеих форм.
assert(std::abs(set_scope::value(channel, 3 * period / 4) + set_scope::peak[channel]) < epsilon); // Три четверти периода дают отрицательный пик.
assert(std::abs(set_scope::value(channel, -period / 4) + set_scope::peak[channel]) < epsilon); // Отрицательное время сохраняет непрерывность фазы при прокрутке.
assert(std::abs(set_scope::value(channel, period / 8) - set_scope::value(channel, period * 5.125)) < epsilon); // Сдвиг на пять целых периодов не изменяет напряжение.
const auto full = set_scope::extrema(channel, 0, 500); // Пятьсот секунд моделируют очень длинную развёртку с сотнями тысяч периодов в пикселе.
assert(full.low == -set_scope::peak[channel] && full.high == set_scope::peak[channel]); // Огибающая обязана сохранять оба пика без алиасинга.
const auto narrow = set_scope::extrema(channel, period * 0.20, period * 0.30); // Внутренний максимум нельзя обнаружить только по концам интервала.
assert(narrow.high == set_scope::peak[channel]); // Аналитический расчёт обязан найти пик между экранными отсчётами.
const auto reverse = set_scope::extrema(channel, period * 0.30, period * 0.20); // Переставленные границы воспроизводят обратное направление выделения.
assert(reverse.low == narrow.low && reverse.high == narrow.high); // Направление просмотра не должно менять диапазон напряжения.
for (int index = 0; index < 300; ++index) { // Непериодическая сетка интервалов выявляет ошибки поиска внутренних экстремумов.
const double first = (index - 150) * period / 37, last = first + period / 13; // Интервалы охватывают отрицательное время и разные положения относительно фронтов.
const auto range = set_scope::extrema(channel, first, last); // Огибающая вычисляется производственным алгоритмом с постоянной сложностью.
for (int sample = 0; sample <= 100; ++sample) { // Плотная независимая выборка проверяет отсутствие потерянных пиков и фронтов.
const double value = set_scope::value(channel, first + (last - first) * sample / 100); // Напряжение берётся внутри проверяемого временного интервала.
assert(value >= range.low - epsilon && value <= range.high + epsilon); // Ни одно значение идеального источника не должно выходить за рассчитанную огибающую.
} // Проверка включает меандр с разрывами и гладкий синус.
} // Всего проверяется более 120 тысяч точек на различных интервалах.
} // Проверены частоты, амплитуды, фаза и длинная развёртка всех четырёх источников.
assert(set_scope::value(4, 0) == 0); // Несуществующий пятый канал безопасно отклоняется.
assert(set_scope::value(0, std::numeric_limits<double>::infinity()) == 0); // Бесконечное время не распространяет NaN в геометрию Qt.
assert(set_scope::extrema(0, 0, std::numeric_limits<double>::quiet_NaN()).high == 0); // Повреждённая граница интервала возвращает определённый пустой диапазон.
return 0; // Нулевой код сообщает об успешной нативной проверке модели Zynq.
} // Исполняемый файл можно запускать на любой платформе с компилятором C++11.