Go Down

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

osmaneralp

I'm trying to use the Kalman code described in this thread. When the angle of my bot changes rapidly, the filter can take 10 cycles to settle. In other words, the computed angle lags the accelerometer angle by as much as 10 cycles. This is making my bot slow to respond. Is this lag normal? Is there anything I can do to speed up the response?

Thanks!
Osman

Patrik

#211
Jan 13, 2011, 03:41 pm Last Edit: Jan 13, 2011, 03:42 pm by X-firm Reason: 1
@osmaneralp

I had something simulare but i found that I had the wrong value when setting the scaling of the gyro rate. Check in the data sheet for you sensor what the sensitivity is for mV/(deg/sec)

Code: [Select]

int getGyroRate() {                                             // ARef=3.3V, Gyro sensitivity=2mV/(deg/sec)
 return int(sensorValue[GYR_Y] * 4.583333333);                 // in quid/sec:(1024/360)/1024 * 3.3/0.002)
}


Also it's important that you have a good value on the ACC_Z and it should be equal when having it standing as up side down...
Quote
For ACC_Z, gravity correction = (0° value - 180° value)/2

Quote

2 - Zeroing sensor
Before aquiring data in the loop, sensors should be zeroed
This means that when the bot is stricly still and vertical, sensors should read "0[ch8243]
except for the vertical axis (Acc_Z), which is sensing gravity (1g)
Zero mesurement is performed in setup:
Code: [Select]

void calibrateSensors() {                                 // Set zero sensor values
 long v;
 for(int n=0; n<3; n++) {
   v = 0;
   for(int i=0; i<50; i++)       v += readSensor(n);
   sensorZero[n] = v/50;
 }
 sensorZero[ACC_Z] -= 102;
}

calibrateSensors() is a one off action, so we have time to average 3 X 50 measurements
Finally, gravity value is deducted to Acc_Z
For ADXL330/335: 1g = 330 mV (+- 10%)
ACC_Z correction for 10 bit ADC and 3.3V AREF: 330/3300*1024 = 102 (to be fine tuned later on)


Hope you find the problem.. What sensor are you using?
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

Patrik

I have now gotten my BlueSmirf and the other parts I was missing to be able to complete my bot.

I tried the wireless communication at 115200 bps and it worked right out of the box. Very happy with it and maybe now I can finalize the bot and the Balancing Bot GUI 2.0..

I have gotten the speed of the communication between the bot and GUI to a acceptable level. I have split ed the data in five groups and each group is sent each fifth loop..

I will post some images and a video on the interface and robot in the end of the week hopefully..  :-/
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

osmaneralp

#213
Jan 13, 2011, 10:43 pm Last Edit: Jan 14, 2011, 06:11 pm by osmaneralp Reason: 1
@Patrik

Thanks for the suggestion. I'll look more closely at the gyro. I'm using an LPY510AL connected to a MCP3302 13-bit a2d converter. I went with an external a2d to try to get more accuracy. Whether or not I need the extra resolution is not yet clear. I can explain how to connect the a2d to get all 13 bits of resolution if anyone's interested.

I'm using the 4X out instead of the 1X out from the gyro. Anyone know if this is a good idea? The 4X out gives 10mv/deg/sec. The a2d has 8096 units in a 2.48v range. That's about 0.3mv/unit. So each a2d unit represents 0.03 deg/s or 0.085 quid/s. This is quite different from the 4.58 quid/s used in this thread. Does this mean I will have to change the kalman matrix parameters?  :-/

The accelerometer is built into the Chumby that also contains the ARM processor which is the brains of my bot. I'm getting good symetrical readings from the acc, so I don't think that's my problem.

Here's a picture of my bot:


--Osman

Ro-Bot-X

So cute! And it's blue! I love it!

Ro-Bot-X

Guys, I have a question, since I won $40 loyalty from SF, I want to get a new IMU board. Question is: should I get the recommended 5DOF IMU ($44.95) OR should I get the new 6DOF IMU that uses I2C ($64.95)?
The advantage of the last one being freeing the analog pins so I can use pots to fine tune the PID and perhaps a better accuracy. But is I2C fast enough in this case? Also the acc-meter has 2 interrupt output pins that you can program to trigger when falling too fast or when new measurement is ready, etc.

