I build a self-balancing robot, at least that what i should have been. now i have tried implementing a complementary filter which combines gyro and accelerometer data, but the problem is that the motor and the IMU (MPU 6050) are on the same board and max. an inch away from each other.

So, if i get it right, the vibrations from the Motor do influence the accelerometer way to much, hence i am not getting any applicable result when the robot is set to the ground.

So, what techniques can i apply to get the absolute orientation?


This, right now, is my code with the complementary filter. My problem is, that even when the motor is off, the yAngle value varies very much from the yAcc value, although the yAcc value is correct. Is there any error in my code causing the gyro drift to break the whole filter?

// 100.0 is dt, 14.375 the gyro-specific resolution
float gyroY = (float)(readY()) / 14.375 / (100.0);
int z = getAccZ();
int x = getAccX();
float yAcc = atan((float)z / (float) x) / PI * 180;
yAngle = 0.98 * (yAngle + gyroY) + (0.02 * yAcc);
  • $\begingroup$ Welcome to Robotics Daniel D., that's a nice first question but it would be good if you could include more details of what you want to achieve, what you tried, what you saw & what you expected to see. Please take a look at How to Ask & tour for more information on how stack exchange works and work through the Robotics question checklist to edit your question to make it clearer. $\endgroup$ – Mark Booth Oct 2 '17 at 16:17

What sort of values are you getting out of your accelerometer? The raw values you get from an accelerometer will not translate into any form of orientation. Here is some good reading for how to get orientation out of such a mems device.

If noise from your motors really is the issue, I would recommend implementing a Finite Impulse Response (FIR) filter. For example a moving average filter might help you out. I recommend keeping the order of the filter low however, as (depending on your Samples per Second) the higher the order, the slower the response time of the data will be. This could introduce a level of error you will have to be careful of when trying to make your robot balance.

  • $\begingroup$ But is my above posted code for the complementary filter right? $\endgroup$ – Daniel D. Oct 3 '17 at 19:03
  • $\begingroup$ Are you sure your dt should be 100? If using SI units that would be 100 seconds. Also I believe your yAcc equation should be float yAcc = atan((float)z / (float) x) * 180 / PI; Otherwise I believe your complementary filter is fine. $\endgroup$ – Jordan Gleeson Oct 3 '17 at 22:52
  • $\begingroup$ Thanks for your anwser, since the measurement takes place every 10 ms, i think dividing it by 100 or alternatively multiplying it times 0.01 is basically the same. $\endgroup$ – Daniel D. Oct 5 '17 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.