And another self balancing robot

Just wanted to share my code, in case someone, one day may find it useful

Video:

Source code:

Self balancing robot based on Arduino UNO ATmega328 microcontroller

Hardware list:
arduino uno
dual mc33926 motor carier
lipo 11.1 v / 1300 mAh power cell
MinIMU-9 Gyro
2x Motors, 12V 1A (max 2A), 50:1 gear ratio, 6kg/cm peak force
big wheels
jy-mcu v1.02 ( Bluetooth RF Transceiver )

Operation basics:

Read raw gyro
Read raw accelerometer
Calculate current angle
Calculate engine torque with PID controller
Correct current position
Do the same thing over and over again ( should be around 100 Hz )

Notes:
I decided against Kalman filter in favour of Complementary Filter
as its has almost same performance but without the complexity of Kalman filter.

Pretty nice! Except for shooting off the table. I don't know what goes into coding one of these, hopefully you can tweak it up.

CrossRoads:
Pretty nice! Except for shooting off the table. I don't know what goes into coding one of these, hopefully you can tweak it up.

According the the hardware list, the only sensor is the gyro IMU and that can detect the bot falling off the table but not prevent it.:wink: It's going to take more than just tweaking the code to keep it on raised surfaces, like some sensors for edge detection.

Still, it's impressive given it's balancing reliably on two wheels and only uses the IMU. Thanks for sharing cyhex!

The shooting off the table part is caused by non tuned bluetooth remote controller.... what brings me to another issue - the hardware list missing the bluetooth serial controller.

Looks really nice!
I've read the PDF in your github, it was very informative and easy to understand.
I'm thinking of building a self balancing robot my self and may I ask how are you controlling the motors?
You don't have encoders so I'm guessing its an open loop design(?), how do you control the torque they output?

bimbambom:
Looks really nice!
I've read the PDF in your github, it was very informative and easy to understand.
I'm thinking of building a self balancing robot my self and may I ask how are you controlling the motors?
You don't have encoders so I'm guessing its an open loop design(?), how do you control the torque they output?

He's using a PID controller to drive the motors based on feedback from the IMU.

jraskell:

bimbambom:
Looks really nice!
I've read the PDF in your github, it was very informative and easy to understand.
I'm thinking of building a self balancing robot my self and may I ask how are you controlling the motors?
You don't have encoders so I'm guessing its an open loop design(?), how do you control the torque they output?

He's using a PID controller to drive the motors based on feedback from the IMU.

That part I got, I was wondering how is he controlling the motor's torque. If for example the PID says a torque of 1 Nm is needed, how does he get the motors to output this exact amount of torque(That requires a certain current while we usually control the voltage).
Anyhow, I read the code and the mc33926 has a current sensor to close a loop on the motors and it handles the motor control.

If for example the PID says a torque of 1 Nm is needed

The PID does no such thing. It simply outputs a dimensionless value that abstractly represents how much adjustment needs to be made to attain/maintain it's 'ideal' state (that is, the robot standing straight up) based on it's input mechanism (the IMU). That value is converted into a PWM output to the motor. The K values are tweaked to provide optimal balance. There are no real 'physics' calculations involved at all. It's just some rather abstract tuning (though the Proportional, Integral, and Differential portions of the PID do have different characteristics regarding how the influence they output value).

The controller(PID in this case) is based on a physical model(Inverted pendulum), the PID values are not 'tweaked' - they can be calculated based on the physical model and according to your requirements(Stability margins/damping/overshoot/optimizing a price function) .
The robot balance it self out by moving, the robot moves by applying torque on the wheels and that torque is generated by the motors.
The torque is proportional to the current, not voltage, you can't simply control the torque(Movement of the robot) with just PWM.
You can send a certain PWM(Voltage) pulse and it would create a torque of X, while using the same PWM pulse in a different scenario(Robot is already moving for example) would create a torque of 0.8*X.
He's using a dedicated IC(mc33926) to control the motors, that IC closes a control loop on the motor's current so he can control the torque from the Arduino.
(Same way the robot balance it self according to user input and IMU measurements the mc33926 does the same to the current based on the user input coming from the Arduino and a current sensor)

