Android Open Source - Fall_Prevention_2013 Manipulator Helper






From Project

Back to project page Fall_Prevention_2013.

License

The source code is released under:

Apache License

If you think the Android project Fall_Prevention_2013 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Licensed to UbiCollab.org under one or more contributor
 * license agreements.  See the NOTICE file distributed 
 * with this work for additional information regarding
 * copyright ownership. UbiCollab.org licenses this file
 * to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * /*  w ww.  j  a  va  2 s. co  m*/
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 ******************************************************************************/
package ntnu.stud.valens.contentprovider.calculations;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * This class handles most of the work in deriving new data from data that
 * already exists in the content provider. In particular, it derives true steps
 * based on the most reliable step detector, and calculates gait parameters
 * (speed and variability).
 * 
 * @author Elias
 */
public class ManipulatorHelper implements Runnable {

  private static final String APP_TAG = "ntnu.stud.valens.contentprovider";

  public static final long GROUP_GAP_THRESHOLD = 10000;
  public static final long GROUP_SIZE_THRESHOLD = 10000;

  private Context context;
  
  public ManipulatorHelper(Context context) {
    this.context = context;
  }
  
  /**
   * The calculation method handles the computation of gait parameters and
   * finds the true steps. Fetches the data for the last 24 hours from the
   * content provider. After calculation, it stores the information back into
   * the proper tables in the content provider. This functions first finds
   * groups of steps, and only if the step group is longer than a certain
   * threshold it uses it to calculate gait speed and variability.
   * 
   * Will only calculate if no calculation has occurred in the same day, to
   * avoid steps being counted multiple times.
   * 
   * @param context
   *            - Any context object. Required for the ContentProviderHelper,
   *            because Android for some reason requires a context to be able
   *            to get access to content providers.
   */
  public void run() {
    // Only update if no update has happened today.
    SharedPreferences prefs = context.getSharedPreferences(
        "ntnu.stud.valens.contentprovider", Context.MODE_PRIVATE);
    long lastUpdateTime = prefs.getLong("lastUpdateTime", 0);
    Log.v(APP_TAG, "LastTimeUpdate: " + lastUpdateTime);
    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(lastUpdateTime);
    Log.v(APP_TAG, "Last update day: " + c.get(Calendar.DATE));
    Log.v(APP_TAG, "Today: " + Calendar.getInstance().get(Calendar.DATE));
    if (!(c.get(Calendar.DATE) == Calendar.getInstance().get(Calendar.DATE))
        || lastUpdateTime == 0) {
      ContentProviderHelper cph = new ContentProviderHelper(context);
      // Get the raw steps for the last 24hours.

      Timestamp now = ContentProviderHelper
          .getHoursBack(Calendar.HOUR - 4);
      Timestamp yesterday = ContentProviderHelper
          .getHoursBack(24 + Calendar.HOUR_OF_DAY - 4);
      List<List<Long>> rawSteps = cph.getRawSteps(yesterday, now);

      // Find the true steps steps. I.e. the steps from the source with
      // the most steps.

      Log.v(APP_TAG, "calculating now!");
      List<Long> bestSource = new ArrayList<Long>();
      for (List<Long> stepList : rawSteps) {
        if (stepList.size() > bestSource.size()) {

          bestSource = stepList;
        }
      }
      Log.v(APP_TAG, "bestSource.size: " + bestSource.size());
      // Store the true steps into the content provider
      cph.storeTrueSteps(bestSource);

      // Find the gait parameters for the true steps of the period and
      // store them in the content provider
      double[] gaitParameters = findGaitParameters(bestSource);
      Log.v(APP_TAG, "Gait parameter: " + gaitParameters[0] + ", "
          + gaitParameters[1]);
      if (!(Double.isNaN(gaitParameters[0]) || Double
          .isNaN(gaitParameters[1]))) {
        cph.storeGaitParameters(gaitParameters, bestSource);
      }
      lastUpdateTime = System.currentTimeMillis();
      SharedPreferences.Editor editor = prefs.edit();
      editor.putLong("lastUpdateTime", lastUpdateTime);
      editor.commit();

    }    
  }

