Accel curve help needed by math wiz.
I have been searching here and google for a while with no luck finding accel formulas that could easily apply (no extra cogs for float) to fix this curve shown below.
Can anyone suggest a quick easy formula to adjust fix the red curve to look more like the blue one?
The idea is, the fix needs to be spread over 4320 loops, and maintain the same start value(0) and end value(MaxSpeed) so that the curve still ends up at the same place at the same time it always did to preserve the profile.
It seems if there is no better way to fix the main curve, then the offset would simply count up to some number, then count back down, possibly even into the negative to retain the same MaxSpeed/Time end point.
Post Edited (Originator) : 10/25/2008 10:31:12 PM GMT
Can anyone suggest a quick easy formula to adjust fix the red curve to look more like the blue one?
The idea is, the fix needs to be spread over 4320 loops, and maintain the same start value(0) and end value(MaxSpeed) so that the curve still ends up at the same place at the same time it always did to preserve the profile.
It seems if there is no better way to fix the main curve, then the offset would simply count up to some number, then count back down, possibly even into the negative to retain the same MaxSpeed/Time end point.
Post Edited (Originator) : 10/25/2008 10:31:12 PM GMT


Comments
·
This is an image of x2 and x1/2 . The former is on the bottom, and the latter is above. I may be able to come up with a solution on how to convert, but it will take a little while.
Post Edited (SRLM) : 10/26/2008 12:54:24 AM GMT
PUB AccelForward(len) 'len = distance to travel based on 30% new target pos aRate := (MinSpeed - MaxSpeed)/Len ' = 34 at 30% dRate := 10 '(MinSpeed - MaxSpeed)/Len a3 := len/2 posold := pos repeat len accel := ((accel - (aRate + A3)) #> MaxSpeed) <# MinSpeed 'a3 is an offset using the length (len) / 2, start subtracting the distance moved from the len/2 a3 := a3 - ||(pos-posold) #> 0 pos := pos + 1 waitcnt(accel + cnt) if newpos < pos Quit decel := accelThis is crude but effective to put the curve on the top side.
So, that said, let's begin.
You have two curves:
The given curve: xn = c
The desired curve: x1/n = a
Where c and a are the values given at point x (the point in your sample list)
So to convert, just use x 1 / logxc· to get the value that you want.
I'll give an example of how to use it:
And, truth be told, I mostly looked at your graph, and skimmed over the rest. Without the full background, it's difficult to make the project in my mind. But, with the graph I can still do the math. [noparse]:)[/noparse]
I have a better idea now, either predefine 10 reference points over the distance of the accel curve, or, define one point as the 'knee' and calculate the rest using a curve/angle value to determine the sharpness/roundness of the curve.
I like the idea much better to be able to semi-graphically define the curve, only in this case the graphic is on paper rather than a GUI.
PUB AccelForward(len) | X 'len = ramp up distance to travel based on 30% new target pos 'phase 1 = MinSpeed(=175_000) - MaxSpeed(=25_000) = 150_000 / phaseLen = len/10 ' example distance 4320 / 10 points = 432 index := 0 phasecounter := 0 PCindex := 0 accel := MinSpeed '175000 example AccelPhase[noparse][[/noparse] 0] := 0 'predefined curve values AccelPhase[noparse][[/noparse] 1] := 20000 AccelPhase[noparse][[/noparse] 2] := 30000 AccelPhase[noparse][[/noparse] 3] := 50000 AccelPhase[noparse][[/noparse] 4] := 90000 AccelPhase[noparse][[/noparse] 5] := 110000 AccelPhase[noparse][[/noparse] 6] := 130000 AccelPhase[noparse][[/noparse] 7] := 135000 AccelPhase[noparse][[/noparse] 8] := 140000 AccelPhase[noparse][[/noparse] 9] := 145000 AccelPhase[noparse][[/noparse] 10] := 150000 PhaseOffset[noparse][[/noparse] 1] := (AccelPhase[noparse][[/noparse] 1] - AccelPhase[noparse][[/noparse] 0] )/ phaseLen 'offset value for each iteration PhaseOffset[noparse][[/noparse] 2] := (AccelPhase[noparse][[/noparse] 2] - AccelPhase[noparse][[/noparse] 1] )/ phaseLen PhaseOffset[noparse][[/noparse] 3] := (AccelPhase[noparse][[/noparse] 3] - AccelPhase[noparse][[/noparse] 2] )/ phaseLen PhaseOffset[noparse][[/noparse] 4] := (AccelPhase[noparse][[/noparse] 4] - AccelPhase[noparse][[/noparse] 3] )/ phaseLen PhaseOffset[noparse][[/noparse] 5] := (AccelPhase[noparse][[/noparse] 5] - AccelPhase[noparse][[/noparse] 4] )/ phaseLen PhaseOffset[noparse][[/noparse] 6] := (AccelPhase[noparse][[/noparse] 6] - AccelPhase[noparse][[/noparse] 5] )/ phaseLen PhaseOffset[noparse][[/noparse] 7] := (AccelPhase[noparse][[/noparse] 7] - AccelPhase[noparse][[/noparse] 6] )/ phaseLen PhaseOffset[noparse][[/noparse] 8] := (AccelPhase[noparse][[/noparse] 8] - AccelPhase[noparse][[/noparse] 7] )/ phaseLen PhaseOffset[noparse][[/noparse] 9] := (AccelPhase[noparse][[/noparse] 9] - AccelPhase[noparse][[/noparse] 8] )/ phaseLen PhaseOffset[noparse][[/noparse] 0] := (AccelPhase[noparse][[/noparse] 10] - AccelPhase[noparse][[/noparse] 9] )/ phaseLen PhaseChange[noparse][[/noparse] 1] := phaseLen 'values to indicate when to change to next PhaseOffset value PhaseChange[noparse][[/noparse] 2] := phaseLen * 2 PhaseChange[noparse][[/noparse] 3] := phaseLen * 3 PhaseChange[noparse][[/noparse] 4] := phaseLen * 4 PhaseChange[noparse][[/noparse] 5] := phaseLen * 5 PhaseChange[noparse][[/noparse] 6] := phaseLen * 6 PhaseChange[noparse][[/noparse] 7] := phaseLen * 7 PhaseChange[noparse][[/noparse] 8] := phaseLen * 8 PhaseChange[noparse][[/noparse] 9] := phaseLen * 9 'PhaseChange[noparse][[/noparse] 10] := Len 'doesn't need 10 {{ accel is derived by MinSpeed - MaxSpeed + offset . An example is 175000 - 25000 = 150000 + offset the speed of the motor is determined by PWM, PWM is derived from an Error produced by a Profile generating routine below, which increments/decrements a position counter (pos). A PID calculator compares an encoder value to the position, and computes a corresponding PWM motor speed to compensate for the Error. Using waitcnt with the Minimum speed as the starting (slower) speed, amounts are subtracted from the Minimum speed to increase the speed. }} repeat len accel := ((accel - PhaseOffset[noparse][[/noparse]Index] ) < # MinSpeed) #> MaxSpeed 'reduce waitcnt by Phase[noparse][[/noparse]index] pos := pos + 1 if phasecounter == PhaseChange[noparse][[/noparse] PCindex] 'if phasecounter has reached 1rst phase end, or ex 432 (len/10)... index++ 'then go to next phaseOffset value PCindex++ 'and increment the PhaseChange index phasecounter+ 'increment the phasecounter waitcnt(accel + cnt) 'waitcnt = value to set speed of pulses if newpos < pos 'if new position has been rec'd, get out and go decel somewhere else Quit decel := accel 'let decel value be same value as value that accel left off atPost Edited (Originator) : 10/26/2008 9:55:11 PM GMT
Actually the code above is what is working out fine for 10 predefined points, it take the 10 points and calculates the 10 ranges of offset values, there are no other if statements needed as the counter bumps up the index keeping everything working at the right time.
Thanks for the advice, very helpful.