attach method
Attach this RxIMU to the Frame's dataResponse characteristic stream.
Implementation
Stream<IMUData> attach(Stream<List<int>> dataResponse) {
// TODO check for illegal state - attach() already called on this RxIMU etc?
// might be possible though after a clean close(), do I want to prevent it?
// the subscription to the underlying data stream
StreamSubscription<List<int>>? dataResponseSubs;
// Our stream controller that transforms the dataResponse elements into IMUData events
_controller = StreamController();
_controller!.onListen = () {
dataResponseSubs = dataResponse
.where((data) => data[0] == imuFlag)
.listen((data) {
// data structure: [flag, ?, float, float, float, float, float, float]
// offsets: 0, 1, 2..5, 6..9, 10..13, 14..17, 18..21, 22..25
// total length should be at least 2 + 6*4 = 26 bytes.
if (data.length < 26) {
// Not enough data for 6 floats + header
return;
}
final byteData = ByteData.sublistView(Uint8List.fromList(data));
// Read 6 32-bit little-endian floats starting at offset 2
double cX = byteData.getFloat32(2, Endian.little);
double cY = byteData.getFloat32(6, Endian.little);
double cZ = byteData.getFloat32(10, Endian.little);
double aX = byteData.getFloat32(14, Endian.little);
double aY = byteData.getFloat32(18, Endian.little);
double aZ = byteData.getFloat32(22, Endian.little);
// Get raw values
var rawCompass = (cX, cY, cZ);
var rawAccel = (aX, aY, aZ);
// Add to buffers
_compassBuffer.add(rawCompass);
_accelBuffer.add(rawAccel);
_controller!.add(IMUData(
compass: _compassBuffer.average,
accel: _accelBuffer.average,
raw: IMURawData(
compass: rawCompass,
accel: rawAccel,
),
));
}, onDone: _controller!.close, onError: _controller!.addError);
_log.fine('ImuDataResponse stream subscribed');
};
_controller!.onCancel = () {
_log.fine('ImuDataResponse stream unsubscribed');
dataResponseSubs?.cancel();
_controller!.close();
};
return _controller!.stream;
}