Go Down

Topic: Balancing robot for dummies (Read 151930 times) previous topic - next topic

gbm

HI guys look @ this I am working with another type of PID, I use a variable time PID.
I save the time of every loop and I use it to give a "weight" to every single acquisition.
It works very well:
http://www.gioblu.com/tutorials/programmazione/102-che-cose-lalgoritmo-pid

I think this solution works better then fixed time pid
Community robotica / programmazione Arduino
www.gioblu.com

kas

#106
Nov 19, 2010, 07:50 am Last Edit: Nov 19, 2010, 05:33 pm by kas Reason: 1
Hi gbm,

I followed the link, looks quite interesting. PID algorithm and tuning are definitly the key points for efficient balancing.
In our global village, you have to bite the bullet and use the Dominant Language (used to be French some centuries ago  ::)).
gbm, care to prepare a "variable PID for dummies" and post it here ???

kas

Quote
@kas
Are you happy with the xbee kit? How are you implementing it on the kas bot? Do you have the shield on the bot and the USB explorer card in the PC?


Quote
Great progress on the balancing part, but is anyone working on remote control for this Arduino robot? I

built several balancing robots using NXT and VEX kits and this is a great learning project, but I hesitate to spend

$400 until I see that someone has implemented remote control of some kind. I think that just the robot without RC

is not complete.

keep it up guys, you are doing a good job!


I am very happy with Xbees, they work beautifully   8-)

On the bot side, shield with Gyro/Acc combo and Xbee

(Some wires have been removed for better viewing)


For debugging and PID tuning, the Xbee Explorer USB dongle is directly connected to the PC
Same as a USB cable, except there is no cable  ;), which is useful for a moving bot



For R/C I use a Nunchuck joystick plugged on the Xbee wireless shield

The micro joystick which is soldered on the shield will be used as trims for robot translation and rotation

Everything is up and running

RWehner

@Kas

One simple method that I have discovered from:
http://www.rtfa.net/2009/01/02/arduino-ir-remote-control-more-advanced demonstrates how to control the arduino using an IR remote. I bought the IR receiver and universal remote from Radioshack for $20.

The code to get everything working is included at the site above. It basically reads the IR signal from the remote and translates each button's unique pulse combination into an integer. Using a case structure, you can specify commands to execute for each button. Should be pretty straightforward.

-Ross

kas

Hi Ross

Thanks for the link  :)
IR memotes are nice and inexpensive for R/C
They are very good at ON/OFF control, but for Analog/proportional they lack flexibility.
In our case, analog joysticks are much better for the job

I will post new tutorials (encoders, R/C control) later this week

tecabe

Quote
Hi Nahua, welcome
Thanks for your PM and the nice words
your bot is balancing pretty well, congratulation  

P(i)D tuning seems optimal
The forward/backward drift is typical and normal, it will disappear with your encoder implementation

Are you still using EMG30 motors?? can you quantify backlash ??

Oh... one last comment. Don't be shy, make it taller  


Hey Kas...

Yes, Im using the EMG30 motors andbacklash is quite low, just a couple of millimeters with the 10 cm wheels. I can make a video if you need so see it with your own eyes.

Will try to add more deckers and make it taller soon :)

Im starting to implement encoders and then make:
torque = P1 + D1 + P2 + D2
(1 = error from sensor --> complementary filter)
(2 = error from encoders)

I'm going crazy now adjusting PIDs so I started graphing things in Processing, still couldn't get anything as I wanted... maybe a PID expansion tutorial needed?

thanks god you are making more tutorials about RC and encoders, cant wait for them!

thanks for the recommendations!

osmaneralp

Many thanks to everyone, especially kas, for this awesome thread. I'm building my own balancing robot, and I've learned a lot here. I think I've read every post, but I might have missed something. Can someone please give me some guidance on these points:
1. Is a 10ms loop sufficient, or should I try to go faster if my peripherals allow it?
2. I can't access the A2D on my CPU. I need to purchase a separate A2D chip to read the gyro. Is a 10 bit A2D sufficient, or should I go 12 bits?
3. Can anyone suggest a good standalone A2D for a balancing robot?

TIA. I hope I can post a movie of my robot balancing soon!

--Osman

Patrik

#112
Nov 22, 2010, 06:40 am Last Edit: Nov 22, 2010, 06:49 am by X-firm Reason: 1
@kas

I have now bean test running the robot with the battery you showed me on ebay.. I have just bean playing with the PID parameters for a hour or so but I'm not getting the robot to stand "still".

It was to long a go I worked with PID so I need to read up a little..

The robot Is starting to get heavy, 2.359 kg  :o, don't know if that can give me some troubles..

I will try some more and post a video of my success or failure..
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

kas

#113
Nov 23, 2010, 08:06 am Last Edit: Nov 23, 2010, 03:45 pm by kas Reason: 1
@tecabe
Quote
Im starting to implement encoders and then make:
torque = P1 + D1 + P2 + D2
(1 = error from sensor --> complementary filter)
(2 = error from encoders)
You are on the right track  ;)
More info later this week



