SvenskaEnglish

The self-balancing robot is working quite well

In the video you can see that the robot stays at roughly the same spot on the floor and handles a lighter push without any problem. To achieve this I have two cascade PID controllers and low pass filter on both wheel speed and the robot's angle.

Microprocessors

As an Arduino does not have a lot of processing power, I chose to use a total of 3 microprocessors:

  1. A standalone Arduino Uno takes pulses from the tachometer on each wheel and converts it to a speed. The speed is sent to the main micro processor.
  2. One more stand alone Arduino Uno to view and adjust parameters. Also drives the display. The parameters are sent to the main micro processor.
  3. Arduino Leonardo is the brain. It receives information from the console and the engine speed sensor via I2C.

Basic control theory

Two cascaded PID controllers. The first has speed as setpoint (always 0 in this case) and angle as output. If the robot is moving forward, the controller will have a positive input value and send a negative output value. This means that the robot will want to lean back to slow down.

PID number 2 takes care of the robot's angle relative to the floor. The setpoint is the output of the previous PID controller. Normally the set point will range from -3 to 3. Zero corresponds to the robot standing completely straight up. The output signal is connected to the engine management system and range from -100 to 100. -100 corresponds to full voltage to the motors in reverse direction.

To get cleaner inputs I use FIR filters for both angle and wheel speed. Low-pass filter blocks rapid change (for example, sensor noise) from passing through.

For the angle relative to the floor, a IMU with accelerometer and gyro is used. A complementary filter combines the signals from these and provides an output signal that can be used.

Source

I had the objective that all code for this project should be open sourced and available for download from github. The readme contains links to libraries I have used.

Improvements that could be made

  • Better parameters to the FIR filter. Much could probably be done on the wheel speed.
  • On-the-fly programming over the air with Xbee. This means that you can send new code to the robot without USB cable. Will make programming more flexible.
  • Radio control would be nice.

Photos

Components

I am also publishing cad and drawings.

Tagged with: , ,
Posted in Self-balancing robot
18 Comments »The self-balancing robot is working quite well
  1. Luke says:

    Really fun to watch. Good job

  2. Magnus says:

    Fun!
    Do you think it would be easier to get the robot to balance "stable" If the rods are not flexade so mkt .... more shelves?

    • sebnil says:

      The bars are fairly stable even though it may not be visible in the video. What I think would make the biggest difference right now is better filtering of the input signal from the wheel speed. Better pass filtering would probably make time more enjoyable.

  3. chay says:

    !!!

    You wrote:
    -->
    The setpoint is the output of the previous PID controller. Normally, the setpoint will vary between -3 och 3 där 0 corresponds to the robot to stand completely straight up.
    <--

    I don't understand och or dar and a google search hasn't helped. I wonder what these terms mean. Any chance you could point me to a reference or give me a short explanation?

    Great project. Thanks for sharing.

    • sebnil says:

      It is a bad automatic translation. Should be "Normally the setpoint will vary between -3 and 3 where 0 corresponds to the robot standing completely straight.". So the output from the first PID will be an angle between -3 and +3 angles.

  4. geejay says:

    1. arduino for reading accelerometer and gyro, convert them to angles in degrees then send to the leonardo
    2. another arduino for just reading the motor speed and direction, then send it to leonardo
    3. the leonardo then read the PID parameters for the wheel and angle, then control motors? is this the way it works? or you can elaborate further?

    • sebnil says:

      No but quite close.
      1. Arduino for reading motor speed and direction.
      2. One arduino for the console. Drives the lcd and the buttons.
      3. Arduino Leonardo with motorshield as the brain. Communicates with 1 and 2 via i2c. Reads angle from the IMU (also via i2c). Handles the PIDs and outputs voltage to the motors.

  5. geejay says:

    No but quite close.
    1. Arduino for reading motor speed and direction.
    2. One arduino for the console. Drives the lcd and the buttons.
    3. Arduino Leonardo with motorshield as the brain. Communicates with 1 and 2 via i2c. Reads angle from the IMU (also via i2c). Handles the PIDs and outputs voltage to the motors.

    -------

    If this is the case, I can only use two arduino if I will be using potentiometers to set the PID values and no LCD display.

    All PID's exist in the leonardo and even the reading of the angle from the IMU only the motors has dedicated mcu for interpretation of the wheel encoders..

    In your source codes, which is for the 1st arduino, 2nd arduino and for the leonardo? thanks.

  6. Rick Bonart says:

    I was wondering if you might help me. I have succesfully used my arduino and a 5DOF analog IMU to accurately get my robots tilt with a complimentary filter.

    My difficulty is making the thing balance. My first attempt was to simple use the map function input from the IMU to 0 to 255 and sent it to a Sabertooth motor controller. It kind of works but was very jittery.

    Then I advance to the PID library. But very hard to tune. It drifts. I can send my code and processing graph. Any tips?

    • sebnil says:

      Do you have any feedback from the speed of the robot? Mine drifted a lot and that is why I have two cascaded PIDs instead of just one. Here is a video without feedback from wheel speed http://www.youtube.com/watch?v=gl07a232G98
      You can see that it drifts quite a lot.

      • Rick Bonart says:

        I do have the ability to get encoder position and but haven't implimented yet. I'm having a great deal of difficulty with basic balancing. If I could make mine balance like yours in the video link with drift I would consider myself very well off.

        I used the PID library developed by Brett but can't make it work.

        What did you use for input, setpoint and tuning.

        I used an a mapped quantity from the IMU for input: input = map( compAngle, 57,117,0,255);

        That's 8 bit resolution to an adjusted verticle angle of 87degrees. I used 127 as the setpoint.

        Problem is the PID output is zero at verticle and scale for one direction of tilt to 255 but won't go below zero in the oposite direction.

        • sebnil says:

          > What did you use for input, setpoint and tuning.
          Input is the angle. 0 means it is standing straight.
          Setpoint 0.
          For tunings see https://github.com/sebnil/Selfbalancing-robot/blob/master/selfbalancingrobot/configurations.txt

          >Problem is the PID output is zero at verticle and scale for one direction of tilt to 255 but won’t go below zero in the oposite direction.
          This is a problem. You will not get it working without an input error that is either negative or positive depending on the angle. Try to rotate the dof to see if that solves the problem.

          • Rick Bonart says:

            OK I tried again using the raw angle as input and changing setpoint to zero (vertical). The input error as I tip robot side to side has both positive and negative values. But the output increases in value as robot tips to one side but once I reach the setpoint zero and tip to other side the output will not change.

            It's definitely the problem, but it's the PID. Or a least that's what the processing graph shows. And correlates to the documentation that output will be 0 to 255. I'm just stuck on how to make zero degree tilt equal 127 output. Which would be balanced for the motors.

  7. Rick Bonart says:

    The issue is resolved. I just needed to use the SetOutputLimit function. Now the output is scaled.

    May I ask how did you tune the PID?

    • sebnil says:

      Good to hear! I tuned it with the console on the top just trying new values. I figured that I needed quite large values to keep it stable. Perhaphs I will do a proper mathematical model in the future but probably not.

  8. shoaib says:

    can u tell me the name of microcontroller gyrometer and accelerometer and pid use in it... so that i easily purchase thm from market.. thanx

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>