

Queue Test
Tsamp - 순환 버퍼처럼 쓰던 배열을 큐로 바꿔서 교차 상관, 변화량 계산 다시 구현해서 Test 교차 상관 계산 범위가 -1~1의 범위를 벗어남
@2338ba20710f77cebc7e0fb6967332db20c7695b
--- ArcCTRL-23-NEXTSQ-CPU1/Main_Resource/source/FaultProcess.cpp
+++ ArcCTRL-23-NEXTSQ-CPU1/Main_Resource/source/FaultProcess.cpp
... | ... | @@ -9,6 +9,8 @@ |
9 | 9 |
|
10 | 10 |
#include "Cpu1DeviceDefine.h" |
11 | 11 |
|
12 |
+int FT_chk = 0; |
|
13 |
+ |
|
12 | 14 |
void InitFaultSet() |
13 | 15 |
{ |
14 | 16 |
memset(&Fault, 0, (sizeof(Fault) / sizeof(int))); |
... | ... | @@ -230,7 +232,7 @@ |
230 | 232 |
Dout.Data.bit.Ch00 = 1; |
231 | 233 |
Dout.Data.bit.Ch01 = 1; |
232 | 234 |
|
233 |
- if(FT_uv_vis_correlation == 0) |
|
235 |
+ if(FT_chk == 0) |
|
234 | 236 |
{ |
235 | 237 |
FT_uv_vis_correlation = uv_vis_correlation; |
236 | 238 |
FT_uv_ir_correlation = uv_ir_correlation; |
... | ... | @@ -240,9 +242,15 @@ |
240 | 242 |
FT_uv_ir_change_correlation = uv_ir_change_correlation; |
241 | 243 |
FT_vis_ir_change_correlation = vis_ir_change_correlation; |
242 | 244 |
|
245 |
+ FT_uv_change_magnitude = uv_change_magnitude; |
|
246 |
+ FT_vis_change_magnitude = vis_change_magnitude; |
|
247 |
+ FT_ir_change_magnitude = ir_change_magnitude; |
|
248 |
+ |
|
243 | 249 |
FT_stddev = stddev; |
244 | 250 |
FT_adaptive_threshold = adaptive_threshold; |
245 | 251 |
FT_latest_change = latest_change; |
252 |
+ |
|
253 |
+ FT_chk = 1; |
|
246 | 254 |
} |
247 | 255 |
|
248 | 256 |
|
... | ... | @@ -430,8 +438,14 @@ |
430 | 438 |
FT_uv_ir_change_correlation = 0; |
431 | 439 |
FT_vis_ir_change_correlation = 0; |
432 | 440 |
|
441 |
+ FT_uv_change_magnitude = 0; |
|
442 |
+ FT_vis_change_magnitude = 0; |
|
443 |
+ FT_ir_change_magnitude = 0; |
|
444 |
+ |
|
433 | 445 |
FT_stddev = 0; |
434 | 446 |
FT_adaptive_threshold = 0; |
435 | 447 |
FT_latest_change = 0; |
448 |
+ |
|
449 |
+ FT_chk = 0; |
|
436 | 450 |
} |
437 | 451 |
|
--- ArcCTRL-23-NEXTSQ-CPU1/Main_Resource/source/RoutineTsamp.cpp
+++ ArcCTRL-23-NEXTSQ-CPU1/Main_Resource/source/RoutineTsamp.cpp
... | ... | @@ -6,17 +6,20 @@ |
6 | 6 |
// Author : KimJeongWoo |
7 | 7 |
// Last modified Date : |
8 | 8 |
//-------------------------------------------------------// |
9 |
- |
|
10 | 9 |
#include "Cpu1DeviceDefine.h" |
10 |
+#include <numeric> // std::accumulate와 std::inner_product를 위해 필요 |
|
11 |
+#include <vector> |
|
12 |
+#include <cmath> // For sqrt() and std::abs() |
|
11 | 13 |
|
12 |
- int Testpcs4 = 0; |
|
13 |
- int Adc_BUTTON = 0; |
|
14 |
+int Testpcs4 = 0; |
|
15 |
+int Adc_BUTTON = 0; |
|
14 | 16 |
|
15 |
- int Chk_Botton = 0; |
|
16 |
- int Chk_Botton_pre = 0; |
|
17 |
+int Chk_Botton = 0; |
|
18 |
+int Chk_Botton_pre = 0; |
|
17 | 19 |
|
18 |
-//순환 버퍼 |
|
19 |
-#define BUFFER_SIZE 5 //10 이상 커지면 순간적인 변화를 계산하지 못함? |
|
20 |
+// 순환 버퍼 |
|
21 |
+#define BUFFER_SIZE 10 |
|
22 |
+#include <cmath> // For sqrt() and std::abs() // 10 이상 커지면 순간적인 변화를 계산하지 못함? |
|
20 | 23 |
int currentIndex = 0; |
21 | 24 |
|
22 | 25 |
int UV_buffer[BUFFER_SIZE]; |
... | ... | @@ -28,119 +31,329 @@ |
28 | 31 |
|
29 | 32 |
// 변화량을 저장할 배열 |
30 | 33 |
int UV_change[BUFFER_SIZE], VIS_change[BUFFER_SIZE], IR_change[BUFFER_SIZE]; |
31 |
-int prev_avg =0; |
|
34 |
+int prev_avg = 0; |
|
32 | 35 |
|
33 |
-// 상관 계수를 계산하는 함수 |
|
34 |
-double calculate_correlation(const int *x, const int *y, int n) { |
|
35 |
- long long sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; |
|
36 |
- for (int i = 0; i < n; ++i) { |
|
37 |
- sum_x += x[i]; |
|
38 |
- sum_y += y[i]; |
|
39 |
- sum_x2 += (long long)x[i] * x[i]; |
|
40 |
- sum_y2 += (long long)y[i] * y[i]; |
|
41 |
- sum_xy += (long long)x[i] * y[i]; |
|
36 |
+////////////////////////////////////////////////////////// |
|
37 |
+// 큐 구조체 정의 |
|
38 |
+typedef struct { |
|
39 |
+ int items[BUFFER_SIZE]; |
|
40 |
+ int front; |
|
41 |
+ int rear; |
|
42 |
+ int size; |
|
43 |
+ double total; // 총합을 저장하기 위한 변수 |
|
44 |
+ int lastValue; // 마지막으로 추가된 값 |
|
45 |
+} Queue; |
|
46 |
+ |
|
47 |
+// 큐 초기화 함수 |
|
48 |
+void initQueue(Queue *q) { |
|
49 |
+ q->front = 0; |
|
50 |
+ q->rear = -1; |
|
51 |
+ q->size = 0; |
|
52 |
+ q->total = 0; |
|
53 |
+ q->lastValue = 0; // 초기화 시 마지막 값은 0으로 가정 |
|
54 |
+ memset(q->items, 0, sizeof(q->items)); |
|
55 |
+} |
|
56 |
+ |
|
57 |
+// 큐에 데이터 추가 및 누적 계산 수행 함수 |
|
58 |
+void enqueueAndUpdateStats(Queue *q, int value) { |
|
59 |
+ // 이전 값 저장 |
|
60 |
+ int prevValue = (q->size > 0) ? q->items[q->rear] : 0; |
|
61 |
+ |
|
62 |
+ // 큐에 데이터 추가 |
|
63 |
+ if (q->size == BUFFER_SIZE) { |
|
64 |
+ // 큐가 꽉 찼을 때, 가장 오래된 데이터를 빼고 새 데이터 추가 |
|
65 |
+ q->total -= q->items[q->front]; // 총합에서 가장 오래된 데이터 제거 |
|
66 |
+ q->front = (q->front + 1) % BUFFER_SIZE; |
|
67 |
+ } else { |
|
68 |
+ q->size++; |
|
42 | 69 |
} |
70 |
+ q->rear = (q->rear + 1) % BUFFER_SIZE; |
|
71 |
+ q->items[q->rear] = value; |
|
72 |
+ q->total += value; // 새 값 추가로 총합 업데이트 |
|
73 |
+ |
|
74 |
+ // 마지막 값 업데이트 |
|
75 |
+ q->lastValue = value; |
|
76 |
+ |
|
77 |
+ // 평균 및 변화량 계산은 필요에 따라 진행 |
|
78 |
+} |
|
79 |
+ |
|
80 |
+// 큐에서 데이터 제거 함수 (이 예제에서는 사용하지 않음) |
|
81 |
+int dequeue(Queue* q) { |
|
82 |
+ if (q->size == 0) { |
|
83 |
+ // printf("Queue is empty\n"); |
|
84 |
+ return -1; |
|
85 |
+ } |
|
86 |
+ else { |
|
87 |
+ int item = q->items[q->front]; |
|
88 |
+ q->front = (q->front + 1) % BUFFER_SIZE; |
|
89 |
+ q->size--; |
|
90 |
+ return item; |
|
91 |
+ } |
|
92 |
+} |
|
93 |
+//////////////////////////////////////////////////////// |
|
94 |
+ |
|
95 |
+// 큐 내 데이터의 평균을 계산하는 함수 |
|
96 |
+double calculateAverage(Queue* q) { |
|
97 |
+ int sum = 0; |
|
98 |
+ int i = 0; |
|
99 |
+ if (q->size > 0) { |
|
100 |
+ int idx = (q->front + i) % BUFFER_SIZE; |
|
101 |
+ sum += q->items[idx]; |
|
102 |
+ i++; |
|
103 |
+ } |
|
104 |
+ return q->size > 0 ? (double)sum / q->size : 0; |
|
105 |
+} |
|
106 |
+ |
|
107 |
+// 큐 내 모든 데이터의 평균 변화량을 계산하는 함수 |
|
108 |
+double calculateAverageChange(Queue* q) { |
|
109 |
+ if (q->size < 2) { |
|
110 |
+ // 큐에 데이터가 2개 미만일 때는 평균 변화량을 계산할 수 없음 |
|
111 |
+ return 0.0; |
|
112 |
+ } |
|
113 |
+ |
|
114 |
+ int currentIdx = q->front; |
|
115 |
+ int nextIdx = (currentIdx + 1) % BUFFER_SIZE; |
|
116 |
+ |
|
117 |
+ int changeSum = q->items[nextIdx] - q->items[currentIdx]; |
|
118 |
+ int count = 1; |
|
119 |
+ |
|
120 |
+ while (nextIdx != q->rear) { |
|
121 |
+ currentIdx = nextIdx; |
|
122 |
+ nextIdx = (nextIdx + 1) % BUFFER_SIZE; |
|
123 |
+ |
|
124 |
+ int currentChange = q->items[nextIdx] - q->items[currentIdx]; |
|
125 |
+ changeSum += currentChange; |
|
126 |
+ count++; |
|
127 |
+ } |
|
128 |
+ |
|
129 |
+ // 평균 변화량 계산 |
|
130 |
+ return (double)changeSum / count; |
|
131 |
+} |
|
132 |
+ |
|
133 |
+//////////////////////////////////////////////////////////////////////////// |
|
134 |
+// 상관 계수를 계산하는 함수 |
|
135 |
+double calculate_correlation(const int* x, const int* y, int n) { |
|
136 |
+ long long sum_x = std::accumulate(x, x + n, 0LL); |
|
137 |
+ long long sum_y = std::accumulate(y, y + n, 0LL); |
|
138 |
+ long long sum_x2 = std::inner_product(x, x + n, x, 0LL); |
|
139 |
+ long long sum_y2 = std::inner_product(y, y + n, y, 0LL); |
|
140 |
+ long long sum_xy = std::inner_product(x, x + n, y, 0LL); |
|
141 |
+ |
|
43 | 142 |
double numerator = (double)n * sum_xy - sum_x * sum_y; |
44 | 143 |
double denominator = sqrt(((double)n * sum_x2 - sum_x * sum_x) * ((double)n * sum_y2 - sum_y * sum_y)); |
45 |
- if (denominator == 0) return 0; // 분모가 0이면, 상관관계를 계산할 수 없음 |
|
144 |
+ |
|
145 |
+ if (denominator == 0) |
|
146 |
+ return 0; // 분모가 0이면, 상관관계를 계산할 수 없음 |
|
147 |
+ |
|
46 | 148 |
return numerator / denominator; |
47 | 149 |
} |
48 | 150 |
|
49 |
-void RoutineTsamp() |
|
50 |
-{ |
|
51 |
- |
|
52 |
-// PllRun(); |
|
53 |
- Lpf1stRun(); |
|
54 |
- FaultChecker(); |
|
55 |
- |
|
56 |
- if(Testpcs4 == 1) |
|
57 |
- { |
|
58 |
- EepromWriteAdcScale(); |
|
59 |
- Testpcs4 = 0; |
|
60 |
- } |
|
61 |
- if(Testpcs4 == 2) |
|
62 |
- { |
|
63 |
- EepromReadAdcScale(); |
|
64 |
- Testpcs4 = 0; |
|
151 |
+double calculateCorrelationFromQueues(Queue* q1, Queue* q2) { |
|
152 |
+ if (q1->size != q2->size || q1->size < 2) { |
|
153 |
+ // 큐의 크기가 다르거나 데이터 포인트가 2개 미만이면 계산할 수 없음 |
|
154 |
+ return 0; |
|
65 | 155 |
} |
66 | 156 |
|
67 |
-// receivedChar = SCI_readCharBlockingFIFO(SCIC_BASE); |
|
68 |
-// SCI_writeCharBlockingFIFO(SCIC_BASE, receivedChar); |
|
157 |
+ int n = q1->size; |
|
158 |
+ long long sumX = 0, sumY = 0, sumX2 = 0, sumY2 = 0, sumXY = 0; |
|
159 |
+ |
|
160 |
+ for (int i = 0; i < n; ++i) { |
|
161 |
+ int idx1 = (q1->front + i) % BUFFER_SIZE; |
|
162 |
+ int idx2 = (q2->front + i) % BUFFER_SIZE; |
|
163 |
+ int x = q1->items[idx1]; |
|
164 |
+ int y = q2->items[idx2]; |
|
165 |
+ |
|
166 |
+ sumX += x; |
|
167 |
+ sumY += y; |
|
168 |
+ sumX2 += x * x; |
|
169 |
+ sumY2 += y * y; |
|
170 |
+ sumXY += x * y; |
|
171 |
+ } |
|
172 |
+ |
|
173 |
+ double numerator = n * sumXY - sumX * sumY; |
|
174 |
+ // 상관 계수를 계산하는 함수 내에서 sqrt 사용 시 타입 명확히 하기 |
|
175 |
+ double denominator = sqrt(static_cast<double>((n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY))); |
|
176 |
+ |
|
177 |
+ if (denominator == 0) { |
|
178 |
+ // 분모가 0이면, 상관관계를 계산할 수 없음 |
|
179 |
+ return 0; |
|
180 |
+ } |
|
181 |
+ |
|
182 |
+ return numerator / denominator; |
|
183 |
+} |
|
184 |
+ |
|
185 |
+// 변화량의 크기를 계산하는 함수 |
|
186 |
+double calculate_change_magnitude(const int* change_array, int n) { |
|
187 |
+ double sum = 0.0; |
|
188 |
+ for (int i = 0; i < n; i++) { |
|
189 |
+ sum += std::abs(change_array[i]); // 변화량의 절대값을 더함 |
|
190 |
+ } |
|
191 |
+ return sum / n; // 평균을 반환 |
|
192 |
+} |
|
193 |
+ |
|
194 |
+ |
|
195 |
+double calculateChangeMagnitudeFromQueue(Queue* q) { |
|
196 |
+ if (q->size < 2) { |
|
197 |
+ // 큐에 데이터가 2개 미만일 때는 변화량을 계산할 수 없음 |
|
198 |
+ return 0.0; |
|
199 |
+ } |
|
200 |
+ |
|
201 |
+ double changeSum = 0; |
|
202 |
+ int prev = q->items[q->front]; // 시작 요소를 이전 요소로 설정 |
|
203 |
+ |
|
204 |
+ for (int i = 1; i < q->size; ++i) { |
|
205 |
+ int idx = (q->front + i) % BUFFER_SIZE; // 순환 인덱싱 |
|
206 |
+ int current = q->items[idx]; // 현재 요소 |
|
207 |
+ changeSum += std::abs(current - prev); // 이전 요소와의 차이(변화량)의 절대값 더하기 |
|
208 |
+ prev = current; // 현재 요소를 다음 루프의 이전 요소로 설정 |
|
209 |
+ } |
|
210 |
+ |
|
211 |
+ return changeSum / (q->size - 1); // 변화량의 평균 반환 |
|
212 |
+} |
|
213 |
+ |
|
214 |
+void calculateAverageStddevAndAdaptiveThresholdFromQueue(Queue* q, double& avg, double& stddev, double& adaptive_threshold) { |
|
215 |
+ if (q->size == 0) { |
|
216 |
+ // 큐가 비어있으면 계산 불가 |
|
217 |
+ avg = 0; |
|
218 |
+ stddev = 0; |
|
219 |
+ adaptive_threshold = 0; |
|
220 |
+ return; |
|
221 |
+ } |
|
222 |
+ |
|
223 |
+ // 평균 계산 |
|
224 |
+ double sum = 0; |
|
225 |
+ for (int i = 0; i < q->size; ++i) { |
|
226 |
+ int idx = (q->front + i) % BUFFER_SIZE; |
|
227 |
+ sum += q->items[idx]; |
|
228 |
+ } |
|
229 |
+ avg = sum / q->size; |
|
230 |
+ |
|
231 |
+ // 표준 편차 계산 |
|
232 |
+ double sum_sq_diff = 0; |
|
233 |
+ for (int i = 0; i < q->size; ++i) { |
|
234 |
+ int idx = (q->front + i) % BUFFER_SIZE; |
|
235 |
+ double diff = q->items[idx] - avg; |
|
236 |
+ sum_sq_diff += diff * diff; |
|
237 |
+ } |
|
238 |
+ stddev = sqrt(sum_sq_diff / q->size); |
|
239 |
+ |
|
240 |
+ // 적응형 임계값 설정 |
|
241 |
+ adaptive_threshold = avg + 2 * stddev; |
|
242 |
+} |
|
243 |
+ |
|
244 |
+///////////////////////////////////////////////////////////////////////////////////// |
|
245 |
+void RoutineTsamp() { |
|
246 |
+ static Queue uvQueue; |
|
247 |
+ static Queue visQueue; |
|
248 |
+ static Queue irQueue; |
|
249 |
+ static int initialized = 0; |
|
250 |
+ |
|
251 |
+ if (!initialized) { |
|
252 |
+ initQueue(&uvQueue); |
|
253 |
+ initQueue(&visQueue); |
|
254 |
+ initQueue(&irQueue); |
|
255 |
+ initialized = 1; |
|
256 |
+ } |
|
257 |
+ |
|
258 |
+ Lpf1stRun(); |
|
259 |
+ |
|
260 |
+ // if (Testpcs4 == 1) |
|
261 |
+ // { |
|
262 |
+ // EepromWriteAdcScale(); |
|
263 |
+ // Testpcs4 = 0; |
|
264 |
+ // } |
|
265 |
+ // if (Testpcs4 == 2) |
|
266 |
+ // { |
|
267 |
+ // EepromReadAdcScale(); |
|
268 |
+ // Testpcs4 = 0; |
|
269 |
+// } |
|
270 |
+ |
|
69 | 271 |
|
70 | 272 |
ModbusACheckBuffer(); |
71 | 273 |
|
274 |
+ // 새 센서 값 추가 |
|
275 |
+ enqueueAndUpdateStats(&uvQueue, CH4_UV_Flt); |
|
276 |
+ enqueueAndUpdateStats(&visQueue, CH4_VIS_Flt); |
|
277 |
+ enqueueAndUpdateStats(&irQueue, CH4_IR_Flt); |
|
278 |
+ |
|
279 |
+// ///////////////////////////////////////////// |
|
280 |
+// UV_buffer[currentIndex] = CH4_UV_Flt; // 배열에 센싱값 저장 |
|
281 |
+// VIS_buffer[currentIndex] = CH4_VIS_Flt; // 배열에 센싱값 저장 |
|
282 |
+// IR_buffer[currentIndex] = CH4_IR_Flt; // 배열에 센싱값 저장 |
|
283 |
+// |
|
284 |
+// // 센서 값 갱신 및 변화량 계산 |
|
285 |
+// UV_change[currentIndex] = CH4_UV_Flt - CH4_UV_prev; // UV 변화량 계산 |
|
286 |
+// VIS_change[currentIndex] = CH4_VIS_Flt - CH4_VIS_prev; // VIS 변화량 계산 |
|
287 |
+// IR_change[currentIndex] = CH4_IR_Flt - CH4_IR_prev; // IR 변화량 계산 |
|
288 |
+// |
|
289 |
+// // 현재 값을 '이전 값'으로 저장 |
|
290 |
+// CH4_UV_prev = CH4_UV_Flt; |
|
291 |
+// CH4_VIS_prev = CH4_VIS_Flt; |
|
292 |
+// CH4_IR_prev = CH4_IR_Flt; |
|
293 |
+// |
|
294 |
+// currentIndex = (currentIndex + 1) % BUFFER_SIZE; // 인덱스 갱신 |
|
295 |
+ |
|
296 |
+ if (CH4_UV_Flt > CH4_UV_max) |
|
297 |
+ CH4_UV_max = CH4_UV_Flt; // 새로운 최대값 발견 시 갱신 |
|
298 |
+ if (CH4_VIS_Flt > CH4_VIS_max) |
|
299 |
+ CH4_VIS_max = CH4_VIS_Flt; // 새로운 최대값 발견 시 갱신 |
|
300 |
+ if (CH4_IR_Flt > CH4_IR_max) |
|
301 |
+ CH4_IR_max = CH4_IR_Flt; // 새로운 최대값 발견 시 갱신 |
|
302 |
+ |
|
303 |
+ FaultChecker(); |
|
304 |
+ |
|
72 | 305 |
Chk_Botton = Din.Data.bit.Button; |
73 | 306 |
|
74 |
- if((Chk_Botton_pre == 0)&& (Chk_Botton == 1)) |
|
75 |
- { |
|
307 |
+ if ((Chk_Botton_pre == 0) && (Chk_Botton == 1)) { |
|
76 | 308 |
FaultReset = 1; |
77 | 309 |
} |
78 |
- else |
|
79 |
- { |
|
310 |
+ else { |
|
80 | 311 |
FaultReset = 0; |
81 | 312 |
} |
82 | 313 |
Chk_Botton_pre = Chk_Botton; |
83 | 314 |
|
84 |
- ///////////////////////////////////////////// |
|
85 |
- UV_buffer[currentIndex] = CH4_UV_Flt; // 배열에 센싱값 저장 |
|
86 |
- VIS_buffer[currentIndex] = CH4_VIS_Flt; // 배열에 센싱값 저장 |
|
87 |
- IR_buffer[currentIndex] = CH4_IR_Flt; // 배열에 센싱값 저장 |
|
315 |
+// // 임계값을 넘었을 때만 계산 |
|
316 |
+// if (SystemFault == 1) { |
|
317 |
+// uv_vis_correlation = calculate_correlation(UV_buffer, VIS_buffer, BUFFER_SIZE); |
|
318 |
+// uv_ir_correlation = calculate_correlation(UV_buffer, IR_buffer, BUFFER_SIZE); |
|
319 |
+// vis_ir_correlation = calculate_correlation(VIS_buffer, IR_buffer, BUFFER_SIZE); |
|
320 |
+ uv_vis_correlation = calculateCorrelationFromQueues(&uvQueue, &visQueue); |
|
321 |
+ uv_ir_correlation = calculateCorrelationFromQueues(&uvQueue, &irQueue); |
|
322 |
+ vis_ir_correlation = calculateCorrelationFromQueues(&visQueue, &irQueue); |
|
88 | 323 |
|
89 |
- // 센서 값 갱신 및 변화량 계산 |
|
90 |
- UV_change[currentIndex] = CH4_UV_Flt - CH4_UV_prev; // UV 변화량 계산 |
|
91 |
- VIS_change[currentIndex] = CH4_VIS_Flt - CH4_VIS_prev; // VIS 변화량 계산 |
|
92 |
- IR_change[currentIndex] = CH4_IR_Flt - CH4_IR_prev; // IR 변화량 계산 |
|
324 |
+ // 변화량의 크기 계산 |
|
325 |
+// uv_change_magnitude = calculate_change_magnitude(UV_change, BUFFER_SIZE); |
|
326 |
+// vis_change_magnitude = calculate_change_magnitude(VIS_change, BUFFER_SIZE); |
|
327 |
+// ir_change_magnitude = calculate_change_magnitude(IR_change, BUFFER_SIZE); |
|
328 |
+ uv_change_magnitude = calculateChangeMagnitudeFromQueue(&uvQueue); |
|
329 |
+ vis_change_magnitude = calculateChangeMagnitudeFromQueue(&visQueue); |
|
330 |
+ ir_change_magnitude = calculateChangeMagnitudeFromQueue(&irQueue); |
|
93 | 331 |
|
94 |
- // 현재 값을 '이전 값'으로 저장 |
|
95 |
- CH4_UV_prev = CH4_UV_Flt; |
|
96 |
- CH4_VIS_prev = CH4_VIS_Flt; |
|
97 |
- CH4_IR_prev = CH4_IR_Flt; |
|
332 |
+ // UV 평균과 표준 편차 계산 |
|
333 |
+// double sum = 0, sum_sq_diff = 0; |
|
334 |
+// for (int i = 0; i < BUFFER_SIZE; ++i) { |
|
335 |
+// sum += UV_buffer[i]; |
|
336 |
+// sum_sq_diff += (UV_buffer[i] - (sum / BUFFER_SIZE)) * (UV_buffer[i] - (sum / BUFFER_SIZE)); |
|
337 |
+// } |
|
338 |
+// double avg = sum / BUFFER_SIZE; |
|
339 |
+// stddev = sqrt(sum_sq_diff / BUFFER_SIZE); |
|
340 |
+// adaptive_threshold = avg + 2 * stddev; |
|
98 | 341 |
|
99 |
- currentIndex = (currentIndex + 1) % BUFFER_SIZE; // 인덱스 갱신 |
|
342 |
+ calculateAverageStddevAndAdaptiveThresholdFromQueue(&uvQueue, avg, stddev, adaptive_threshold); |
|
100 | 343 |
|
344 |
+ // 최신 값과 바로 이전 값 사이의 변화율 계산을 위한 인덱스 계산 |
|
345 |
+ // int latest_index = (currentIndex - 1 + BUFFER_SIZE) % BUFFER_SIZE; |
|
346 |
+ // int prev_index = (latest_index - 1 + BUFFER_SIZE) % BUFFER_SIZE; |
|
101 | 347 |
|
102 |
- if(CH4_UV_Flt > CH4_UV_max) CH4_UV_max = CH4_UV_Flt; // 새로운 최대값 발견 시 갱신 |
|
103 |
- if(CH4_VIS_Flt > CH4_VIS_max) CH4_VIS_max = CH4_VIS_Flt; // 새로운 최대값 발견 시 갱신 |
|
104 |
- if(CH4_IR_Flt > CH4_IR_max) CH4_IR_max = CH4_IR_Flt; // 새로운 최대값 발견 시 갱신 |
|
348 |
+ // latest_change = UV_buffer[latest_index] - UV_buffer[prev_index]; |
|
349 |
+ // latest_change = avg - prev_avg; |
|
350 |
+ // prev_avg = avg; |
|
105 | 351 |
|
106 |
- // 버퍼가 한 바퀴 돌았을 때 상관 계수 계산 |
|
107 |
- if (currentIndex == 0) |
|
108 |
- { |
|
109 |
- uv_vis_correlation = calculate_correlation(UV_buffer, VIS_buffer, BUFFER_SIZE); |
|
110 |
- uv_ir_correlation = calculate_correlation(UV_buffer, IR_buffer, BUFFER_SIZE); |
|
111 |
- vis_ir_correlation = calculate_correlation(VIS_buffer, IR_buffer, BUFFER_SIZE); |
|
112 |
- |
|
113 |
- // 변화량의 상관관계 계산 |
|
114 |
- uv_vis_change_correlation = calculate_correlation(UV_change, VIS_change, BUFFER_SIZE); |
|
115 |
- uv_ir_change_correlation = calculate_correlation(UV_change, IR_change, BUFFER_SIZE); |
|
116 |
- vis_ir_change_correlation = calculate_correlation(VIS_change, IR_change, BUFFER_SIZE); |
|
117 |
- |
|
118 |
- |
|
119 |
- // 평균과 표준 편차 계산 |
|
120 |
- double sum = 0, sum_sq_diff = 0; |
|
121 |
- for (int i = 0; i < BUFFER_SIZE; ++i) { |
|
122 |
- sum += UV_buffer[i]; |
|
123 |
- sum_sq_diff += (UV_buffer[i] - (sum / BUFFER_SIZE)) * (UV_buffer[i] - (sum / BUFFER_SIZE)); |
|
124 |
- } |
|
125 |
- double avg = sum / BUFFER_SIZE; |
|
126 |
- stddev = sqrt(sum_sq_diff / BUFFER_SIZE); |
|
127 |
- adaptive_threshold = avg + 2 * stddev; |
|
128 |
- |
|
129 |
- // 최신 값과 바로 이전 값 사이의 변화율 계산을 위한 인덱스 계산 |
|
130 |
- int latest_index = (currentIndex - 1 + BUFFER_SIZE) % BUFFER_SIZE; |
|
131 |
- int prev_index = (latest_index - 1 + BUFFER_SIZE) % BUFFER_SIZE; |
|
132 |
- |
|
133 |
- |
|
134 |
-// latest_change = UV_buffer[latest_index] - UV_buffer[prev_index]; |
|
135 |
- latest_change = avg - prev_avg; |
|
136 |
- prev_avg = avg; |
|
137 |
- |
|
138 |
- if (abs(latest_change) > adaptive_threshold) { |
|
139 |
- // 변화율이 적응형 임계값을 초과하는 경우 처리 |
|
140 |
- // 예: 알림 발송, 로깅, 경고 등 |
|
141 |
- SET_FT_UV_Level = adaptive_threshold; |
|
142 |
- } |
|
143 |
- } |
|
352 |
+ // if (abs(latest_change) > adaptive_threshold) { |
|
353 |
+ // // 변화율이 적응형 임계값을 초과하는 경우 처리 |
|
354 |
+ // // 예: 알림 발송, 로깅, 경고 등 |
|
355 |
+ // SET_FT_UV_Level = adaptive_threshold; |
|
356 |
+ // } |
|
357 |
+// } |
|
144 | 358 |
} |
145 |
- |
|
146 | 359 |
|
--- Common_Resource/CommonLibrary/include/SystemVar.h
+++ Common_Resource/CommonLibrary/include/SystemVar.h
... | ... | @@ -82,6 +82,10 @@ |
82 | 82 |
extern double uv_ir_change_correlation; |
83 | 83 |
extern double vis_ir_change_correlation; |
84 | 84 |
|
85 |
+extern double uv_change_magnitude; |
|
86 |
+extern double vis_change_magnitude; |
|
87 |
+extern double ir_change_magnitude; |
|
88 |
+ |
|
85 | 89 |
extern double FT_uv_vis_correlation; |
86 | 90 |
extern double FT_uv_ir_correlation; |
87 | 91 |
extern double FT_vis_ir_correlation; |
... | ... | @@ -94,10 +98,17 @@ |
94 | 98 |
extern double adaptive_threshold; |
95 | 99 |
extern int latest_change; |
96 | 100 |
|
101 |
+extern double FT_uv_change_magnitude; |
|
102 |
+extern double FT_vis_change_magnitude; |
|
103 |
+extern double FT_ir_change_magnitude; |
|
104 |
+ |
|
97 | 105 |
extern double FT_stddev; |
98 | 106 |
extern double FT_adaptive_threshold; |
99 | 107 |
extern int FT_latest_change; |
100 | 108 |
|
109 |
+extern double avg; |
|
110 |
+extern double stddev; |
|
111 |
+extern double adaptive_threshold; |
|
101 | 112 |
extern int SystemReady; |
102 | 113 |
// |
103 | 114 |
//extern int FlagInvGating; |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?