Skip to content
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

Merged
merged 88 commits into from
Jan 8, 2018

Conversation

ronzeiller
Copy link
Contributor

@ronzeiller ronzeiller commented Jan 2, 2018

Based on the PR#89 here are some further developments:

  • A second long button press on the IMUMonitorPage within 5 Seconds after the first long press writes offset values for heel & pitch into the EEPROM
  • If the BNO055 is fully calibrated (all cals = 3) then the calibration offset values are written to EEPROM automatically every 30 Minutes.
  • At startup of KBox calibration values and offset for heel/pitch are read from EEPROM
  • integrated sysCal into the IMUMonitorPage and sysCal > 0 into IMUService::isMagCalibrated() for better SKUpdate 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

roll = eulerAngles.z();
pitch = eulerAngles.y();
heading = fmod(eulerAngles.x() + 270, 360);
if (_config.mounting == VerticalStbHull) {
Copy link
Owner

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.

Copy link
Owner

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.

Copy link
Contributor Author

@ronzeiller ronzeiller Jan 3, 2018

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 {
Copy link
Owner

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank You

bool IMUService::readHeelPitchOffset() {
struct PersistentStorage::IMUHeelPitchOffsets o;

if (PersistentStorage::writeImuHeelPitchOffsets(o)) {
Copy link
Owner

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.

Copy link
Contributor Author

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).
@coveralls
Copy link

Coverage Status

Coverage decreased (-5.7%) to 66.57% when pulling 368f6fb on ronzeiller:rz_imu-more-stuff into 2eab8fd on sarfata:master.

uint8_t axisConfig = 0b00001001;
uint8_t signConfig = 0b00000000;

if (_config.mounting == VerticalTopToBow) {
Copy link
Owner

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.

Copy link
Contributor Author

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

@coveralls
Copy link

Coverage Status

Coverage decreased (-4.5%) to 67.78% when pulling 61ca6e5 on ronzeiller:rz_imu-more-stuff into 2eab8fd on sarfata:master.

@ronzeiller
Copy link
Contributor Author

@sarfata
small question about cosmetics:

you code:

if ( .... ) {
...
}
else {
...
}

In google c++ style guide is different?
https://google.github.io/styleguide/cppguide.html#Conditionals

@sarfata
Copy link
Owner

sarfata commented Jan 4, 2018

@sarfata
small question about cosmetics:

you code:

if ( .... ) {
...
}
else {
...
}

In google c++ style guide is different?
https://google.github.io/styleguide/cppguide.html#Conditionals

I was wrong. Fixing to the right code style.

SKHub &_skHub;
Adafruit_BNO055 bno055;
uint8_t sysCalib, gyroCalib, accelCalib, magCalib;
uint8_t _sysCalib, _gyroCalib, _accelCalib, _magCalib;
uint8_t _axisConfig, _signConfig;
Copy link
Owner

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.

Copy link
Contributor Author

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!

Copy link
Owner

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.

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
Copy link
Owner

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.

Copy link
Contributor Author

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?

Copy link
Owner

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.


if ( changed ) {
INFO("Offset changed: Heel -> %.3f | Pitch -> %.3f", SKRadToDeg(_offsetRoll), SKRadToDeg(_offsetPitch));
if (_timeSinceLastSetOffset < 5000) {
Copy link
Owner

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?

Copy link
Contributor Author

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.

// (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() {
Copy link
Owner

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.

Copy link
Contributor Author

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)

Copy link
Owner

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.

_skHub.publish(update);

// Save calibration values to EEPROM every 30 Minutes, if BNO055 is fully calibrated
if (bno055.isFullyCalibrated() && _timeSinceLastCalSave > 1800000) {
Copy link
Owner

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.

Copy link
Contributor Author

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.

Copy link
Owner

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.

sarfata and others added 7 commits January 3, 2018 23:17
 - 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
@coveralls
Copy link

Coverage Status

Coverage decreased (-1.08%) to 66.501% when pulling 60a2fe2 on ronzeiller:rz_imu-more-stuff into b0342cb on sarfata:master.

@sarfata
Copy link
Owner

sarfata commented Jan 8, 2018

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!

⛵️

@sarfata sarfata merged commit a418dc4 into sarfata:master Jan 8, 2018
@sarfata
Copy link
Owner

sarfata commented Jan 8, 2018

Ah we forgot to update the README! I will push another commit summarizing the changes. Please help me remember in the future ;)

@ronzeiller ronzeiller deleted the rz_imu-more-stuff branch February 11, 2018 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Save accelerometer/gyro/compass calibration and restore it when rebooting
3 participants