Patrik

#216
Jan 14, 2011, 08:44 am Last Edit: Jan 14, 2011, 08:46 am by X-firm Reason: 1
@osmaneralp

I'm using a similar sensor I think and it's running in 4X mode. I got the following gyro rate as below but then I use a Arduino analog port directly.

Quote

I'm using a nother GYR called LPR510AL and that one has a sensitivity of 10 mV/(°/s) at ±100°/s. ( and it's running in 4X mode)

It looks like I have made a miss calculation where it should have been:  

// ARef=3.3V, Gyro sensitivity=10mV/(deg/sec)
// in quid/sec:(1024/360)/1024 * 3.3/0.010)
return int((sensorValue[GYR_Y] * 0,9166679)*-1);

Measurement range:       ±100°/s and ±400°/s
Sensitivity:       10 mV/(°/s) and 2.5 mV/(°/s)



@Ro-Bot-X

I know to little about the SPI buss but I love the idea to getting the analog ports free. If you buy it and it works good I will defiantly go for one later on to..


The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

Patrik

@kas
@osmaneralp
@Ro-Bot-X
@GuzZzt

I would like to have a page on the projects homepage with some example robots that has used this project to be able to build a balancing robot or something else...

If you feel that this project had helped you with your bot could you send me a link to a homepage or a build blog there you describe your bots and what components you have used. With some images and videos etc.

Otherwise send some text and the images and links to videos and I can make a page on my web server for the bot..
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

kas

Quote
I got my hands on a free L298N H-Bridge: http://www.st.com/stonline/books/pdf/docs/1773.pdf
Unfortunately it only can handle spikes of 3 A (repetitive 2.5 A). Did you ever get an idea of what currents are used? I plan on making the bot relatively small...
I would take the motor stall current as the H-bridge amp requirement

Quote
Also, have you ever run into speed problems from the microcontroller? Is 16 MHz fast enough?
16 MHz is fast enough

Quote
My understanding was that the sensors act as the feedback to tell the motors direction and speed, so a motor encoder is not necessary. I see you made the same statement in your initial post.
You will get "basic" balance w/o encoders, but the bot will drift forward/backward




Quote
I have now gotten my BlueSmirf and the other parts I was missing to be able to complete my bot.
...
I will post some images and a video on the interface and robot in the end of the week hopefully..
Congratulation Patrik
I will also post my XBee version this week end ;) ;)




Ro-Bot-X

Ok, I ordered the 6DOF IMU. It has I2C interface, not SPI. Standard speed is 100k/s, faster speed is 400k/s. To poll the sensor we need the Wire library, I have experience working with I2C sensors and I have 4 Arduinos on a robot linked through I2C interface. So, I hope it will work fine. The only thing I have a problem with is the 3.3V interface. I'll see what I can do. I think I need to use 4.7k pull up resistors tied to 3.3V instead of 5V. Also, the sensor needs 3.3V that I will get from the Arduino board directly (I still need to check the current requirements).

I will create a blog page with my attempt, although it did not work because of the design I tried just to see if it works. New version coming as soon as I will get the new IMU.

kas

08:16 14/01/2011
@Osmaneram
Nice bot  :)
I played with a MPC3208 ADC which is the 8 input version
As far as I remember, those are 12 bit ADC's with 4096 units (not 8096)  :o
Please clarify

Your IMU board may have a different noise pattern that may require specific Kalman filter tuning.
The ADC should not inpact Kalman tuning (it didn't on my setup)



@Ro-Bot-X
I am also tempted to go digital for several reasons
- analogic is noisy by nature
- additional features
- this is the future...

I2C frequency is in the 100KHz range, don't be affraid
Please try it and let us know the outcome, we all need guinea pigs  ;) ;)



osmaneralp

