Hi Kevin,
On 23 Dec 2016, at 15:26, Kevin Townsend wrote:
I'm probably getting ahead of myself diving into this before the
sensor API is nailed down, but if we wanted to add some generic helper
functions that make use of the sensor API, what would be a good
location or what to organize them as a package? It isn't always easy
to organize things like this by sensor type since there is a lot of
overlap.
Well, certainly ahead of me. I’m just looking at this stuff now,
sorry about that.
Comments inline, as I think some of it belongs in the sensor interface,
some is probably better a separate package.
I can think of two helper packages we might want to add as a core test
case, that are useful for testing and getting actionable, useful
output from the sensor API:
ORIENTATION
Using only an accelerometer you can get rough roll/pitch values:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/blob/development/src/drivers/sensors/accelerometers/accelerometers.c#L81
If you add a magnetometer you can get rough roll/pitch/heading values:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/blob/development/src/drivers/sensors/sensorfusion.c#L78
If you add a gyroscope, you can do proper 9DOF sensor fusion using a
variety of algorithms and get better quality roll/pitch heading
(madgwick, mahoney, etc.).
All of this will require at a minimum magnetometer calibration to
compensate for hard and soft iron errors, and probably gyroscope
calibration to remove the zero drift error. Accel calibration helps,
but isn't as critical as the mag and gyro.
All of the above can probably be fit into a package based on sensor
'orientation', which might be a natural organizational unit?
I think this belongs in the core sensor package itself, or as a
sub-directory of hw/sensor (i.e. hw/sensor/orientation). Orientation is
a very common transformation and having a unified API for it makes sense
to me, unless you think that the various factors that go into
orientation (e.g. accuracy) vary greatly based upon the type of sensor
that you’re looking at, and therefore the algorithms themselves will
vary greatly.
FILTERS
A second very important helper unit is something that implements basic
DSP algorithms to filter raw sensor data. This is critical in my
opinion, but often neglected in open source systems.
This should contain things like a simple moving average filter, a
basic FIR and IIR filter (that can take coefficients from
Octave/Matlab), and a other very common but useful filters that will
help remove noise from less expensive sensors like the lsm303dlhc.
For example, see:
* *iir.c* here:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/tree/development/src/drivers/filters/iir
* Simple and weighted moving average filters here:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/tree/development/src/drivers/filters/ma
The iir.c example above has some notes on calculating the coefficients
for a 2 pole butterworth filter, or determining the coefficients
internally. It's a limited example, but I think the right direction to
move things:
* Octave Butterworth Example:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/blob/development/src/drivers/filters/iir/iir.c#L57
* Calculating Butterworth Directly:
https://github.com/microbuilder/LPC11U_LPC13U_CodeBase/blob/development/src/drivers/filters/iir/iir.c#L269
To me, this is a separate package in core, but very useful.. Also, being
able to apply simulated data through a filter and get reliable results
(and standard scripts to graph those results.)
My biggest question comes in: what are the standard types that we allow
to be passed to these filters? Is it just floats, or do we allow you
to, for example, pass accelerometer directly.
BONUS POINTS: PEDOMETER
A third package that could be implemented that would be a useful
example for BLE is taking accelerometer data and turning it into a
pedometer, which can be done with some reasonably straight forward
code. I have some code I can recycle for this, but it isn't publicly
available on Github.
I think this is interesting for BLE and I can help here, but the two
above are more critical.
Yeah, I think this is useful. I’m not sure this belongs in the core,
but perhaps a package that uses Mynewt? I could be convinced otherwise,
if folks think it should be OS level.
Kevin
PS: Some of the code above is quite old and I'm not terribly proud of
it and would do things differently today and I've reimplemented these
elsewhere differently, but I think the examples are at least valid as
an illustration or where things need to move to be useful in the real
world.
:-)
Very useful.
Sterling