davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Fri Jun 11, 2021 8:17 pm

emma1997 wrote:
Fri Jun 11, 2021 6:37 pm
davek0974 wrote:
Thu Jun 10, 2021 11:40 am
The motor speed seems too low, maybe need bigger wheels
I've been following this thread from start and find it fascinating having built a few myself back in the Trinity College Contest days. I suspect, if anything, smaller wheels would be better. More torque and faster response w/o stalling. Are you ramping up/down the steppers properly?

IMO the language chosen may not be best for this type work. I found Python (or any interpreter) very difficult to do time critical applications and prefer C or ASM. PID easy for either of those last two. Also found hand tuned complementary filters preferable to Kalman.

Of course this was back in the old days before everybody just depended on prefab libraries. We had to write all our own from scratch back then. And beware getting trampled by Mastodons. lol
My speed comment may have been wrong, I have been doing some more tests today using PWM and directlly relating the speed to tilt, its more agreeable so far but not there yet of course :D

From what i have read, which is a fair bit :roll: the gyro gives good angles but is too sensitive to vibrations, the accelerometer gives poorer angles and will drift over time but is not affected by vibrations - the solutions seems to be a mix of the two.

It may well be that I have chosen a tough language as a starter project and that is also backed up by 99% of balancing 'bots being done on an Arduino using what appears to be 99% the code :D But i'm not giving up yet.

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 8:13 am

I made a mistake in my last repo update. I forgot that I flipped the roll and pitch values due to how my device is oriented, but that matters little, because I added a bunch of stuff to the script. The repo has been fully updated to reflect all changes


  • Kalman filters can optionally be applied to raw accel and gyro data
  • more print stuff has been added
  • 100 samples are taken in the constructor to prime Kalman filters so, you don't have to ditch any readings
-------------------------------------------------------------------------

I feel like you are going about this all wrong. I'm not a robot engineer, but I understand how center of gravity works. It seems like your method is to drive the robot based on how much it's about to fall over. In other words, the wheels are governed by the lean, but it doesn't seem like you have a method in place to govern the lean, which means that your robot may be able to self balance, but you'll never have control over it. I suggest that you use 3 motors. The third motor will have an arm and a ball on it and it's entire purpose will be to change the center of gravity for the robot to compensate for whatever the wheels are doing. Think of a unicyclist. The feet are always powering the wheels, but the hips are always compensating for the new center of gravity. A tightrope walker could also be used in this example. Basically I am suggesting that you stick a tightrope walker on the robot axle. It adjusts it's "rod" to compensate for the movement of the "rope" (axle). This reverses the coupling of the robots mobility from adjusting the speed by how much it is about to fall over to adjusting the center of gravity by how much it is moving.

@drift

There is eventual drift in the accelerometer but we're talking about decimals. Make your robot work without the decimals. At top speed what is the absolute most your robot should compensate for, 30 degrees (if that)? Even with the method above there is a margin of error zone and it's going to be an entire degree or 2 in either direction. Accelerometer drift is far from a concern you should have right now. It might take hours for it to finally drift enough to matter. Actually, with a decent amount of math and using the center of gravity method I suggested, you don't need an accelerometer, at all. A cleverly constructed and weighted gimbal is all you might need and let gravity figure it out. If all else fails, just add a 3rd wheel to your self-balancing robot or run it on really wide semi-flat tires :D :D :D

We had to write all our own from scratch back then

I still do this. I don't care what language I'm using.

....hand tuned complimentary filters

I could make that happen.

Code: Select all

#first
compx = roll
compy = pitch

#all future
xrate = gx / 131.0
yrate = gy / 131.0
compx = userA * (compx + xrate * delta) + userB * roll
compy = userA * (compy + yrate * delta) + userB * pitch

right?
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 9:22 am

Thanks OMG, i'm an engineer but also not a robot engineer :) :)

