 |
|
 |
| Parallax Forums > Public Forums > Completed Projects > Balancing Robot Using Ping | Forum Quick Jump
|
|  JohnBF Registered Member
        Date Joined Dec 2006 Total Posts : 101 | Posted 1/1/2007 10:10 AM (GMT -7) |   | |
My goal is to build a balancing robot that can roam and avoid obstacles. As a first step I built a simpler robot that can balance in place or move slowly forward or backward over a level surface.
I posted a video at http://www.youtube.com/watch?v=L6SGsV9uHfs
I used mostly components from my last Boe-Bot project: Parallax continuous rotation servos, a BOE development board with a BS2sx chip and Ping to measure tilt angle. The balance point can be moved slightly fore or aft with on-board buttons to choose stationary or slowly moving behavior and to fine tune for different environments. The chassis is made from Radio Shack perf board. For power I’m using five Ni-CDs, whose low internal resistance provides quicker surges as the servos constantly start, stop, and change direction. The only non-Parallax working parts are 3” model airplane wheels.
I chose the Ping as tilt sensor after tests showed it to be the most accurate of the sensors I had on hand from previous projects. I collected data by running the robot with the serial cable attached, holding the cable to minimize it's affect on balance. Not elegant, but it worked.
The closed feedback loop is based on Andy Lindsay’s wonderfully clear explanation of how to implement a PID loop on a Basic Stamp. For this application I found that for the integral term, rather than maintaining a running total, I got better results with a leaky accumulator which remembers only the previous two errors.
I’m eager to start a more sophisticated balancing robot and I’d appreciate any ideas or advice:
I’d like to go with a gyro/accelerometer combination. I already have a Memsic 2125. What’s the best choice for gyro? Perhaps the ADXRS300 on a breakout board from SparkFun.com? Does anyone have ideas or leads on information about algorithms to utilize these sensors on a Basic Stamp or SX chip (preferably in SX/B)?
I’d like to use DC motors. Any suggestions on motors that have a little more torque, a little more speed, and a little less latency than hobby servos?
Thanks!
Below is the latest version of the pBasic code.
/John
' {$STAMP BS2sx}
' {$PBASIC 2.5}
'
' Balancer.BS2X. A simple two wheel balancing robot using a
' Ping))) sensor for tilt angle.
'
' John Fisher, January 2007
'
' -----[ I/O DEFINITIONS ]---------------------------------------
buttonBottom PIN 10
buttonTop PIN 11
rwheel PIN 12
lwheel PIN 13
ping PIN 14
speaker PIN 15
' -----[ CONSTANTS/PARAMETERS ]----------------------------------
' PID contstnts:
Kp CON 2
Ki CON 2
Kd CON 4
'Meaningful names for error array index:
Current CON 0
Sum CON 1
Last CON 2
SecondtoLast CON 3
Delta CON 4
' -----[ VARIABLES ]--------------------------------------------
pTime VAR Word ' raw value from Ping)))
drive VAR Word ' value sent to Motors
error VAR Word(5)
p VAR Word ' proportional term
i VAR Word ' integral term
d VAR Word ' derivative term
SetPoint VAR Word
counter VAR Nib
' -----[ INITIALIZATION ]----------------------------------------
Reset:
GOSUB ProgramStartSound
SetPoint = 540
' -----[PROGRAM CODE ]-------------------------------------------
Main:
IF buttonTop = 1 THEN
SetPoint = SetPoint + 1
FREQOUT speaker, 12, 1350 ' confirm button push
PAUSE 175
ENDIF
IF buttonBottom = 1 THEN
SetPoint = SetPoint - 1
FREQOUT speaker, 12, 1250 ' confirm button push
PAUSE 175
ENDIF
DO
PULSOUT ping, 12
PULSIN ping, 1, pTime
IF (pTime<425)OR(pTime>625)THEN GOTO Main 'Shut down motors
'if beyond recoverable
'tilt angle.
error(current) = setPoint - pTime
p = error * Kp
error(Sum)=error(Current)+error(Last)+error(SecondtoLast)
i = Ki * error(Sum)
error(Delta) = error(Current) - error(Last)
d = Kd * error(Delta)
drive = p + d + i
GOSUB Motors
error(SecondtoLast) = error(Last)
error(Last) = error(Current)
' Code to send runtime data to debug goes here. The
' Parallax oscilloscope was used to check the actual
' time between motor pulses so the pause in the motor routine
' could be adjusted to stay close to 20 ms. The main value
' of using the BS2sx was that the BS2 was not fast enough
' to read the sensor, calculate the motor input, send
' data to debug, and get back to the motors within 20 ms.
LOOP
END
' -----[ SUBROUTINES ]-------------------------------------------
ProgramStartSound:
FOR counter = 4 TO 1
FREQOUT speaker, 30, (1320) - (counter * 36)
PAUSE 100
NEXT
RETURN
Motors:
PULSOUT lwheel, (1871 + drive) MIN 1625 MAX 2111
PULSOUT rWheel, (1875 - drive) MIN 1625 MAX 2125
PAUSE 3
RETURN
| | Back to Top | | |
 |  Forrest Registered Member
        Date Joined Aug 2004 Total Posts : 1289 | Posted 1/1/2007 10:54 AM (GMT -7) |   | | That's very impressive. I would not have thought the Ping))) was accurate and responded fast enough to accomplish this feat. It's amazing you were able to accomplish a balancing rebot with such few components. | | Back to Top | | |
     |  JohnBF Registered Member
        Date Joined Dec 2006 Total Posts : 101 | Posted 1/2/2007 11:26 AM (GMT -7) |   | Thanks, Thanos. I did look at your excellent project and it helped give me confidence to try one of my own. I will definitely try an RF solution to robot-world communcations.
