BOE-Balancer Program

I am starting this thread because once again I am going to try to do something I don't know how to do! I designed a balancing BOE-Bot (though I bet I am not the first) that is going to be programmed in Blocklyprop and use a PID.
So I will be posting a lot of questions in a quest for help with this.

Comments

Has anybody used the LSM9DS1 in a project? When I try the calibration routine the P26 and P27 LEDs never turn off. The only code lines I am using for this right now is the initialize block and the calibration block.

"When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

AAAHHH! Some things, even simple ones, can be a real pull. After putting encoders on I could not get them to calibrate and realized I had standard speed servos on it which do not work with the encoders. So switched to high speed encoders and also decided to put the Parallax li-on battery pack in it which completely changed how everything fit together, so I did a complete redesign and rebuild. That took most of the day and now I am charging the li-on battery pack. Getting there, slowly getting there. Been reading everything I can on PID's and I think I have that in control. (self delusion is a necessity in robotics!)

Carol: Way to dive right in. You've certainly taken a lot upon yourself in this heady endeavor! Sometimes it pays to walk before running. A lot of people have made BoeBots balance using just a PING sensor instead of IMU or gyro/accelerometers. Might this be an intermediate step worth checking off?

"When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

I have done a couple of Lego segways, one with a gyro and one with a light sensor but both were in Lego's graphical language and most of it was already
coded. Only fine tuning and adjusting was needed from me. So this will be a first for me and is a prelude to a bigger project, a robot that balances on a ball.
There are a lot of self balancers out there and plenty of code snippets but I want to do it in Blocklyprop so I am sort of breaking some new ground a little bit.
BTW, what the heck is that thing between the wheels and sticking out the back of your robot? I want to use the Ping to make this robot have some roaming behavior.

I like the idea of the ball balancing bot. That would be real interesting.

I believe the thing sticking out in the vid that erco posted is like a kick-stand to prevent the bot from falling completely over if it gets off balance. That way it is not smacking on the floor or table if it falls. just a guess though.

I've posted this several times, but it's neat to see how simply this guy got his robot balancing with just a 555 timer & analog circuitry, using a light sensor.

"When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

I am almost ready to video mine. I have finally got a working PID in Blocklyprop and will be tuning my bot today.
It has been hard but a lot of fun. I am really getting hooked on the Blocklyprop. I will show code too. Then you
can all tell me what could have been done better!

"When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

I am having equipment trouble. Trying to troubleshoot it now.
I may have damaged this PABWX when thrashing around. I am
testing it for trouble but I do have another PABWX to use if this
is broken. Did you make the BOE-Balancer in your video? Now I
know what that thing between its wheels is for! Keep it from
slamming on its face. I have the PID written and it seems to work
but the robot is just not stable enough. So I need to go through every
system to see what is wrong. I am hoping it is not because Blocklyprop
does not do floating point math. I don't know all the little work
around formulas people use to simulate floating point results.

It shouldn't need to be done in floating point as long as you have enough precision in the longs. When I did it, it was useful to have two terms - One for the gyro readings, and another (independent) for the angle value. If you try to PID on just the angle value, you need a LOT of precision to keep it balanced, because you want to be able to respond to very small changes in angle. For that reason I found it better to just feed the gyro readings directly into the PID for derivative term, and use the angle value for P and another D term, then mix them all together.

I am using the angle reading from the accelerometer and the speed of rotation from the gyro. My thinking on this is the gyro gives me the rate of change and the angle gives the current place the robot is at so the gyro provides the porportional value needed to speed up or down the motors. They are incorporated together for the speed of wheels.

That's a HoverflyGimbal controller, but it's essentially the same hardware. Are you using the raw accelerometer value to compute the angle? If so, you'll need to filter the living heck out of it to get anything useful. I'd recommend a complimentary filter for this, because you can just do a simple gyro + accel filter to get a decent result, then feed that filtered angle value into the PIDs.

Specfifically at the function called UpdateComplimentaryFilter(). This code takes a gyro and accel sample from a Prop and does the computation on a PC, but it demonstrates the idea pretty solidly. That said, if Blockly doesn't let you use floats, this may be a little trickier.

We definitely had to filter the gyro data but since the only element we needed from it was its proportion of speed we just divided it by 180 to bring its values down to within the speed limits of the servos.

I was sidelined for a while and having serial terminal problems which turned out to be self-imposed and am
now back to work on the BOE-Balancer. I am not having much trouble with making a PID in Blocklyprop but
just can't dial in the robot enough at the beginning to make it stable. It is either not responsive enough or
overshooting. I have not found the sweet spot. You can not make it stable in the first stage of the PID but it
should be trying to stand. I have tried it with encoders, without encoders, with high speed servos and regular
CR servos. It is very close but not close enough. I will keep trying...............................Once again I am eating
something bigger than my head.

How do you all handle the bot not being perfectly balanced? As in, what if the bot is only stationary when the robot is angled at 3 degrees? The PID is looking for that sweet spot of a specific angle, right? Do you have some way to set the "trim" (whether that is via a remote app or hardcoded doesn't matter)? Or is there something I'm not thinking of that allows you to have a balancing and stationary robot without the need for a perfectly balanced chassis or angle trim?

DavidPropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.

And do you get better results with the accel + gyro at the top, bottom, or one at each end? I'm thinking as close to the axles as possible so that the swinging of the top has as little affect on the accelerometer as possible.

DavidPropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.

Find the physical balance point of your robot and reading the numbers from your IMU or whatever you are using to balance with, use that number as your setpoint.
A setpoint is one of the parameters of your PID. It is essentially the balance point of your robot. Only in an ideal world is it ever at 0.

The top doesn't swing - the bottom does. You want the top to have a decent amount of mass, so it's more likely to stay stationary as the wheels move. Picture a broomstick being balanced on a hand - the top of the broom barely moves at all, so this is the point least subject to stray accelerations. The position of the gyro matters less.

The sweet spot should be consistent, so once you've found "true level" through a calibration routine, that should work as your set point. It may require an offset because of weight imbalance on the craft, but that's typically handled by integral term in the PID.

I fused the accelerometer and gyro readings together to produce a more accurate and faster responding angular reading, and just used the raw gyro numbers for the rotation rate. I also found that the motor output required to balance isn't linear with angle - it's more like 1 / cos(Angle). When the bot is vertical, it's perpendicular to the floor, and that's the direction the wheels move, so all movement goes more or less directly into rotating the bot. If you're at 30 degrees, you need to move the motors farther to make a similar change in your angle - motor impulses at this point are cos(30) = 0.866 effective at rotating you.

This effect is amplified because the effect of gravity is affected by this as well, but inverted - When perfectly vertical, gravity has zero effect on your rotation. The further you are off center, the stronger the effect of gravity, in this case, it's sin(Angle).

So, cumulatively, if you're at zero, everything is peachy. If you're slightly off zero, gravity starts to accelerate you away from it, and your motors have to work harder to push you back to it, so you need to ramp your PID response based on your current angle to account for all of this.

Thanks Jason, I did know that it is a reverse pendulum, I printed your post and will apply the ideas you gave me to what I am doing.
I did merge both readings into one but my setpoint is a minus number and it seems to me to cause anomalies in reversing the motor
speeds from positive to negative. I have also tried dividing the gyro output by 360 or 180 to bring the numbers down to something the
motors can use. Am I barking up a wrong path there?