-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write & Read BNO055 Calibration and heel/pitch offsets to/from EEPROM #110
Conversation
src/host/services/IMUService.cpp
Outdated
roll = eulerAngles.z(); | ||
pitch = eulerAngles.y(); | ||
heading = fmod(eulerAngles.x() + 270, 360); | ||
if (_config.mounting == VerticalStbHull) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use a switch statement here. The compiler will throw a warning for the values of the enum that we are not visiting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this config has a slight issue: The pitch up is measured as negative. It should be positive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use a switch statement here. The compiler will throw a warning for the values of the enum that we are not visiting.
Done
I think this config has a slight issue: The pitch up is measured as negative. It should be positive
I took your original settings, but I think I mixed up positions. Now port hull is default.
But all positions should be tested, if they are correct, may be you could do it, or I will do, when I am back home next week.
//TODO: damping and automatic damping according to service frequency | ||
#include "host/config/IMUConfig.h" | ||
|
||
class IMUMonitorPage : public Page, public SKSubscriber { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pushing a commit to fix indentation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank You
src/host/services/IMUService.cpp
Outdated
bool IMUService::readHeelPitchOffset() { | ||
struct PersistentStorage::IMUHeelPitchOffsets o; | ||
|
||
if (PersistentStorage::writeImuHeelPitchOffsets(o)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want to call read
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes :-)
Thanks
This function is not implemented yet but anyway ;) Also, some minor cosmetic changes to code style (sorry could not help myself).
src/host/services/IMUService.cpp
Outdated
uint8_t axisConfig = 0b00001001; | ||
uint8_t signConfig = 0b00000000; | ||
|
||
if (_config.mounting == VerticalTopToBow) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here we should use an enum to make sure we cover all the cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now switch statement and yet non configured positions commented out in enum
@sarfata you code:
In google c++ style guide is different? |
I was wrong. Fixing to the right code style. |
src/host/services/IMUService.h
Outdated
SKHub &_skHub; | ||
Adafruit_BNO055 bno055; | ||
uint8_t sysCalib, gyroCalib, accelCalib, magCalib; | ||
uint8_t _sysCalib, _gyroCalib, _accelCalib, _magCalib; | ||
uint8_t _axisConfig, _signConfig; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you made these two member variables of the IMUService class? I do not think we need them to be here. They can be local variables when we initialize the sensor like they were before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I was not aware, that it makes a lot of difference.
Sure I will bring them back!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just makes the object a little bigger in memory. These classes are allocated on the heap when we start the program. The local variables inside functions are allocated on the stack. If possible, it's better to use stack than heap for us.
src/host/util/PersistentStorage.h
Outdated
private: | ||
// Addresses of elements in flash storage | ||
static const uint16_t magicAddress = 0; | ||
static const uint16_t versionAddress = 4; | ||
static const uint16_t nmea2000ParamsAddress = 8; | ||
static const uint16_t bno055CalOffsetsAddress = 20; // 11 x 2 Byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will replace this by nmea2000ParamsAddress + sizeof(NMEA2000Params)
this way it will always be correct even if we change the size of the NMEA2000Params
. Let me know if you see any problem with this.
Of course we will need to upgrade the version too when we do that so that old data is considered invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aah, now I know why you did the version!
The disadvantage could be:
Other values on higher addresses stored, e.g. Logging of total NM will get lost too
And you will have more writing-processes at the end.
May be there should be space reserved for permanent values or clear values which have fixed size and you put things which are not clear yet to higher addresses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah right now it does not handle that well.
src/host/services/IMUService.cpp
Outdated
|
||
if ( changed ) { | ||
INFO("Offset changed: Heel -> %.3f | Pitch -> %.3f", SKRadToDeg(_offsetRoll), SKRadToDeg(_offsetPitch)); | ||
if (_timeSinceLastSetOffset < 5000) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand why you have <5000
here. That means you only save if it's been less than 5sec that we started? That means you cannot save if you wait more than 5s after booting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first idea was, that with the first "long press" the offset is made temporary and a second "long press" will store it to flash.
Now I think it makes no sense, so the offset could be stored at first press.
But, I think I like the idea, that a second "long press" could reset offset to zero.
src/host/services/IMUService.cpp
Outdated
// (e.g. called with long button press in IMUMonitorPage) | ||
// If an setOffset will be done a second time within 5 Seconds, | ||
// the values will be stored into EEPROM and loaded at start of KBox | ||
void IMUService::setHeelPitchOffset() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you use heel
sometimes and roll
some other times? I think it's a bit confusing and we should probably use only one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that e.g. openCPN or any display shows "heel" and not "roll"
And also when we come to performance calculations everywhere is mentioned "heel"
Remember, when I asked you to change the wording to "heel"?
It is a pity, that SignalK has chosen "roll"....
So I took "heel" as much as possible and let roll where it has to be (IMU sensor, SignalK)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also what NMEA2000 is using: https://github.com/ttlappalainen/NMEA2000/blob/master/src/N2kMessages.h#L403
It's ok to use heel on the display but I do not think we should use it in the code. Having two names for the same thing is just confusing and I am tempted to follow what everyone else is doing here.
src/host/services/IMUService.cpp
Outdated
_skHub.publish(update); | ||
|
||
// Save calibration values to EEPROM every 30 Minutes, if BNO055 is fully calibrated | ||
if (bno055.isFullyCalibrated() && _timeSinceLastCalSave > 1800000) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_timeSinceLastCalSave
is never initialized. You should initialize it to the value of the timer so that it automatically saves the first time it's fully calibrated. And this should be a static const
member of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First point is clear.
But why static const?
If the sensor looses calibration and later on will get calibrated again, the new values should be written again to flash I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constant (1800000
) should be a const
. Only this. Sorry my comment was not clear.
I have implemented all of this in the PR i pushed to you.
- Use an array for BNO055 calibration data to avoid having to assign registers one by one. - Save IMUCalibration with offsets since we are very likely to read/write them together. - Also include with calibration the mounting position because the calibration very likely needs to be rest when the mounting position changes. - Use "roll" everywhere instead of pitch
Rz imu more stuff changes
No problem with your change on calibration. Sounds good to me. I think this is all as good as it can get for now so merging now and we can still do more changes later! Thanks a lot. Major contribution here! ⛵️ |
Ah we forgot to update the README! I will push another commit summarizing the changes. Please help me remember in the future ;) |
Based on the PR#89 here are some further developments:
sysCal
into theIMUMonitorPage
andsysCal > 0
intoIMUService::isMagCalibrated()
for betterSKUpdate
of heading.May be sysCal should even be 3 as it was in original KBox, just to be sure that heading values are more trustworthy and reliable.
@sarfata :
Please check if PersistentStorage is used ok, especially if the data length of NMEA2000Parameters is calculated right.
And I doubt if it is possible to write int to flash as I do.....
May be it is easier to make you as contributor to change whatever you want?
closes #74 #65