Do-it-yourself self-balancing...things...have been around almost as long as commercial self-balancing things. Obviously the homemade versions are not as smooth, reliable, or failsafe as the real thing, but they are still pretty captivating. And they make great mechanical/electrical builds with some interesting control theory mixed in. In the final step, I provide a few references to good DIY self-balancing...whatever...builds.

In 2007, I helped with this other self-balancing scooter build at the MIT Edgerton Center, and since then we've gotten many interesting questions by email about how it works. Baseline self-balancing functionality is actually surprisingly simple, and maybe the purpose of this Instructable is to take this simplicity to the extreme. To that end, I present: Seg...stick.

Segstick is a self-balancing...well, literally some kind of broomstick I found in the MITERS workshop. It is powered directly by two DeWalt cordless drills chucked to two 6" wheels. The controller is an Arduino. Additional supporting devices include an Inertial Measurement Unit (IMU) from Sparkfun and two motor drivers from Pololu.

Is it the best DIY self-balancing vehicle ever? No, not even close. But it only took about two days to build, and it is stripped down to the bare necessities. Thus, I hope to point out the modules and concepts involved in making any self-balancing vehicle rather than the specifics of this one. To start with, some physics...

Step 1: Physics Says It's Easier to Build a Full-size Self-balancing Thing.

One question we get a lot is: Can this work on some kind of miniature self-balancing robot? Yes, but, the laws of physics make it harder to control a small inverted pendulum bot than a full-sized rideable self-balancing vehicle. 

For one, the mechanical time constant of a small self-balancing robot is faster. Imagine the difference between trying to balance a broomstick on your finger and trying to balance a pencil on your finger. The controller for a small robot has to be that much faster to keep up with the physical system.

Additionally, a human rider takes some of the burden off the electronic controller, since the human mind is a pretty good controller too. For example, the accelerometers used on self-balancing platforms can't distinguish between standing still and moving at a constant velocity, but a human rider can. The human rider can adjust by leaning forwards or backwards to speed up or slow down.

So, this Instructable focuses on a full-size vehicle, albeit a relatively small one. In the final step, there are some links to balancing robots.

Step 2: Gathering.

Having decided to build a full-sized self-balancing vehicle, there are a number of essential components and modules to acquire. Here is a complete list of parts used to build the Segstick. Details of and alternatives to several components will be presented in later steps.

Big-Ticket Items ($411):
2x DeWalt DC759 18V Cordless Drill (eBay, $60ea new w/o battery or case)
1x DeWalt DC9096 18V Battery (eBay, $40)
2x Polulu High-Power 18v25 Motor Driver ($50ea)
1x Gravitech Arduino Nano 3.0 ($35)
1x Sparkfun Razor 6DOF IMU ($60)
2x AndyMark 6" FIRST Wheel ($13ea)
2x AndyMark 1/2" Keyed Hub ($15ea)

McMaster-Type Stuff:
2x Mounted 1/2" Bearings (5913K61)
4x 1/2" Shaft Collar (9414T11)
1x Precision 1/2" Keyed Shaft (1497K131)
1x 1/8" Key Stock (98535A130)

- Plywood (3/4", 1/2")
- Hose Clamps or Extremely Large Zip Ties.
- 1/4-20 Bolts and Nuts
- Breadboard or Protoboard
- Wire, Heat Shrink, Solder
- 5k or 10k Potentiometer.
- Polarized 2-Pin Power Connectors (e.g. Deans)
- Heat Sink Material

And Most Importantly:
- A Stick.

Step 3: Drive Motors, Choosing.

Segstick uses two DeWalt DC759 18V cordless drills as drive motors. Cordless drills are great because you get a motor, a gearbox, and a way to couple to the drive shaft together in one package. They are also available cheaply on eBay used or without the battery, charger, and case.

Cordless drills are not so great because the chuck often has a lot of backlash, which makes controlling the vehicle difficult. I've been informed that some low-end drills actually have less backlash because they don't have an anti-backdrive feature on the chuck. You might also be more willing to sacrifice a cheap drill like this than a nice, working DeWalt.