as a noob I just did loads of reading - the theory that gels in my porridge of a brain was that the basic SBR is an inverted pendulum - the top is much heavier than the bottom hence most have the battery up top. To keep it balanced you monitor tilt and then drive the wheels in the same direction to force the base back under the top - it sounds simple and the brain can handle it with ease when balancing a broom on the finger, it's the same thing. Taller ones are easier to build than smaller ones it is said, mine is pretty tall at about 300mm

I think i can get the gist of your third motor idea but my reply would have to be - why ? :D

These things are pretty much all 2-motor and pretty much all work, they are split into two vague camps - controllable and just balancing. To gain control it seems you just alter the target angle a little so instead of shooting for zero or vertical angle, it shoots for 3 degrees and because it is off vertical it now must move forwards to achieve that angle = forward motion.

My No1 issue at present seems to be that when i power it up the IMU is giving me 0 degrees as vertical which is as desired, I let it bounce about a bit, maybe 10 -15 seconds, and you hear it getting lost (the steppers get faster and faster), if i then place it back on its vertical stand the IMU is now giving me maybe 5 - 10 degrees as zero hence it cannot balance because it has lost target zero. I have no idea why this is, the motor drives are decoupled by capacitors at each feed point, i have added an extra 0.1uF on the supply to them as well for any higher frequency noise, the 'scope' does not show any radical amount of noise really.

Until I can power up, bash it about and still retain zero at rest, I think I am wasting my time touching anything else program wise at least. The build is not really any different than many i have seen, its currently on breadboard but then so many others are. Maybe I'll pull the IMU off the breadboard and mount it on its own plastic bracket on the chassis.????

I have not tried the filtered data yet, my coffee table setup does seem to go back to zero after a beating so it may be better data or a better device even, will find out later...

hippy
Posts: 10187
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 11:07 am

davek0974 wrote:
Sat Jun 12, 2021 9:22 am
I think i can get the gist of your third motor idea but my reply would have to be - why ? :D
Indeed. Other SBR's don't need to have that added so it shouldn't be required here.

I am not convinced a two-wheel SBR needs two motors. It seems to me it could be driven by a single motor and a single axle.

The choice of two may simply be because it's easier or cheaper to fit two motors instead of one, and having them separate may help adjust for wheel slippage if including wheel rotation feedback. But maybe that is part of refining things for better results.
davek0974 wrote:
Sat Jun 12, 2021 9:22 am
Until I can power up, bash it about and still retain zero at rest, I think I am wasting my time touching anything else program wise at least.
I would agree. The entire concept rests on the IMU indicating it is upright when it is. If it can't do that; nothing else is going to work - garbage in, garbage out.

It might be worth taking the IMU off the SBR and experimenting with it on the work bench, getting it to work better.

It would be worth comparing as part of the SBR and separate anyway. If it's all hunky dory when on its own but not as part of the SBR that will indicate it's the fitting to SBR which is the issue, not the IMU hardware or software.

Any issue when fitted to the SBR may not be typical electromagnetic interference; it could potentially be magnetic interference.

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 11:20 am

2 things

1) I made a really stupid mistake and I fixed it. I don't even want to admit what the mistake was, because it was so dumb. It is fixed now and that's all that matters
2) I added a complimentary filter feature. The repo has been updated in it's entirety The very last example under Usage explains the complimentary filter.