Beau, I haven't tried jingling keys, but the Ping is definitely sensitive to ambient noise that gets into the ultrasonic range, maybe from harmonics. Forget Kalman filtiers - we need jingle filters for the Ping!
/John | | Back to Top | | |
   |  Steve Joblin Registered Member

       Date Joined Dec 2004 Total Posts : 794 | Posted 1/6/2007 6:30 AM (GMT -7) |   | | Very cool! quick physics question... I assume you want to move the batteries up a few inches so that the center of mass is moved up... why? Isn't something that has it's center of mass lower to the ground usually considered to be more stable (thinking about SUV's vs sports cars flipping over, or how it is easier for a child to learn to ski than an adult because they are lower to the ground and inherintly more stable)? | | Back to Top | | |
  |  Steve Joblin Registered Member

       Date Joined Dec 2004 Total Posts : 794 | Posted 1/6/2007 6:38 PM (GMT -7) |   | | Thanks Zoot... amazing how when you get a picture in your head it all makes sense! | | Back to Top | | |
 |  JohnBF Registered Member
        Date Joined Dec 2006 Total Posts : 101 | Posted 1/6/2007 8:44 PM (GMT -7) |   | I'm not sure of the physics of this, but observing my bot suggests that raising the center of gravity and also distributing the weight further fore and aft both add stability within a recoverable range of tilt angles, but the trade-off is that they narrow the revoverable range of tilt angles. I think that both of the above changes add rotational inertia which resist disturbances, but once they get moving they make it harder for a given drive train to overcome before falling.
Larger wheels definitely help the bot to balance, but I'm not sure why. Maybe it's just that the larger wheels give the small servos more speed along the ground. Seems like more than that, but I don't know what.
Another question I can't get my arms around is this: when the motor makes the drive shaft and wheels turn, how does that effect the rest of the robot? I can't figure out whether a wheel turning clockwise generates a clockwise or counterclockwise force to the chassis. And are the two wheels generating the same force to the chassis, or opposite forces? In each configuration of my bot I found an unexpected turning tendency. Maybe this is because of the opposite rotation of the two wheels.
Sure wish I had paid more attention when I took physics in college.
/John | | Back to Top | | |
 |  Zoot [ robots ]

       Date Joined Apr 2006 Total Posts : 1716 | Posted 1/7/2007 10:02 AM (GMT -7) |   | Somebody said... I'm not sure of the physics of this, but observing my bot suggests that raising the center of gravity and also distributing the weight further fore and aft both add stability within a recoverable range of tilt angles,
I think the fore and aft distribution will work against you unless the weight is brought down near the ground (like an inverted "U" braced across the top of your 'bot with weights at the bottom of the descenders). You will also have considerable inertia with that kind of setup (meaning more power & time to effect a result).
The larger wheels help mostly to give you greater speed in a shorter time -- i.e., faster corrections. There will be a inverse trade-off in power, of course. It is also possible that getting the pivot point of your balance a bit higher above the wheel's contact with the ground helps, but like you, my physics suffers at that point.
Your tendency to turn may be slight mismatches in servo speeds -- send the same pulse to both servos and you probably won't get exactly the same speed on either one. You might want to set up manual neutral/max/PID constants for EACH wheel to get them tuned (in the absence of real-world encoders, that is).
Have you seen the Bal-bot site? They have a very tall balancing 'bot with the battery weight way, way up high. Very large wheels, too, relative to the size of the 'bot.
www.balbots.com/product_info.php?cPath=21&products_id=28
I guess they had a fire and are not shipping product anymore, which is too bad. When the going gets weird, the weird turn pro. -- HST | | Back to Top | | |
 |  lboucher Registered Member
        Date Joined Jan 2007 Total Posts : 137 | Posted 1/7/2007 9:16 PM (GMT -7) |   | From what I have figured out about the physics of this.
The higher the center of mass is, the greater the damping effect on the whole system. THis is good because as can be seen in the video the servos are jerking around alot and causeing it to overshoot back and forth. So if I move the batteries higher it will not overshoot so bad and become more stable.
The other trade of is between height and the max speed of the servos. The servos have enough torque to do the job but top speed is an issue. Basicly there is a direct relationship between max motor speed and recoverable tilt angle. If I move the center of mass I restrict the recoveable angle for a given maximum motor speed.
This means the higher the center of mass the more important it is to have a very precise measure of tilt angle to drive the motors with. The way I have the bot set up right now the ping is very close to the center of the body and at an angle. I need to get rid of the angle and have it point straigt down when balanced so that the change in ping time will be equal in either tilt direction. And i need to move it out from the bode a few inches to get the additional precision needed to move the Center of mass uppward effectively.
Also anyone ever heard of the Grand Challenge. I was on the VA Tech Team. | | Back to Top | | |
 |  lboucher Registered Member
        Date Joined Jan 2007 Total Posts : 137 | Posted 1/13/2007 5:34 PM (GMT -7) |   | | | |
 |  JohnBF Registered Member
        Date Joined Dec 2006 Total Posts : 101 | Posted 1/15/2007 1:59 PM (GMT -7) |   | Looks great! I guess part of the lesson here is that short of much more sophisticated arrangements, Ping))) is a pretty good sensor for a balancing robot. And very convenient -- the Parallax mounting bracket places it just the right distance forward.