Another option is to use gearmotors from the robotics market, such as the BaneBots P80. You can see these deployed on our first balancing vehicle, as well as Charles Guan's Segfault. These gearboxes give you considerably more gear ratio options (12:1, 16:1, 27:1) and will have less backlash than the DeWalts. The downsides are a higher price and more fabrication required for mounting and attaching a wheel.

Step 4: Drive Motors, Modding.

If you do choose to go with cordless drills, they will require a bit of hacking to work as balancing vehicle motors. Mainly, this involves getting direct access to the two motor terminals. The drill's motor controller, as nice as it may be, can't do four-quadrant (reversible) motor control, which is required for this project.

The mod is pretty quick: After opening the drill case (you will need a Torx driver for the DeWalt case), disconnect the motor leads from the trigger controller. File down a slot in the two halves of the case through which these leads can be passed. Then, reassemble.

Step 5: Drive Wheels.

Real Segway wheels are huge. There are good reasons to use large wheels (better performance on cracks and rough terrain, for example). For the purpose of building a homemade self balancing vehicle, I've found it easier to use smaller wheels. Segstick's wheels are almost absurdly small (6"). But something in the range of 8-12" would work well with the gear ratios available in cordless drills (low gear) or commercial robot-type gearboxes.

It can be tricky to find good drive wheels for a project like this. The vast majority of wheels you might find lying around are caster wheels, with bearings built in. Drive wheels have some way of transmitting torque from a rotating shaft to the wheel, such as a key. The DeWalt drill chucks can accept up to a 1/2" keyed shaft. Some other drills may only go up to 3/8"...avoid these.

Here are some good places to look for drive wheels:

AndyMark, a supplier for FIRST robotics parts. Segstick use 6" AndyMark wheels with a keyed 1/2" hub.

Skyway also sells nice drive wheels in larger sizes.

Of course, you can also make a caster wheel into a drive wheel by fabricating and/or attaching a hub. Depending on your level of machining experience, this may be easier than trying to find a drive wheel exactly the size you want.

Step 6: It's Starting to Look Like A...something.

Unfortunately, you can't just stick the wheels on a shaft, put it in the drill, strap it to a stick, and go. (I wish...that was my original intention.) The drill chuck can't handle that much bending load. So, external bearings to support the rider weight are very necessary. Segstick uses mounted 1/2" ball bearings (McMaster PN: 5913K61). These are great because they can tolerate quite a bit of misalignment.

The process: Cut a piece of 3/4" plywood to the dimensions for the deck (where you put your feet), which will also hold the drills, bearings, and eventually the electronics. Then, mark out some holes for the bearings and for extra-extra-large zip ties to hold the drill in place. Hose clamps might work too. Then, drilled all those holes.

Pro Tip: If you leave one drill unmodified until the very end, you can use it to make everything else. ;)

The bearings are attached with 1/4-20 bolts. In this case, they require 1/2" spacers to match the height of the drill. While fastening everything down, it's useful to put the drive shaft into the bearing and drill chuck, and possibly even to have the drill motor running. This ensures good alignment as things are zip-tied/screwed/bolted/what have you. 

When everything is ready to go, the wheels go on with locking collars on either side to constrain them axially. Don't forget the key! And don't forget to tighten the chuck...a lot!

Step 7: And Now, the Hard Part.

Anyone can strap wheels to a stick, right? The magic behind a self-balancing thing is in the electronics. The controller must read in accelerometer and gyro data, calculate the angle of the stick, and command the motors to take corrective action, keeping the rider upright. This process of sensing a physical variable (angle), making a decision, and executing a corrective action that will affect that variable is called feedback control

Usually, the controller is some kind of microprocessor. In some rare cases, one might be compelled for unknown reasons to do it entirely with analog circuitry. Segstick instead uses a more conventional digital controller implemented on everybody's favorite: the Arduino. Specifically, it uses the Arduino Nano 3.0 from Gravitech. But any Arduino will do.

For sensing, Segstick uses the Sparkfun Razor 6DOF IMU. Really, you only need one accelerometer axis and one gyro axis, as will be discussed in the next step, but this package is so convenient and allows you to mount the board any way you want. Since it uses all 3.3V sensors, it will need to be powered from the Arduino's 3.3V output. Each sensor outputs an analog voltage which is read in by the Arduino's analog to digital converter (ADC). More on that in the next step.

