Let's Make Robots!


Balance First - Hopefully




Top down of the Locked Anti-Phase board

"Doubtful" - Which is how I feel about making this thing actually balance, thus the name.

First attempt at a balancer - going with a couple downward IR sensors, gear motors, large wheels, and inverted pendulum approach. I've seen it done in a Basic Stamp so it should work in a BX24 which is what I've used most over time. I do have an Adruino board in the box but would rather stick with a language I know to get this started.

The overall concept is a locked anti-phase PWM control of geared motors using two Sharp IR sensors to read distance to ground and top vertical mounted batteries for an inverted pendulum solution.

Two 4xAAA battery packs will be mounted vertically back to back for top weight. Small home built BX24 CPU board mounted just above the PWM H-Bridge board.

This motor board is wired for locked anti-phase using an H-Bridge and a 74HC04 inverter which provides for two total pins for motor control - Left and Right. The PWM rate determines if the motor is moving forward, backward, or locked at zero. This uses more current I guess but takes away any freewheeling possibilities or motor kick in surging (hopefully at least).

Just the BASEicsMotors are some micro geared versions but they do have some gear slack which is a concern. Just a little but I'm guessing it could play havoc with keeping things balanced. Time will tell. If I find something better I'll swap them out but they are brand new "out of the bag" motors which I am not overaly happy with.

I may need to adjust the IR sensors to angle out more for better response after I get it wired up and some test code running. Hopefully not as I would like to end up with a "hood" or something that pretty much covers it all up and has some LDRs and sonar sensors in it for object avoidance.

The top button will be used to 'calibrate' or orient the code when first starting up and the on/off switch is in the middle which will switch between run and a built in charging jack like my others bots are.

I do plan on adding an output LED that ligths when the thing thinks it's balanced for debugging purposes.

I know, the long screws are UGLY - I will be replacing them with appropriate ones when I can find some that will fit right.

Overall this should be a challenge and we'll see how it goes. Long term I do not want something that just stands there balancing so getting it to move will be the next step IF if ever actually does balance.

Worst case if I can never get it to balance I'll add a tail wheel and have a tall skinny robot to run around. :-)



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

awesome robot! never thought it was possible without those gyros/acclerometers/compass things. i think making those sharp IRs angle out more will surely help stabilize it but anyways it is still much stable :p

Looking forward to any progress :)

