• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Arduino Head tracker

Fallegon

Active member
#1
Not sure how many people would be interested in this, but Im making it for myself anyway and Ill just share the project. This is an arduino nana with a mpu6050 board hooked up to a 3.5 mm female that outputs a ppm code for (Im assuming any mono jack buddy box system. Im using spektrum) my transmitter. I have fatsharks hdo, dont think it matters, but Iv hijacked the battery leads into a 5v regulator and maintained a 7.4v out back to the goggles. It works really well and when im done priting the case Ill upload everything.
 

Attachments

Fallegon

Active member
#2
So pertaining to this project, I finished the case and the code is fixed and useable for amyone.
20190601_172422.jpg
trying to print a thingy to attach to my fatsharks but.. Its annoying.
 

kilroy07

Well-known member
#3
I was just starting to do some research on the mpu6050 for a project I came up with...
I'll be following your progress.

I'm guessing that is a custom board... Very nice and clean looking...
 

Fallegon

Active member
#4
Yeah I really like the board so far. I've looked at other possibilities for gyro work. I know there a 9 axis one and a simple 3 axis one. You could probably get away with any of them. With this board, and I'm sure the other too, there is a very high yaw drift upon start up. After about 3-5 seconds the yaw axis will get a grip and start to work correctly. I've let the serial monitor go for a while and there's no apparent drift in the long run so I'm not worried. The button on top is for re-centering and it works great. I'm in blender currently working on a 2 axis gimbal. One that doesn't use the servos as the axis point and look stupid and just overall be a wonky pos glued to the nose... I'll also have more degrees of view instead of being restricted to the servos capabilities.
 

clolsonus

Active member
#5
We all have our own way to tie up our own boat, but just in case it helps here are a couple thoughts.

For a voltage regulator, I really like this one: https://www.adafruit.com/product/1065 It is all self contained and has zero voltage sag under load. There are higher amp versions available if your project draws more current than this one supports. It's maybe a bit more expensive, but it is nice. Pololu has some slightly less expensive (and more guts out) voltage regulators that are also rock solid with no voltage sag under load that are also a good option.

My experience with mems gyros is that there is always some amount of random bias each time you power them up. Also the amount of drift can change with temperature. (i.e. as your electronics warm up or as they adjust to outside air temps.) There are many ways to account for startup drift, but I have had pretty good luck with a the following routine for self-zeroing my gyros on startup.

Quick over view. I setup two smoothing filters for each gyro axis: the first filter is over a shorter time period, the 2nd filter is over a longer time period. If the two filters are very close to the same value it means the board is relatively stable. If the board is being handled or moved, these will likely never agree. So the routine runs for a while looking for 4 continuous seconds of stability and then uses this value as the "bias". From that point on, this bias is subtracted from the raw readings. This isn't the complete end-to-end story, but it is a nice starting point.

