Copying over accelerometer_app as a starting point

Verbatim copy from the SDK[1]'s sample/cceleromater_app directory

[1] git@bitbucket.org:suunto/movesense-device-lib.git
master
denes 6 years ago
parent 5ae9e4ff61
commit db9dcbed36

@ -0,0 +1,252 @@
#include "AccelerometerSampleService.h"
#include "app-resources/resources.h"
#include "common/core/debug.h"
#include "meas_acc/resources.h"
#include "whiteboard/builtinTypes/UnknownStructure.h"
#include <float.h>
#include <math.h>
const char* const AccelerometerSampleService::LAUNCHABLE_NAME = "SampleA";
#define SAMPLE_RATE 13
static const whiteboard::ExecutionContextId sExecutionContextId =
WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA::EXECUTION_CONTEXT;
static const whiteboard::LocalResourceId sProviderResources[] = {
WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA::LID,
};
AccelerometerSampleService::AccelerometerSampleService()
: ResourceClient(WBDEBUG_NAME(__FUNCTION__), sExecutionContextId),
ResourceProvider(WBDEBUG_NAME(__FUNCTION__), sExecutionContextId),
LaunchableModule(LAUNCHABLE_NAME, sExecutionContextId),
isRunning(false)
{
}
AccelerometerSampleService::~AccelerometerSampleService()
{
}
bool AccelerometerSampleService::initModule()
{
if (registerProviderResources(sProviderResources) != whiteboard::HTTP_CODE_OK)
{
return false;
}
mModuleState = WB_RES::ModuleStateValues::INITIALIZED;
return true;
}
void AccelerometerSampleService::deinitModule()
{
unregisterProviderResources(sProviderResources);
mModuleState = WB_RES::ModuleStateValues::UNINITIALIZED;
}
/** @see whiteboard::ILaunchableModule::startModule */
bool AccelerometerSampleService::startModule()
{
mModuleState = WB_RES::ModuleStateValues::STARTED;
return true;
}
void AccelerometerSampleService::onUnsubscribeResult(whiteboard::RequestId requestId,
whiteboard::ResourceId resourceId,
whiteboard::Result resultCode,
const whiteboard::Value& rResultData)
{
DEBUGLOG("AccelerometerSampleService::onUnsubscribeResult() called.");
}
void AccelerometerSampleService::onSubscribeResult(whiteboard::RequestId requestId,
whiteboard::ResourceId resourceId,
whiteboard::Result resultCode,
const whiteboard::Value& rResultData)
{
DEBUGLOG("AccelerometerSampleService::onSubscribeResult() called. resourceId: %u, result: %d", resourceId.localResourceId, (uint32_t)resultCode);
whiteboard::Request relatedIncomingRequest;
bool relatedRequestFound = mOngoingRequests.get(requestId, relatedIncomingRequest);
if (relatedRequestFound)
{
returnResult(relatedIncomingRequest, wb::HTTP_CODE_OK);
}
}
whiteboard::Result AccelerometerSampleService::startRunning(whiteboard::RequestId& remoteRequestId)
{
if (isRunning)
{
return whiteboard::HTTP_CODE_OK;
}
DEBUGLOG("AccelerometerSampleService::startRunning()");
// Reset max acceleration members
mMaxAccelerationSq = FLT_MIN;
mSamplesIncluded = 0;
wb::Result result = getResource("Meas/Acc/13", mMeasAccResourceId);
if (!wb::RETURN_OKC(result))
{
return result;
}
result = asyncSubscribe(mMeasAccResourceId, AsyncRequestOptions(&remoteRequestId, 0, true));
if (!wb::RETURN_OKC(result))
{
DEBUGLOG("asyncSubscribe threw error: %u", result);
return whiteboard::HTTP_CODE_BAD_REQUEST;
}
isRunning = true;
return whiteboard::HTTP_CODE_OK;
}
whiteboard::Result AccelerometerSampleService::stopRunning()
{
if (!isRunning)
{
return whiteboard::HTTP_CODE_OK;
}
if (isResourceSubscribed(WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA::ID) == wb::HTTP_CODE_OK)
{
DEBUGLOG("AccelerometerSampleService::stopRunning() skipping. Subscribers still exist.");
return whiteboard::HTTP_CODE_OK;
}
DEBUGLOG("AccelerometerSampleService::stopRunning()");
// Unsubscribe the LinearAcceleration resource, when unsubscribe is done, we get callback
wb::Result result = asyncUnsubscribe(mMeasAccResourceId, NULL);
if (!wb::RETURN_OKC(result))
{
DEBUGLOG("asyncUnsubscribe threw error: %u", result);
}
isRunning = false;
releaseResource(mMeasAccResourceId);
return whiteboard::HTTP_CODE_OK;
}
// This callback is called when the resource we have subscribed notifies us
void AccelerometerSampleService::onNotify(whiteboard::ResourceId resourceId, const whiteboard::Value& value,
const whiteboard::ParameterList& parameters)
{
DEBUGLOG("onNotify() called.");
// Confirm that it is the correct resource
switch (resourceId.localResourceId)
{
case WB_RES::LOCAL::MEAS_ACC_SAMPLERATE::LID:
{
const WB_RES::AccData& linearAccelerationValue =
value.convertTo<const WB_RES::AccData&>();
if (linearAccelerationValue.arrayAcc.size() <= 0)
{
// No value, do nothing...
return;
}
const whiteboard::Array<whiteboard::FloatVector3D>& arrayData = linearAccelerationValue.arrayAcc;
uint32_t relativeTime = linearAccelerationValue.timestamp;
for (size_t i = 0; i < arrayData.size(); i++)
{
mSamplesIncluded++;
whiteboard::FloatVector3D accValue = arrayData[i];
float accelerationSq = accValue.mX * accValue.mX +
accValue.mY * accValue.mY +
accValue.mZ * accValue.mZ;
if (mMaxAccelerationSq < accelerationSq)
mMaxAccelerationSq = accelerationSq;
}
// 13Hz 5sec
if (mSamplesIncluded > 5 * 13)
{
// Reset counter and notify our subscribers
WB_RES::SampleDataValue sampleDataValue;
sampleDataValue.relativeTime = relativeTime;
sampleDataValue.value = sqrtf(mMaxAccelerationSq);
// Reset members
mSamplesIncluded = 0;
mMaxAccelerationSq = FLT_MIN;
// and update our WB resource. This causes notification to be fired to our subscribers
updateResource(WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA(),
ResponseOptions::Empty, sampleDataValue);
}
}
break;
}
}
void AccelerometerSampleService::onSubscribe(const whiteboard::Request& request,
const whiteboard::ParameterList& parameters)
{
switch (request.getResourceConstId())
{
case WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA::ID:
{
// Someone subscribed to our service. Start collecting data and notifying when our service changes state (every 10 seconds)
whiteboard::RequestId remoteRequestId;
whiteboard::Result result = startRunning(remoteRequestId);
if (isRunning)
{
return returnResult(request, whiteboard::HTTP_CODE_OK);
}
if (!whiteboard::RETURN_OK(result))
{
return returnResult(request, result);
}
bool queueResult = mOngoingRequests.put(remoteRequestId, request);
(void)queueResult;
WB_ASSERT(queueResult);
break;
}
default:
ASSERT(0); // Should not happen
}
}
void AccelerometerSampleService::onUnsubscribe(const whiteboard::Request& request,
const whiteboard::ParameterList& parameters)
{
switch (request.getResourceConstId())
{
case WB_RES::LOCAL::SAMPLE_ACCELEROMETER_DATA::ID:
stopRunning();
returnResult(request, wb::HTTP_CODE_OK);
break;
default:
returnResult(request, wb::HTTP_CODE_BAD_REQUEST);
ASSERT(0); // Should not happen
}
}
void AccelerometerSampleService::onRemoteWhiteboardDisconnected(whiteboard::WhiteboardId whiteboardId)
{
DEBUGLOG("AccelerometerSampleService::onRemoteWhiteboardDisconnected()");
stopRunning();
}
void AccelerometerSampleService::onClientUnavailable(whiteboard::ClientId clientId)
{
DEBUGLOG("AccelerometerSampleService::onClientUnavailable()");
stopRunning();
}