You said that you are experiencing bad drift problems. I am not. My device seems to drift by about .04 every 3 or 4 minutes. I took off my decoupling capacitor the same day I put it on cause it didn't seem like it was doing anything. I also have mine on a breadboard. My MPU6050 is also not connected directly to the pico 3.3v output, but running off a breadboard rail that's being fed from a bunny-hop off my sdcard reader Vcc connection. So, I have some slop in my circuit, but my MPU works pretty decent. I think the complimentary filter works better than the Kalman. Unlike my Kalman you can customize it a bit. I know you said that you don't want to make more code changes, but maybe you should make 1 more. I made the filter for you. If you want, I'll even rename it get_davek0974() (I'm not really gonna do that :D, but I did really include it so you have yet another option)
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

Nitro_fpv
Posts: 103
Joined: Tue Mar 30, 2021 11:56 am
Location: Switzerland

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 11:45 am

To successfully build a self-balancing robot, you only need three things that have to work.

- The angle and angular velocity (IMU)
- The regulator
- The mechanics

You can calculate part 1 yourself using the raw data of an IMU, or you can use an IMU that calculates the entire fusion independently.
The data must be good and drift-free for the controller.
Part 2, the controller:
This is the simplest thing to do, a simple PD controller is enough for this task, and the movements will be excellent.
The P Relger is fed with the angular speed (gyro).
The D controller is fed with the angle (Euler, Quaternion or some other absolute value).
Part 3, the mechanics (engine)
It has to be smooth and easy to address by means of a value (for example PWM or I2C etc.) in terms of speed and direction.

I'll be home in about 2 weeks and can show a project here.
At the moment I'm on the field and I'm happy when I have internet!

Here is an example, this is a simple PD controller! :

https://youtu.be/9afIRWvspV8

Greeting

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 12:46 pm

OneMadGypsy wrote:
Sat Jun 12, 2021 11:20 am
I think the complimentary filter works better than the Kalman. Unlike my Kalman you can customize it a bit. I know you said that you don't want to make more code changes, but maybe you should make 1 more. I made the filter for you. If you want, I'll even rename it get_davek0974() (I'm not really gonna do that :D, but I did really include it so you have yet another option)
I am honoured :)

No problem with any changes, its all up in the air at present anyway :)

I have the filter working and data looks good, will start with default settings and roll from there. :D

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 7:45 pm

This is where I'm at for a dead rest. I'm going to just let it roll for an hour (or two) and see what the numbers look like then. I have it in "overkill mode" ~ which is what I'm calling it when you apply kalman and complimentary simultaneously at 50 samples each, With a samplerate divider of 100, and a dlpf of DLPF_BW_5 (the slowest one)

Image

I made changes to my script that only I have access to right now.

Code: Select all

def handler(data:tuple):
    if 'mpu' in globals():
        mpu.print_from_angles(data)

cfg = dict(
    rate       = 100      , 
    dlpf       = DLPF_BW_5, 
    filtered   = F_ANGLES , 
    filtertype = FT_BOTH  , 
    angles     = True
)
mpu = MPU6050(1, 6, 7, 2, (1368, -1684, 416, 20, -6, 49), handler, **cfg)

if mpu.passed_self_test:
    mpu.start()
    

Edit: It's already been going about 15 minutes, since I captured that screenshot, and it doesn't seem to have changed, at all. Pretty much the exact same numbers. Actually, I'm going to start this test over and have it write a mean to a file every 10,000 iterations (ie, a kind of long time cause I have it running really slow). I want better data than "it pretty much looks the same". My above image will still hold water. I haven't touched the device. It's going to spit out the same numbers when I start this over. And actually that part doesn't even matter. What matters is how much the mean floats in this file I'm going to write to.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sat Jun 12, 2021 10:05 pm

Well, I let it roll for an hour and this is the results:

Code: Select all

averages: 50       total samples:60000   
rmin: -0.022   rmax: 0.001   
rolldiff: 0.023   
pmin: 0.008    pmax: 0.039   
pitchdiff: 0.031

If we look at rolldiff and pitchdiff you wuld think those numbers represent drift, but it's more like a heartbeat cause the numbers ended pretty much the same as they started and in the middle it was really similar too. At (let's call it) the 2/5ths and 4/5ths mark areas there was a bit of a swell, and honestly, I have a bad feeling that it was partially due to me walking through the room. I was trying to be like a ninja but this is an old house. Things flex and this is an incredibly sensitive device. I'm going to try this again when I go to sleep.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 8:16 am

Have been running my coffee table IMU this morning, it seems it has a variance that is pretty constant, restarts seem to always show the same or very similar results, even over 1000's of loops...

Code: Select all

