mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-17 02:45:05 +00:00
117 lines
4.0 KiB
C
117 lines
4.0 KiB
C
// SPDX-License-Identifier: Apache-2.0
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include <tactility/concurrent/task_event_group.h>
|
|
#include <tactility/error.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* Location service. Location providers (e.g. GPS) report fixes to the service.
|
|
* The most recent fix of a regular provider is used while it's less than 2 minutes old.
|
|
* Otherwise, the most recent fix of a fallback provider (e.g. IP geolocation) is used, if there is one.
|
|
* Providers only run while there is at least one subscription.
|
|
*/
|
|
|
|
#define LOCATION_PROVIDER_ID_MAX_LENGTH 15
|
|
|
|
/** Horizontal accuracy in meters of a fix with LOCATION_PRECISION_APPROXIMATE */
|
|
#define LOCATION_APPROXIMATE_ACCURACY_METERS 3000.0f
|
|
|
|
enum LocationPrecision {
|
|
/** Providers only report fixes with a horizontal accuracy of LOCATION_APPROXIMATE_ACCURACY_METERS or worse */
|
|
LOCATION_PRECISION_APPROXIMATE,
|
|
/** Providers report fixes as accurate as they can */
|
|
LOCATION_PRECISION_PRECISE,
|
|
};
|
|
|
|
/**
|
|
* A location fix. Values the provider doesn't know are NAN for floating point fields and 0 for the others.
|
|
* Accuracies are the radius of 68% confidence, in the unit of the value they belong to.
|
|
*/
|
|
struct Location {
|
|
/** Degrees in WGS84, positive is north */
|
|
double latitude;
|
|
/** Degrees in WGS84, positive is east */
|
|
double longitude;
|
|
/** Meters */
|
|
float horizontal_accuracy;
|
|
/** Meters above mean sea level */
|
|
float altitude;
|
|
/** Meters above the WGS84 ellipsoid */
|
|
float ellipsoidal_altitude;
|
|
/** Meters */
|
|
float vertical_accuracy;
|
|
/** Speed over ground in meters per second */
|
|
float speed;
|
|
/** Meters per second */
|
|
float speed_accuracy;
|
|
/** Direction of travel in degrees clockwise from true north, in range [0, 360) */
|
|
float course;
|
|
/** Degrees */
|
|
float course_accuracy;
|
|
/** Number of satellites used for the fix */
|
|
uint8_t satellites;
|
|
/** Time of the fix according to the provider, in milliseconds since the Unix epoch */
|
|
int64_t time_ms;
|
|
/** Milliseconds since boot when the service received the fix */
|
|
uint64_t uptime_ms;
|
|
/** Id of the provider that reported the fix */
|
|
char provider[LOCATION_PROVIDER_ID_MAX_LENGTH + 1];
|
|
};
|
|
|
|
/**
|
|
* Allow or disallow the use of location services. The service only runs while allowed. The choice is persisted.
|
|
* Location services are disallowed by default.
|
|
*/
|
|
error_t location_set_enabled(bool enabled);
|
|
|
|
bool location_is_enabled(void);
|
|
|
|
/** Set the precision that providers should report. The choice is persisted. */
|
|
error_t location_set_precision(enum LocationPrecision precision);
|
|
|
|
enum LocationPrecision location_get_precision(void);
|
|
|
|
/**
|
|
* Get the current fix. Without subscriptions, this is the last known fix.
|
|
* @param[out] location the fix
|
|
* @retval ERROR_NOT_FOUND when no fix was reported since the service started, or location services are disabled
|
|
*/
|
|
error_t location_get(struct Location* location);
|
|
|
|
/**
|
|
* Caller-owned subscription: the service signals @a bit on the event group whenever a new current fix is reported.
|
|
* Read the fix with location_get().
|
|
* @warning Fields other than `bit` are for internal use only.
|
|
*/
|
|
struct LocationSubscription {
|
|
uint32_t bit;
|
|
|
|
struct {
|
|
struct TaskEventGroup* event_group;
|
|
struct LocationSubscription* next;
|
|
} internal;
|
|
};
|
|
|
|
/**
|
|
* Subscribing starts the providers when location services are enabled. They stop when the last subscription is removed.
|
|
* @param[in,out] sub subscription to register, must stay alive until unsubscribed
|
|
* @param[in] event_group caller-owned group to wait on, must outlive @a sub
|
|
* @retval ERROR_RESOURCE @a event_group has no free bits left
|
|
* @retval ERROR_INVALID_STATE @a sub is already registered
|
|
*/
|
|
error_t location_subscribe(struct LocationSubscription* sub, struct TaskEventGroup* event_group);
|
|
|
|
/** @retval ERROR_NOT_FOUND when @a sub is not registered */
|
|
error_t location_unsubscribe(struct LocationSubscription* sub);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|