@ -0,0 +1,123 @@
#pragma once
#include <whiteboard/LaunchableModule.h>
#include <whiteboard/ResourceClient.h>
#include <whiteboard/ResourceProvider.h>
#include <whiteboard/containers/RequestMap.h>
#include "wb-resources/resources.h"
class AccelerometerSampleService FINAL : private whiteboard::ResourceClient,
private whiteboard::ResourceProvider,
public whiteboard::LaunchableModule
{
public:
/** Name of this class. Used in StartupProvider list. */
static const char* const LAUNCHABLE_NAME;
AccelerometerSampleService();
~AccelerometerSampleService();
private:
/** @see whiteboard::ILaunchableModule::initModule */
virtual bool initModule() OVERRIDE;
/** @see whiteboard::ILaunchableModule::deinitModule */
virtual void deinitModule() OVERRIDE;
/** @see whiteboard::ILaunchableModule::startModule */
virtual bool startModule() OVERRIDE;
/** @see whiteboard::ILaunchableModule::stopModule */
virtual void stopModule() OVERRIDE { mModuleState = WB_RES::ModuleStateValues::STOPPED; }
/**
* Subscribe notification callback.
*
* @param request Request information
* @param parameters List of parameters
*/
virtual void onSubscribe(const whiteboard::Request& request,
const whiteboard::ParameterList& parameters) OVERRIDE;
/**
* Unsubscribe notification callback.
*
* @param request Request information
* @param parameters List of parameters
*/
virtual void onUnsubscribe(const whiteboard::Request& request,
const whiteboard::ParameterList& parameters) OVERRIDE;
/**
* Whiteboard disconnect notification handler.
*
* This can be used for example to cleanup possible subscription related information of clients from
* the remote whiteboard.
*
* @param whiteboardId ID of the whiteboard that has been disconnected.
*
* @see whiteboard::ResourceProvider::onSubscribe
* @see whiteboard::ResourceProvider::onUnsubscribe
*/
virtual void onRemoteWhiteboardDisconnected(whiteboard::WhiteboardId whiteboardId) OVERRIDE;
/**
* Local client 'disconnect' notification handler.
*
* This can be used for example to cleanup possible subscription related information of the client.
*
* @see whiteboard::ResourceProvider::onSubscribe
* @see whiteboard::ResourceProvider::onUnsubscribe
*/
virtual void onClientUnavailable(whiteboard::ClientId clientId) OVERRIDE;
/**
* Callback for resource notifications.
* Note that this function will not be called for notifications that are
* of types WB_RESOURCE_NOTIFICATION_TYPE_INSERT or WB_RESOURCE_NOTIFICATION_TYPE_DELETE,
* just for notifications that are of type WB_RESOURCE_NOTIFICATION_TYPE_UPDATE.
*
* @param resourceId Resource id associated with the update
* @param rValue Current value of the resource
*/
virtual void onNotify(whiteboard::ResourceId resourceId, const whiteboard::Value& value,
const whiteboard::ParameterList& parameters);
/**
* Callback for asynchronous UNSUBSCRIBE requests
*
* @param requestId ID of the request
* @param resourceId Successful request contains ID of the resource
* @param resultCode Result code of the request
* @param rResultData Successful result contains the request result
*/
virtual void onUnsubscribeResult(whiteboard::RequestId requestId,
whiteboard::ResourceId resourceId,
whiteboard::Result resultCode,
const whiteboard::Value& rResultData);
/**
* Callback for asynchronous SUBSCRIBE requests
*
* @param requestId ID of the request
* @param resourceId Successful request contains ID of the resource
* @param resultCode Result code of the request
* @param rResultData Successful result contains the request result
*/
virtual void onSubscribeResult(whiteboard::RequestId requestId,
whiteboard::ResourceId resourceId,
whiteboard::Result resultCode,
const whiteboard::Value& rResultData);
private:
whiteboard::Result startRunning(whiteboard::RequestId& remoteRequestId);
whiteboard::Result stopRunning();
whiteboard::ResourceId mMeasAccResourceId;
whiteboard::RequestMap<2, void> mOngoingRequests; // For storing relations of incoming & outgoing requests
bool isRunning;
size_t mSamplesIncluded;
float mMaxAccelerationSq;
};