Loop:302  Min: -0.13  Max:  0.23  Cur:  0.03
Loop:303  Min: -0.13  Max:  0.23  Cur:  0.10
Loop:304  Min: -0.13  Max:  0.23  Cur:  0.09
Loop:305  Min: -0.13  Max:  0.23  Cur: -0.01
Loop:306  Min: -0.13  Max:  0.23  Cur: -0.04
Loop:307  Min: -0.13  Max:  0.23  Cur:  0.12
Loop:308  Min: -0.13  Max:  0.23  Cur: -0.04
Loop:309  Min: -0.13  Max:  0.23  Cur:  0.05
Loop:310  Min: -0.13  Max:  0.23  Cur:  0.06
Loop:311  Min: -0.13  Max:  0.23  Cur: -0.05

I'm thinking for a hyper-sensitive device, sitting on a coffee table on a wood floor, +/- 0.25 of a degree is pretty impressive no?

I'll be taking this device to the robot later after running the same tests on that one.

Code: Select all

#from machine import Pin, Timer
import utime
from mpu6050 import MPU6050 


# Setup the MPU6050 IMU
sda = 14
scl = 15
bus = 1
gyro_range = 0 # range [250, 500, 1000, 2000]
accel_range = 0 # range [2, 4, 8, 16]
d_rate = 32
d_dlpf = 3 # = DLPF_BW_42
offsets=(-614, 3111, 1368, 68, -16, 118)
#offsets = (-628, 3115, 1364, 69, -16, 117)
mpu = MPU6050(bus, sda, scl, ofs=offsets, gyro=gyro_range, accel=accel_range, rate=d_rate, dlpf=d_dlpf)

  
# Complimentary filter settings
alpha = 0.8 # Percent of accel data to use, 1-alpha is percent of gyro to use
samples = 5 # Number of samples to take


# Static calibration, if needed
print("Static cal...")
avg = 0
static = 0
readings = 250
for t in range(0, readings+5):
    if (t > 4): # Dump the first 5 readings as 1st two are always odd
        angles = mpu.get_complimentary(alpha, samples)
        avg += angles.roll
static = avg/readings
print("Done")

print(static) #lets see the calibration number...


roll_min = 0
roll_max = 0
t=0
if mpu.passed_self_test:
    while True:
        angles = mpu.get_complimentary(alpha, samples)
        
        if (t > 25): #let it settle for 25 readings
            if (angles.roll < roll_min): roll_min = angles.roll
            if (angles.roll > roll_max): roll_max = angles.roll      
        
        print("Loop:{:3.0f}  Min:{:6.2f}  Max:{:6.2f}  Cur:{:6.2f}".format(t , roll_min, roll_max, angles.roll))
        
        t+=1
        
        utime.sleep_ms(100)



davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 10:30 am

Well, its seems drift is ok now, I think, I was probably wrong in the first place :D

I can get stable numbers from the IMU on the 'bot, shake it about and it generally returns to where it started, in numbers at least.

I think my issue has now moved on to motor control, I am using PWM at present, feeding it a frequency and the drives a direction - they are step/dir A498 boards. I can make them spin at variable speeds, stop, reverse etc.

I'm now looking for that missing link - how to scale and connect IMU data to the drive. It seems most use PID for this but as usual I'm struggling to correlate Arduino to uPython and come up with sensible numbers, I really do have no idea here and because everyone is just boiler-plating the same code, there is none or very little description of what goes on and why.

I do know now that simply connecting the angle to the drive does not work, it just makes it dance about all over the bench :) so ultra-simplistic does not work.

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 11:32 am

Earlier when I suggested the arm idea you had me at a loss for a moment when you said "yeah but why". I have an answer. My suggested version could jump ramps and balance itself in mid-air. :D well, at least for pitch. You'd need another arm for roll or one hell of a universal joint. Actually, with some clever timing and math the arm could first be used to throw it's weight (like a skateboarder) to get massive amounts of air, and then recenter in midair for perfect landings.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 11:53 am

I can see a point but not going into it simply because its a step more advanced than a basic SBR which is proven to work. :D

To me, this video shows nothing more than pure magic, and yet its pretty old - https://youtu.be/8BtDuzu2WeI
They can do that and I cannot even figure out one on two wheels, makes me feel pretty dumb sometimes :oops: :oops: Ok, so i know there is some serious money in there and a lot of knowledge no doubt but balancing on one point, stable and not rocking all over the place :shock:

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 12:19 pm

