尝试优化Lugre动态摩擦模型中的参数

时间:2019-05-06 20:40:16

标签: python numpy scipy physics ode

我用CSV收集了摩擦模型每个输出的数据。该模型将表面之间的接触想象为一维刚毛,它们像弯曲的弹簧一样对弯曲产生反应。摩擦力的模型如下:

FL(V,Z) = sig0*Z +sig1*DZ/Dt +sig2*V 

其中V是表面Z的速度是鬃毛的挠度,DZ / Dt是挠度,等于:

DZ/Dt = V + abs(V)*Z/(Fc + (Fs-Fc)*exp(-(V^2/Vs^2))
      = V + abs(V)*Z/G(V)
      = V + H(V)*Z

其中Fc是物体在运动中的摩擦力(恒定),Fs等于使物体运动所需的力(常数> Fc),而Vs是在域之间转换所需的总速度(a我实验得出的常数)。滑块的速度和位置以CSV格式提供,并且所有摩擦力都随时间变化。我还创建了速度随时间(三角函数)的易于积分的方法。

问题所在:代码与我尝试将列表传递给函数的方式(我认为)相符。

该函数将参数SEEMS传递给工作(从另一个简单地绘制数据的文件中获取),但是我试图对DZ / Dt进行数值积分,并将sig参数拟合到导入的摩擦数据。

我导入了什么

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from scipy import optimize
import pylab as pp
from math import sin, pi, exp, fabs, pow

参数

Fc=2.7  #N
Fs=8.2  #N
Vs=.34  #mm/s

初始条件

ITime=Time[0]
Iz=[0,0,0]

建立摩擦模型

def velocity(time):
    V=-13/2*1/60*pi*sin(1/60*pi*time+pi)       
    return V

def g(v,vs,fc,fs,sig0):
    G=(1/sig0)*(fc+(fs-fc)*exp(-pow(v,2)/pow(vs,2)))
    return G

def h(v,vg):
  H=fabs(v)/vg
  return H

def findz(z, time, sig):
  Vx=velocity(time)
  VG=g(Vx,Vs,Fc,Fs,sig)
  HVx=h(Vx,VG)
  dzdt=Vx+HVx*z
  return dzdt

def friction(time,sig,iz):
  dz=lambda z,time: findz(z,time,sig)
  z=odeint(dz,iz,time)
  return sig[0]*z+sig[1]*findz(z,time,sig[0])+sig[2]*velocity(Time)

应返回Constructed函数和数据之间的差,并且 产生包含优化参数的列表

def residual(sig):
  return Ff-friction(Time,sig,Iz)

SigG=[4,20,1]
SigVal=optimize.leastsq(residual,SigG)

print "parameter values are ",SigVal  

这将返回

line 56, in velocity
    V=-13/2*1/60*pi*sin(1/60*pi*time+pi)

TypeError: can't multiply sequence by non-int of type 'float'

这与我传递列表有关吗?

1 个答案:

答案 0 :(得分:0)

正如我在评论中所提到的,Velocity()可能是导致错误的原因,它很可能是因为它使用了时间值,而您将整个列表/数组(具有多个值)传递给了Velocity(),当您在friction()中调用时。

使用一些选择的值,并在缩短代码长度并通过ITime而不是Time之后,代码可以正确运行,但是您可以自行判断这是否是您想要实现的目标。下面是我的代码:

import numpy as np
from scipy import optimize
from scipy.integrate import odeint
from math import sin,  pi,  exp,  fabs

# Parameters
Fc = 2.7  #N
Fs = 8.2  #N
Vs = .34  #mm/s

# define test values for Ff and Time
Ff    = np.array([100, 50, 50])
Time  = np.array([10, 20, 30])

# Initial_conditions
ITime = Time[0]
Iz    = np.array([0, 0, 0])

# Building the friction model
V    = lambda                   t: (-13 / 2) * ( 1 / (60 * pi * sin(1 / 60 * pi * t + pi)))      
G    = lambda v, vs, fc, fs, sig0: (1 / sig0) * (fc + (fs - fc) * exp(-v**2 / vs**2))
H    = lambda               v, vg: fabs(v) / vg
dzdt = lambda         z,  t,  sig: V(t) + H(V(t), G(V(t), Vs, Fc, Fs, sig)) * z


def friction(t, sig, iz):
  dz = lambda z, t: dzdt(z, t, sig)
  z  = odeint(dz, iz, t)
  return sig[0]*z + sig[1]*dzdt(z, t, sig[0]) + sig[2]*V(t)

# Should return the difference between the Constructed function and the data
# and yield a list containing the optimized parameters

def residual(sig):

  return Ff-friction(ITime, sig, Iz)[0]

SigG   = np.array([4, 20, 1])
SigVal = optimize.leastsq(residual, SigG, full_output = False)

print("parameter values are ", SigVal )

输出:

parameter values are  (array([    4.        ,  3251.47271228, -2284.82881887]), 1)