a methode for steering servos and e-mots
nomad
Posts: 276
hi
here a little applications for steering
with the formula:
X = ((X * weight-1)+ Xf) / weight)
x = basevalue
xf = endvalue
if x < xf -> rampUp
if x > xf -> rampDown
weight: must greater as 1.0
if greater weights longer way to endpoint (smoother)
as attachment a paint-image from the curves vs.weights ramping.jpg
it's all
regards
nomad
here a little applications for steering
with the formula:
X = ((X * weight-1)+ Xf) / weight)
x = basevalue
xf = endvalue
if x < xf -> rampUp
if x > xf -> rampDown
weight: must greater as 1.0
if greater weights longer way to endpoint (smoother)
Ramper_vers_10.spin
for : programm basics for ramping Servos Up/down
- from darwinWeights2.c
========================================================================= *
THIS PROGRAMM IS UNDER THE GNU-LICENCE
========================================================================= *
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
==========================================================================*
* Contributions:
* parallax.com
* http://www.parallax.com
*
* Spieleprogrammierung M. DeLoran
* page 145 ff. Mathematics
* Author: John Olsen
engl. game programming gems, edited by mark deloura *==========================================================================*
}
CON
_CLKMODE = XTAL1 + PLL16X 'Set to ext crystal, 16x PLL, 80MHz Clock
_XINFREQ = 5_000_000 'Frequency on XIN pin is 5 MHz
VAR
LONG Xnew ' dynamic Value
LONG Xold ' "
LONG X ' servoValue
LONG Xf ' EndValue
' if on 1.time Xf is greater as X then RampUp
' if on 1.time Xf is smaller as X then RampDown
LONG weight ' dynamics greater smoother
'intermediate results
LONG w1, z1, z2, z3, z4, z5, z6
' value for abort repeat-loop
LONG ab1, endval
' values for Float32-stuff from propNN2.spin
long testerror
long vlong
word vword
byte vbyte
OBJ
text : "vga_text" ' create vgaText-object
f : "Float32Full"
fp : "FloatString"
PUB Main
f.start
text.start(16)
text.str(string(13,"Ramper-Vers 0.10 VGA Output ProtoBoard",13,13,$C,5,$C,1))
rampUP
waitcnt(96_000_000+cnt) ' wait only for looking the output of UP
rampDown
PUB rampUp
ab1 := 1.0
weight := 30.0
Xold := 90.0
Xnew := Xold
X := 10.0
Xf := 100.0 ' EndPos only for graphic Screen y-pos is up
endval := f.FSub(Xf,ab1)
REPEAT ' originalformula: X := ((X * (weight-1.0)+Xf) / weight)
w1 := f.FSub(weight,1.0) ' w1 := weight-1.0
z1 := f.FMul(X,w1) ' z1 := X * w1
z2 := f.FAdd(z1,Xf) ' z2 := z1 + Xf
z3 := f.FDiv(z2,weight) ' z3 := z2 / weight
X := z3
text.out($0D) ' newline
text.str(fp.FloatToString(X)) ' old without Float32Stuff -> text.dec(X)
text.out($0D) ' new line
' do something
' you can change X, Xf, weight dynamical
IF X > endVal
text.out($0D) ' newline
text.str(string(13,"Its UP and Quit",13,13,$C,5,$C,1))
text.out($0D) ' newline
Xnew := X
QUIT
PUB rampDown
weight := 30.0
X := Xnew
Xf := 10.0
endval := f.FAdd(Xf,ab1)
REPEAT ' originalformula: X := ((X * (weight-1.0)+Xf) / weight)
w1 := f.FSub(weight,1.0) ' w1 := weight-1.0
z1 := f.FMul(X,w1) ' z1 := X * w1
z2 := f.FAdd(z1,Xf) ' z2 := z1 + Xf
z3 := f.FDiv(z2,weight) ' z3 := z2 / weight
X := z3
text.out($0D) ' newline
text.str(fp.FloatToString(X)) ' old without Float32Stuff -> text.dec(X)
text.out($0D) ' new line
' do something
' you can change X, Xf, weight dynamical
IF X < endVal
text.out($0D) ' newline
text.str(string(13,"Its Down and Quit",13,13,$C,5,$C,1))
text.out($0D) ' newline
Xnew := X
QUIT
{------------------------------------------------------------------------------------}
as attachment a paint-image from the curves vs.weights ramping.jpg
it's all
regards
nomad

Comments
I'm pretty sure English is not your native language. You use "weight" where I think you want "wait". Not that this is a big deal, but it might confuse folks that think that your servo driver will use the "weight" of whatever you are controlling, confusing them. Please, this is not meant to be offensive. It's simply a bit confusing...
Did you mean weight, as in mass? Or wait, as in time?
-Parsko
you have the correct-answer
regards
nomad
dX/(xf-X) = dt/weight
as can easily be seen by re-arranging Nomad's equation (Note: there is a typo in it, should read:
X = (X * (weight-1)+ Xf) / weight )
The solution is (simple calculus):
-ln(xf-X) = t/weight + c
or
X = xf - (xf-x0)*exp(-t/weight)
(as the enclosed graphics also show)
"weight" is a time scaling parameter, i.e. seconds, minutes, hours - or in other words: "how fast things are going"
When you have no transcendent functions in your toolbox, numerical integration of the derivative might SOMETIMES
come out faster than computing the formula itself... However not when using emulated floating point instructons
And there are also control laws which have no simple primitive
----
Edit: Well, had a lot of typos myself here...
Post Edited (deSilva) : 8/18/2007 7:42:24 AM GMT