For controlling the motors, Segstick uses two Polulu High-Power 18v25 motor drivers. These are tiny but powerful reversible motor controllers capable of providing up to 25A each.  I decided to add a heat sink to them, but they seem to run cool enough without it. They do require large-gauge wiring to the battery and to the drill motor leads.

The circuit schematic is shown below. How you implement it (breadboard, protoboard, printed circuit board) is up to you. I did it on a vector board that I later cut to size. Soldered connections will generally be more reliable than breadboard-type connections on a moving vehicle, so I'd recommend using sockets for the components but directly soldering wired connections.

Step 8: Software Overview.

The Segstick's software is written in C for the Arduino. The full software is attached below as a text file. It's only about 120 lines of code, aided somewhat by the convenient Arduino libraries. The code is commented, but for the next few steps I'll go through the important parts of the control algorithm, since this is where the magic happens.

The feedback controller really has two critical components: a digital filter that merges signals from the accelerometer and the gyro into a reliable angle estimate, and a proportional-derivative (PD) control algorithm that determines the corrective action to create by outputting voltage to the motors. These two components are the key to making a good self-balancing platform.

Other less glamorous but also important ancillary functions are signal input and scaling, steering, PWM generation, output limiting, and debugging. I'll briefly mention these, too, in the next few steps.

Step 9: Two Sensors, One Angle.

Another common self-balancing question: Does it use an accelerometer? Or a gyro?

Answer: Both.

The reason for using two sensors even though there is only one relevant physical variable (angle) is because each type of sensor has advantages and disadvantages by itself. By mixing the best parts of each together, a better overall estimate of the angle is achieved. I wrote this all up in this white paper, but here I will give a brief summary.

The Accelerometer.
It measures acceleration, right? Well, not really. It measure force per unit mass. So it will measure the force due to gravity as if it were an actual acceleration. The sensitivity for the Sparkfun Razor IMU is given as 300mV/g, meaning the output will change by 0.3V per 9.8m/s^2 of acceleration.

How is this converted into an angle? Well imagine using the accelerometer axis that is pointed in the direction of travel of the vehicle. As the vehicle pitches forward, the axis sees positive force due to gravity. As the vehicle pitches backwards, it sees negative force. It's tempting to say that the gain should be 300mV/90º, since pitching 90º corresponds to 1g. However, it's the slope of the output near 0º that matters, and thanks to trigonometry this slope happens to be 300mV/rad or 300mV/57.3º. See the image below for an illustration of this.

Since the Arduino's ADC gives a 10-bit value based on a 5V reference, you can calculate the gain on the raw ADC value by:

(57.3º/0.3V)*(5V/1024LSB) = 0.932º/LSB

LSB (least significant bit) is just a way of saying one bit. This is the value by which to multiply the raw analog value to get an angle in degrees. Note that you also need to subtract the zero angle offset from the analog signal. This is best found experimentally, by holding the platform at zero angle and reading off the value.

So why not just use the accelerometer to measure the angle and be done? The problem is that the accelerometer can't tell the difference between gravity and actual acceleration. So, if the platform is perfectly level but the vehicle accelerates forwards, it will register the same as tilting backwards. Taking a long-term average, though, the only "acceleration" that remains is gravity. Unfortunately, long-term averaging is not conducive to snappy feedback control. Enter...

The Gyroscope.
More accurately it should be called an angular rate sensor, since it has little to do with an actual flywheel-based gyroscope. It reports back a signal proportional to the rate of rotation. On a balancing platform, its sensitive axis would be parallel to the axis of rotation of the wheels. The Sparkfun IMU gyros have a sensitivity of 3.33mV/º/s on the 4x channels, meaning the output changes 3.33mV for every º/s of rotation.

Since the Arduino's ADC gives a 10-bit value based on a 5V reference, you can calculate the gain on the raw ADC value by:

[(1º/s)/0.00333V]*(5V/1024LSB) = 1.466(º/s)/LSB

This is the value by which to multiply the raw analog input to get an angular velocity in degrees-per-second. Like the accelerometer, the zero offset for the gyro must be subtracted first. It can be found by holding the platform stationary and reading off the analog value.