#221
Jan 14, 2011, 06:11 pm Last Edit: Jan 14, 2011, 06:13 pm by osmaneralp Reason: 1
Quote
I played with a MPC3208 ADC which is the 8 input version
As far as I remember, those are 12 bit ADC's with 4096 units (not 8096)  
Please clarify


@kas Good catch. I'm actually using a 3302, which is a four channel 13-bit differential input a2d. The extra bit compared to the 32xx parts is a sign bit. To take advantage of the sign bit, the a2d input voltage must swing above and below the a2d vref. If the vref of your arduino is tied to 3.3v, you the input voltage from the gyro will never go above vref, and so you only get 12 bits.

To get the full 13 bits, take the vref from the gyro, which on my gyro is 1.241v, and connect it to the vref on the a2d and channel 1 on the a2d. Take the vout from the gyro and connect it to channel 0 on the a2d. Configure the a2d to run in differential mode. This means that the a2d will compare channel 0 to channel 1. If the voltage on channel 0 is greater than the voltage on channel 1, the output of the a2d is positive and the sign bit is 0, otherwise the sign bit is 1 which indicates a negative value. In addition to the sign bit, there are 12 more bits of resolution. This means that you get 12 bits from 0 to vref, and another 12 bits from vref to 2 x vref. That's 13 bits effective resolution.

Whether or not all 13 bits will be useful is not yet clear!  :-/

--Osman

prof_jazz

#222
Jan 14, 2011, 07:33 pm Last Edit: Jan 14, 2011, 07:35 pm by prof_jazz Reason: 1
Hi Kas,

compliments for your great job and info.

I have terminated a self balancing robot very similar to your (same IMU), except for motors.

I used 6V HITEC HS-325HB hacked to run continuosly, but this motors are not enough for he job they have to do.

I tried to make the robot less high but it became too instable..

anyway I order the same Your Pololu equipment...waiting for shipment.

Two questions:

(1) in the setup, with the function calibrateSensors(); you have to put the robot (each time you switch it on) exactly in the static equilibrium position in order to evaluate zero values (exept for z).

is this a little bit boring and could produce errors (if it is not perfectly perpendicular)?

If during the calibrateSensors() i'll give a tilt, the Robot will work to keep the tilt!

maybe there is something that I cannot understand?

(2) what do You use to recharge the 12V batteries?


thanks,

bye,

Prof

kas

Hi prof_jazz, welcome  :)
please let us have a photo of your new pet

Quote
I used 6V HITEC HS-325HB hacked to run continuosly, but this motors are not enough for he job they have to do
I also waste one year following this track  ;)

Quote
(1) in the setup, with the function calibrateSensors(); you have to put the robot (each time you switch it on) exactly in the static equilibrium position in order to evaluate zero values (exept for z).
is this a little bit boring and could produce errors (if it is not perfectly perpendicular)?
If during the calibrateSensors() i'll give a tilt, the Robot will work to keep the tilt!
No No...
If you tilt the bot forward before calibrateSensors(), it will move forward and find a vertical equilibrium
This will happen only with encoder(s) implementation, look here

Quote
(2) what do You use to recharge the 12V batteries?
I ordered the battery charger shown here




kas

#224
Jan 15, 2011, 12:12 pm Last Edit: Jan 16, 2011, 07:29 am by kas Reason: 1
      [size=14] ** Balancing robot for dummies **[/size]


[size=14]Part seven: Xbee wireless control, KasBot V 3.0[/size]

The objective is to obtain basic motion control (Forward/Backward, Stop Right/Left)
Xbee modules act as a serial line replacement, a USB cable without the cable :)
See post #82 for more info


[size=14]1) controller side:[/size]

Shopping list at post #77
Transmitter with Nunchuck joystick controller is shown on post #107
The additional micro joystick and the 3 LED's will be used for advanced features wich are beyong the scope of this basic KasControl V1.0

Nunchuk_kas.h does take care of the I2C communication with the joystick
Code: [Select]
// Nunchuck_kas.h        joystick functions ----------------------------------------------------------------

#include "Wprogram.h"
#include <Wire.h>

