Wheelchair Movement Detector

A Flutter package for detecting and tracking wheelchair movement using device sensors (accelerometer and gyroscope).

Features

  • 🎯 Real-time movement detection
  • 📏 Distance tracking (session and total)
  • ⚡ Velocity calculation
  • ⏱️ Time tracking (moving time and session duration)
  • 🔄 Turn detection (left/right)
  • 🎚️ Automatic sensor calibration
  • 📊 Smoothed data using rolling averages

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  wheelchair_movement_detector: ^0.0.1

Then run:

flutter pub get

Usage

Basic Implementation

import 'package:wheelchair_movement_detector/wheelchair_movement_detector.dart';

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final WheelchairMovementDetector _detector = WheelchairMovementDetector();
  MovementData? _currentData;

  @override
  void initState() {
    super.initState();
    _initializeDetector();
  }

  Future<void> _initializeDetector() async {
    // Initialize the detector (includes calibration)
    await _detector.initialize();
    
    // Listen to movement data updates
    _detector.movementDataStream.listen((data) {
      setState(() {
        _currentData = data;
      });
    });
  }

  @override
  void dispose() {
    _detector.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (_currentData == null) {
      return CircularProgressIndicator();
    }

    return Column(
      children: [
        Text('Movement: ${_currentData!.movementType}'),
        Text('Distance: ${MovementFormatters.formatDistance(_currentData!.sessionDistance)}'),
        Text('Speed: ${MovementFormatters.formatVelocityKmh(_currentData!.velocity)}'),
      ],
    );
  }
}

Available Methods

// Initialize and start tracking
await detector.initialize();

// Reset current session
detector.resetSession();

// Reset all data
detector.resetAll();

// Get average speed
double avgSpeed = detector.calculateAverageSpeed();

// Get current data snapshot
MovementData currentData = detector.currentData;

// Clean up when done
detector.dispose();

MovementData Properties

class MovementData {
  final bool isMoving;              // Whether currently moving
  final String movementType;         // "Stationary", "Moving", "Moving Fast", "Turning Left", "Turning Right"
  final double totalDistance;        // Total distance in meters
  final double sessionDistance;      // Session distance in meters
  final double velocity;             // Current velocity in m/s
  final DateTime sessionStartTime;   // When session started
  final Duration totalMovingTime;    // Total time spent moving
  final DateTime? movingStartTime;   // When current movement started
  final bool isCalibrating;          // Whether calibration is in progress
}

Formatting Utilities

The package includes helpful formatting utilities:

// Format distance
String distance = MovementFormatters.formatDistance(150.5); // "150.50 m"

// Format duration
String time = MovementFormatters.formatDuration(Duration(seconds: 3665)); // "01:01:05"

// Format velocity
String speedKmh = MovementFormatters.formatVelocityKmh(2.5); // "9.0 km/h"
String speedMs = MovementFormatters.formatVelocityMs(2.5);   // "2.50 m/s"

Requirements

  • Flutter SDK: >=3.0.0
  • Dart SDK: >=3.0.0
  • Platform support: Android, iOS (devices with accelerometer and gyroscope)

Permissions

Android

No special permissions required.

iOS

No special permissions required.

How It Works

  1. Calibration: On initialization, the detector calibrates for 3 seconds to measure baseline sensor noise
  2. Movement Detection: Uses accelerometer data to detect movement above threshold
  3. Distance Calculation: Integrates velocity over time using kinematic equations
  4. Smoothing: Applies rolling averages to reduce sensor noise
  5. Turn Detection: Uses gyroscope z-axis rotation to detect left/right turns

Example App

See the example folder for a complete implementation with UI.

To run the example:

cd example
flutter run

Best Practices

  • Mount the phone securely to the wheelchair for best accuracy
  • Keep the phone in the same orientation during use
  • Allow calibration to complete before moving
  • Reset session between different tracking periods

Known Limitations

  • Distance calculation uses accelerometer integration which can accumulate drift over time
  • Accuracy depends on phone placement and mounting stability
  • Works best with consistent, smooth movements

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details