Yeah, cause that's not a "single wheel" robot. It's a single ball robot, so it's more like a 360 wheel robot (one for every degree in a circle). It's just applying the same logic that you're trying to implement but it can do it in every direction. You even said yourself that the taller they are the easier they are to balance. That thing is like 6 feet tall. If it really was a single wheel robot it would immediately fall over with it's current design.

This is a single wheel robot, and it's got a fairly wide wheel.

Image
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 12:41 pm

Yes, my apologies, ballbot :D Still pretty cool i think though

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 1:45 pm

I worked on my script some more (not available to the public yet). Look how tight I have my numbers. I wasn't trying to get zeroes. I just wanted deviation to be as small as possible.

Image

The way I have this setup. gyro and accel data is passed through a kalman filter before angles are concocted. Then the mean of 50 complimentary filter samples of the angles are established. It's not necessarily an optimized approach, but it is a fairly accurate one. The results seem to vary by 6/100ths of a degree. I intend to floor my results for my purpose so, I believe I am well within in the range of getting very accurate results. My purpose will create speed based on tilt (I guess yours will, too), but my tilt will be capped at 45 degrees, and my speed will be something like 1(or 2) extra pixel of speed per 15 degrees, or something like that. It really depends on the game it is applied to.
Last edited by OneMadGypsy on Sun Jun 13, 2021 2:03 pm, edited 2 times in total.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:00 pm

Looking good, certainly tighter than my results using complimentary filter alone :D

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:03 pm

Ya know, the little game I intend to make today could actually be used to test your robot without even having to put your robot together. All you would need is a display, and to take the "game" part out. The dot on the screen would represent how your robot responds to tilt and all you would have to do is reverse my math so the dot moves against the tilt. Then you just play with all the numbers until the dot stays in the center of the screen no matter how you tilt it. Whatever math it takes to keep the dot in the center of the screen (by traveling there :D), regardless of tilt, and regardless of G force, is the same math it is going to take to keep your robot upright. I don't know if that's helpful, for you. If it is, I can save a version of my game before I add the actual game part.


Personally, I think it's awesome that I'm over here building a game controller and an example game, and essentially the same code could be used to drive your robot :D
Last edited by OneMadGypsy on Sun Jun 13, 2021 2:16 pm, edited 1 time in total.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:12 pm

Ooh, i can see the idea of a virtual build but never thought or seen it, i do know that things can be fully modelled in a virtual world though

I can have a play if its something you can put together of course, hopefully I can make sense of it in the way it needs to be :)

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:20 pm

It's actually very simple. Speed is determined by tilt with the destination always being the center of the screen. The tricky part for you is torque and friction, cause whatever speed the dot is moving at is not the immediate speed you are going to get out of your wheels. That's where you have to do a bunch of tests with your motors, so you keep the dot in the middle of the screen, but realistically based on the response and behavior of your physical parts. If I were you I would stick an sdcard on the robot and have it log every piece of information you can think of to it. Then you can crunch that data and and hopefully determine the tweaks that need to be made.

For instance, and with completely made up numbers:

Let's say your robot was moving at 5 (whatever 5 means) and the tilt of the robot changed by 3 degrees causing your robot to ramp up to 5.4, but that is exactly when it fell over, and it fell over forward. You know you need more speed, but you also have some solid numbers so you can start working the ends toward the middle to get the right speed. Then you can crunch all these various numbers and determine whether the math is always the same or if you need a more dynamic equation that can create the proper percentages based on numerous factors. In other words, it may not be as simple as currentPitch/maxPitch*speed, I can almost guarantee it wont be, but how can you ever get it right if you don't know the exact numbers that aren't working?


One way you could get good data is to create a lookup table of canned speeds and create some simple formula that turns angles into lookup table indexes. Then you can log that info and just keep changing the lookup table til you get it right. Then you take all the right and see if you can reverse engineer it into a formula. Just dividing all the working speeds by all of their associated angles will give you numbers. If those numbers are very similar you may be able to just average them, and creating a formula out of that would be very simple. If the numbers aren't very similar, then you can determine by what percentage they go up by. Maybe those numbers will be very similar and you can average those. You need data. Lots of it.

