BjarneBitscrambler / OrientationSensorFusion-ESP

Files for performing orientation sensor fusion using NXP version 7 algorithm, ported to Espressif platforms.
BSD 3-Clause "New" or "Revised" License
23 stars 12 forks source link

Implementing Library For Other Sensors #26

Open mason-stafford opened 3 years ago

mason-stafford commented 3 years ago

Hi @BjarneBitscrambler , First of all thanks for sharing such an awesome library and complete description in examples and header files, it's really helpful. But with all these, implementing the library for another sensor is still confusing. I checked the whole library more than once and It looks like using this library for another sensors is a little bit impossible. It's gonna be great if you help making a better and more understandable simple code : Lets consider that I have my raw sensor data as ax,ay,az,gx,gy,gz,mx,my,mz variables which is in standard units and frequency for library. 1.Which header files have to be included in main script? 2.How should I feed these variables to sensor fusion? 3.How should I calibrate the whole IMU ACC,GYRO,MAG?(cause I couldn't find any calibration function for GYRO) 4.How should I get the Quaternion data as output?

also making a simple script like above looks like to be so challenging cause the main fusion header file is using build and board files and I couldn't find any possible way to pass the raw sensor data to filter. anyways I hope there is an easier way. Kind Regards, Mason.

dpazz commented 1 year ago

I'm trying too to implement this library for another sensor (in my case a GY breakout board containing an Invensense 9250 accel/gyro/mag chip plus a Bosch BMP280 baro/temp chip latched to the former internal passthru I2C bus). The problem I'm facing is that this very comprehensive library seems to be tied to te NSX/Freescale sensor architecture and it is difficult to understand at what level of abstaction insert a different sensor archtecture (in this case a combo of three basic sensor -accel, gyro and mag- plus the baro/temp BMP280). I would like to use this library already implemented fusion algorithms in combination with the Signalk companion library (the final goal of my project is to use this sensor in a boat SignalK environment). Any hint/suggestion on the path to be followed will be very appreciated. Regards Daniele Pazzaglia

BjarneBitscrambler commented 1 year ago

Yes, I agree it's a bit daunting to start modifying this library for other sensor hardware. First off, you've probably read this library's Customizing and Modifying section (https://github.com/BjarneBitscrambler/OrientationSensorFusion-ESP#customizing-and-modifying), which gives an overview of the files involved, but I'll mention it for others who are browsing this topic.

To be more specific, here are the steps I would follow to adapt the library for other sensor hardware (which may not be the most efficient or 'proper' - I do not consider myself an expert programmer):

Depending on how different the I2C comms of the new hardware are from the NXP sensors, you may have to adjust hal_i2c.cc. For example, the I2C rate is set to 400kHz in I2CInitialize() - this may or may not be correct for other hardware.

Also depending on your hardware's definition of axes, you may have to remap one or more of the sensor's x,y,z outputs to match the coordinate system used by the fusion algorithm. Check hal_axis_remap.c for details.

I hope that this is enough to get you on the road to successfully using the library with another sensor. If you have specific problems/questions, please let me know. My time availability varies a lot, but if I am able to help I will. Good luck!

dpazz commented 1 year ago

Yes, I agree it's a bit daunting to start modifying this library for other sensor hardware. First off, you've probably read this library's Customizing and Modifying section (https://github.com/BjarneBitscrambler/OrientationSensorFusion-ESP#customizing-and-modifying), which gives an overview of the files involved, but I'll mention it for others who are browsing this topic.

To be more specific, here are the steps I would follow to adapt the library for other sensor hardware (which may not be the most efficient or 'proper' - I do not consider myself an expert programmer):

* clone/copy the library code

* compile it to ensure your development environment is setup correctly

* rename the files `driver_fxas21002.*`, and `driver_fxos8700.*` to reflect the hardware that you are using, without actually editing the files themselves yet.  Edit the other source files to reference your new `driver_*` files instead of the old ones.  If all three orientation functions (gyro, magnetometer, accelerometer) are integrated in one IC (instead of 2 as with NXP), then you can probably simplify things by having just one set of driver_* files instead of two.

* compile again to confirm that the filename changes haven't broken anything

* rewrite the `FXAS21002_Init()`, `FXAS21002_Read()`, `FXOS8700_Init()`, and `FXOS8700_Read()` functions in the `driver_*` files to perform the setup and read functions for your new hardware. This will require diving into the specs for your hardware to see what particular I2C commands and registers are used. You'll have to also change the low-level command definitions that perform tasks like checking the accelerometer FIFO:
 (// Command definition to read the number of entries in the accel FIFO.
registerReadlist_t          FXOS8700_DATA_READ[] =
{
    { .readFrom = FXOS8700_OUT_X_MSB, .numBytes = 6 }, __END_READ_DATA__
};
* update the `driver_sensors.h` file to reflect the new initialization and read functions that you have created. You can choose to rename the FXOS/FXAS functions here to reflect the actual hardware you are using, or (to minimize the number of changes percolating through the code) just live with the names as currently given.  If I were to re-write my code, I would choose generic names for these functions, like `Accelerometer_Init()`, and map them to hardware-specific functions like `FXAS_Accel_Init()` all in one place to provide a level of hardware abstraction.

* compile to confirm that you are able to retrieve values from your particular hardware. It might, during this and the preceding 2 steps, be easier to just focus on getting one parameter (e.g. gyro) working at a time - the other parameters can be simulated by replacing the existing code with empty functions or ones that return known values.

Depending on how different the I2C comms of the new hardware are from the NXP sensors, you may have to adjust hal_i2c.cc. For example, the I2C rate is set to 400kHz in I2CInitialize() - this may or may not be correct for other hardware.

Also depending on your hardware's definition of axes, you may have to remap one or more of the sensor's x,y,z outputs to match the coordinate system used by the fusion algorithm. Check hal_axis_remap.c for details.

I hope that this is enough to get you on the road to successfully using the library with another sensor. If you have specific problems/questions, please let me know. My time availability varies a lot, but if I am able to help I will. Good luck!

I apologize for the delay in my reply to your kind advice. The delay was due to the malfunctioning of the harware breakout I was using (many 9250 breakout boards are fake and sent with MPU 6250 that has only accel & gyro sensors, so I've to research for alternatives and learn about other orientation sensor families). I'll follow your suggestions but ther's a basic issue I'm thinkering a lot. My research drove me to understand that there are basically two types of orientation sensors families nowaday: a "raw" one (like te one used in your project) where the execution of the fusion algorithms (Kalman filter or others like Madgwick or Mahony) is in charge of the MCU ESP32 or similar (in this case the focus of the driver library is to have efficient acces to raw data produced by the sensors to feed the algorithm computations at best; by the way Adafruit did a good job unifying all this stuff in one library https://github.com/adafruit/Adafruit_AHRS ), and an "intelligent" or "smart" one where the sensor chip has integrated an MCU capable of executing direcly the fusion algorithms (in this case the driver library has access to computed fusion data by the sensor itself, like Euler vectors or quaternions), This second family is obviously capable to produce raw data as the "raw" one thus in principle it is possible to use smart sensor in dumb mode and consequently adapt the code following your hints. Bit it should be a pity, IMHO. I think that a reworking to your library should take into account this substantial difference of sensor approach and have a switch (or a separate version) for the different abstraction layer imposed by the different sensor families. Now I'm working with BNO055 Bosh smart sensor and the ICM-20948 of TDK Invensense (I attach the pdf of both for your info). Let me stop to bore you tellig where I'm now: starting with the Bosh unit what library use (the one from Bosh itself or the one from Adafruit referenced by platformio) and after to decide at what level of abstraction rework your code. I'll keep you informed of my progress if any in the next future. Regards. Daniele bst-bno055-ds000.pdf DS-000189-ICM-20948-v1.5.pdf