C-like:
// stay alive for up to 15 seconds looking for agreement between a 1
// second low pass filter and a 0.1 second low pass filter.  If these
// agree (close enough) for 4 consecutive seconds, then we calibrate
// with the 1 sec low pass filter value.  If time expires, the
// calibration fails and we run with raw gyro values.
void calibrate_gyros(float gx, float gy, float gz) {
    static const float cutoff = 0.005;
    static float gxs = 0.0;
    static float gys = 0.0;
    static float gzs = 0.0;
    static float gxf = 0.0;
    static float gyf = 0.0;
    static float gzf = 0.0;
    static elapsedMillis total_timer = 0;
    static elapsedMillis good_timer = 0;
    static elapsedMillis output_timer = 0;

    if ( gyros_calibrated == 0 ) {
        Serial.print("Initialize gyro calibration: ");
        gxs = gx;
        gys = gy;
        gzs = gz;
        gxf = gx;
        gyf = gy;
        gzf = gz;
        total_timer = 0;
        good_timer = 0;
        output_timer = 0;
        gyros_calibrated = 1;
    }
    
    gxf = 0.9 * gxf + 0.1 * gx;
    gyf = 0.9 * gyf + 0.1 * gy;
    gzf = 0.9 * gzf + 0.1 * gz;
    gxs = 0.99 * gxs + 0.01 * gx;
    gys = 0.99 * gys + 0.01 * gy;
    gzs = 0.99 * gzs + 0.01 * gz;
    
    // use 'slow' filter value for calibration while calibrating
    gyro_calib[0] = gxs;
    gyro_calib[1] = gys;
    gyro_calib[2] = gzs;

    float dx = fabs(gxs - gxf);
    float dy = fabs(gys - gyf);
    float dz = fabs(gzs - gzf);
    if ( dx > cutoff || dy > cutoff || dz > cutoff ) {
        good_timer = 0;
    }
    if ( output_timer >= 1000 ) {
        output_timer = 0;
        if ( good_timer < 1000 ) {
            Serial.print("x");
        } else {
            Serial.print("*");
        }
    }
    if ( good_timer > 4100 || total_timer > 15000 ) {
        Serial.println();
        // set gyro zero points from the 'slow' filter.
        gyro_calib[0] = gxs;
        gyro_calib[1] = gys;
        gyro_calib[2] = gzs;
        gyros_calibrated = 2;
        imu_update(); // update imu_calib values before anything else get's a chance to read them
        Serial.print("Average gyros: ");
        Serial.print(gyro_calib[0],4);
        Serial.print(" ");
        Serial.print(gyro_calib[1],4);
        Serial.print(" ");
        Serial.print(gyro_calib[2],4);
        Serial.println();
        if ( total_timer > 15000 ) {
            Serial.println("Result: too much motion failed.");
        } else {
            Serial.println("Result: success.");
        }
    }
}
 

Fallegon

Active member
#6
Huh.. I thought about a smoother but I personally didnt think it was necessary. Once the drift goes away and you recenter the position it works very well. All the code will be open sourced once I post it so feel free to mess with it.

Also the reason I'm using a 5v regulator instead of a buck converter is due to the coils. I didnt want anything to interfere with the gyros or the video signal. I'm also not that experienced with this stuff so I didn't know how much it would interfere so I just went the regulator route. Again Im no expert so if you think a buck converter wouldnt mess with the gyros at that distance then give it a go. I dont really know what the devices mah ussage is so the step down from 7.4 to 5 didnt seem like inefficiency would be a big deal.
 
Last edited:

clolsonus

Active member
#7
Huh.. I thought about a smoother but I personally didnt think it was necessary. Once the drift goes away and you recenter the position it works very well. All the code will be open sourced once I post it so feel free to mess with it.
No worries, I always have used the raw sensor data coming out of the IMU, but perhaps you are using the internal DLFP or whatever it's called? In my work we have our own 15-state kalman filter that estimates orientation that is augmented by gps so it converges to true heading (without needing a magnetometer.) But we are navigating a UAV ... for a head tracker that would be total overkill and our system actually needs the aircraft movement to converge (your head will be relatively stationary.) I'm just tossing out ideas in case they are helpful.

Also the reason I'm using a 5v regulator instead of a buck converter is due to the coils. I didnt want anything to interfere with the gyros or the video signal. I'm also not that experienced with this stuff so I didn't know how much it would interfere so I just went the regulator route. Again Im no expert so if you think a buck converter wouldnt mess with the gyros at that distance then give it a go. I dont really know what the devices mah ussage is so the step down from 7.4 to 5 didnt seem like inefficiency would be a big deal.
I'm confident the buck converter won't interfere with the IMU, but I have no idea if/how it would affect video. I think if you are happy with your current solution and it's solid, then it's great. In a past project I used a castle creations BEC (both the 10amp little one and the 20 amp dual output with heat sync.) It was always a chore to dial up the output voltage so under load I would get about 5v. When I switched to the traco power regulator it was nice to have a rock solid exact 5.00 volts no matter what I plugged in. But we were attaching more things including GPS, 800mhz linux computer, 100mw radio modem, and possibly servos ... so I'm sure our load was substantially more than yours.

Mostly it's fun to see people mix in some arduino bits into their hobby projects, so I enjoy jumping in with my tiny slice of experience.

