detectTurn method

Turning detectTurn({
  1. required List<SensorEvent> gyroData,
  2. required double gyroActualRate,
  3. required DateTime startTime,
  4. required double angleThreshold,
})

Detects the turning event in TUG test using gyroscope data.

Integrates angular velocity over time to detect when the user turns around. The algorithm:

  1. Starts analysis 2 seconds after the given start time (delay for walking)
  2. Integrates gyroscope y-axis data to calculate cumulative angle
  3. Detects when angle exceeds the threshold (indicating a turn)
  4. Returns both start and end indices of the turning motion

Returns a Turning object with start/end indices, or (-1, -1) if no turn detected.

Implementation

Turning detectTurn({
  required List<SensorEvent> gyroData,
  required double gyroActualRate,
  required DateTime startTime,
  required double angleThreshold,
}) {
  if (gyroData.isEmpty) return Turning(startIndex: -1, endIndex: -1);

  final delay =
      (0.5 * gyroActualRate.toInt())
          .floor(); // 0.5 seconds delay for walking phase
  final minimumAngle =
      angleThreshold / 10; // Minimum angle to consider a turn
  double sum = 0.0; // Cumulative angle integration
  int turnStartIndex = -1;

  // Find starting point after delay from start time
  var startIndex = gyroData.indexWhere((a) => a.timestamp.isAfter(startTime));
  for (int i = startIndex + delay; i < gyroData.length - 1; i++) {
    // Calculate time delta for integration
    final dt =
        gyroData[i].timestamp
            .difference(gyroData[i - 1].timestamp)
            .inMilliseconds /
        1e3;
    if (dt <= 0) continue; // Skip if time difference is zero or negative

    // Integrate angular velocity to get cumulative angle
    sum += gyroData[i].y * dt;

    final absSum = sum.abs();

    // Mark start of turn when minimum angle threshold is reached
    if (absSum >= minimumAngle && turnStartIndex == -1) {
      turnStartIndex = i;
    }

    // Reset if angle drops below minimum (false positive)
    if (absSum < minimumAngle) {
      turnStartIndex = -1; // Reset if angle drops below threshold
    }

    // Complete turn detected when full angle threshold is reached
    if (absSum >= angleThreshold) {
      return Turning(startIndex: turnStartIndex, endIndex: i);
    }
  }

  return Turning(startIndex: -1, endIndex: -1);
}