1aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung/* 2aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * Copyright (C) 2016 The Android Open Source Project 3aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * 4aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * you may not use this file except in compliance with the License. 6aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * You may obtain a copy of the License at 7aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * 8aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * http://www.apache.org/licenses/LICENSE-2.0 9aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * 10aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * Unless required by applicable law or agreed to in writing, software 11aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * distributed under the License is distributed on an "AS IS" BASIS, 12aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * See the License for the specific language governing permissions and 14aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung * limitations under the License. 15aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung */ 16aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 17a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include <chre.h> 18aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung#include <cinttypes> 19aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 207621b3267fd2ff1068d7aa7d75441d68646226abBrian Duddie#include "chre/util/macros.h" 21a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include "chre/util/nanoapp/log.h" 22746ea0ecb99d3f758da17292db549b29720c4442Andrew Rossignol#include "chre/util/nanoapp/sensor.h" 23aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung#include "chre/util/time.h" 24aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 25a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#define LOG_TAG "[ImuCal]" 26a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol 27e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 28aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chungnamespace chre { 29e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolnamespace { 30e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 31e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 32aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chungnamespace { 33aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 34aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chungstruct SensorState { 35aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const uint8_t type; 36aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung uint32_t handle; 37aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung bool isInitialized; 38aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung bool enable; 39aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung uint64_t interval; // nsec 40aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung uint64_t latency; // nsec 41aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung chreSensorInfo info; 42aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung}; 43aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 44aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan ChungSensorState sensors[] = { 45aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung { .type = CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE, 46aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .enable = true, 47aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .interval = Seconds(2).toRawNanoseconds(), 48aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .latency = 0, 49aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung }, 50aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung { .type = CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE, 51aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .enable = true, 52aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .interval = Seconds(2).toRawNanoseconds(), 53aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .latency = 0, 54aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung }, 55aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung { .type = CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER, 56aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .enable = true, 57aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .interval = Milliseconds(80).toRawNanoseconds(), 58aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .latency = Seconds(4).toRawNanoseconds(), 59aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung }, 60aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung { .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE, 61aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .enable = true, 62aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .interval = Milliseconds(80).toRawNanoseconds(), 63aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .latency = Seconds(4).toRawNanoseconds(), 64aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung }, 65aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung { .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD, 66aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .enable = true, 67aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .interval = Milliseconds(80).toRawNanoseconds(), 68aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung .latency = Seconds(4).toRawNanoseconds(), 69aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung }, 70aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung}; 71aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 72aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung} // namespace 73aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 74e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolbool nanoappStart() { 75a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("App started on platform ID %" PRIx64, chreGetPlatformId()); 76aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 77aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { 78aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung SensorState& sensor = sensors[i]; 79aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung sensor.isInitialized = chreSensorFindDefault(sensor.type, &sensor.handle); 80a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("sensor %d initialized: %s with handle %" PRIu32, 81a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol i, sensor.isInitialized ? "true" : "false", sensor.handle); 82aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 83aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung if (sensor.isInitialized) { 84aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung // Get sensor info 85aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung chreSensorInfo& info = sensor.info; 86aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung bool infoStatus = chreGetSensorInfo(sensor.handle, &info); 87aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung if (infoStatus) { 88a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("SensorInfo: %s, Type=%" PRIu8 " OnChange=%d" 89a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol " OneShot=%d minInterval=%" PRIu64 "nsec", 90a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol info.sensorName, info.sensorType, info.isOnChange, 91a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol info.isOneShot, info.minInterval); 92aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } else { 93a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGE("chreGetSensorInfo failed"); 94aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 95aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 96aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 97aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung // Subscribe to sensors 98aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung if (sensor.enable) { 99aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung float odrHz = 1e9 / sensor.interval; 100aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung float latencySec = sensor.latency / 1e9; 101aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung bool status = chreSensorConfigure(sensor.handle, 102aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS, sensor.interval, 103aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung sensor.latency); 104a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Requested data: odr %f Hz, latency %f sec, %s", 105a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol odrHz, latencySec, status ? "success" : "failure"); 106aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 107aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 108aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 109aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 110aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung return true; 111aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung} 112aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 113e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolvoid nanoappHandleEvent(uint32_t senderInstanceId, 114e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol uint16_t eventType, 115e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol const void *eventData) { 116aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung switch (eventType) { 117aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung case CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA: 118aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung case CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA: 119aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung case CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA: { 120aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const auto *ev = static_cast<const chreSensorThreeAxisData *>(eventData); 121aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const auto header = ev->header; 122aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const auto *data = ev->readings; 123aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 124aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung // TODO: replace by cal algo 125aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung float x = 0, y = 0, z = 0; 126aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung for (size_t i = 0; i < header.readingCount; i++) { 127aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung x += data[i].v[0]; 128aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung y += data[i].v[1]; 129aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung z += data[i].v[2]; 130aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 131aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung x /= header.readingCount; 132aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung y /= header.readingCount; 133aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung z /= header.readingCount; 134aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 135a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("%s, %d samples: %f %f %f", 136746ea0ecb99d3f758da17292db549b29720c4442Andrew Rossignol getSensorNameForEventType(eventType), header.readingCount, x, y, z); 137aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung break; 138aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 139aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 140aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung case CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA: 141aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung case CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA: { 142aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const auto *ev = static_cast<const chreSensorFloatData *>(eventData); 143aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung const auto header = ev->header; 144aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 145aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung // TODO: replace by cal algo 146aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung float v = 0; 147aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung for (size_t i = 0; i < header.readingCount; i++) { 148aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung v += ev->readings[i].value; 149aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 150aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung v /= header.readingCount; 151aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 152a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("%s, %d samples: %f", 153746ea0ecb99d3f758da17292db549b29720c4442Andrew Rossignol getSensorNameForEventType(eventType), header.readingCount, v); 154aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung break; 155aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 156aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 157aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung default: 158a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGW("Unhandled event %d", eventType); 159aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung break; 160aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung } 161aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung} 162aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 1632b9d71a9f6a9e8cc0e787957d022154231f29962Brian Duddievoid nanoappEnd() { 164aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung // TODO: Unscribe to sensors 165a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Stopped"); 166aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung} 167aa499877f69da5b99776f5b58ee5ecee824ddbc8Meng-hsuan Chung 168e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 1699d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // anonymous namespace 1709d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // namespace chre 171e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 1729d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/util/nanoapp/app_id.h" 1739d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/platform/static_nanoapp_init.h" 174e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 1759d5b500a223ef73560f0dce38f50b809bde5dd0dBrian DuddieCHRE_STATIC_NANOAPP_INIT(ImuCal, chre::kImuCalAppId, 0); 176e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 177