My latest tech-crush is micropython (or circuit python). I've started to push in the direction of a 100% python UAV autopilot. I'm not sure I'll get there exactly. It will probably have major subcomponents still written in C++ (with python wrappers) but I'm maybe 50% of the way there with my currently working system (a hybrid of C++ and python and linux and arduino-- err teensyduino ), so time will tell. It seems like most of the UAV DIY'ers evaporated into other interests, but I made the mistake of drinking the coolaid, and now I also do this stuff for my day job at a university.)

Curt.
 

Fallegon

Active member
#8
Yeah I got a barometer and a pitot tube to mess around with. The ultimate goal is to have a display in the airplanes cockpit that can show me all my stats cause I genuinely hate osd. Anywho since the headtracker is mostly done its on to the gimbal. Heres the work in progress.
20190602_213307.jpg
doing it this way cause I want more than 90 degree rotation. Also learned a lot about gears in the process so thats cool.
 

Fallegon

Active member
#9
Well this ^^^ gimbal didnt work and neither did this one vvv (top of the image).
20190606_175319.jpg
This new one ( bottom image) should work better. I have ordered some metal geared 5 gram servos and I plan on using a bit of grease in the gears so the servos dont have to work as hard.
 

Fallegon

Active member
#10
Heres the upgraded gimbal.. This one works.. after many many attempts.. I have 3 gram servos wroking this one.. it will work with 5 gram aswell. Very touchy and Ill post the files when I feel their ready. This one is going in my glider.
20190611_221613.jpg 20190611_221559.jpg
 

FoamyDM

Building Fool-Flying Noob
#11
I would love making one of these... So very interested. There was a guy in the UK who sold a kit... But might not be anymore.
Have you considered. Using 0802 motor? Or TINY stepper motors to control it? I am useless regarding how. Just seems possible, Esp. now. I would love a micro can on a headtracked micro gimbal.
 

Fallegon

Active member
#13
Here is said gimbal on the glider im working on. There is a few more problems with the code I need to iron out before its ready. Also not sure if I should try and make it more user friendly with a display and menu but I dont see a lot of people being interested in this so Im not sure.
20190615_114007.jpg
 

Fallegon

Active member
#14
ok so here's the working code to this thing. I'm having this issue where after the first button reset the high end of the yaw which should peek at 1900ms jumps down to 1100ms instead of capping at 1900. However once I hit the button reset again to re-center it stops happening. So I'm not really sure whats going on. I've also left all the filler from the other mpu6050 code as to not steal his work. I'll clean it up later tho.

https://github.com/ScratchWarbirds/HeadTracker-Project/blob/master/HeadTracker code
 

Fallegon

Active member
#15
20190616_134520.jpg
so to kinda wrap this project up. It seems like the head tracker gives the values to the controller regardless of servo limits on the transmitter. I was really hoping that each model I have on my transmitter could contain the gimbal settings per plane but that doesnt seem to be the case. So anyone using this head tracker will have to program the settings manually in the code for each model. Which in a future version could justify a screen and buttons but for just my use I prolly wont do that.
 

Fallegon

Active member
#16
Ok I changed my mind. Im going to be re doing this head tracker a bit. I essentially do want to put a screen and button set up together to adjust trim and profile setting per model on location.
20190822_193321.jpg
Finished up this yak I had laying around and added a gimbal for testing.
 

FoamyDM

Building Fool-Flying Noob
#17
I hope to be testing this out early this week, I realized I have a Skyzone sky02s+ which has a head tracker module inside (a main reason I bought it.) I might be able to try this sooner than I thought... are you almost ready to post your .stl files. for the camera mount.

I wonder if we could do a mount with a thrust vectoring style setup. Here's my idea. I have noticed that the whoop cameras are nearly Pilot head size on a pilot figure. I would love to mount the camera in the pilot's helmet and use a visor to hide it. by setting up the swivel as a thrust vectoring rig. (facing forward flight) and mounting the servos elsewhere (like the body of the pilot) we could have some really exciting results.

that we as in the RC community. while I'm sure most of us have thought it. I don't see it implemented so a good solution must NOT be at the ready.
 

Fallegon

Active member
#18
Im having trouble understanding what you mean. Are you looking for a way to better hide the servos for a gimbal or do you want the plane to fly in the direction you look. Technically you could do the latter with my rig. A better gimbal however would just take some time engineering it.