  /**
   * Finds the gait parameters based on a list of steps, i.e. a step group.
   * 
   * @param steps
   *            - The list of steps that gait parameters should be calculated
   *            from.
   * @return - An array of doubles containing two elements, the first being
   *         the gait speed, the second being the gait variability.
   */
  private double[] findGaitParameters(List<Long> steps) {
    // Stores intervals and the current step group temporarily
    List<Long> tempIntervals = new ArrayList<Long>();
    List<Long> tempGroup = new ArrayList<Long>();
    // Maintains current lists of mean and std
    double mean = 0d, std = 0d;
    int numberOfGroups = 0;

    for (int i = 0; i < steps.size() - 1; i++) {
      // If the current group is empty, this step is the beginning of a
      // new group
      if (tempGroup.isEmpty()) {
        tempGroup.add(steps.get(i));
      }
      // If the gap between the two steps are larger than a threshold, we
      // consider the old tempGroup as a single group, and the new step as
      // the beginning of a new one.
      else if (steps.get(i) - steps.get(i - 1) > GROUP_GAP_THRESHOLD) {
        // Look at the old step group, check if it is larger than
        // threshold.
        if (steps.get(i - 1) - tempGroup.get(0) > GROUP_SIZE_THRESHOLD) {
          // If it is, it is significant, and we store the intervals.
          for (int j = 1; j < tempGroup.size(); j++) {
            tempIntervals.add(tempGroup.get(j)
                - tempGroup.get(j - 1));
          }
          // Calculate mean and std for the intervals
          numberOfGroups++;
          double tempMean = calculateMean(tempIntervals);
          mean += tempMean;
          std += calculateStd(tempIntervals, tempMean);
          tempIntervals.clear();
        }
        // Then discard the group and start a new one.
        tempGroup.clear();
        tempGroup.add(steps.get(i));
      }
      // If the gap is smaller than the threshold, then the new step is a
      // part of the tempGroup.
      else {
        tempGroup.add(steps.get(i));
      }
    }

    // Finally, choose to either store the final group, or discard it,
    // depending on size
    if (tempGroup.size() > 0
        && tempGroup.get(tempGroup.size() - 1) - tempGroup.get(0) > GROUP_SIZE_THRESHOLD) {
      for (int j = 1; j < tempGroup.size(); j++) {
        tempIntervals.add(tempGroup.get(j) - tempGroup.get(j - 1));
      }
      numberOfGroups++;
      double tempMean = calculateMean(tempIntervals);
      mean += tempMean;
      std += calculateStd(tempIntervals, tempMean);
    }

    // Now, find the mean of means, and mean of stds
    mean = mean / numberOfGroups;
    std = std / numberOfGroups;
    return new double[] { mean, std };
  }

  /**
   * Calculates the mean of a list of values.
   * 
   * @param values
   *            - a list of numbers
   * @return the mean
   */
  private static double calculateMean(List<Long> values) {
    double mean = 0.0f;
    for (Long f : values) {
      mean += f;
    }
    return mean / values.size();
  }

  /**
   * Calculates the standard deviation of a list of values
   * 
   * @param values
   *            - the list of values
   * @param mean
   *            - the mean for the same list of numbers
   * @return the standard deviation
   */
  private static double calculateStd(List<Long> values, double mean) {
    double std = 0.0f;
    for (Long f : values) {
      std += (f - mean) * (f - mean);
    }
    std = std / values.size();
    return Math.sqrt(std);
  }

}




Java Source Code List

ntnu.stud.valens.contentprovider.CPValensDB.java
ntnu.stud.valens.contentprovider.DBSchema.java
ntnu.stud.valens.contentprovider.Main.java
ntnu.stud.valens.contentprovider.ValensDataProvider.java
ntnu.stud.valens.contentprovider.calculations.AlarmManagerBroadcastReceiver.java
ntnu.stud.valens.contentprovider.calculations.ContentProviderHelper.java
ntnu.stud.valens.contentprovider.calculations.ManipulationStarter.java
ntnu.stud.valens.contentprovider.calculations.ManipulatorHelper.java
ntnu.stud.valens.demonstration.Constants.java
ntnu.stud.valens.demonstration.NotificationBroadcastReciever.java
ntnu.stud.valens.demonstration.activity.ClearHistory.java
ntnu.stud.valens.demonstration.activity.ContactPerson.java
ntnu.stud.valens.demonstration.activity.CreateContact.java
ntnu.stud.valens.demonstration.activity.EventDetail.java
ntnu.stud.valens.demonstration.activity.EventList.java
ntnu.stud.valens.demonstration.activity.LaunchActivity.java
ntnu.stud.valens.demonstration.activity.MainScreen.java
ntnu.stud.valens.demonstration.activity.NewContact.java
ntnu.stud.valens.demonstration.activity.Related.java
ntnu.stud.valens.demonstration.activity.Settings.java
ntnu.stud.valens.demonstration.activity.Statistics.java
ntnu.stud.valens.demonstration.activity.WriteName.java
ntnu.stud.valens.demonstration.connectivity.AlarmManagerBroadcastReceiver.java
ntnu.stud.valens.demonstration.connectivity.ContentProviderHelper.java
ntnu.stud.valens.demonstration.connectivity.DatabaseContract.java
ntnu.stud.valens.demonstration.connectivity.DatabaseHelper.java
ntnu.stud.valens.demonstration.datastructures.Contact.java
ntnu.stud.valens.demonstration.datastructures.Event.java
ntnu.stud.valens.demonstration.datastructures.RiskStatus.java
ntnu.stud.valens.demonstration.listadapters.EditContactAdapter.java
ntnu.stud.valens.demonstration.listadapters.EventListAdapter.java
ntnu.stud.valens.demonstration.widget.WidgetProvider.java
ntnu.stud.valens.stepdetector.DetectStepsThread.java
ntnu.stud.valens.stepdetector.LaunchActivity.java
ntnu.stud.valens.stepdetector.Methods.java
ntnu.stud.valens.stepdetector.StepMainServiceStarter.java
ntnu.stud.valens.stepdetector.StepMainService.java
ntnu.stud.valens.stepdetector.Values.java
ntnu.stud.valens.stepdetector.calibration.CalibrationActivity.java
ntnu.stud.valens.stepdetector.calibration.CalibrationStartTask.java
ntnu.stud.valens.stepdetector.calibration.CalibrationThread.java