mirror of
https://github.com/google/pebble.git
synced 2025-03-25 21:09:05 +00:00
151 lines
7.5 KiB
C
151 lines
7.5 KiB
C
#pragma once
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "applib/accel_service.h"
|
|
#include "util/time/time.h"
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------
|
|
// Equates
|
|
// number of samples per second
|
|
#define KALG_SAMPLE_HZ 25
|
|
|
|
// Number of grams per kilogram
|
|
#define KALG_GRAMS_PER_KG 1000
|
|
|
|
typedef struct KAlgState KAlgState;
|
|
|
|
// This value in the encoded_vmc field of a KalgSleepMinute structure indicates that the
|
|
// watch was not worn
|
|
#define KALG_ENCODED_VMC_NOT_WORN 0
|
|
|
|
// The minimum value if the watch was worn
|
|
#define KALG_ENCODED_VMC_MIN_WORN_VALUE 1
|
|
|
|
// The maximum amount of time it takes for the sleep algorithm to figure out that the user
|
|
// woke up. This is used by activity_algorithm_kraepelin.c at compile time so it must be
|
|
// hard-coded. The correct value is checked in kalg_init() using a PBL_ASSERT since it can't
|
|
// be checked at compile time.
|
|
// should be: KALG_SLEEP_PARAMS.max_wake_minutes_early + KALG_SLEEP_HALF_WIDTH + 1
|
|
#define KALG_MAX_UNCERTAIN_SLEEP_M 19
|
|
|
|
// Activity types, used in KAlgSleepSessionCallback callback
|
|
typedef enum {
|
|
// ActivityType_Sleep encapsulates an entire sleep session from sleep entry to wake, and
|
|
// contains both light and deep sleep periods. An ActivityType_RestfulSleep session identifies
|
|
// a restful period and its start and end times will always be inside of a ActivityType_Sleep
|
|
// session.
|
|
KAlgActivityType_Sleep,
|
|
|
|
// A restful period, these will always be inside of a ActivityType_Sleep session
|
|
KAlgActivityType_RestfulSleep,
|
|
|
|
// A "sigificant" length walk
|
|
KAlgActivityType_Walk,
|
|
|
|
// A run
|
|
KAlgActivityType_Run,
|
|
|
|
// Leave at end
|
|
KAlgActivityTypeCount,
|
|
} KAlgActivityType;
|
|
|
|
// Sleep stats, returned by kalg_get_sleep_stats
|
|
typedef struct {
|
|
time_t sleep_start_utc; // start time of a recent sleep session. 0 if no session recently
|
|
// detected, where "recent" means within the last
|
|
// minimum_sleep_session_length minutes (currently 60).
|
|
uint16_t sleep_len_m; // how many minutes of that sleep are *certain*, 0 if none.
|
|
time_t uncertain_start_utc; // start time of the uncertain area of the sleep session, which
|
|
// always continues until the present time, 0 if none.
|
|
} KAlgOngoingSleepStats;
|
|
|
|
// Callback called by kalg_activities_update to register activity sessions.
|
|
// @param[in] context the context passed to kalg_activities_update()
|
|
// @param[in] activity_type the type of activity
|
|
// @param[in] start_utc start time of the activity
|
|
// @param[in] len_sec length of the activity
|
|
// @param[in] ongoing true if the activity is still ongoing, false if it ended
|
|
// @param[in] delete if true, delete this session that was previously added
|
|
// @param[in] steps the number of steps taken in this activity
|
|
// @param[in] resting_calories the number of resting calories burned
|
|
// @param[in] active_calories the number of active calories burned
|
|
// @param[in] distance_mm the distance covered, in millimeters
|
|
typedef void (*KAlgActivitySessionCallback)(void *context, KAlgActivityType activity_type,
|
|
time_t start_utc, uint32_t len_sec, bool ongoing,
|
|
bool delete, uint32_t steps, uint32_t resting_calories,
|
|
uint32_t active_calories, uint32_t distance_mm);
|
|
|
|
// Callback called by kalg_analyze_samples and kalg_compute_activities to record
|
|
// statistics. This is used during algorithm development, not during normal runtime. The algorithm
|
|
// passes a list of statistic names and their values to this callback so that they can be
|
|
// collected and summarized
|
|
// @param[in] num_stats the number of elements in the names and stats arrays
|
|
// @param[in] names list of statistic names
|
|
// @param[in] stats the value for each statistic
|
|
typedef void (*KAlgStatsCallback)(uint32_t num_stats, const char **names, int32_t *stats);
|
|
|
|
// Return the amount of space needed for the state
|
|
uint32_t kalg_state_size(void);
|
|
|
|
// Init the state, return true on success
|
|
// @param[in] stats_cb if not NULL, this callback will be called while analyzing samples with
|
|
// statistics that are computed.
|
|
bool kalg_init(KAlgState *state, KAlgStatsCallback stats_cb);
|
|
|
|
// Analyze a set of accel samples
|
|
// @param[in] state the state structure passed into kalg_init
|
|
// @param[in] samples array of accel samples
|
|
// @param[in] num_samples number of samples in the samples array
|
|
// @param[out] consumed_samples The number of samples that were just consumed to compute steps
|
|
// For many algorithms, this will often be 0 because the algorithm will wait until
|
|
// it has stored up a larger batch before it runs the step algorithm on the samples.
|
|
// @return number of steps counted
|
|
uint32_t kalg_analyze_samples(KAlgState *state, AccelRawData *samples, uint32_t num_samples,
|
|
uint32_t *consumed_samples);
|
|
|
|
// Return the last minute's stats and reset them for the next minute. The minute stats are logged
|
|
// and also used for computing sleep
|
|
// @param[in] state the state structure passed into kalg_init
|
|
// @param[out] vmc the vmc (Vector Magnitude Counts) value is returned here
|
|
// @param[out] orientation the orientation value is returned here
|
|
// @param[out] still true if no movement above noise threshold was detected
|
|
void kalg_minute_stats(KAlgState *state, uint16_t *vmc, uint8_t *orientation, bool *still);
|
|
|
|
// Used by unit tests - run the partial epoch that hasn't been processed yet by
|
|
// kalg_analyze_samples()
|
|
// @param[in] state the state structure passed into kalg_init
|
|
// @return number of steps counted
|
|
uint32_t kalg_analyze_finish_epoch(KAlgState *state);
|
|
|
|
// Feed new minute data into the activity detection state machine. This logic looks for non-sleep
|
|
// activities, like walks, runs, etc.
|
|
// @param[in] state the state structure passed into kalg_init
|
|
// @param[in] utc_now current timestamp in UTC
|
|
// @param[in] steps number of steps taken in the last minute
|
|
// @param[in] vmc VMC for the last minute
|
|
// @param[in] orientation average orientation for the last minute
|
|
// @param[in] plugged_in true if watch is plugged into charger
|
|
// @param[in] resting_calories number of resting calories burned in the last minute
|
|
// @param[in] active_calories number of active calories burned in the last minute
|
|
// @param[in] distance_mm distance covered in millimeters in the last minute
|
|
// @param[in] sessions_cb this callback will be called by kalg_compute_activities() for every
|
|
// session that it finds.
|
|
// @param[in] context passed to the sessions_cb
|
|
void kalg_activities_update(KAlgState *state, time_t utc_now, uint16_t steps, uint16_t vmc,
|
|
uint8_t orientation, bool plugged_in, uint32_t resting_calories,
|
|
uint32_t active_calories, uint32_t distance_mm, bool shutting_down,
|
|
KAlgActivitySessionCallback sessions_cb, void *context);
|
|
|
|
// Return the timestamp of the last minute that was processed for the given activity type
|
|
// @param[in] state the state structure passed into kalg_init
|
|
// @param[in] activity which type of activity
|
|
time_t kalg_activity_last_processed_time(KAlgState *state, KAlgActivityType activity);
|
|
|
|
// Get sleep stats
|
|
// @param[out] stats this structure is filled in with the sleep stats
|
|
void kalg_get_sleep_stats(KAlgState *state, KAlgOngoingSleepStats *stats);
|
|
|
|
//! Tells the algorithm whether or not it should automatically track activities
|
|
//! @param enable true to start tracking, false to stop tracking
|
|
void kalg_enable_activity_tracking(KAlgState *kalg_state, bool enable);
|