His code is published for all to see. Go read it. There are no physical computations. There are no torque calculations. I'll sum it up as thus:
He reads an IMU and computes an angle based on those readings.
He feeds that angle into a PID controller that, with three tweakable parameters (Kp, Ki, Kd) outputs a raw value.
He clamps this raw value to the range his motor controller wants to use.
He feeds this value into the motor controller, that simply linearly converts it to some PWM output to drive the motors.

With the exception of some remote control code, that is ALL his code does. Again, the code is available. You are arguing that he is doing things that simply aren't in his code. That's the beauty of PID controllers. You can spend days, weeks, even months, developing an accurate physical representation in code that MAY be able to properly balance your robot, or you can spend hours writing a simple PID controller, and maybe another couple of hours tweaking the PID to balance your robot. This is a method that has been used thousands of times by a variety of people, myself included.

I did read his code, did you?
Here's the relevant parts,

DCMotor m1(5,3);
DCMotor m2(11,9);

m1.run(speed);
m2.run(speed);

He feeds this value into the motor controller, that simply linearly converts it to some PWM output to drive the motors.

It's not linear, there is a control loop on the current.
"The MC33926 works with 3 – 5 V logic levels, supports ultrasonic (up to 20 kHz) PWM, and features current feedback".

There is a physical model behind it, you're just choosing to ignore it by 'tweaking' the PID with trial and error instead of actually doing the calculations. It would take less than an hour to build a physical model, find the differential equations(Also available on wiki), find the PID gains with Root Locust or any other method. It's a very common homework assignment given to students(My self included).

With the exception of some remote control code, that is ALL his code does.

You're right about that.
Again, all I'm trying to say is that the motor controller handles the torque control for him. This is why most projects like it use an encoder or a motor controller, using just an H-brdige and PWM probably won't work well.

jraskell:
There are no real 'physics' calculations involved at all. It's just some rather abstract tuning (though the Proportional, Integral, and Differential portions of the PID do have different characteristics regarding how the influence they output value).

So, if I got your point, you arbitrarily fixed some values for Ti and Td and then you played with the static gain K until you achieved the desired response? That simple?

It's very cool, the theory actually does work :-).

However, it's bent over like an old man with a bad back. You notice that result of it being bent over
so is that, it takes much longer [ie, moves farther] to stabilize when moving away from the camera
than towards the camera. And this problem is worse when the external disruption is greater - thus
running all the way off the table before stabilizing.

So, if I got your point, you arbitrarily fixed some values for Ti and Td and then you played with the static gain K until you achieved the desired response? That simple?

In the first post he said he was making corrections at around 100Hz, because of that the PID values do not have to be perfect. The closer the PID values are the quicker the robot will stabilize and save power. The robot is relatively slow compared to the electronics controlling it so, if you overshoot your corrections you can still recover control.

However, it's bent over like an old man with a bad back. You notice that result of it being bent over
so is that, it takes much longer [ie, moves farther] to stabilize when moving away from the camera
than towards the camera. And this problem is worse when the external disruption is greater - thus
running all the way off the table before stabilizing.

You are right it has an "unbalanced" frame, thus making the balancing asymmetrical, fixing that evolves rebuilding the frame so the center of gravity would be on the wheel axis - and that involves cutting tools and screwing stuff, my very least favorite thing to do... ( in my defense - i am a software developer :wink: )....

Maybe you can compensate in s.w., by using different feedback gains between
forward and rearward movement.

The PDF was great. I learned a lot. I am relatively new to this platform, and my C experience is really way before the ++ came into play.

The code shared at the link above is a library as I understand it. bRobot.cpp and bRobot.h . I understand where to put the libraries in the folder, but I see no code that would call the libraries.

I would appreciate any help anyone can give.
Thanks
Louis