Hi Osman, welcome, thanks for your comments
Quote
1. Is a 10ms loop sufficient, or should I try to go faster if my peripherals allow it?
100hz is plenty. I adjusted loop time up to 200Hz without any significant change in attitude.
Try for yourself and make sure that your processor can cope with the situation (STD_LOOP_TIME - lastLoopUsefulTime should be >o), especially if you send wired or wireless debug info to your PC

Quote
2. I can't access the A2D on my CPU. I need to purchase a separate A2D chip to read the gyro. Is a 10 bit A2D sufficient, or should I go 12 bits?
Go for a 12 bit ADC

Quote
3. Can anyone suggest a good standalone A2D for a balancing robot?
I strongly suggest MCP3204 or 3208. I am currently testing this chip, source code available on request





@Patrik
Quote
The robot Is starting to get heavy, 2.359 kg  , don't know if that can give me some troubles..
You built a balancing sumo  :) :)
Keep us aware

osmaneralp

@kas
Quote
I strongly suggest MCP3204 or 3208. I am currently testing this chip, source code available on request

That's good to hear. I have a 10 bit MCP3008 that I wan going to use on another project. I start with that and swap it out when I can get the 3208.

How did you read the SPI bus? Does your processor support SPI, or did you implement a bit banged solution?

Many thanks!
--Osman

Jon D.

Thanks for answer kas, I'm sorry for really slow answer. I actually didn't notice that the thread continued on the next page:P

I don't have much time for debugging these days, as I have exams. But soon is the christmas vacation, and that means I have plenty of time experimenting 8-)

kas:
Quote
Finally make sure your gravity compensation for the "vertical" accelerometer is OK


I have "tuned" the accelrometer Z-axis so that the angle calculated from accelrometer is zero when the robot is at equalibrium. Then I tilted the robot physically 45 degrees(measured with tool) and checked that the angle was about correct. The angle read from the accelrometer was approx 2 degrees at 45 degrees, which shouldn't be a problem as this error will be very little at the small angles from the robot will(hopefully) work around.

The gyro sign is also correct, positive accelrometerangle -> positive gyro output. The only problem is that when integrating the gyro without adjusting with accelrometer(no kalman or complimentaryfilter), the integrated angle is way to small. However, dividing the sensitivity constant for the gyro(which makes the reading 3 times bigger), the angle seems about right. But I don't like solutions like this when I don't know why the reading is wrong in the first place..

Anyways, here is a video of the balance robot attempting to balance. I suspect that the estimation of the angle is a bit slow, so that the robot is a bit "late" in compensating.

Video: http://www.youtube.com/watch?v=w6XP9V11lhM

The video also shows the Java-based software on the computer which is used to tune the controller on the roboot wirelessly over XBee. By the way, it is running state-feedback instead of tradisional PID control, that's why the text on the software is K1,K2,K3 instead og P,I and D.  

Will be back with more info about the angleproblem when I'm done with my exams, until then thanks for the help! I appreciate it :)

Jon, Norway

Patrik

@kas

A balancing sumo is the right word for it and it has some trouble to be able to stand. I will try to lighten it when I get some more time for it.

I started to check the differences of the motors by using the encoders to try to see the distance the motors turned in a constant time and get a factor for the diff. I drive the motors in both directions in four different speeds 50, 100, 200, 250..

I made a sketch for the Arduino and a GUI sketch in processing based on the Balancing Bot GUI, and thought that this cant be so hard to do just see the diff. and calculate a factor for the faster motor but that was not the case..

The first run gave me the results like in the image below, where the motors behaved very different in forward to backward motion. When going forward for a time constant(2000ms) and then sending the drive_motor(0) the motor continued running in free spin for a short while. But when running backward  the motor brakes for a short while.

//image See the blog post on my blog

Speed   L        R
255       7662       : 7413
-255       -5516       : -5541

150       6582       : 6386
-150       -4901       : -4872

50       3342       : 3291
-50       -2747       : -2705

As you can see the behavior is very different in the two directions..

I changed the drive_motor function like below and tried again and the result was better but is I going about this in the right way?
Code: [Select]

int Drive_Motor(int torque)  {
 if (torque > 0)  {
   // drive motors forward
   digitalWrite(InA_R, LOW);
   digitalWrite(InB_R, HIGH);
   digitalWrite(InA_L, LOW);                      
   digitalWrite(InB_L, HIGH);        
   forward = true;    
 }else if(torque < 0) {     // drive motors backward
   digitalWrite(InB_R, LOW);
   digitalWrite(InA_R, HIGH);                      
   digitalWrite(InB_L, LOW);
   digitalWrite(InA_L, HIGH);                      
   torque = abs(torque);
   forward = false;
 }else{
   if(forward){
     digitalWrite(InA_R, HIGH);                      
     digitalWrite(InB_R, LOW);
     digitalWrite(InA_L, HIGH);                      
     digitalWrite(InB_L, LOW);
   }else{
     digitalWrite(InA_R, LOW);                      
     digitalWrite(InB_R, HIGH);
     digitalWrite(InA_L, LOW);                      
     digitalWrite(InB_L, HIGH);
   }
 }
 //if(torque>5) map(torque,0,255,30,255);
   analogWrite(PWM_R,torque * motorOffsetR);
   analogWrite(PWM_L,torque * motorOffsetL);
   Serial.println(torque,DEC);
}