To get from degrees-per-second to degrees, the gyro signal can be integrated. For every step in time, the gyro signal multiplied by the duration of time between steps gives an incremental change in angle. The total angle is the running sum of these increments. This causes a problem, though: If the gyro signal is not exactly zero when the platform isn't rotating (and it never will be) the integration will drift. With no absolute reference, there is no way to correct for this drift with the gyro signal alone. However, for short durations, the gyro provides a very sensitive angle estimate that is immune to noise from horizontal acceleration of the vehicle

So one sensor is great for short-term, fast-response angle estimates. The other is great for long term, drift-free absolute angle averages. Are you starting to see where this is going?...

Step 10: A Very Flattering Filter.

To combine the two sensor readings together in a way that produces the best angle estimate, a special technique called a complementary filter is used. (No, not a complimentary filter, and definitely not a Kalman filter.) The filter is really just a single line of code:

angle = A * (angle + rate * DT) + (1 - A) * (float) accel_raw * A_GAIN;

Okay, so it's a long line. You can also do it with an op-amp or two.

This filter does exactly what is necessary in this scenario: it favors the gyroscope reading for short time durations and the accelerometer average reading for long time durations. Let's break it down:

A is the factor that determines the cutoff time for trusting the gyro and filtering in the accelerometer. It's always between 0 and 1, usually close to 1. In this case, A is defined to be 0.962. This means that at every time step, 96.2% of the new angle measurement comes from the old angle measurement plus the integrated gyro measurement. The remaining 3.8% comes from the accelerometer. This slowly averages in the accelerometer over many time steps.

DT is the time in seconds between program loops, the time step. Here it is defined to be 0.020 and is set by delay(20) at the end of the loop. The code in the loop itself take much less than 20ms, so the delay dominates the time step.

