104 lines
3.3 KiB
C++
104 lines
3.3 KiB
C++
#include <iostream>
|
|
#include <vector>
|
|
#include <random>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <cmath>
|
|
#include <iomanip>
|
|
|
|
const int SAMPLE_RATE_MS = 20;
|
|
const int SAMPLES_PER_SECOND = 1000 / SAMPLE_RATE_MS;
|
|
const int TOTAL_SECONDS = 60;
|
|
|
|
std::default_random_engine rng(std::random_device{}());
|
|
std::uniform_real_distribution<double> changeDist(-0.25, 0.25);
|
|
std::uniform_real_distribution<double> driftDist(-0.05, 0.05);
|
|
std::uniform_real_distribution<double> heartAttackChance(0.0, 1.0);
|
|
std::uniform_int_distribution<int> startBpmDist(30, 210);
|
|
|
|
double clampBPM(double bpm) {
|
|
if (bpm == 0.0) return 0.0;
|
|
if (bpm < 30.0) return 30.0;
|
|
if (bpm > 210.0) return 210.0;
|
|
return bpm;
|
|
}
|
|
|
|
int main() {
|
|
std::vector<int> bpmHistory;
|
|
double bpm = startBpmDist(rng);
|
|
double drift = driftDist(rng);
|
|
int outOfRangeSeconds = 0;
|
|
bool emergency = false;
|
|
bool emergencyNotified = false;
|
|
bool cardiacArrestInjected = false;
|
|
|
|
std::vector<double> currentSecondSamples;
|
|
int secondCounter = 0;
|
|
|
|
std::cout << "Starting real-time heart rate monitoring...\n" << std::endl;
|
|
|
|
while (secondCounter < TOTAL_SECONDS) {
|
|
double sum = 0.0;
|
|
|
|
for (int i = 0; i < SAMPLES_PER_SECOND; ++i) {
|
|
// Inject cardiac arrest
|
|
if (!cardiacArrestInjected && secondCounter >= 20 && secondCounter < 40 && heartAttackChance(rng) < 0.005) {
|
|
bpm = 0.0;
|
|
cardiacArrestInjected = true;
|
|
} else if (bpm != 0.0) {
|
|
bpm += changeDist(rng) + drift;
|
|
bpm = clampBPM(bpm);
|
|
}
|
|
|
|
currentSecondSamples.push_back(bpm);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(SAMPLE_RATE_MS));
|
|
}
|
|
|
|
drift = driftDist(rng);
|
|
|
|
// Calculate 1-second average
|
|
double sumSecond = 0.0;
|
|
for (double val : currentSecondSamples) sumSecond += val;
|
|
int avgBPM = static_cast<int>(std::round(sumSecond / currentSecondSamples.size()));
|
|
bpmHistory.push_back(avgBPM);
|
|
currentSecondSamples.clear();
|
|
|
|
// Print real-time 1-second BPM
|
|
std::cout << "Second " << secondCounter + 1 << " - Calculated Avg BPM: " << avgBPM << std::endl;
|
|
|
|
// Emergency check
|
|
if (avgBPM < 40 || avgBPM > 200) {
|
|
outOfRangeSeconds++;
|
|
} else {
|
|
outOfRangeSeconds = 0;
|
|
}
|
|
|
|
if (!emergency && outOfRangeSeconds >= 3) {
|
|
emergency = true;
|
|
emergencyNotified = false;
|
|
}
|
|
|
|
if (emergency) {
|
|
if (!emergencyNotified) {
|
|
std::cout << "[buzzer active]" << std::endl;
|
|
std::cout << "[vibrator active]" << std::endl;
|
|
emergencyNotified = true;
|
|
}
|
|
std::cout << "[Bluetooth message sent: urgency = TRUE]" << std::endl;
|
|
} else if ((secondCounter + 1) % 10 == 0) {
|
|
int count = std::min(60, static_cast<int>(bpmHistory.size()));
|
|
int sumLast = 0;
|
|
for (int i = bpmHistory.size() - count; i < bpmHistory.size(); ++i) {
|
|
sumLast += bpmHistory[i];
|
|
}
|
|
int avgLast = sumLast / count;
|
|
std::cout << "[Bluetooth message sent: urgency = FALSE, avg BPM = " << avgLast << "]" << std::endl;
|
|
}
|
|
|
|
secondCounter++;
|
|
}
|
|
|
|
std::cout << "\nMonitoring session ended.\n";
|
|
return 0;
|
|
}
|