Now it looks like the Arduino and the motor controller is behaving in the same way in both directions. I need to take some more readings to see if the differences that are left are linear in some way.. It feels like there are a difference between the motors in both directions but also that both motors are going faster forward, and that I think is created by the motor control??..
See image below..

//image See the blog post on my blog
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

Patrik

I'm not entirely happy with the backlash in my motors and I wounder what you guys thinks of using two brushless motors and some belt transmission?? Like in beautifulsmalls robot..
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

kas

#118
Nov 25, 2010, 08:06 am Last Edit: Nov 25, 2010, 08:30 am by kas Reason: 1
@Osman
Quote
How did you read the SPI bus? Does your processor support SPI, or did you implement a bit banged solution?
ATmega168 and 328 are supposed to have built-in hardware support for SPI
I still manage the MCP3208 by the bits
Look here and here

What processor are you using ??



@Jon
Shall I understand that you build robot at school??  lucky guy :D
You are also lucky because robot technology will develop quickly, and you will probably never fear unemployment...
I understand you are developing a different software, but still, can you check your raw sensor value and make sure that you get a symetrical pattern, as per photos in reply #113
Looking at the bot height, I suspect you are not a shy guy  ;)
Anycase, good luck for your exams. I hope you will come back later and give us additional infos on state-feedback.


@Patrik
Belt transmission is probably the way to go for zero backlash, but not easy to implement
Are you using the Pololu 350RPM motors ??
I confirm that backlash is noticiable, but it doesn't prevent proper balancing.

Quote
I started to check the differences of the motors by using the encoders to try to see the distance the motors turned in a constant time and get a factor for the diff. I drive the motors in both directions in four different speeds 50, 100, 200, 250..
I will read your blog entry and come back soon

beautifulsmall

#119
Nov 26, 2010, 08:52 pm Last Edit: Nov 26, 2010, 10:49 pm by meatmydesk Reason: 1
cheap velocity encoders for belt transmission:
just connected adns-7550 mouse encoders , SPI-4wire, to my DsPic board, sub $10 for chip and lens, (laser diode integrated into 7550) Mouser. soldering a bit fiddly, with the very small fet on the data sheet, smaller than sc70!!.
but, excellent results with the belt sprayed with metallic spray. the 7550 reports surface quality to aid positioning, 60 inch/sec max rate , within balance robot thresholds, 2000 counts per inch, better than $30 heds encoders. Ive also tried it on the wheel wall (gold sprayed) and get excellent velocity data. 2.5mm airgap lens to moving surface but not critical.
format of spi_read(address,data)  (hex AA,DD)
ADDRESS : 7550 spi read is MSB=0, write MSB=1, this is different from BMA180,ADXL345? which has read as MSB=1WR MSB=0.


// ++++++++++++++++ mouse 7550 ++++++++++++++++++++++++++++++++
int mouse7550_init() // uses slave select A9
{

     spi_write(0x3a5a);  // power on reset
pause(10);
     spi_read(0x2e00);   //observation reg read clears it
pause(10);
     spi_read(0x0200);   //read form reg 2
      spi_read(0x0300);   //read form reg 2
      spi_read(0x0400);   //read form reg 2
      spi_read(0x0500);   //read form reg 2
     spi_write(0x3C27);   //reserved
     spi_write(0x220A);   //reserved
     spi_write(0x2101);   //reserved
     spi_write(0x3C32);   //reserved
     spi_write(0x2320);   //reserved
     spi_write(0x3C05);   //reserved
     spi_write(0x37B9);   //reserved

     spi_write(0x1a40);   //laser cfg0 , range NNxxxxxx
     spi_write(0x1cff);   //laser power 8 bits ff=100%
     spi_write(0x1d00);   //complement of reg 1C,laser powert
     spi_write(0x1fB0);   //complement of D7,D6,cfg0

     spi_write(0x1260);   //resolution 0x xNNx xxxx
     // resolution  NN =0 =400
     //NN=01 = 800 , NN=10 = 1200 , NN=11=1600
     
return 0;
}

//+++++++++++++++++++++++++ mouse encoder ++++++++++++++++++++++
int mouse_x_read()
{
int temp;
unsigned int low,high;
int x;

low=spi_read(0x0300);   //read form reg 2
temp=spi_read(0x0400);  
high=spi_read(0x0500);   //read form reg 5

low=(low & 0x00ff);
high=((high & 0x0f0) <<4);

x=(high | low);

return (x);
}

Go Up