BoeBot using PID
Bot Learner
Posts: 9
Hi all.
I'm new to this stuff and I'm working with the Boe-Bot Robotics kit. I finished the exercises in the book and noticed the jittering with the·programs in chapters 7 & 8 for following another boe bot. I read the Better Boe-Bot IR Distance Measurements paper by Andy and incorporated the new hardware design and software. Still quite a lot of jitter, so I read the PID Control Intro with the Basic Stamp. I've tried to incorporate PID in the software using the new circuit, but I'm running out of variable space. Not being a math wizard, I may be doing more than necessary. Here's the code:
' BoeBotFollowingWithPidAlgorithm.bs2
' Demonstrates how a combination of proportional, integral, and
' derivative control influence error correction in a feedback loop.
·
' {$STAMP BS2}
' {$PBASIC 2.5}
·
'
[noparse][[/noparse] Constants ]
·
SetPoint······· CON···· 2···················· ' Set point
Kpl·············· CON···· -15·················' L & R proportionality constants
Kpr············· CON···· 15
Kil·········· ···· CON···· -15··················' L & R integral constants
Kir·············· CON···· 15
Kdl············· CON···· -15··················' L & R derivative constants
Kdr············· CON···· 15
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
Offset··········· CON···· 750·················' Servo not moving
·
'
[noparse][[/noparse] Variables ]
·
irDetectLeft··· VAR···· Bit
irDetectRight· VAR···· Bit
distanceLeft·· VAR···· Nib
distanceRight· VAR···· Nib
errorLeft······· VAR···· Word(4)·············' Four different types of errors
errorRight····· VAR···· Word(4)
p·················· VAR···· Word··················' Proportional term
i··················· VAR···· Word··················' Integral term
d·················· VAR···· Word················· ' Derivative term
pulseLeft······ VAR···· Word················· ' Output
pulseRight·····VAR· ···Word
·
'
[noparse][[/noparse] Initialization ]
·
FREQOUT 1, 1000, 3000
·
'
[noparse][[/noparse] Main Routine ]
·
DO
·
· GOSUB Get_IR_Distances
·
· ' Calculate error.
· errorLeft(Current) = SetPoint - distanceLeft
· errorRight(Current) = SetPoint - distanceRight
·
· ' Calculate left proportional term.
· p = Kpl * errorLeft(Current)
·
· ' Calculate left integral term.
· errorLeft(Accumulator) = errorLeft(Accumulator) + errorLeft(Current)
· i = Kil * errorLeft(Accumulator)
·
· ' Calculate left derivative term.
· errorLeft(Delta) = errorLeft(Current) - errorLeft(Previous)
· d = Kdl * errorLeft(Delta)
·
· ' Calculate left output.
· pulseLeft =· p + i + d + Offset MIN 650 MAX 850
·
· ' Calculate right proportional term.
· p = Kpr * errorRight(Current)
·
· ' Calculate right integral term.
· errorRight(Accumulator) = errorRight(Accumulator) + errorRight(Current)
· i = Kir * errorRight(Accumulator)
·
· ' Calculate right derivative term.
· errorRight(Delta) = errorRight(Current) - errorRight(Previous)
· d = Kdr * errorRight(Delta)
·
· ' Calculate right output.
· pulseRight = p + i + d + Offset MIN 650 MAX 850
·
· ' Save current error to previous error before next iteration.
· errorLeft(Previous) = errorLeft(Current)
· errorRight(Previous) = errorRight(Current)
·
· GOSUB Send_Pulse
·
LOOP
·
'
[noparse][[/noparse] Subroutine - Get_IR_Distances ]
·
Get_IR_Distances:
·
· distanceLeft = 0
· distanceRight = 0
·
· FOR DIRB = 1 TO 7
·
··· FREQOUT 7,1,38500
··· irDetectLeft = IN8
··· distanceLeft = distanceLeft + irDetectLeft
·
·· ·FREQOUT 3,1,38500
··· irDetectRight = IN2
··· distanceRight = distanceRight + irDetectRight
·
· NEXT
·
· RETURN
·
'
[noparse][[/noparse] Subroutine - Send_Pulse ]
·
Send_Pulse:
·
· PULSOUT 13, pulseLeft
· PULSOUT 12, pulseRight
· PAUSE 5
· RETURN
Anyone have any comments/suggestions?
Thanks,
Bot Learner
I'm new to this stuff and I'm working with the Boe-Bot Robotics kit. I finished the exercises in the book and noticed the jittering with the·programs in chapters 7 & 8 for following another boe bot. I read the Better Boe-Bot IR Distance Measurements paper by Andy and incorporated the new hardware design and software. Still quite a lot of jitter, so I read the PID Control Intro with the Basic Stamp. I've tried to incorporate PID in the software using the new circuit, but I'm running out of variable space. Not being a math wizard, I may be doing more than necessary. Here's the code:
' BoeBotFollowingWithPidAlgorithm.bs2
' Demonstrates how a combination of proportional, integral, and
' derivative control influence error correction in a feedback loop.
·
' {$STAMP BS2}
' {$PBASIC 2.5}
·
'
[noparse][[/noparse] Constants ]
·
SetPoint······· CON···· 2···················· ' Set point
Kpl·············· CON···· -15·················' L & R proportionality constants
Kpr············· CON···· 15
Kil·········· ···· CON···· -15··················' L & R integral constants
Kir·············· CON···· 15
Kdl············· CON···· -15··················' L & R derivative constants
Kdr············· CON···· 15
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
Offset··········· CON···· 750·················' Servo not moving
·
'
[noparse][[/noparse] Variables ]
·
irDetectLeft··· VAR···· Bit
irDetectRight· VAR···· Bit
distanceLeft·· VAR···· Nib
distanceRight· VAR···· Nib
errorLeft······· VAR···· Word(4)·············' Four different types of errors
errorRight····· VAR···· Word(4)
p·················· VAR···· Word··················' Proportional term
i··················· VAR···· Word··················' Integral term
d·················· VAR···· Word················· ' Derivative term
pulseLeft······ VAR···· Word················· ' Output
pulseRight·····VAR· ···Word
·
'
[noparse][[/noparse] Initialization ]
·
FREQOUT 1, 1000, 3000
·
'
[noparse][[/noparse] Main Routine ]
·
DO
·
· GOSUB Get_IR_Distances
·
· ' Calculate error.
· errorLeft(Current) = SetPoint - distanceLeft
· errorRight(Current) = SetPoint - distanceRight
·
· ' Calculate left proportional term.
· p = Kpl * errorLeft(Current)
·
· ' Calculate left integral term.
· errorLeft(Accumulator) = errorLeft(Accumulator) + errorLeft(Current)
· i = Kil * errorLeft(Accumulator)
·
· ' Calculate left derivative term.
· errorLeft(Delta) = errorLeft(Current) - errorLeft(Previous)
· d = Kdl * errorLeft(Delta)
·
· ' Calculate left output.
· pulseLeft =· p + i + d + Offset MIN 650 MAX 850
·
· ' Calculate right proportional term.
· p = Kpr * errorRight(Current)
·
· ' Calculate right integral term.
· errorRight(Accumulator) = errorRight(Accumulator) + errorRight(Current)
· i = Kir * errorRight(Accumulator)
·
· ' Calculate right derivative term.
· errorRight(Delta) = errorRight(Current) - errorRight(Previous)
· d = Kdr * errorRight(Delta)
·
· ' Calculate right output.
· pulseRight = p + i + d + Offset MIN 650 MAX 850
·
· ' Save current error to previous error before next iteration.
· errorLeft(Previous) = errorLeft(Current)
· errorRight(Previous) = errorRight(Current)
·
· GOSUB Send_Pulse
·
LOOP
·
'
[noparse][[/noparse] Subroutine - Get_IR_Distances ]
·
Get_IR_Distances:
·
· distanceLeft = 0
· distanceRight = 0
·
· FOR DIRB = 1 TO 7
·
··· FREQOUT 7,1,38500
··· irDetectLeft = IN8
··· distanceLeft = distanceLeft + irDetectLeft
·
·· ·FREQOUT 3,1,38500
··· irDetectRight = IN2
··· distanceRight = distanceRight + irDetectRight
·
· NEXT
·
· RETURN
·
'
[noparse][[/noparse] Subroutine - Send_Pulse ]
·
Send_Pulse:
·
· PULSOUT 13, pulseLeft
· PULSOUT 12, pulseRight
· PAUSE 5
· RETURN
Anyone have any comments/suggestions?
Thanks,
Bot Learner
Comments
Don't do that now though, because it'll only confuse things. The current goal is to get a working prototype. After that, you can start experimenting with how much memory you can retrive. For your working prototype, you only really need one word. The next suggestion will save you three.
The first thing I'd do to retrieve enough RAM to test the prototype is get rid of P, I, and D. How? By adding everything into driveLeft and driveRight. P, I, and D are intermediate terms, and therefore disposeable. Each time throught the loop, start by setting pulseLeft and pulseRight to zero. Then, instead of p = kpl * errorLeft(Current), use pulseLeft kpl * errorLeft(current). Next, instead of i = kil * errorLeft(accumulator), use pulseLeft = pulseLeft + (kil * errorLeft(accumulator)). Instead of d = kdl * errorLeft(Delta), use pulseLeft = pulseLeft + (kdl * errorLeft(Delta)). At the end, you'll need pulseLeft = pulseLeft + Offset.
See how that works? Even though you're not using the variables P, I, and D, you are still performing the P, I, and D calculateions and adding them up as you go.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
PBASIC has two kinds of fractional multiplications: */ and **. The */ operator multiples by a number of 256ths and ** multiplies by a number of 65536ths. For **, the fraction has to be smaller than 1. Lets say you want value = value X 3.1416. 3.1416 has to be redefined in terms of 256ths. Simply multiply 3.1416 by 256, and use the integer result in your */ operation. So the equivalent operation with */ is value = value */ 804. Let's say you want to multiply a value by 0.7071. You can use ** for a more accurate calculation since your multiplying by a value that's less than 1. In this case, you are multiplying by a number of 65536ths. So multiply 0.7071 by 65536, and use the integer portion of the result in your ** calculation. The equivalent operation is value = value ** 46341.
You'll probably want to do this work in a subroutine that also deals with negative results. Reason being, */ and ** only work properly with positive integers. Start with a small program that allows you to enter an error. First, store the sign of each term by storing bit15 of that term. If the term is negative, bit15 will be 1; otherwise, it'll be 0. Try declaring two bit variables, signA and signB. Then, use the ABS operator to do positive calculations. You will then have a positive result and two bits. If exclusive-or of signA nd signB is is 1, then the result is negative. If it's 0 the result is positive. So IF (signA ^ signB) THEN result = - result.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 5/9/2007 1:22:37 AM GMT
I tried the suggestions in your first reply. That gets the word count to 10, which works. Now I just have to figure out why the boebot keeps going in a backwards circle regardless of the distance of the detected object.
Bot Learner
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Okay. I read your posts above and did some more reading on PID control. I also read the PID Control section of the Industrial Control Student Guide. I have a program that works, but is still herky/jerky. What I'm having the most trouble understanding is the comments you made about fractional calculations. How and why are fractional calculations incorporated?
Here's the latest code. (It might seem familiar :-) )
' BoeBotFollowingWithPidAlgorithm2.bs2
' {$STAMP BS2}
' {$PBASIC 2.5}
'
[noparse][[/noparse] Constants ]
SetPoint·········· CON···· 1················ ' Set point
Kpl················· CON···· 10··············· ' L & R proportionality constants
Kpr················· CON···· -10
Kil·················· CON···· 2················ ' L & R integral constants
Kir·················· CON···· -2
Kdl················· CON···· 2················ ' L & R derivative constants
Kdr················· CON···· -2
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
Offset············· CON···· 750·············' Servo not moving
'
[noparse][[/noparse] Variables ]
irDetectLeft······ VAR···· Bit
irDetectRight·····VAR···· Bit
distanceLeft······VAR···· Nib
distanceRight·····VAR···· Nib
errorLeft·········· VAR···· Word(4)·········· ' Four different types of errors
errorRight········ ·VAR···· Word(4)
pulseLeft·········· VAR···· Word············· ' Output
pulseRight········· VAR···· Word
Sign················ VAR·····Word············· ' Used to hold sign for calculations
'
[noparse][[/noparse] Initialization ]
FREQOUT 1, 1000, 3000
'
[noparse][[/noparse] Main loop ]
DO
· GOSUB Get_IR_Distances
· GOSUB Calc_Drive
· GOSUB Send_Pulse
LOOP
'
[noparse][[/noparse] 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
'
[noparse][[/noparse] Calculate Error ]
ErrorCalc:
· ' Calculate error
· errorLeft(Current) = SetPoint - distanceLeft
··errorRight(Current) = SetPoint - distanceRight
··RETURN
'
[noparse][[/noparse] Proportional Drive - Sign adjusted ]
PropCalc:
· Sign = errorLeft(Current)
· GOSUB SetSign
· pulseLeft = Kpl * ABS errorLeft(Current)
· pulseLeft = pulseLeft * Sign
· Sign = errorRight(Current)
· GOSUB SetSign
· pulseRight = Kpr * ABS errorRight(Current)
· pulseRight = pulseRight * Sign
· RETURN
'
[noparse][[/noparse] Integral Drive - Sign Adjusted ]
IntCalc:
· errorLeft(Accumulator) = errorLeft(Accumulator) + errorLeft(Current)
· Sign = errorLeft(Accumulator)
· GOSUB SetSign
· errorLeft(Accumulator)· = ABS errorLeft(Accumulator) * Kil
· errorLeft(Accumulator)· = errorLeft(Accumulator)· * Sign
· errorRight(Accumulator) = errorRight(Accumulator) + errorRight(Current)
· Sign = errorRight(Accumulator)
· GOSUB SetSign
· errorRight(Accumulator) = ABS errorRight(Accumulator)· * Kir
· errorRight(Accumulator)· = errorRight(Accumulator)· * Sign
· RETURN
'
[noparse][[/noparse] Derivative Drive ]
DerivCalc:
· errorLeft(Delta) = errorLeft(Current) - errorLeft(Previous)
· pulseLeft = pulseLeft + (Kdl * errorLeft(Delta))
· errorRight(Delta) = errorRight(Current) - errorRight(Previous)
· pulseRight = pulseRight + (Kdr * errorRight(Delta))
· RETURN
'
[noparse][[/noparse] Set sign of value ]
SetSign:
· IF Sign.BIT15 = 0 THEN SignPos············ 'If signbit is 1, then negative
· Sign = -1
· RETURN
· SignPos:
··· Sign = 1
· RETURN
'
[noparse][[/noparse] Subroutine - Get_IR_Distances ]
Get_IR_Distances:
· distanceLeft = 0
· distanceRight = 0
· FOR DIRB = 1 TO 7
··· FREQOUT 7,1,38500
··· irDetectLeft = IN8
··· distanceLeft = distanceLeft + irDetectLeft
··· FREQOUT 3,1,38500
··· irDetectRight = IN2
··· distanceRight = distanceRight + irDetectRight
· NEXT
· RETURN
'
[noparse][[/noparse] Subroutine - Send_Pulse ]
Send_Pulse:
· PULSOUT 13, pulseLeft
· PULSOUT 12, pulseRight
· PAUSE 5
· RETURN
Thanks foryour help.
Bot Learner
DEBUG DEC pulseLeft, " ", DEC pulseRight, CR
The values are nowhere near the 650 to 850 range most of the time. Start by revisiting the PID Stamps in Class Mini Projects post. Then, insert DEBUG commands to find if each calculation is doing what it's supposed to do when you manually measured distances using the Debug Terminal.· You'll need to insert a bunch of DEBUG commands in your code to see the results of each calculation.· Once you get the calculations fixed, go back and comment all the DEBUG commands because they will take too much time and slow down your code.
I'll answer your math question in a second post.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Although this has been a·lesson in implementing the PID algorithm, I suspect it won't do any better than the ramping code even when it's tuned.· Smoothing isn't really PID's main function, it's tracking, and noise should be pre filtered.·
Along·the pre filtering·lines, combining averaging and maybe some extreme and/or delta exclusion code will help as a pre filter for either the ramping or PID code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 5/11/2007 7:15:04 AM GMT
Both programs work quite well! The concepts will come in handy with other projects like the Crawler Kit and the Gripper Kit just to name two.
I'll take your suggestion and insert DEBUG coimmands in my code to look at the steps its going through and make sure I get the results I expect from the calculations. I also revisited the PID Stamps in Class Mini Projects post again and I noticed that in the front end you state "In coming Chapters, you will use PID to smooth out the Boe-Bot’s following behavior, and improve its line following performance." Do these "coming Chapters" currently exist, or are they forthcoming?
Thanks again for all the help!!
Bot Learner
Actually, you are helping create those chapters!· · This is the first working dual PID loop Boe-Bot code I know of, and it's got me pretty fired up to refine it and start writing.· It'll probably be a couple weeks before I find enough spare time though.·
The·DEBUG code is already in BoeBotFollowingWithPidAlgorithmsCorrected.bs2.· Just uncomment the DEBUG commands, and you'll be able to go through it by·hand and·verify that it is doing what it's supposed to.· I did that to make sure my own advice was correct.··Unfortunately, I ended up loosing track of the·changes I made and it was getting late, so I posted the working·prototype instead of suggestions about how to·get there.· Sorry about that.· For best results at this point, do a line by line comparison between your code and the·Corrected and challenge any mysterious changes.
The next step will be to examine the IR measurement noise by datalogging a few distance detection sessions in EEPROM.· After examining the noise, a software filter will be written to pre-filter that type of noise.· It'll be the best smoothing solution, and it will significantly improve both the PID and ramping examples.·
To get started, place the Boe-Bot at various distances (find the middle of a given measurement zone), and then write and run datalogging code and store·various series of IR distance measurements in a spreadsheet.· For an example datalogging and storing data in a spreadsheet, see Smart Sensors and Applications, Chapter 6, Activity #2 through #6:
Smart Sensors & Applications
Smart Sensors and Applications Text (.pdf)
Smart Sensors Code and Spreadsheet (.zip)
Andy
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 5/11/2007 7:41:29 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
I'll also look at the datalogging and try that. I've already started looking at filters and am looking at Tracy Allen's Stamp II math note #5 as a starting point. (http://www.emesystems.com/BS2math5.htm)
I did the line by line comparison and the only question I have has to do with the Calc_Drive subroutine. Every time through the main loop this subroutine is performed. Then the Send_Pulse subroutine is done. However, within the Calc_Drive subroutine a call is made to the Send_Pulse subroutine. On first look it seems redundant, but it obviously works, since the control is a lot more herky/jerky without the extra call even if I add the PAUSE command to the Send_Pulse subroutine. Why is that?
The rest of the code makes sense. I like the way you do the fractional calculations and sign adjustments in the same routine. Clean and simple.
I hope others find the code samples you came up with as useful as I do.
Bot Learner
Hmmm, yes, Tracy's low pass filter code has potential.· Definitely worth a try.· Condencing the PID code to free up three words will be the first order of business.
Fortunately, there's no real difference between the cost of the individual parts and the cost of the kit.· There are some cool Boe-Bot + Ping))) and Accelerometer projects posted in the Stamps in Class "Mini Projects" section.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 5/11/2007 11:04:52 PM GMT
I was reading the PID Control Intro with the BASIC Stamp thread in Stamps in Class, and wanted to try it on my Boe-Bot since I was VERY attracted by the PEKbot video you posted of that very cool Propeller-based robot... (BTW I think I'll get the Propeller Education Kit as soon as possible, and this should be in July, because I'm going in the US (I actually live in France and shipping is unfortunately very expensive . Hopefully Parallax (or UPS) will reduce shipping price to Europe one day...?))
Ok so I tried to make the program (the code is below) and the results don't look very good, but I believe the BS2 can't do as good as the Propeller... Here is a video: www.youtube.com/watch?v=hzv63xnls34
Can I improve the program some way? Should I try better PID constants? Which ones?
Here's the code
Thanks in advance
Nice code. You can fix the fact that the Boe-Bot runs into the target by putting limits on your error(accumulator) variables. Right now, they are accumulating too far, and then taking too long to decay after the correction has been made. Take a look at the code attached to my 5/11/2007 12:09 AM (GMT -7) post for an approach that uses MIN and MAX to limit the accumulator variables.
There are also some physical adjustments you can make to keep the Boe-Bot from wagging its tail so much. (1) Mount the servos on the outside of the chassis. This slightly dampens its turning tendency. (2) Move the IR detectors toward the middle by two rows on the breadboard, and mount the IR LEDs on the outermost left and right. They should still be pointed very slightly outward, but not as much as they are now.
My thought was the same as yours, that the PID code on the Boe-Bot should work as well as the PEKbot code. It may still be possible, but it's going to take some additional code. The Boe-Bot and PEKbot are using two different distance detection algorithms, and I think there is less noise per measurement in the PEKbot's detection system. In other words, the PEKbot's IR detection signal to noise ratio (SNR) is higher than the Boe-Bot robot's.
In the PEKbot example, the integral is having a secondary effect, filtering some of the nose. Integral isn’t really intended to be used that way. Integral is supposed to make the output home in on its set point value, regardless of external forces that overwhelm the proportional component. It "accumulates" until the output fully corrects the input. Well, actually there is some overshoot and maybe some ringing, but eventually, it makes the system's output home in on the correct set point.
A more conventional (and correct) approach is to pre filter the IR detector noise. This should help further improve your Boe-Bot's PID performance. Even on the PEKbot, this would make it possible to reduce the integral and get it to settle more quickly on its set point distance. For more info, take a look at this thread's posts between 5/11/2007 12:33 PM (GMT -7) and 5/11/2007 3:42 PM (GMT -7).
Yeah, the Propeller Education Kit (PE Kit) is great for robotics prototyping. It's multiple cogs (processors) make it possible to simultaneously control all the actuators, poll all the sensors, and communicate with numerous other robots and/or processors. Fortunately, July isn't too far away. Even so, our sales department may have some tips for reducing the shipping costs to France. I'll check and post a follow-up here.
Andy
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
I'll try the modifications as soon as I can.
And what limits do you think I should choose?
I don't get what the following code means (your code): do the MIN and MAX only apply to the following variable or to the hole expression? How do these actually work?
errorLeft(accumulator) + IntErrorOffset MAX IntErrorMax MIN IntErrorMin - IntErrorOffset
ps: I had a look at the Propeller manual: spin looks really cool!! object oriented is fantastic!! (I know C++, so I know what that means...) It's got to be very powerful!
Why is this?
So how can I do it?
your offset was just for shifting and coming back...
And I guess my limit values were actually too big!!
Here's the new code
[noparse][[/noparse]70 and 130: I like it with a bit more integral, so that I see the cool little turning 'delay']
Sorry for my previous posts...
Post Edited (bietz) : 5/15/2007 9:35:51 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Andy
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.