@ -0,0 +1,43 @@
#include "AccelerometerSampleService.h"
#include "movesense.h"
MOVESENSE_APPLICATION_STACKSIZE(1024)
MOVESENSE_PROVIDERS_BEGIN(1)
MOVESENSE_PROVIDER_DEF(AccelerometerSampleService)
MOVESENSE_PROVIDERS_END(1)
MOVESENSE_FEATURES_BEGIN()
// Explicitly enable or disable Movesense framework core modules.
// List of modules and their default state is found in documentation
OPTIONAL_CORE_MODULE(DataLogger, true)
OPTIONAL_CORE_MODULE(Logbook, true)
OPTIONAL_CORE_MODULE(LedService, true)
OPTIONAL_CORE_MODULE(IndicationService, true)
OPTIONAL_CORE_MODULE(BleService, true)
OPTIONAL_CORE_MODULE(EepromService, true)
OPTIONAL_CORE_MODULE(BypassService, false)
OPTIONAL_CORE_MODULE(SystemMemoryService, false)
OPTIONAL_CORE_MODULE(DebugService, false)
OPTIONAL_CORE_MODULE(BleStandardHRS, false)
OPTIONAL_CORE_MODULE(BleNordicUART, false)
OPTIONAL_CORE_MODULE(CustomGattService, false)
// NOTE: It is inadvisable to enable both Logbook/DataLogger and EepromService without
// explicit definition of Logbook memory are (see LOGBOOK_MEMORY_AREA macro in movesense.h and eeprom_logbook_app).
// Default setting is for Logbook to use the whole EEPROM memory area.
// NOTE: If building a simulator build, these macros are obligatory!
DEBUGSERVICE_BUFFER_SIZE(6, 120); // 6 lines, 120 characters total
DEBUG_EEPROM_MEMORY_AREA(false, 0, 0)
LOGBOOK_MEMORY_AREA(0, 384 * 1024);
APPINFO_NAME("Sample Accelerometer");
APPINFO_VERSION("1.1.0");
APPINFO_COMPANY("Movesense");
// NOTE: SERIAL_COMMUNICATION macro has been DEPRECATED
BLE_COMMUNICATION(true)
MOVESENSE_FEATURES_END()

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.4)
enable_language(C CXX ASM)
if(NOT DEFINED MOVESENSE_CORE_LIBRARY)
# Give error that user must provide path to movescount-core library
message(FATAL_ERROR "Path to movesense-core library not set. Add -DMOVESENSE_CORE_LIBRARY=<path_to_core_lib> to cmake command line")
endif()
if(NOT IS_ABSOLUTE ${MOVESENSE_CORE_LIBRARY})
set(MOVESENSE_CORE_LIBRARY ${CMAKE_BINARY_DIR}/${MOVESENSE_CORE_LIBRARY})
endif()
include(${MOVESENSE_CORE_LIBRARY}/MovesenseFromStaticLib.cmake REQUIRED)

