I've been working on a self balancing robot (http://goo.gl/D4Sl61) using Arduino UNO, IMU is 6 DOF MPU6050 (GY521) Accel + Gyro, L298N Motor Driver, 2 x 12V 122rpm DC motors with 80mm wheels.
To get correct angle, I’m using Kalman filter which is providing results with little noise, here is the Processing video: - YouTube.
I've posted the source code (sketch + libraries) on my GitHub repo:
The robot oscillates a couple of times before it falls over (up to 3 seconds max). I have 3 potentiometers for PID tunings. I've spent quite some time trying to tune the system but with no success. Any help would be much appreciated.
I've seen this method mentioned on a number of self balancing robot projects. I've already tried tuning the robot like that quite a few times but with no success. I'm not sure if the issue is in code or maybe the design itself. I tried to replicate the design from other self balancing robot projects I found online...
You are correct that you do not need a Kalman filter. You also do not need an accelerometer. Check out the attached document for some of the myths concerning balancing robots.
Perhaps your tuning knobs don't cover the stable region. Try changing the range on your various tuning knobs (one at a time) to allow for finer tuning as you approach usable settings.
johnwasser:
Perhaps your tuning knobs don't cover the stable region. Try changing the range on your various tuning knobs (one at a time) to allow for finer tuning as you approach usable settings.
For kp i tried ranges from 0 to max output, for ki i tried ranges from 0 to 4 times max output and for ki very small values... everything as advertised on other projects but no luck.
I was suggested to try out this implementation for MPU6050 (instead of reading and combining data using Kalman filter): http://goo.gl/A1W2uP
After I implemented that I got far better results than before, still not balancing but I haven't had the time to play with PID tuning yet. I plan to add a running average filter and place the MPU a little closer to the base of the robot. I hope that it will improve stability and the robot would finally balance. Here is a clip of current progress, even though the robot is still not balancing: Dropbox - Error - Simplify your life
Using a Kalman or any other form of filter introduces latency into your control loop, which will make it much harder to keep the loop stable. Think of it this way: more delay means less phase margin.
I'm not using Kalman, just reading the MPU6050 values I get. After some PID tuning and adjusting the wheel speeds this is the result I get. Hope to improve stability a bit more:
I think you might need a feedback from your motors. DC motors have a dead zone and do not start to move until the applied voltage overcomes it's friction/robot weight. It will usually overshoot right after its first move. In other words, the voltage-speed control is non linear. You might also notice that the motor will operate at different speed when different load is used at the same voltage. When there is a load, your motor driver's input speed differs from the actual motor's output speed.
Perhaps you might want to attach a tachometer or use motors with encoders. Either of these device will be able to feedback the motor's actual speed. Then you can use PID to tune the motor's speed.
Try to tune your motor's speed response first, making sure that it's speed can be controlled linearly before tuning the balancing PID.
thw777:
Try to tune your motor's speed response first, making sure that it's speed can be controlled linearly before tuning the balancing PID.
I have noticed a lag when the robot gets an offset from the vertical position. It takes a split of a second for motors to start moving. Is that a dead zone? I feel like the motors should have started to move slowly, but they lag and then they start to move fast right away. The robot is balancing, but I think the robot would balance much better if the wheels would turn a bit more responsively from the vertical position. How to compensate for that dead zone? Currently I output the speed from 0->255. Should I map the speed of 0->255 to something like 30(or so)->255 to compensate for the wheels not moving due to the friction of the wheels and the weight of the robot? Is there a way to get the linear speed control (or close to that) of the wheels with current motors without adding additional components like encoders?
When the PID responds to a small error, the resulting output will be small. It sounds as though, as suggested, your motors don't do anything for low values of PWM.
Should I map the speed of 0->255 to something like 30(or so)->255 to compensate
The dead zone problem is common for DC motors. Using the Lego NXT I was able to record the motor input and the wheel position while my robot was balancing to get an accurate fit for my model of input vs output. You could see that for small values of motor input the wheel position was not moving even though the motor input was small but non-zero. I have a plot of this phenomenon but can't manage to post it here.
Hi! How did you add the dead zone compensation? Only by adding an offset to the PWM signal?
Thanks!
PS: I'm working on a balancing robot too, but I don't get full stability. It gets perturbations from it's own start-stop acceleration that makes it drift a little bit too much
Here's my self-balancer without gyros or accelerometers:
It uses one IR range sensor to measure pitch angle, then differentiate that to get pitch rate. These feed a PID controller for stability.
I'm working on a new version without the IR range sensor because that system only works on smooth flat surfaces. I built and IMU with a Kalman filter on the Arduino Due using the Eigen C++ library for the matrix math. Next step is to integrate it all.