Since the whole thing can be done with Parallax parts, maybe this could be a Boe-Bot/Ping))) AppNote. It's a really fun project and a surprising and impressive accomplishment for this collection of parts.
/John | | Back to Top | | |
    |  Whit Registered Member

       Date Joined Mar 2007 Total Posts : 1580 | Posted 6/5/2007 9:48 PM (GMT -7) |   |
JohnBF said...
Since the whole thing can be done with Parallax parts, maybe this could be a Boe-Bot/Ping))) AppNote. It's a really fun project and a surprising and impressive accomplishment for this collection of parts.
/John
I agree. lboucher's BOE Bot version is pretty cool - and I think I already have all the parts! Hey lboucher, how about some pictures of the configuration of your balancing bot?
Whit+
"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths." - Walt Disney
Post Edited (Whit) : 6/6/2007 4:55:08 AM GMT | | Back to Top | | |
 |  markward Registered Member
        Date Joined Dec 2007 Total Posts : 7 | Posted 1/6/2008 8:15 AM (GMT -7) |   | | This is great stuff. I'm interested in trying this with a BS2, memsic 2125, and ir bumpers and pretty much a stock boebot. Looking for it to roam. Stumbling blocks? | | Back to Top | | |
 |  markward Registered Member
        Date Joined Dec 2007 Total Posts : 7 | Posted 1/29/2008 9:45 PM (GMT -7) |   | Man... this was a really enjoyable project. Code, picture and video attached. Not a whole lot new here, the design is pretty simplistic and v. similar to others. Code pasted below is courtesy of Andy Lindsey's many PID discussions and only slightly modified. Able to take advantage of his fractional multiplication to really fine tune the PID. All I can say is that industrial strength velcro and a glue gun are a prototypers best friend. One thing of note - I managed to get away with using only a BS2. You'll see a steel rod glued to the "chassis" (really just a sheet of reinforced perf board). Really helped to move the center of mass up and slow down oscillations. It's all about tuning the PID. One thing I noticed is that you have to balance the tuning of the PID just up to saturation of the servos, then pull it back a bit - seemed to be the sweet spot. Also, keep in mind that with this PID algorithm, the coefficients are proportional to the resolution AND output values of your sensor. In the end I needed to cheat with a wall power supply cuz my alkalines were just not cutting it.
