How to use Activity Recognition to detect walking/running vs on_foot
Asked Answered
D

3

6

In Google Play Services Activity Recognition there is

DetectedActivity.RUNNING,
DetectedActivity.WALKING,
DetectedActivity.ON_FOOT

when ever I get an activity update for either walking or running I get ON_FOOT

how do I differentiate?

I know it says that RUNNING and WALKING : "This is a sub-activity of ON_FOOT"

Thanks for your help.

Demarcation answered 17/7, 2014 at 23:44 Comment(1)
Try their sample: github.com/googlesamples/android-play-location "ActivityRecognition"Meaningless
E
2

I've observed similar behavior. My theory is that when you receive a ActivityRecognitionResult object, it will often contain several parseable DetectedActivity objects each with a confidence score specified by an integer. In the case of WALKING, there will be at least two DetectedActivity objects - one DetectedActivity object for ON_FOOT with a higher confidence level, and one DetectedActivity object for WALKING with a lower or equal confidence level.

In practice I imagine you'll often get some permutation of ON_FOOT + WALKING || RUNNING, or all three with varying confidence scores, with ON_FOOT likely being the highest.

Emolument answered 21/7, 2014 at 14:24 Comment(0)
C
6

The walkingOrRunning() method provided by emil10001 works, however it will not be able to get the activity(running or walking) with the highest confidence, this because, the condition of the second if clause in his for loop always compares the activity's confidence to 0.

To clarify this, let assume we pass a List of size 2 "probableActivities" as argument to the walkingOrRunning() method i.e: we call walkingOrRunning(probableActivities).

Supposing,

List probableActivities = [ activity1, activity2 ],

where:

activity1 = "walking" with 75% confidence

activity2 = "running" 5% confidence.

In brief, the excution of the method walkingOrRunning(probableActivities) is as follows:

1)After the 1st iteration of the for loop, myActivity = "walking"

2)After the 2nd iteration of the for loop, myActivity = "running"

and the method retruns "running" as the activity type , meanwhile we expect the returned activity to be "walking".

In sum, in order to get the activity type (walking/running) with the highest confidence, I modified walkingOrRunning() method to the following

[ fyi: I have implemented and tested the code and it's working as expected, I welcome any feedback/comment/question].

 private DetectedActivity walkingOrRunning(List<DetectedActivity> probableActivities) {
    DetectedActivity myActivity = null;
    int confidence = 0;
    for (DetectedActivity activity : probableActivities) {
        if (activity.getType() != DetectedActivity.RUNNING && activity.getType() != DetectedActivity.WALKING)
            continue;

        if (activity.getConfidence() >= confidence) {
            confidence = activity.getConfidence();
            myActivity = activity;
        }
    }

    return myActivity;
}
Charleton answered 17/9, 2016 at 21:6 Comment(0)
B
3

As Sam mentioned, the WALKING and RUNNING activities come in as secondary activities in a list (ActivityRecognitionResult.getProbableActivities()), and you'll need to parse them out.

// Get the update
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);

// Get the most probable activity from the list of activities in the update
DetectedActivity mostProbableActivity = result.getMostProbableActivity();

// Get the type of activity
int activityType = mostProbableActivity.getType();

if (activityType == DetectedActivity.ON_FOOT) {
    DetectedActivity betterActivity = walkingOrRunning(result.getProbableActivities());
    if (null != betterActivity)
        mostProbableActivity = betterActivity;
}

private DetectedActivity walkingOrRunning(List<DetectedActivity> probableActivities) {
    DetectedActivity myActivity = null;
    int confidence = 0;
    for (DetectedActivity activity : probableActivities) {
        if (activity.getType() != DetectedActivity.RUNNING && activity.getType() != DetectedActivity.WALKING)
            continue;

        if (activity.getConfidence() > confidence)
            myActivity = activity;
    }

    return myActivity;
}

I tested the above code this evening, both walking and running and it seemed to do fairly well. If you don't explicitly filter on only RUNNING or WALKING, you will likely get erroneous results.

Baggy answered 23/7, 2014 at 3:41 Comment(1)
In the case where getProbableActivities is { ON_FOOT, WALKING, RUNNING }, your walkingOrRunning method is going to return RUNNING, when you really probably want to return WALKING, since it has higher confidence. I think you want to break when you find the first RUNNING or WALKING activity that meets your confidence threshold.Bergman
E
2

I've observed similar behavior. My theory is that when you receive a ActivityRecognitionResult object, it will often contain several parseable DetectedActivity objects each with a confidence score specified by an integer. In the case of WALKING, there will be at least two DetectedActivity objects - one DetectedActivity object for ON_FOOT with a higher confidence level, and one DetectedActivity object for WALKING with a lower or equal confidence level.

In practice I imagine you'll often get some permutation of ON_FOOT + WALKING || RUNNING, or all three with varying confidence scores, with ON_FOOT likely being the highest.

Emolument answered 21/7, 2014 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.