static uint8_t nunchuck_buf[6];                             // array to store nunchuck data,

void nunchuck_init()  {
 Wire.begin();                                                  // join i2c bus as master
 Wire.beginTransmission(0x52);                                  // transmit to device 0x52
 Wire.send(0x40);                                        // sends memory address
 Wire.send(0x00);                                        // sends a zero.  
 Wire.endTransmission();                                  // stop transmitting
}

void nunchuck_send_request()  {                             // Send a request for data to nunchuck
 Wire.beginTransmission(0x52);                                  // transmit to device 0x52
 Wire.send(0x00);                                        // sends one byte
 Wire.endTransmission();                                  // stop transmitting
}

char nunchuk_decode_byte (char x)  {                         // Encode data to format that most wiimote drivers
 x = (x ^ 0x17) + 0x17;                                     // except only needed if you use one of the regular
 return x;                                                  // wiimote drivers
}

int nunchuck_get_data()  {                                   // Receive data back from the nunchuck
 int cnt=0;
 Wire.requestFrom (0x52, 6);                                  // request data from nunchuck
 while (Wire.available ()) {                               // receive byte as an integer
   nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
   cnt++;
 }
 nunchuck_send_request();                                  // send request for next data payload
 if (cnt >= 5)     return 1;                               // If we recieved the 6 bytes, then go print them
 return 0;                                                 // failure
}                                                           // returns 1 on success read, returns 0 on failure

int nunchuck_joyx()  {                                     // returns value of x-axis joystick
 return nunchuck_buf[0];
}

int nunchuck_joyy()  {                                     // returns value of y-axis joystick
 return nunchuck_buf[1];
}

This is a strip down version of the code that can be found in the Arduino Playground section.
We only use the joystick data, (we have enough accelerometers in this project  ;))
More info on wiring and code here

The main code uses a communication protocol based on 3 Bytes:
  controlByte = 'd'      (just says "hey, I am coming with new joystick data !!")
  dataByte_1 = value of y-axis joystick
  dataByte_2 = value of x-axis joystick

To reduce traffic, data is only sent when joystick is moved
Code: [Select]
// ** Kas Control V10     Balancing bot RC with nunchuk **  

// Yellow: Clock SCL (AI5)  Red: 3.3V  Green: Data SDA(AI4)  Write: Ground
// serial data format:   <controlByte> <dataByte_1> <dataByte_2> <CR>
// V1.0 basic control

#include <Wire.h>
#include "Nunchuck_kas.h"

int refreshTime = 100;                                    // time in millisecs between Nunchuck poolings
long lastPulse = 0;
char controlByte = 0;
char dataByte_1 = 0;                                      // joystick data
char dataByte_2 = 0;

void setup()  {
 Serial.begin(19200);
 nunchuck_init();                                         // send the initilization handshake
 delay(100);
 nunchuck_joyx();
 nunchuck_joyy();
}

void loop()  {
 if (millis() - lastPulse >= refreshTime) {                // x ms have passed
   checkNunchuck();
   lastPulse = millis();                                   // save the time of last pulse
 }
}

void checkNunchuck()  {
 static int Byte1_ant, Byte2_ant;
 nunchuck_get_data();
 controlByte = 'd';
 dataByte_1 = map(nunchuck_joyy(), 27, 218, 0, 40);        // nunchuck joystick North/South                    
 dataByte_2 = map(nunchuck_joyx(), 27, 218, 0, 40);        // nunchuck joystick East/West
 dataByte_1 = constrain(dataByte_1, 0, 40);                                
 dataByte_2 = constrain(dataByte_2, 0, 40);
 if((dataByte_1!=Byte1_ant)||(dataByte_2!=Byte2_ant))  {
   updateBot();
   Byte1_ant = dataByte_1;
   Byte2_ant = dataByte_2;
 }
}

void updateBot()    {                                       // send data stream
   Serial.print(controlByte);        
   Serial.print(dataByte_1);    
   Serial.print(dataByte_2);
   Serial.print("\n");
}


...........


Go Up