I can give you one hint if you use the log method. Make it write the log as code (json or something). That way you don't have any work to do reformatting it to stick it in some loop that starts telling you what averages and what-not are.
Last edited by OneMadGypsy on Sun Jun 13, 2021 2:49 pm, edited 1 time in total.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

davek0974
Posts: 301
Joined: Mon Jul 22, 2019 1:52 pm

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:44 pm

Hmm, ok i can look into some data logging, i have seen SD card stuff for the pico.

Doesn't it need to know about mass and acceleration etc to model it?
Let's say your robot was moving at 5 (whatever 5 means) and the tilt of the robot changed by 3 degrees causing your robot to ramp up to 5.4, but that is exactly when it fell over, and it fell over forward. You know you need more speed, but you also have some solid numbers so you can start working the ends toward the middle to get the right speed. Then you can crunch all these various numbers and determine whether the math is always the same or if you need a more dynamic equation that can create the proper percentages based on numerous factors. In other words, it may not be as simple as currentPitch/maxPitch*speed, I can almost guarantee it wont be, but how can you ever get it right if you don't know the exact numbers that aren't working?
Thats fine but i can gain no speeds etc as without attaining balance it cannot move - it just falls over :D - its a catch 22 i think ?

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:56 pm

i have seen SD card stuff for the pico.

There's a somewhat advanced sdcard reader script in my sdcard repo. I also built a command line interface so you can get data into the terminal from the sdcard right from the pico.

Thats fine but i can gain no speeds etc as without attaining balance it cannot move - it just falls over

It's not going to attain balance if the wheels aren't doing anything. There is some speed that it is always moving, unless you have the body perfectly balanced on the axle, at rest.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

hippy
Posts: 10187
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 2:57 pm

davek0974 wrote:
Sun Jun 13, 2021 11:53 am
They can do that and I cannot even figure out one on two wheels, makes me feel pretty dumb sometimes :oops: :oops:
There's no shame in not being as clever as those who can do better. Those who can do it were probably no better than the rest of us when they started. It is aptitude, commitment to their speciality, the ability to pursue their interests and fund that pursuit, which has taken them to where they are. It is unrealistic to expect to be far along their path when taking one's own first steps.

Sleds and four wheel platform 'stick balancers', two-wheeled self-balancing bots, ball-bots, inside-of-ball bots, pogo-bots, and all the rest are all extensions of the same basic principles but with increasing complexity and refinement. I expect, unless one is exceptionally skilled, as it is for most things, it is difficult to jump straight into the more complex without having gained experience of the simple first.

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 5:46 pm

This is my absolute final version of the MPU6050 driver. Some things have changed and they are all documented in the repo, but I will tell you the more important ones here:

  • the interrupt pin and offset arguments in the constructor have been flipped. This is because it used to be in this order (...pin, pin, interrupt pin, offsets, interrupt callback, ...), and I felt like it made more sense to put interrupt specific things together instead of pins. Especially since interrupt stuff isn't required, but the offset is in a way. It makes it so the first 4 to 6 arguments can be positional and you don't need to use the keyword since none of them will be skipped.
  • Way too many arguments have been added to the constructor. It's actually a bit ridiculous, but it allows you customization of everything and then after the constructor everything is really slim and simple. It's not so bad if you use a dict to declare all the necessary vars and then use it as **kwargs (as the filter example at the absolute bottom of my repo does)
  • get_complementary is not a thing anymore. Now flags are supplied to the constructor that tell the driver how to juggle filters and everything is gathered via either angles or data
  • you can't exactly tell the driver how many samples to use for complimentary filters. The sample number is now determined by half of rate. If you use the default rate (4) then every complementary filtered angle will be the average of 2 samples. I did it this way because the constructor is already ridiculous, I don't like making a bunch of setters for after-the-fact, and if your sample rate divider for the device is (ex) 4 why would you then get (ex) 100 complementary filter samples. Dividing the number by 2 seemed legit enough for me.

