Hi everyone.
Can magnetometers like HMC5883L (or a different product, MPU9250, BNO055 etc.) be calibrated by rotating them only 360 degrees around their own axis? And then tilt compensation will be required. Since the vehicle will be heavy, I cannot rotate it in all axes. Jarzebski's HMC5883L library mentions that this can be done and is supported by a video. It also uses MPU6050 for tilt compensation.
Virtual Anchor and many RC autopilot systems perform calibration by rotating only around their own axis and can find their direction without any problems even in the ripples on the water. However, unfortunately I could not achieve this with Jarzebski's libraries. The purpose of giving Jarzebski's library as an example is because it is the only application that calibrates only by rotating around its own axis and that I have seen that applies tilt compensation.
If there is a different library or application, I can try that too. If anyone can guide me on this issue, I would really appreciate it.
For heavy vehicles, 2D calibration of the magnetometer and heading calculation using atan2() works fine, but you still need to rotate the vehicle+mounted magnetometer 360 degrees about the Z axis to obtain the calibration data. Tilt compensation is not needed if tilt is less than about 10 degrees.
Ellipse fitting code for offset removal and scale factor normalization, using either Matlab/GNU Octave or Python, is posted here.
Here it takes the calibrated offset values.
I calculate the offsets I get with atan2 but I have no way of knowing how much the slope will be. There will be times when it is below 10 degrees, and times when it can be above. So I think I will need slope compensation.
The min/max approach to calculating offsets often does not work well, and the offsets are only part of the total correction, which includes correcting for differences in X and Y scale factors, plus "soft iron" environmental distortions.
Got it. With the codes I use, only hard iron offsets are taken. But for 2D calibration, both hard iron and soft iron offsets need to be applied.
In the project I am trying to create, when the system starts, if calibration has not been done before, calibration is started and these values ββare saved to eeprom.
Necessary calculations will be made with the saved values ββand tilt compensation needs to be applied with MPU6050..
Therefore, I will not be able to use any graphics. So I am trying to find something that will only work on Arduino.
Sorry if I used the wrong expression. The vehicle will be used on a sea vessel, not a land vehicle.
It will inevitably be affected by the waves. However, I cannot perform a 3D calibration on this vehicle. My best option is to perform calibration by rotating the vehicle on its own axis a few times while it is running.
If 2D calibration and tilt compensation is not successful, unfortunately the project must be terminated before it starts..
I have endless respect for your knowledge on this subject. I always see that you are the biggest supporter on this kind of topics in the forum.
But I can't help but ask. There are Virtual Anchors (e.g. Minn Kota, Haswing) used on boats. Also, the vast majority of RC Autopilot systems (except Ardupilot) only rotate on their own axis, calibrate the magnetometer and reach their destination without any problems.
What do you think is the process in these, I wonder what you think about this?
True. They don't require tilt compensation to reach their destination, because the short term errors caused by wave action cancel out over the journey.
Here is a demo that I did many years ago using a BN0055 as a 2D compass. Watch the 1/2 meter LOA boat bounce on the waves, then return to within 2 meters of the starting point.
This is a great idea. Frankly, I thought it could be supported by GPS. But then I researched Virtual Anchors and thought it wouldn't be possible because GPS can't get direction when stationary (very small movements). So, how can a code structure be created as you mentioned?
I have this video, you also gave me the codes. I remember we talked about this in a different topic a while ago. But I still don't know how I can manage this project without slope compensation. So what kind of control mechanism should I set up so that the direction is not affected by the waves?
The code that I wrote does the "wave compensation" by simply pretending that there are no errors, except heading versus bearing.
The errors caused by random wave action cancel out on average! You are overthinking the problem, and some experiments will show that this really does work.
Here is the portion of the code (used in the video above) that navigates one leg of a course, following a bearing calculated between the current and target GPS coordinates. The magnetometer heading is used for the heading error correction. Steering in this case is twin screws, not rudder.
gps_last_fix = millis();
gps_latlon(&lat, &lon);
gps_parse_enable(); //re-enable parsing
gps_bearing = (int) (course_to(lat, lon, lat2, lon2, &distance)+0.5);
dist_to_go = distance + 0.5;
// To take into account wind and currents,
// substitute calculated GPS bearing for point_bearing
point_bearing = gps_bearing;
num_sats = gga_num_sats();
// leg navigation. Have course bearing from GPS coordinates of current loc and finish
yaw = get_heading(); //read magnetometer
imu_heading = wrap360(yaw + yaw_offset); //declination correction and compass wrap
// update LCD display
clear();
print_long(point_bearing);
print(" ");
print_long(imu_heading);
lcd_goto_xy(1,1);
print_long(num_sats);
print("s ");
print_long(dist_to_go);
// heading error and PID steering
error = heading_error(point_bearing, imu_heading);
//error is positive if current_heading > bearing (compass direction)
//positive bias acts to reduce left motor speed, so bear left
bias = (kp*error)/10; //Kp in tenths (Ki, Kd not necessary in water)
// the motor routines internally limit the argument to {-255, 255}
set_m1_speed(motorSpeed-bias); //left motor
set_m2_speed(motorSpeed+bias); //right motor
// check for recent GPS fix
if (millis() - gps_last_fix > gps_timeout) //5 seconds, currently
{
set_motors(0,0); //stop motors
clear();
print(" GPS-to"); //timeout!
printf("E,%lu,5,0,0,0,0\n",millis()); //error dump
delay(300);//wait a bit
}
else {
if ((millis()-timer) > timeout || dist_to_go < 3)
{
// leg timeout or at goal, stop motors
clear();
if (dist_to_go < 3) print("DIST");
else print("TIME");
set_motors(0,0);
delay(1000); //drift a bit
leg++; //count course legs accomplished
}
Thanks again for the codes. I understand the logic, I will complete the codes and start testing them as soon as possible. I will keep you informed about the project
Hello again.
Progress on my project:
I have currently calibrated the HMC5883L module in 2D and observed that there is not much deviation in the slope of the pitch movement with some filters.
However, unfortunately, in case of an error in the roll axis, serious deviations occur in the direction information. Therefore, unfortunately, I cannot use this module.
I always know your advice about the BNO055 modules, "a very old and problematic system", I have read this in many places, but I want to prefer this one because of the automatic slope compensation information. However, I have also read many articles about the automatic calibration it performs every time it is opened, and the fact that it gives 5-10 degrees of error every time it is opened.
I know that you recommend the ICM-20948 module, but unfortunately this product is not available in my country.
There is the AltIMU-10 v4 module, but I had so much difficulty with the slope compensation in other modules that I am now afraid of this type of module.
What do you think I should do? There is a module called BOARDOZA-BNO055, should I use this module?
AltIMU-10 v4 should I prefer this?
Please answer by keeping in mind that I will only do 2D calibration and I need tilt compensation..