rate is the gyro reading, converted to degrees per second.
accel_raw*A_GAIN is the accelerometer reading, converted to degrees. It is very important that these two be in the same unit base before adding together. (You can't add apples to oranges.)

The time constant of the filter is the duration of time at which the gyroscope reading starts to be filtered out heavily and the accelerometer reading starts to be averaged in heavily. It's actually a continuous process, but the time constant is a single measure of where the balance begins to shift. The time constant is:

tau = DT*(A)/(1-A) = 0.5s

So, for this filter, the gyro is trusted for about 0.5 seconds and the accelerometer start to average in significantly after that. This value can be tweaked by changing A.

Step 11: The Control Part of the Controller.

Maybe the rest of the software is just setup for this part: the feedback control algorithm that actually decides how to correct for leaning and keep the platform balanced. For the Segstick, I used a proportional-derivative (PD) controller, a subset of PID control.

Proportional. This is a corrective action that scales proportionally to the angle. If the stick leans forward twice as far, the corrective action is twice as great. This is like the "spring constant" of the system, applying a restoring force as the stick moves away from vertical.

Derivative. This is a corrective action that scales proportionally to the derivative of the angle, or the angular rate. If the stick is falling twice as fast, the corrective action is twice as great. This is like the "damping constant" of the system, applying a force that resists rotation in either direction.

Together, this forms a mass-spring-damper system, except with virtual springs and dampers. The relative spring constant and damping constant affect how much the system oscillates as it corrects for angular displacement. Simple, right? Here's the code:

output += angle * KP + rate * KD;

Yep, simple. output is the command to be sent to the motors. KP and KD are tweaked until it balances (or goes goes totally unstable). One subtlety here is that the output command is incremented by the value output by the PD controller. So, if the angle is held at some offset from vertical, the motor command will keep increasing. It's like adding an extra integral to the system, as shown in the block diagram below.

Usually in feedback diagrams, the feedback path has a negative sign, but it really depends on the way the motors are set up. Choosing the sign for output can either be done in software (-= instead of +=) or in hardware by just swapping the motor leads. If both wheels start moving the wrong way in response to the angle, you can flip the sign. If one wheel starts moving the wrong way, you can just swap its motor leads.

Step 12: Steering, and Other Loose Ends.

Steering is accomplished the same way it would be on a tank-drive robot: differential commands sent to the left and right motors. For example, increasing the speed of the left motor while decreasing the speed of the right motor will make it turn right. This is readily implemented based on the signal read in from the steering potentiometer.

Outputting to the motors is done by setting a pulse width modulated (PWM) signal on the motor controller inputs. In Arduino land, this is done with analogWrite(). However, the default Arduino PWM frequency is way too low for motor control, so I added some direct register manipulation to force it to be 15.625kHz. Since the controllers are reversible, I use a small forest of if statements to figure out what to put on the DIR pins and whether or not to invert the output command.

One very important part of writing good control software is managing data types. You can see in the code that I often explicitly typecast to make sure I'm getting exactly the data type I want at every step of the calculation. Nothing is worse than having your controller freak out because a variable overflowed. For that reason, I also apply limiting at each step to ensure that the variables stay within appropriate ranges. For example, analogWrite() takes an integer value between 0 and 255, so I limit the outputs to this range at every step of the calculation.

Step 13: Sticking It All Together.

The stick is screwed in place, the electronics are all wired, and everything is clipped to an 18V DeWalt battery. (I suggest testing wheels-up with a power supply first.)

Here's a quick video of the Segstick jerkily wandering around:

Step 14: Links to Better Self-balancing Things.

Also on Instructables:
Self balancing one wheeled electric skateboard - Awesome build by XenonJohn.
Easy build self balancing skateboard/robot/segway platform - also XenonJohn.
Angle measurement using gyro, accelerometer and Arduino - More complementary filter.

Some close to home:
The DIY Segway - MIT Edgerton Center Summer Engineering Workshop, 2007.
Segfault - Charles Guan's totally analog balancing scooter.
The Uno - By BPG Motors.

The original [copy]:
Building a Balancing Scooter - Trevor Blackwell.

Robot versions:
Balancing robot Wheeley - I like the technical explanation.

<p>Nice work! Thanks for sharing</p>
<p>great and thanx for share...</p>
<p>Nice one...</p>
<p>Awesome work</p>
<p>Great One</p>
Great project
<p>Awesome job.</p>
<p>Wow...Its really awesome</p>
<p>Qu&eacute; buena idea! Cool!!</p>
<p>I'd love one of these around our campus.</p>
<p>Great idea</p>
<p>lovely, creative</p>
amazing.i am going follow your instructions to make one.but i know nothing about programing and electrions.so dont think my questions are simple and stupid.i really dont know.<br>1.Can i use different motor driver?<br>2.Can alter the structures of the car(eg distance between two wheels,size of standing board....)<br>if these changes will effect the program to run smoothly?<br>thanks
answer, please! what is the function of steering pot? How it affects on the controlling of ballancing robot?
The steering pot applies a differential command to the motors, after all the balancing calculations. It adds some amount to one motor and subtracts some amount from the other motor, which causes the platform to turn. The amount it adds and subtracts is set by the steering gain, KS.
<p>Just a note to let you know I have added this to the collection: Cordless Drills Hacking for Other Uses !</p><p>&gt;&gt; <a href="https://www.instructables.com/id/Cordless-Drills-Hacking-for-Other-Uses/" rel="nofollow">https://www.instructables.com/id/Cordless-Drills-Hacking-for-Other-Uses/</a></p><p>Take a look at a bunch of project involving odd uses of drills.</p><p>and for even more drill info</p><p>&gt;&gt; <a href="https://www.instructables.com/id/Cordless-Drills-A-Collection-of-Collections/" rel="nofollow">https://www.instructables.com/id/Cordless-Drills-A-Collection-of-Collections/</a></p>
<p>Regarding Step 10,</p><p>I've seen accelerometers with specs that say 'capable of measuring accelerations with output data rates from 1 Hz to 10 kHz'.</p><p>If the motion will be under 10khz, do you think a gyro is still needed? Or will the readings be so noisy that even when operating under 10khz, the accelerometer data will still need to be filtered with gyro data?</p>
<p>awesome stuff.. thank you</p>
<p>great stuff</p>
<p>You Sir, are a legend.</p>
<p>sure thing</p>
<p>awesome stuff.. cheers</p>
<p>This Segstick really very good?</p><p>I want it too...))</p>
<p>I understand that the point of this build is the balancing part... but I'm interested in everything but that part. </p><p>My son has muscular dystrophy and is in a wheelchair full time. Visiting other peoples houses can be tough because the wheelchair is so big and heavy. I've been looking for a solution for a smaller footprint chair to bring into a home and I think this is it.</p><p>I'd keep the platform/drill/wheels, but skip the stick part and replace that with a joystick. Seems to me like it shouldn't be hard to have a joystick as input and have the arduino calculate the values for the motor drivers. (Not that I have any idea how to do it -- but it seems a lot simpler than making it self-balancing)</p><p>Here's an idea of the chair that I would mount the platform on...</p><p><a href="http://jenmadeit.com/2014/02/14/scooter-to-chair-upgrade/" rel="nofollow">http://jenmadeit.com/2014/02/14/scooter-to-chair-upgrade/</a></p><p>Do you think this is a possibility? I have no soldering or electrical experience. What are the odds that you could help me build it???</p>
Wow this is crazy! I could never build this, but my husband is really handy, so I might have to get him to take a look.
Can you please tell me where I can find the schematic for the controller board. Machine Science is asking for BOM + schematic + CPL. I could not find those. <br> <br>Thanks <br>-r
The controller on this project is different from the one on the &quot;DIY Segway&quot; project, which was based on a Machine Science board. This one is simply and Arduino Nano (manufactured by Gravitech, sold by many distributors) connected to sensors as in Step 7. Unfortunately, it seems that Sparkfun has discontinued the 6DOF Razor IMU in favor of newer, cheaper digital versions. I haven't converted this project over to digital sensors yet, so you'd have to adapt it on your own. <br> <br>Hope that helps!
Thanks Scolton for your reply. Do you think using the newer sensor to be a challenge? I ask this since I have no experience what so ever working with electronic boards and sensors. Was the older sensor an analog one? And does the new one still connect to the same ports as the older one?
How did you calculate the angle from the accelerometer? none of my values from several different methods seem to work very well, or line up with the angle from the gyro.
Steps 9 and 10 have all the details for how the accelerometer and gyro are merged together to create an angle estimate. I also have it in Steps 14 and 15 of my PCB Quadrotor instructable for a different IMU. <br> <br>For the accelerometer, I use a small-angle approximation that says sin(theta) ~ theta, in radians. This is good to within 5% between -30&Acirc;&ordm; and 30&Acirc;&ordm;. So, to get the angle you need to subtract a &quot;zero&quot; value and then scale by the correct constant. <br> <br>If you need to work outside of -30&Acirc;&ordm; to 30&Acirc;&ordm;, the most common method is to take the arctan of two accelerometer axes.
hi scolton.<br>here i got 2 18x25 pololu motor driver but the pins are<br>TIXN<br>ERR<br>RST<br>TX<br>RX<br>VIN<br>GND<br><br>instead of<br>V+<br>5V<br>FF2<br>FF1<br>RESET<br>PWM<br>DIR<br>as shown in your 18x25 motor driver<br><br>so plz tell me what r the PWM &amp; DIR pin in my motor driver.<br>
Seems like you got the 18v25 Motor Controller instead of the 18v25 Motor Driver. Pololu separates &quot;drivers&quot; which have no on-board logic from &quot;controllers&quot; which have an on-board microcontroller. Drivers take a PWM and direction input and directly send it to the motor. Controllers need a different kind of interface. <br> <br>On the controller, you should be able to use the RC interface (pins labeled RC1 and RC2) and the Arduino servo library to command the motors.
Where did you get the heat sinks for the Polulu High-Power 18v25 motor drivers and how did you attach them? <br> <br>A picture would be nice... <br> <br>thanks
They came from a scrap bin, but any old heat sink should work. A processor heat sink might be the right size (but overkill).<br><br>To attach, I used screws from the board into the heat sink. I put a couple of layers of Kapton tape between the board and the sink to insulate it.
Thanks Shane-<br><br>after a little bit of thought, I am thinking of taking the fan off an old PC CPU heat-sink and just suspending it with 4 standoffs above both Pololu controllers but without a heat sink or mechanical contact point. This should be better than nothing I hope...
Another question for you: <br> <br>Your schematic shows A0 - A5 of the arduino connected to the Razor 6D0F but your code only uses A0 for the accelerometer input and A4 for the gyro input. <br> <br>Is it necessary to connect the other Razor 6D0F outputs (A1 - A3 &amp; A5) to the arduino and if so why? <br> <br>(I might want to use those analog inputs for other things...) <br> <br>thanks
No, it's not necessary to connect the other four IMU outputs to the Arduino. I connected them since they were convenient and because I didn't know which way I was going to mount the board. But you only need one accelerometer axis and one rate axis.
Hey Shane,<br><br>I'm working on making a small robot balance, you can see my first attempt in this blog post:<br>http://makerandomstuff.blogspot.com/2011/12/introduction-fail-way-crappy-balancing.html <br>I've tweaked the platform a bit to make things neater but I'm still having trouble balancing.<br><br>The sensors from the Wii Motion Plus (gyros) and Wii Nunchuck (accelerometers) are outputting data over I2C and I'm filtering it to get g_roll, a_roll, and a filtered angle, so I think that part's good.<br><br>When I try to have my robot balance, it either oscillates a lot, or responds too slowly. I think the problem lies in my Kp/Kd values, my motor responsiveness, or my robot's small size (or a combination of 2 or more).<br><br>Any suggestions?
Cool project! It sounds like you're running up against what I call the &quot;robot segway&quot; problem. It's the reason I said in the Instructable that I think building a robot segway is actually harder than building a full-size rideable segway. You're right that the small size makes it harder to control (faster time constant, like balancing a pencil on your finger as opposed to a broom). But there's something else even more fundamental that makes it hard:<br><br>The sensors are inertial, meaning they respond to acceleration. They can't distinguish between standing still and moving with a constant velocity. So, even when tuned properly, the robot segway can't really stand still by itself. It will either oscillate (if the gains are high) or stay near vertical but drift off in one direction until the motors can't keep up, at which point it falls over.<br><br>A human rider can sense that the segway is drifting off in one direction and correct by leaning forwards or backwards to bring it back to zero speed. To mimic this, the controller would need to know the velocity (maybe from wheel encoders) and control it to be zero. This adds extra states to the control system and makes it more complicated. I attempted an autonomous balancing robot with no encoders with moderate success here:<br><br>http://scolton.blogspot.com/2011/05/mini-segstick-my-mid-quals-crisis-robot.html<br><br>Others have definitely done it with success. There are a few links to robot segways in the last step of the Instructable. Another option is to use radio control to guide it as a human rider would, preventing it from building up too much velocity when it should be standing still. Here's an example of that solution in action:<br><br>http://machinescience.wordpress.com/2011/11/29/ps2-module-controls-two-wheeled-balancing-robot/
Drifting problems aside, I still haven't been able to get it to balance like some of the other robot segways I've seen. Staying upright for at least 30 seconds is doable, right?<br><br>I've gotten my hands on a cheap nunchuck clone so I'll be updating the sensor system soon, and maybe making things a bit more solid. <br><br>I also have some motors with quadrature encoders built in (9v LEGO NXT motors) so maybe I'll go somewhere with that. Is there any chance I could take a look at the code you used for your mini-segstick? Maybe I can integrate encoders with that strategy.
Hello Scolton,<br><br>I still can not stabilize my Segway. Also, I had a problem with my IMU and the gyro stopped working, so I had to use another one. The gyro I had at hand is an Epson XV-3500 (http://www.epson-electronics.de/upload/PresidioIndustries/product/QuartzCrystalDevices/Sensors/GyroSensor/XV-3500CB_710020500_data.pdf) whose sensitivity is 0.67 mV / deg / sec. My accelerometer is the ADXL335. I'm supplying 3.3V.<br><br>The calculation bellow is correct?<br><br>Accelerometer (ADXL-335):<br>(57.3 &deg; / 0.3V) * (5V/1024LSB) = 0.932 &deg; / LSB<br><br>Gyroscope (XV-3500):<br>[(1 / s) / 0.00067V] * (5V/1024LSB) = 7.287 (&deg; / s) / LSB (?????)<br><br>The value for the gyroscope seems very high and the Segway completly unstable.<br><br>Kind regards,<br>Marcos
Am I correctly reading the datasheet for the gyro that it has:<br><br>Sensitivity: 0.67mV/(deg/s)<br>Range: +/-100(deg/s)<br><br>and that thus the voltage range is only +/-60.7mV, full scale? <br><br>If so, this sensitivity may not be suitable for use with the Arduino's ADC (at 5V or 3.3V reference). The signal might be just too small to get useful information out of. Even the Sparkfun Razer IMU gyro is cutting it close in terms of the available resolution, given the low angular rates typical on a balancing platform. (Under normal operation, 10-20(deg/s) might be the maximum rate.)
Scolton, first of all thanks for your paper. I think everyone should read, it's really enlightening.<br><br>I think not because this project (http://diysegway.blogspot.com/) uses the same sensor and works very well (really stable). I would like to test the Trevor algoritm. The angle and the angle_rate are the tilt angle of the scooter in radians and its derivative in radians/sec. Is it the same that are in your code (rate and angle)? So, can I use the bellow code together your code? Are in same unit system?<br><br>Thanks for your help, I'm learning a lot!<br><br>balance_torque = 5.0 * (angle - rest_angle) + 0.4 * angle_rate;<br><br>overspeed = max(0, cur_speed - 0.5) ;<br>if (overspeed &gt; 0) { <br> overspeed_integral = min(0.4, overspeed_integral + min(0.2, overspeed+0.05) * dt) ;<br>} <br>else { <br> overspeed_integral = max(0, overspeed_integral - 0.04*dt);<br>} <br>rest_angle = 0.4*overspeed + 0.7*overspeed_integral;<br><br>steer_cmd = 0.07/(0.3+abs(cur_speed)) * steer_knob;<br>cur_speed += 1.2 * balance_torque * dt;<br>left_motor_pwm = balance_torque + cur_speed + steer_cmd;<br>right_motor_pwm = balance_torque + cur_speed - steer_cmd;
I have been having problems making mine stable also but just stumbled across something yesterday in another tutorial about building an arduino segway that I plan to investigate. <br> <br>In that application, they are using a sparkfun razor gyro &amp; accelerometer which is connected to the 3.3v just as it is in Scolton's instructible but what is different is they tie the 3.3v line on the arduino to the Aref pin an then use the following command in the setup section of the code: <br> <br>analogreference(EXTERNAL); <br> <br>Here is the explanation: <br>the normal range for the 10 bit ADC (pins A0-A5) is 0 - 1023, where 0vDC input yields a value of 0 and 5vDC yields a value of 1023. If you plug a 3.3v sensor into an arduino analog input, the maximum value that an arduino can read is approximately 675 or so. (3.3v / 5v *1023), to get full range using a 3.3v device, you must connect the desied reference volage (3,3v) to the analog reference pin (aref) an add a line of code to the end of the setup() function to tell the arduino to use an external analog reference voltage. <br> <br> <br>I haven't tried it yet but this might smotthen things out as mine has been vey sporatic... <br> <br>If you get a chance to try this before I do, please report back waht you find. <br> <br>thanks
What are you talking to me sounds correct, but I think it is not the solution to problems. I think I've seen most of the tutorials found on the internet and I found more stable until today was one of the first to be created: the Trevor's algoritm. He did several tests, both in high and low speed. I'm thinking of rewriting the code from it to a version compatible with the Arduino, but it will not be easy. The code it is large and somewhat complex. Would you be willing to help?<br><br>My MSN is marquinho-a [at] hotmail [dot] com, and my Gtalk is marcospassos.com [at] gmail [dot] com. You can add me and talk more to share experiences.<br><br>Kind regards,<br>Marcos
Hello Scolton,<br><br>I'm using a Sparkfun 5 DOF, OSMC controller and two 450w 24v motors (MY1018z). Although my Segway can balance itself, it can't balance a person (seems to have no force, slowly). I've noticed my Gyro (IDG-500) has <br>2 mV/&deg;/s of sensivity, so my LSB is [(1&ordm;/s)/0.002V]*(5V/1024LSB) = 2.4140625(&ordm;/s)/LSB, right? Anyway, it can't balance as well. <br><br>I also have noticed that over time the platform starts to get steep and considers it as level.<br><br>Do you have any tip?<br><br>Thanks,<br>Marcos

About This Instructable




More by scolton:PCB Quadrotor (Brushless) Seg...stick. 
Add instructable to: