Skip to content
Snippets Groups Projects
bestrobot.py 3.58 KiB
Newer Older
mehtank's avatar
mehtank committed
from scipy import log, sqrt, linspace, logspace, meshgrid, zeros, absolute
mehtank's avatar
mehtank committed
from scipy.optimize import minimize

def isstable(model):
    return 2*model[1]*model[2] + model[2]*model[2] - 2*model[0]

mehtank's avatar
mehtank committed
def tf((f,g,h), w):
    """
    Return the complex value of linearized transfer function T(jw)
    """
    return (g*1j*w + f)/(-w*w + (g+h)*1j*w + f)

def tflogmag(model, w):
mehtank's avatar
mehtank committed
    """
    Return the log of the magnitude of the linearized transfer function
        log[ |T(jw)| ]
    """
mehtank's avatar
mehtank committed
    return log(absolute(tf(model, w)))
mehtank's avatar
mehtank committed

mehtank's avatar
mehtank committed
def htflogmag(model, w):
mehtank's avatar
mehtank committed
    """
    Return the log of the magnitude of the linearized headway transfer function
        log[ |1-T(jw)| ]
    """
mehtank's avatar
mehtank committed
    return log(absolute(1-tf(model,w)))
mehtank's avatar
mehtank committed

def kstable(human, robot, w, eta=2):
    """
    Return the maximum number of human cars 
        that can be string-stabilized by a single robot car
        for an oscillatory perturbation of frequency w
    """
    return -tflogmag(robot,w)/tflogmag(human,w)

def ksafe(human, robot, w, eta=2):
    """
    Return the maximum number of human cars 
        that can be "safely" followed by a single robot car
        for an oscillatory perturbation of frequency w
        by 
    """
    return (log(eta)-htflogmag(robot,w)) / tflogmag(human,w)

TOL = 1e-6

mehtank's avatar
mehtank committed
def maxkfn(human, robot, eta, kfn):
mehtank's avatar
mehtank committed
    f,g,h = human
mehtank's avatar
mehtank committed
    maxw = sqrt(-isstable(human))
    return minimize(lambda w : kfn(human, robot, w, eta), 1, bounds=[(TOL,maxw-TOL)])#.fun[0]
mehtank's avatar
mehtank committed

def maxk(human, robot, eta):
mehtank's avatar
mehtank committed
    return min(maxkfn(human, robot, eta, kstable), maxkfn(human, robot, eta, ksafe))
mehtank's avatar
mehtank committed

'''
def bestrobotstable(human):
    cons = ({'type': 'ineq', 'fun': lambda x: 2*x[1]*x[2] + x[2]*x[2] - 2*x[0] },)
    return minimize(lambda robot : -maxkstable(human, robot), 
            (0.1, 0, 0.1), 
            bounds=[(0, 0.2), (0, 0), (0, 0.2)],
            constraints=cons)

def bestrobotsafe(human, eta):
    cons = ({'type': 'ineq', 'fun': lambda x: 2*x[1]*x[2] + x[2]*x[2] - 2*x[0] },)
    return minimize(lambda robot : -maxksafe(human, robot, eta), 
            (0.1, 0, 0.1), 
            bounds=[(0, 0.2), (0, 0), (0, 0.2)],
            constraints=cons)
'''

def bestrobot(human, eta):
    #cons = ({'type': 'ineq', 'fun': lambda x: 2*x[1]*x[2] + x[2]*x[2] - 2*x[0] },)
    return minimize(lambda robot : -maxk(human, robot, eta).fun[0], 
            [0.001, 0, 0.001], 
            #constraints=cons,
            bounds=[(0, 0.2), (0, 0), (0, 0.2)])

if __name__ == "__main__":
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import pyplot as plt
    from cfm import IDM, CFM

    hmodel = IDM(a=0.3,b=3,t=1.5,s0=2,v0=30)
    hmodel.go(0.5)
    human = (hmodel.f, hmodel.g, hmodel.h)

mehtank's avatar
mehtank committed
    maxw = sqrt(-isstable(human))
mehtank's avatar
mehtank committed

    eta=2

    print bestrobot(human, eta)

    '''
    ws = linspace(TOL, maxw-TOL, 101)
    kst = kstable(human, robot, ws)
    ksf = ksafe(human, robot, ws, eta)
    # print "kstable = ", kstable(human, robot, ws)
    plt.plot(ws, kst)
    plt.plot(ws, ksf)
    plt.axis([0, maxw, 0, 100])
    plt.show()

    frng = linspace(0, 0.1, 21)
    hrng = linspace(0, 0.1, 21)
    fs, hs = meshgrid(frng, hrng)
    ks = zeros(fs.shape)
    for fi, f in enumerate(frng):
        for hi, h in enumerate(hrng):
            ks[fi, hi] = maxk(human, (f, 0, h), eta)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(fs, hs, ks)
    plt.show()

    # print maxkstable(human, robot)
    # print maxksafe(human, robot, eta)
    print maxk(human, robot, eta)

    print 
    print "***"
    print 

    print bestrobotstable(human)
    print bestrobotsafe(human, eta)
    # print bestrobot(human, eta)
    '''