@ -0,0 +1,26 @@
# Type of the document
wbres:
version: "2.0"
type: "root"
# Execution context definitions
executionContexts:
application:
numberOfDpcs: 8
numberOfRequests: 20
numberOfResponses: 25
externalThread: true # we run this execution context in main thread
stackSize: 768
priority: normal
meas:
numberOfDpcs: 9
numberOfRequests: 25
numberOfResponses: 10
stackSize: 768
priority: normal
apis:
AccelerometerSample.*:
apiId: 100
defaultExecutionContext: meas

@ -0,0 +1,61 @@
# This file defines Suunto Whiteboard API for Movesense Hackathon 2016 sample
#
swagger: '2.0'
# Document metadata
info:
version: "0.0.0"
title: Movesense Accelerometer sample app API
description: |
This file defines API for Movesense Accelerometer Sample service
See http://movesense.com for more information.
termsOfService: http://suunto.com/wbapi/terms/
contact:
name: Suunto team
url: http://developer.suunto.com
# Paths
paths:
/Sample/Accelerometer/Data/Subscription:
post:
description: |
Subscribe to periodic Data values.
See documentation on product-specific measurement periods at
http://XXX.suunto.com/XXX. If measurement source is unavailable, the
Measurement member will be empty. If present, Measurement member
contains single measurement result.
responses:
200:
description: Operation completed successfully
x-std-errors:
description: See common error codes http://developer.suunto.com/api/std-errors#subscribe
x-notification:
description: New value
schema:
$ref: '#/definitions/SampleDataValue'
delete:
description: |
Unsubscribe from sample data values.
responses:
200:
description: Operation completed successfully
x-std-errors:
description: See common error codes http://developer.suunto.com/api/std-errors#unsubscribe
definitions:
SampleDataValue:
required:
- RelativeTime
- Value
properties:
RelativeTime:
description: Relative time of measurement
type: integer
format: uint32
x-unit: millisecond
Value:
description: Sample Data Value (in practice max absolute acceleration, over about 5 seconds when subscribed)
type: number
format: float
x-unit: m/s^2

@ -0,0 +1 @@
// This file is needed by CMAKE. It can't generate empty libraries.
Loading…
Cancel
Save