Future enhancements: I'm going to see if I can squeeze in a logging function to pull data from the PID to demonstrate exactly how it controls the balance point. Tried it real time with my eb500, but no joy due to lag on servos. Thanks to all those who inspired me to experiment.
Somebody give me a problem, cuz I'm itching to experiment...
Video is here: http://www.youtube.com/watch?v=iZPiLQMy_2o
' BalancingBotUsingpiD.BS2 ' {$PORT COM1} ' {$STAMP BS2} ' {$PBASIC 2.5}
'------ [ Constants ]---------------------------------------------------------- SetPoint CON 130 ' Set point Kp CON $03A0 ' proportional constantc Ki CON $01A0 ' integral constants Kd CON $0100 ' derivative constants
Current CON 0 ' Array index - current error Accumulator CON 1 ' Array index - accumulated error Previous CON 2 ' Array index - previous error Delta CON 3 ' Array index - change in error ServoCenter CON 750 ' Servo not moving IntErrorOffset CON 100 IntErrorMax CON 200 IntErrorMin CON 0
'------ [ Variables ]----------------------------------------------------------
pTime VAR Word error VAR Word(4) ' Four different types of errors pulseLeft VAR Word ' Output pulseRight VAR Word signA VAR Bit signB VAR Bit A VAR Word B VAR Word counter VAR Byte p VAR Word i VAR Word d VAR Word
'------ [ Pins ]---------------------------------------------------------- Ping PIN 14 Left PIN 12 Right PIN 13 log DATA @0
'------ [ Initialization ]----------------------------------------------------- DEBUG CLS SEROUT 1,84,["LABEL,TIME, Dist,P, I, D, Pulsleft, PulseRight",CR] main: DEBUG ?ptime FOR counter = 0 TO 4 error(counter) = 0 NEXT DO LOOP UNTIL IN8=1 DO WHILE IN8=1 GOSUB Get_Ping_Distances IF (ptime = setpoint) THEN GOTO Start LOOP '------[ Main loop ]----------------------------------------------------------- start: IN8=0 FREQOUT 2,2500,2000 DO GOSUB Get_Ping_Distances 'SEROUT 1,84,["DATA,TIME,",SDEC ptime,",",SDEC p,",",SDEC i,",",SDEC d,",",SDEC p+i+d,",",SDEC error,CR] IF (pTime < setPoint - 90) OR (pTime > setPoint + 90) THEN GOTO main GOSUB Calc_Drive GOSUB Send_Pulse 'WRITE log+counter, ptime 'counter = counter+1 LOOP
'------[ Calculate Drive ]-----------------------------------------------------
Calc_Drive: GOSUB ErrorCalc ' Error Calcs GOSUB PropCalc ' Perform proportional error calcs\ GOSUB IntCalc ' Perform Integral Calcs GOSUB DerivCalc ' Perform Derivative calcs RETURN
'------[ Calculate Error ]------------------------------------
ErrorCalc: error(Current) = SetPoint - pTime RETURN
'------[ Proportional Drive - Sign adjusted ]----------------------------------
PropCalc: A = error(Current) B = Kp GOSUB Fractional_Multiply pulseLeft = pulseLeft + A pulseRight= pulseRight - A 'p=A RETURN
'------[ Integral Drive - Sign Adjusted ]--------------------------------------
IntCalc: error(Accumulator) = error(Accumulator) + error(Current) error(Accumulator) = error(Accumulator) + IntErrorOffset MAX IntErrorMax MIN IntErrorMin - IntErrorOffset A = error(Accumulator) B = Ki GOSUB Fractional_Multiply pulseLeft = pulseLeft + A pulseRight= pulseRight - A 'i=A RETURN
'------[ Derivative Drive ]----------------------------------------------------
DerivCalc:
error(Delta) = error(Current) - error(Previous) A = error(Delta) B = Kd GOSUB Fractional_Multiply pulseLeft = pulseLeft + A pulseRight = pulseRight - A error(Previous) = error(Current) 'd=A RETURN
' -----[ Subroutine - Get_IR_Distances ]--------------------------------------
Get_Ping_Distances: PULSOUT PING, 5 PULSIN PING, 1, pTime IF pTime = 0 THEN GOTO Get_Ping_Distances DEBUG HOME, CLS,?ptime RETURN
' -----[ Subroutine - Send_Pulse ]---------------------------------------------
Send_Pulse: PULSOUT Left, 750 + pulseRight MIN 650 MAX 850 PULSOUT Right, 749 + pulseleft MIN 649 MAX 849 pulseLeft = 0 pulseRight = 0 RETURN
' -----[ Subroutine - Fractional_Multiply ]------------------------------------
Fractional_Multiply: signA = A.BIT15 signB = B.BIT15 A = ABS(A) */ ABS(B) IF signA ^ signB THEN A = -A
RETURN
Image Attachment :
 IMG_2485.jpg 1.70Mb (image/jpeg)This image has been viewed 451 time(s). | | | |
| | Back to Top | | |
   | 29 posts in this thread. Viewing Page : 1 2 | | Forum Information | Currently it is Thursday, July 29, 2010 5:19 PM (GMT -7) There are a total of 462,440 posts in 62,066 threads. In the last 3 days there were 90 new threads and 802 reply posts. View Active Threads
| | Who's Online | This forum has 20143 registered members. Please welcome our newest member, ME01. 59 Guest(s), 12 Registered Member(s) are currently online. Details John Abshier, Rayman, Kevin Wood, BradC, Julian800, prof_braino, Harley, Sapieha, Gene Bonin, wiresalot, localroger, Nick McClick |
Forum powered by dotNetBB v2.42EC SP2.02 dotNetBB © 2000-2010 |
|
|