Last active
February 10, 2020 14:30
-
-
Save simplecohesion/6b36be51687334ba7e45d40ac3077759 to your computer and use it in GitHub Desktop.
MetaWear Quaternion Streaming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension MetaWear{ | |
func configureSensorFusion() -> Task<()> { | |
guard isConnectedAndSetup else { | |
return Task<()>.init(error: MetaWearError.operationFailed(message: "device not connected")) | |
} | |
let completionSource = TaskCompletionSource<()>() | |
self.apiAccessQueue.async { | |
mbl_mw_metawearboard_tear_down(self.board) | |
mbl_mw_sensor_fusion_set_mode(self.board, MBL_MW_SENSOR_FUSION_MODE_IMU_PLUS) | |
mbl_mw_sensor_fusion_write_config(self.board) | |
completionSource.trySet(result: ()) | |
} | |
return completionSource.task | |
} | |
func createQuaternionTimerSignal(samplePeriod: UInt32) -> Task<OpaquePointer> { | |
guard isConnectedAndSetup else { | |
return Task<OpaquePointer>.init(error: MetaWearError.operationFailed(message: "device not connected")) | |
} | |
let completionSource = TaskCompletionSource<OpaquePointer>() | |
self.apiAccessQueue.async { | |
mbl_mw_dataprocessor_time_create(self.quaternionSignal, MBL_MW_TIME_ABSOLUTE, samplePeriod, bridgeRetained(obj: completionSource)) { (context, dataPtr) in | |
let _completionSource: TaskCompletionSource<OpaquePointer> = bridgeTransfer(ptr: context!) | |
guard let dataPtr = dataPtr else { | |
_completionSource.trySet(error: MetaWearError.operationFailed(message: "No data pointer")) | |
return | |
} | |
_completionSource.trySet(result: dataPtr) | |
} | |
} | |
return completionSource.task | |
} | |
func startStreamingQuaternion(timerSignal: OpaquePointer, sensorDataBridge: SensorDataBridge) -> Task<()> { | |
guard isConnectedAndSetup else { | |
return Task<()>.init(error: MetaWearError.operationFailed(message: "device not connected")) | |
} | |
let completionSource = TaskCompletionSource<()>() | |
sensorDataBridge.completionSource = completionSource | |
self.apiAccessQueue.async { | |
mbl_mw_datasignal_subscribe(sensorDataBridge.quaternionTimeSignal, bridge(obj: sensorDataBridge)) { (context, dataPtr) in | |
let _sensorDataBridge: SensorDataBridge = bridge(ptr: context!) | |
guard let dataPtr = dataPtr else { | |
if !(_sensorDataBridge.completionSource?.task.completed ?? false) { | |
_sensorDataBridge.completionSource?.trySet(error: MetaWearError.operationFailed(message: "could not subscribe to quaternion streaming")) | |
} | |
return | |
} | |
//return completed task only when first data has streamed | |
if !(_sensorDataBridge.completionSource?.task.completed ?? false) { | |
_sensorDataBridge.completionSource?.trySet(result: ()) | |
} | |
let mblQuaternion = dataPtr.pointee.copy().valueAs() as MblMwQuaternion | |
_sensorDataBridge.metawearHandler?.quaternionData(quaternion: mblQuaternion, metawear: _sensorDataBridge.metawear) | |
} | |
mbl_mw_sensor_fusion_enable_data(self.board, MBL_MW_SENSOR_FUSION_DATA_QUATERNION) | |
mbl_mw_sensor_fusion_start(self.board) | |
} | |
return completionSource.task | |
} | |
func stopStreamingQuaternion(sensorDataBridge: SensorDataBridge) -> Task<()> { | |
guard isConnectedAndSetup else { | |
return Task<()>.init(error: MetaWearError.operationFailed(message: "device not connected")) | |
} | |
let source = TaskCompletionSource<()>() | |
apiAccessQueue.async { | |
mbl_mw_datasignal_unsubscribe(sensorDataBridge.quaternionTimeSignal) | |
mbl_mw_dataprocessor_remove(sensorDataBridge.quaternionTimeSignal) | |
sensorDataBridge.quaternionTimeSignal = nil | |
mbl_mw_sensor_fusion_stop(self.board) | |
mbl_mw_sensor_fusion_clear_enabled_mask(self.board) | |
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { | |
source.trySet(result: ()) | |
} | |
} | |
return source.task | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol MetaWearDelegate: class { | |
func quaternionData(quaternion: MblMwQuaternion, metawear: MetaWear) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct SensorDataBridge { | |
weak var metawearHandler: MetaWearDelegate? | |
var metawear: MetaWear | |
var quaternionTimeSignal: OpaquePointer? | |
var completionSource: TaskCompletionSource<()>? | |
init (_ metawearHandler: MetaWearDelegate, _ metawear: MetaWear) { | |
self.metawearHandler = metawearHandler | |
self.metawear = metawear | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var metaWear: MetaWear | |
var sensorDataBridge: SensorDataBridge | |
metaWear.configureSensorFusion().continueOnSuccessWithTask { | |
return metaWear.createQuaternionTimerSignal(samplePeriod: UInt32(100)) | |
}.continueOnSuccessWithTask { timerPointer in | |
return metaWear.startStreamingQuaternion(timerSignal: timerPointer, sensorDataBridge: sensorDataBridge) | |
}.continueOnError { error in | |
//handle error | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi @simplecohesion,
I got some errors in MetaWear+QuaternionStreaming.swift file.
can you help me, please?
- Value of type 'MetaWear' has no member 'quaternionSignal' (mbl_mw_dataprocessor_time_create(self.quaternionSignal, MBL_M...)
- Cannot assign to property: 'sensorDataBridge' is a 'let' constant (sensorDataBridge.completionSource = completionSource)
- Cannot invoke 'bridge' with an argument list of type '(obj: SensorDataBridge)' (mbl_mw_datasignal_subscribe(sensorDataBridge.quaternionTime...)
- Cannot assign to property: 'sensorDataBridge' is a 'let' constant (sensorDataBridge.quaternionTimeSignal = nil)