1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 /*
30 * Copyright (c) 2019, Texas Instruments Incorporated
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 *
37 * * Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 *
40 * * Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 *
44 * * Neither the name of Texas Instruments Incorporated nor the names of
45 * its contributors may be used to endorse or promote products derived
46 * from this software without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
50 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
55 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
56 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
57 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
58 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 *
60 */
62 #include <iostream>
63 #include "datasource.h"
64 #include <QtCharts/QXYSeries>
65 #include <QtCharts/QAreaSeries>
66 #include <QtQuick/QQuickView>
67 #include <QtQuick/QQuickItem>
68 #include <QtCore/QDebug>
70 #include <QtCore/QtMath>
72 QT_CHARTS_USE_NAMESPACE
74 Q_DECLARE_METATYPE(QAbstractSeries *)
75 Q_DECLARE_METATYPE(QAbstractAxis *)
77 DataSource::DataSource(QQuickView *appViewer, QObject *parent) :
78 QObject(parent),
79 m_appViewer(appViewer)
80 {
81 qRegisterMetaType<QAbstractSeries*>();
82 qRegisterMetaType<QAbstractAxis*>();
84 for (int i=0; i<DISPLAY_VECTOR; i++)
85 {
86 generateData(i, 0, 256);
87 }
89 setPdmStage("Waiting for sensor data......");
90 setAnomalyDetection("");
92 printCalibration = true;
93 printDetection = true;
94 }
96 void DataSource::update(int sel_waveform, QAbstractSeries *series)
97 {
98 if (series && (m_last_read > 0)) {
99 QXYSeries *xySeries = static_cast<QXYSeries *>(series);
100 QVector<QPointF> points = m_data[sel_waveform];
101 // Use replace instead of clear + append, it's optimized for performance
102 qreal x(0);
103 qreal y(0);
104 bool printAnomaly = true;
105 for (int j = 0; j < m_sampleCount; j ++) {
106 y = m_samplesArray[DISPLAY_VECTOR*j + sel_waveform];
107 x = j;
108 /* Time series 4 is for displaying the anomaly detection threshold
109 * (positive value). It is also carrying the stage information
110 * (calibration or anomaly detection): offset of 100 for calibration;
111 * offset of -100 for anomaly detection, as used in motor_pdm_process() */
112 if (sel_waveform==4) {
113 if (y > 100) {
114 y = y - 100;
115 setPdmStage("Calibration......");
116 /* Print the calibration message once */
117 if (printCalibration) {
118 std::cout << "Calibration......" << std::endl;
119 printCalibration = false;
120 }
121 }
122 if (y < -50) {
123 y = y + 100;
124 setPdmStage("Looking for anomaly......");
125 /* Print the detection message once */
126 if (printDetection) {
127 std::cout << "Looking for anomaly......" << std::endl;
128 printDetection = false;
129 }
130 }
131 }
132 points.replace(j, QPointF(x, y));
133 /* Time series 5 is for displaying the anomaly detection results:
134 * value 0 indicates the normal operation, and positive value
135 * anomaly detection threshold*ratio(>1) indicates anomalies */
136 if ((sel_waveform==5) && (y>0)) {
137 setAnomalyDetection("Anomaly detected!!!");
138 /* Print the anomaly message once per the series update.
139 * This allows anomaly messages printed out for the duration
140 * of anomalies without slowing down the QT GUI display. */
141 if (printAnomaly) {
142 std::cout << "Anomaly detected!!!" << std::endl;
143 printAnomaly = false;
144 /* Enable print of the detection message after the anomaly message
145 * in printed out. This is to allow going back to the detection
146 * message when there are no more anomalies. */
147 printDetection = true;
148 }
149 }
150 if ((sel_waveform==5) && (y<=0)) {
151 setAnomalyDetection("");
152 }
153 }
154 xySeries->replace(points);
155 }
156 }
158 int motor_pdm_get_data(int samples_count, double *samples_array);
159 void DataSource::getdata(void)
160 {
161 m_last_read = motor_pdm_get_data(m_sampleCount, m_samplesArray);
162 }
164 void DataSource::generateData(int sel_waveform, int type, int colCount)
165 {
166 // Remove previous data
167 m_data[sel_waveform].clear();
169 std::cout << std::endl << "__generating (" << sel_waveform << ":" << colCount << " type:" << type << ")____" << std::endl;
171 m_sampleCount = colCount;
172 // Append the new data depending on the type
173 QVector<QPointF> points;
174 points.reserve(colCount);
175 m_overlapWindow = type;
176 for (int j(0); j < colCount; j++) {
177 qreal x(0);
178 qreal y(0);
179 points.append(QPointF(x, y));
180 }
181 m_data[sel_waveform] = points;
182 }