[python] Re: Stability Theory - bug :-(
- From: mtb@xxxxxxx
- To: python@xxxxxxxxxxxxx
- Date: Wed, 23 Feb 2005 12:53:15 -0800
At 08:45 PM 2/23/2005 +0100, you wrote:
good news
I'm glad you think so!
the results of your cool app now appear quite
realistic!
Even better...
The airbike data showed a stable range from 28 to 56 km/h
and P3 data showed no stable range at all.
I'll be gone for a couple of days (client trip), but when I get back I'll
sort out the factors which contribute to the "B" and "E" instabilities.
That should give an idea what/if they can be made self-stable. I really
want to add in the human input factor as well as that pivot spring factor.
The output to stdout shows pairs of velocity and a negative
or positive number. The airbike output numbers are positive
from 17.5 to 34.5 km/h, then the output stops.
Why then is the stable range from 28 to 56 km/h?
The DOS output is still in MPH, sorry, I forgot to convert.
Three more features would be nice:
- input of data by file as a possible option
I was thinking of a standard .cfg type file last night
- different wheel sizes (don´t know if that matters at all)
no, only the momentum. It might be good to have wheel weight and diameter
(assuming 95% is in the tire-rim) as the inputs, and calculate momentum
internally instead.
- airbike has 20 cm of positive trail, GUI max are 10 cm
! I didn't realize. I'll change it. Any other limit problems?
Have you thought of making the sourcecode available
for everyone?
Yes, I often do Python (the language) stuff LGPL, only reserving code
authorship. The algorithm below follows Hand's. If anyone can or wants to
program in Python, they could easily extend it. I use the Boa Constructor IDE.
I've been working on a larger cycling software package of my own, so I plan
on including a version of this as a module, and so part of the impetus for
the graphics and GUI. If anyone wants to collaborate, I'd be quite happy,
and anything anyone adds would of course then belong to them and/or the
group. It's a lot more fun and rewarding than writing boring apps for
corporate clients.
The main algorithm is RouthHurwitz (the simpler DOS output is included,
current code is at home).
In this version, lines 62-76 iterate over desired input ranges, you could
make them singular. All are imperial units, and it writes to a file; the
print lines are just commented out 165-172.
If you trace back the b0 and e0 formulas (line 130+), you'll see what
factors are driving them negative, which is the criteria defining
Routh-Hurwitz instability.
Cheers,
Ray
#-----------------------------------------------------------------------------
# Name: FrameGeo.py
# Purpose:
#
# Author: Ray Schumacher
#
# Created: 2005/23/02
# RCS-ID: $Id: FrameGeo.py $
# Copyright: (c) 2005
# Licence: Not-for-profit public use
#-----------------------------------------------------------------------------
#Boa:Frame:wxFrameGeometry
import math
import time
def __test():
outFile=open('results.csv',"w")
outFile.write( 'rearMassTrail'+','+
'htRearMass'+','+
'fM2Piv'+','+
#'frtMassHt'+','+
'wheelbase'+','+
'headAngle'+','+
'forkTrail'+','+
'stableRange[0]'+','+
'stableRange[-1]'+','+
'stableRange[-1]-stableRange[0]'+'\n')
rearMass = 170.0 ## lbm
rearMassTrail = 18. ## in
htRearMass = 14.0 ## in
Ryp = 100000.0 ## lbm in**2
Rzp = 20000.0 ## lbm in**2
alphar = 60.0 * math.pi / 180.0 ## degress to radians
wheelbase = 52.0 ## in
forkTrail = -2.0 ## in
headAngle = 35.0 * math.pi / 180.0 ## degress to radians
frontMass = 30.0 ## lbm
fM2Piv = 12.0 ## in
frtMassHt = 14. ## in
Fyp = 50.0 ## lbm in**2
Fzp = 2000.0 ## lbm in**2
alphaf = 45.0 * math.pi / 180.0 ## degress to radians
CrR = 50.0 ## lbm in
CfR = 50.0 ## lbm in
g = 386.4
## inertias
Ryy = Rzp*(math.cos(alphar))**2+Ryp*(math.sin(alphar))**2
Rzz = Rzp*(math.sin(alphar))**2+Ryp*(math.cos(alphar))**2
Ryz = Rzp*math.cos(alphar)*math.sin(alphar)- \
Ryp*math.sin(alphar)*math.cos(alphar)
Fyy = Fzp*(math.cos(alphaf))**2+Fyp*(math.sin(alphaf))**2
Fzz = Fzp*(math.sin(alphaf))**2+Fyp*(math.cos(alphaf))**2
Fyz = Fzp*math.cos(alphaf)*math.sin(alphaf)- \
Fyp*math.sin(alphaf)*math.cos(alphaf)
startTime = time.time()
for thisRMassTr in range(22, 27):
rearMassTrail = float(thisRMassTr)
print '\n', rearMassTrail
for thishtRearMass in range(15, 20):
htRearMass = float(thishtRearMass)
for thisfM2Piv in range(5, 15):
fM2Piv = float(thisfM2Piv)
for thisfrtMassHt in range(14, 18):
frtMassHt = float(thisfrtMassHt)
lastTime = time.time()
for thiswheelbase in range(50, 60, 2):
wheelbase = float(thiswheelbase)
for thisAngle in range(27, 65):
headAngle = float(thisAngle)
for thisTrail in range(-12, -6):
stableRange = []
forkTrail = thisTrail/2.
## front lengths
hf =
(forkTrail+fM2Piv)*math.sin(headAngle)+frtMassHt*math.cos(headAngle)
lf =
(forkTrail+fM2Piv)*math.cos(headAngle)-frtMassHt*math.sin(headAngle)
## total bike inertias and special front inertia
Tyy =
rearMass*htRearMass**2+Ryy+frontMass*hf**2+Fyy
Tzz =
rearMass*rearMassTrail**2+Rzz+frontMass*(wheelbase+lf)**2+Fzz
Tyz =
-rearMass*htRearMass*rearMassTrail+Ryz-frontMass*hf*(wheelbase+lf)+Fyz
Fll =
frontMass*fM2Piv**2+Fyy*(math.sin(headAngle))**2 - \
Fyz*math.sin(2*headAngle)+Fzz*(math.cos(headAngle))**2
Fly =
-frontMass*hf*fM2Piv-Fyy*math.sin(headAngle)+Fyz*math.cos(headAngle)
Flz =
frontMass*(wheelbase+lf)*fM2Piv-Fyz*math.sin(headAngle)+Fzz*math.cos(headAngle)
## design length ratios
Ktr = forkTrail/wheelbase
Khd = math.cos(headAngle)/wheelbase
mt = rearMass+frontMass
ht = (rearMass*htRearMass+frontMass*hf)/mt
lt =
(rearMass*rearMassTrail+frontMass*(wheelbase+lf))/mt
nu = frontMass*fM2Piv+mt*lt*Ktr
"""print Ryy, Rzz,Ryz
print Fyy,Fzz , Fyz
print Tyy,Tzz,Tyz
print Fll,Fly,Flz
print Ktr,Khd,mt
print ht,lt,nu"""
## coeffs for the lean equation
a1 = Tyy
a2 = -g*mt*ht
a3 = Fly+Ktr*Tyz
a4 =
-(CfR*math.cos(headAngle)+Ktr*(CfR+CrR))+(Tyz*Khd-Ktr*mt*ht)
a5 = g*nu
a6 = -(CfR+CrR)*Khd-Khd*mt*ht
#print a1,a2,a3 ,a4 ,a5 , a6
## coeffs for the steer equation
b1 = Fll+2*Ktr*Flz+(Ktr**2)*Tzz
b2 = Khd*(Flz+Ktr*Tzz)+Ktr*nu
b3 = -g*nu*math.sin(headAngle)
b4 = CfR*math.sin(headAngle)*Khd+nu*Khd
b5 = Fly+Ktr*Tyz
b6 = CfR*math.cos(headAngle)+Ktr*(CfR+CrR)
b7 = g*nu
#print b1,b2,b3,b4,b5,b6,b7
## coeffs for the 4th order polynomial
a0 = a1*b1-a3*b5
b0 = a1*b2-a3*b6-a4*b5
c0 = a1*b3-a3*b7-a5*b5+b1*a2
d0 = a1*b4-b5*a6-b6*a4
e0 = -a4*b7-a5*b6+b2*a2
f0 = -b6*a6
g0 = a2*b3-a5*b7
h0 = a2*b4-a6*b7
i0 = b0*d0*f0-a0*f0**2
j0 = b0*c0*f0+b0*d0*e0-2*a0*e0*f0-h0*b0**2
k0 = b0*c0*e0-a0*e0**2-g0*b0**2
l0 = b0*d0-a0*f0
m0 = b0*c0-a0*e0
"""print 'A =',a0,'>0'
print 'B =',b0,'V>0'
print 'C =',c0,'+',d0,'V**2>0'
print 'D =',e0,'V+',f0, 'V**3>0'
print 'E =',g0,'+',h0,'V**2>0'
print '6th =',l0,'V**3+',m0, 'V>0'
print '7th =',i0,'V**4+',j0,'V**2+', k0, '>0'"""
## print stability
for j in range(0, 100):
PRT = [' ']*7
speed = j
Vmph = speed/2.
Vips = Vmph*5280*12/3600.
A = a0
B = b0*Vips
C = c0+d0*Vips**2
bigD = e0*Vips+f0*Vips**3
E = g0+h0*Vips**2
rOuth6 = l0*Vips**3 +m0*Vips
rOuth7 = i0*Vips**4+j0*Vips**2+k0
"""if A<=0.: PRT[0] = 'A'
if B<=0.: PRT[1] = 'B'
if C<=0.: PRT[2] = 'C'
if bigD<=0.: PRT[3] = 'D'
if E<=0.: PRT[4] = 'E'
if rOuth6<=0.: PRT[5] = '6'
if rOuth7<=0.: PRT[6] = '7'
print 'Vel=', round(Vmph, 2), PRT[0],
PRT[1], PRT[2], PRT[3], PRT[4], PRT[5], PRT[6], rOuth7"""
if min([A,B,C,bigD,E,rOuth6,rOuth7])>0:
stableRange.append(Vmph)
if len(stableRange) and
stableRange[-1]-stableRange[0]>10 and stableRange[0]<10:
outFile.write(str(rearMassTrail)+','+
str(htRearMass)+','+
str(fM2Piv)+','+
#str(frtMassHt)+','+
str(wheelbase)+','+
str(headAngle)+','+
str(forkTrail)+','+
str(stableRange[0])+','+
str(stableRange[-1])+','+
str(stableRange[-1]-stableRange[0])+'\n')
#print '.',
#print
rearMassTrail,htRearMass,fM2Piv,frtMassHt,wheelbase,headAngle,forkTrail, '\t',
stableRange[0], '-', stableRange[-1], '\t', stableRange[-1]-stableRange[0]
#print headAngle, forkTrail, '\t',
stableRange[0], '-', stableRange[-1], '\t', stableRange[-1]-stableRange[0]
print round((97*(time.time()-lastTime) -
(time.time()-startTime))/60, 1), 'mins remain'
outFile.close()
if __name__ == '__main__':
__test()
- References:
- [python] Re: Stability Theory
- From: Ray Schümacher
- [python] Re: Stability Theory
- From: Ray Schümacher
- [python] Re: Stability Theory - bug :-(
- From: mtb
- [python] Re: Stability Theory - bug :-(
- From: Jürgen Mages
Other related posts:
- » [python] Re: Stability Theory - bug :-(
- » [python] Re: Stability Theory - bug :-(
- » [python] Re: Stability Theory - bug :-(
I'm glad you think so!
the results of your cool app now appear quite realistic!
Even better...
The airbike data showed a stable range from 28 to 56 km/h and P3 data showed no stable range at all.
The output to stdout shows pairs of velocity and a negative or positive number. The airbike output numbers are positive from 17.5 to 34.5 km/h, then the output stops. Why then is the stable range from 28 to 56 km/h?
The DOS output is still in MPH, sorry, I forgot to convert.
Three more features would be nice: - input of data by file as a possible option
I was thinking of a standard .cfg type file last night
! I didn't realize. I'll change it. Any other limit problems?
Have you thought of making the sourcecode available for everyone?
- [python] Re: Stability Theory
- From: Ray Schümacher
- [python] Re: Stability Theory
- From: Ray Schümacher
- [python] Re: Stability Theory - bug :-(
- From: mtb
- [python] Re: Stability Theory - bug :-(
- From: Jürgen Mages