There will not be another version. This is the same version I used to keep my angles within 6/100ths of a degree of sway, and I'm satisfied with that. That's probably overkill for my needs. If you decide to upgrade to this version I would highly recommend looking at the docs for the constructor as-well-as the very last example in usage. Nothing else in the docs or examples has changed.

Side note: You may notice that the default values for the filter arguments are NONE. NONE and None are not the same thing. This becomes more apparent in my filters example at the bottom of the repo.
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

User avatar
OneMadGypsy
Posts: 326
Joined: Wed Apr 28, 2021 1:57 am
Location: New Orleans, Louisiana
Contact: Website

Re: Beginner - help with self-balancing robot build

Sun Jun 13, 2021 10:12 pm

Well, if it helps you any, below is my controller script. It uses the latest iteration of my MPU6050 driver (my last post), and my ST7789 driver, however you could use any (pixeled) display and driver that you can maintain a reference to the raw buffer for (because __rect), as long as you are willing to write your own clear and update methods or at least replace the ones here with your driver equivalent. One thing to note is, my roll and pitch are flipped due to how everything is oriented on my breadboard. The below script just makes a square move around the screen at a speed that is determined by tilt amount. I am super happy with the results. The square doesn't travel as long as the board is relatively level, and it doesn't look like it's having a seizure either. You don't have to worry about the dot leaving the screen and causing index errors. Constraints are already in this script.

Code: Select all

from mpu6050 import MPU6050, ANGLE_COMP, FILTER_ANGLES, DLPF_BW_188
from st7789 import ST7789
from machine import Timer, SPI, Pin

_WIDTH  = const(240)
_HEIGHT = const(240)
    
class Player(object):
    def __init__(self, width:int, height:int, color:int, speed:int):
        self.width  = width
        self.height = height
        self.color  = color
        self.x, self.y  = (_WIDTH-width)//2, (_HEIGHT-height)//2
        self.speed = speed
        
    def set_position(self, r:float, p:float) -> None:
        self.x += int(self.speed * (min(45, p)/45))
        self.y += int(self.speed * (min(45, r)/45))
        
        self.x = max(0, min(self.x, _WIDTH -self.width ))
        self.y = max(0, min(self.y, _HEIGHT-self.height))
        
    
class Main(object):
    def __init__(self) -> None:
        self.__display = ST7789(
            spi     = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT)),
            dc      = Pin(17, Pin.OUT),
            rst     = Pin(21, Pin.OUT),
            bl      = Pin(20, Pin.OUT),
            baud    = 62_500_000,
            bright  = 0xF0,
            rot     = 0,
            buff    = memoryview(bytearray(int(_WIDTH*_HEIGHT*2)))
        )    
    
        cfg = dict(
            rate        = 4            , 
            dlpf        = DLPF_BW_188  , 
            filtered    = FILTER_ANGLES, 
            anglefilter = ANGLE_COMP   , 
            angles      = True
        )
        self.__mpu = MPU6050(1, 6, 7, (1368, -1684, 416, 20, -6, 49), **cfg)
        
        self.p = Player(10, 10, 0xccdd00, 20)
        
        self.__timer = Timer(-1)
        self.__timer.init(mode=Timer.PERIODIC, period=1, tick_hz=30, callback=self.game)
      
    @micropython.viper
    def __rect(self, buff:ptr16, x:int, y:int, w:int, h:int, c:int, W:int):
        b, L = ptr16(buff), int(w*h)
        sx = int(x+(y*W))
        for i in range(L):
            b[sx+(W*(i//w))+i%w] = c
            
    def game(self, ticks:Timer) -> None:
        self.__display.clear_buff(0x000000)
        
        self.p.set_position(*self.__mpu.angles)
        
        self.__rect(self.__display.buffer, self.p.x, self.p.y, self.p.width, self.p.height, self.p.color, _WIDTH)
        
        self.__display.update_buff()
        
        
Main()
"Focus is a matter of deciding what things you're not going to do." ~ John Carmack

Return to “MicroPython”