Sure but who has flat concrete handy? And come to that I do have flat concrete handy but I have no guarantees it is actually level!
Hi, yeah that could be done. Tested out the tare in the BNO085 already, and that works quite good. So you could do it on the IMU directly, no need to mess with AOG code with calibration factors etc.
I’ll upload to github the ino code when in some kind of working order along with the python code for the filter, been busy with some other stuff lately
GitHub - jkonno/AOG_wasless python code there
What I tend to do is put a spirit level on the cab floor or other level surface and drive around till I find a level bit!
As you say, quite a lot of proprietary software uses the two direction method which seems a good idea to me!
Yes that works as long as the tractor can be parked on the dead level. The advantage of the two direction method is that it can be done anywhere. But it’s not a critical thing.
Thanks! That’s pretty cool that github can display iPython notebooks.
Zerocorr = (dir1val + dir2val)/2;
If(Zerocorr > 0){
dir = 1; //error is positive right};
else{ dir = 0; //error is negative left };
liveroll = bnoroll - zerocorr;
Forgive my poor syntax in advance. Correction plus a bit to make L or R pop up on the screen.
So if its on a -3 slope with a -2 error built in, dir1 =-5, then when you turn around dir2 = a +3 slope with a -2 built in for a reading of +1. -5+1=-4, -4/2= our built in error of -2.
Bet lets not be crap like deere or trimble. Make it record the test position on an A/B line and have it tell you when to stop to take the reading, as it drives straight with the line. Like the countdown to uturn.
It is critical, if roll is not true 0 then you must ofset your implement the same amount (cm) as roll change setpoint, because setpoint will be altered when you go opposite direction.
I wasn’t maybe clear on that I was thinking exactly about the 2 direction method, but store the correction directly on the IMU. Then you get also the pitch offset on the same calibration and hence the yaw axis is also the true yaw.
Your way would be the best overall I agree but requires knowing the imu romantically to send the data back, the easiest is take the live imu value as is and continue to trim it with the offset. Then when we get the new latest greatest imu in 2024, from another manufacturer the code is still ready to roll.
As long as its near the top of the code heap, the rest of the calculations will not know the difference.
Fantastic idea! Just drive the same AB both directions, stop at the same point in both directions for the readings.
I wish was swift enough on the PC side to pull it off. The microcontroller side is fun to program. The PC side still has me feeling like a caveman , I can see to modify existing code, but still not at the level to blaze a trail of new code.
PC is harder , but its been a little over a year now since starting to learn c#.
True, one could store the rotation matrix, though, quite easily. Then you’d get ”tare” without being dependent on BNO08x only. Take the least squate minimum over a distance driven, for example so it wouldn’t be so sensitive on just one spot being used for the calibration?
That would be a novel way of doing it, but the single spot two direction method is pretty good already.
The only downfall of the commercial systems in this regard is not knowing where that spot is, after you leave it.
@nut, how did you get the information from the BNO08x? I’m using the adafruit library, and have my reports set for the proper frequency, but having a hard time getting them all to come in consistently. Some come in faster, some come in slower. Synchronizing all these reports, along with the NMEA from the GPS is a bit of a challenge.
Another couple of questions.
When the speed drops below a threshold, if the IMU was not being used before, the code calculates a new heading offset for the IMU yaw angle, and then uses that instead of GPS heading. Once that offset is calculated, it’s used whenever the speed is low. When the speed goes high again, we revert to using GPS heading since it’s accurate now, and no longer using the IMU heading. During this time, shouldn’t the code be recalculating the IMU heading offset since we have a good heading to go by? The way the code was laid out, the IMU heading offset is lost every time the imuflag goes False, and only recomputed when the ground speed is below threshold.
For example, would something like this work?
if f.x[3] < was_speedlimit:
imuflag = True
if head_bias is None: # set to None above to indicate not set yet
head_bias = gpscourse[i] - heading_imu[i]
gpscourse[i] = heading_imu[i] + head_bias
imu_on.append(1)
else:
imuflag = False
imu_on.append(0)
# probably would need some kind of smoothing here
head_bias = gpscourse[i] - heading_imu[i]
Also when I convert the quaternions in the game vector mode to euler angles, they come out as trigonomic angles, so the yaw would need to be converted to a compass angle by reversing it with something like (450 - angle ) % 360. Did you do that when you were collecting the data? I assume heading_imu would be an uncorrected compass angle? They way my bno085 is oriented, X faces forward, Z faces up, and a roll to the left is negative, pitch forward is negative, yaw left is positive (a trig angle currently, not a compass angle). With the exception of the yaw angle, is that the direction your numbers go too, and what works with the filter?
Loaded the ino test code I used into github as well, there’s some junk from the ongoing filter to Teensy implementation included as well. There’s also the test data package, just modified the lat/lon a bit so it’s not pointing directly to my front yard on the internet
I’m using the sparkfun library from the AOG package, had to use a different report internal (19 vs 20 ms to get the raw data reports out as well). Sycing with NMEA data you don’t need to worry about as the filter is doing a separate update for the IMU and the GPS. Here:
Yeah, makes sense, although now it just picks the latest heading value when the speed drops below a threashold so it’s syncing every time on one point only. Having a bias variable for the heading is probably a good idea.
Yes, its scaled in the code to 0-360, but like you see from the filter code it needs some extr TLC in the filter implementation, it has to remain continuous and not have sharp jumps so that’s why I did it like that that it’s running over the bounds and keeping track of how many times so that the internal variable in the filter is always continuous.
What is your sample rate of the imu?
Looks like 50 hz.
I ran CMPS at 100Hz standalone imu module with the nano - so it could be accessed at least twice as fast. MAybe 200 hz?
I never dreamt 2 years ago the biggest problem facing us was parts availability
Haven’t even tried with higher rate. The issue was that if I set the report interval identical for raw and rotation vector outputs, one of them drops out.
Pushed a new version to github, runs no problem on 100 Hz update rate. Not finished yet, but proof of concept how to run the sensor fusion on Teensy board (might work even on arduino if computational capacity is enough). Still missing all the code dealing with reverse detection, speed thresholds etc
My thinking is that since the BNO080 already has quite a good sensor fusion algorithm based on the accelerations alone, no need to reinvent that but just add a post-processing layer on top.
Edit: Now an updated version with WAS calculation, gotta test is out tomorrow on a vehicle. Also added a 5 sec stabilization on power up to calculate the initial biases so that the velocity integration doesn’t run wild.