detectStandUp method

int detectStandUp({
  1. required List<SensorEvent> accData,
  2. required double accActualRate,
})

Detects the stand-up event in TUG test using accelerometer data.

Applies low-pass filtering and smoothing to detect peaks in the y-axis accelerometer data after gravity removal. The algorithm:

  1. Removes gravity (9.8 m/s²) from y-axis acceleration
  2. Applies low-pass filter with 4.0 Hz cutoff
  3. Smooths data using 10-sample window
  4. Detects peaks above 0.6 threshold

Returns the index of the first detected stand-up event, or -1 if none found.

Implementation

int detectStandUp({
  required List<SensorEvent> accData,
  required double accActualRate,
}) {
  if (accData.isEmpty) return -1;

  int smoothingWindow = 10;
  double threshold = 0.6; // Acceleration threshold for stand-up detection

  // Process accelerometer data - remove gravity from y-axis
  var processedAccData = lowPassFilter(
    accData.map((e) => e.y - 9.8).toList(),
    4.0, // Low-pass filter cutoff frequency
  );

  // Apply smoothing using moving average window
  List<double> smoothedAcc = List<double>.filled(
    processedAccData.length,
    0.0,
  );
  for (int i = 0; i < processedAccData.length; i++) {
    double sum = 0.0;
    int count = 0;
    // Calculate moving average within window bounds
    for (
      int j = (i - smoothingWindow ~/ 2).clamp(
        0,
        processedAccData.length - 1,
      );
      j <= (i + smoothingWindow ~/ 2).clamp(0, processedAccData.length - 1);
      j++
    ) {
      sum += processedAccData[j];
      count++;
    }
    smoothedAcc[i] = sum / count;
  }

  // Detect peaks in smoothed data that exceed threshold
  for (int i = 1; i < smoothedAcc.length - 1; i++) {
    bool isPeak =
        smoothedAcc[i] > smoothedAcc[i - 1] &&
        smoothedAcc[i] > smoothedAcc[i + 1];

    if (isPeak && smoothedAcc[i] > threshold) {
      return i; // Return index of first detected stand-up event
    }
  }

  return -1;
}