Yes you are correct, I moved the code and concept over to this (http://letsmakerobots.com/node/34945) for now until I have a better motor set for Doubtful but it does provide better resolution/response angeled out.There is a sweet point - too much angle and you get a very non linear output which is made even worse by the nonlinear output of the sharp sensor. Honestly I think it will take a basic gyro/accel set to make it work. Been reading and researching and finally beginning to understand how to possibly go that direction with a complementary filter setup. Leaning a lot at least, will have to see if I can apply any of it. Stephen

Hey man, I had not given due attention to this project yet. But today I give it a good look and I see this is very interesting project. And your construction is also very good. I'll keep an eye in this project.

Nice! Keep at it.

Posted a video of the first attempts at balancing Doubtful.

PID tuning seems to be close but I think the motors may not have enough torque to drive it. Thinking of getting some smaller wheels/tires first and then replacing motors with something stronger if needed. Nothing near to useable yet but first evening's attempt.

Video is using single sensor pointing straight down. Also thought about angling the sensor out some to get more resolution but that doesn't really seem to be the issue right now.

Opinions? Ideas?




No doubts that you Stephen can do it. Looks good already.
Thanks for the support. Maybe so, I actually wrote the code yesterday but no way to test or tune yet. Waiting for some crimp pins, connectors and hoods to arrive to finish up the wiring and then it's off to giving it a go. Stephen

Standby then.

But Stephen, how do you approach the pendulum problem? Do you use some kind of PID controller?

Yes - it will have to have basic PD or PID controls to work... below is the raw code before testing. Compiles but haven't loaded and run. This sub will run as a multi-tasking item to keep balance. I hope to be able to adjust the LeftSpeed/RightSpeed global variables in the main loop code to provide for motion. Those are basically an offset to the balance point. Of course this is all on paper.. err.. screen for now. Will be interesting how it works out. I was going to start with P and then add in I or D as needed. I believe I am going to have to use single variables as well to get some workable numbers somewhere in there for scaling.

Any of it make sense? Anyone have better suggestions?

Edit: This is all code from around the web for the most part...


'** Main balancing loop - runs multi-tasking to keep things running right

'** Should be able to adjust the LeftSpeed, RightSpeed variables to get motion
Sub	Balance()
	'*** P(ID) variables
	Dim P			As Integer	'** Calc Prop value
	Dim I			As Integer	'** Calc Int value
	Dim D			As Integer	'** Calc Der value
	Dim MyError		As Integer	'** Working error
	Dim Kp			As Integer	'** Prop multiplier
	Dim Ki			As Integer	'** Int multiplier - If used, 0 if now
	Dim Kd			As Integer	'*** If used
	Dim FrontReading	As Integer
	Dim RearReading	As Integer
	Dim ErrorSum		As Integer
	Dim ErrorLast		As Integer
	Dim ErrorCurrent	As Integer
	Dim ErrorSecondToLast As Integer
	Dim ErrorDelta	As Integer
	Dim Drive			As Integer
	Dim LeftMotor		As Integer
	Dim RightMotor	As Integer
	Const LEDOutput	As Byte=6

	'** PID Constants
	Kp 	= 1
	Ki 	= 0		'** Adjust to 0 for no effect
	Kd 	= 0		'** Adjust to 0 for no effect

 '** Multitaksing loop	
		FrontReading = GetADC(FrontIR)		'** Get current front distance reading
	'**	RearReading = GetADC(RearIR)		
	'** We COULD use the front / rear comparison to see if we have an edge
	'** I.e. we have a growing front distance but back is fine THEN we have an
	'** edge drop off or something else is wrong such as a ramp DOWN
	'** vice verses as well if growing back distance but front is fine something up behind?
	MyError = MyFrontSetPoint - FrontReading	'** Get error value - only looking at FRONT
	'** Do we need to validate, normalize or compare front/rear readings here?
	'** Do we need to do  series AVERAGE reading here or will ID of PID handle spikes?
	'** Calc P)orportional error
		P = Kp * MyError
	'** Calc I)ntegral
	   	ErrorSum = ErrorCurrent + ErrorLast + ErrorSecondToLast
	   	I = Ki * ErrorSum
	   	'** Calc D)erivitative 
		ErrorDelta = ErrorCurrent - ErrorLast
	  	D = Kd * ErrorDelta
	'** Total up the Drive needed
		Drive = P + D + I

		'** Light up the LED *IF* we are within the balance limit
		'** Balance limit is just a number - need to adjust until it works best
		If ABS(Drive) < 100 Then
			Call PutPin(LEDOutput, bxOutputHigh)
			Call PutPin(LEDOutput, bxOutputLow)
		End If
		'** Save errors for I and D future calcs
		ErrorSecondToLast 	= ErrorLast
	   	ErrorLast 		= ErrorCurrent
		LeftMotor = Drive + (LeftSpeed + 128)
		If LeftMotor < -128 then 
			LeftMotor = -128
		End If
		If RightMotor > 128 then 
			RightMotor = 128
		End If
		RightMotor = Drive + (RightSpeed + 128)
		If RightMotor < -128 then 
			RightMotor = -128
		End If
		If RightMotor > 128 then 
			RightMotor = 128
		End If
		'** Do NOT drive motors during calibration time period
		'** We are checking this var which should be faster than re-reading GetPIN()
		'** I would think do at least - trying to make multi-tasking loop as clean as possible
		If NOT CalibrateON Then
			Call DriveMotors(LeftMotor, RIghtMotor)
		End If
End Sub