Python 如何将对象空间加速度集成到世界空间位置(2D)

Python 如何将对象空间加速度集成到世界空间位置(2D),python,physics,numerical-methods,differential-equations,inertial-navigation,Python,Physics,Numerical Methods,Differential Equations,Inertial Navigation,我想在对象坐标中对二维加速度数据进行双重积分,以获得世界坐标中的二维位置。物体总是指向速度的方向(假设是火车) 因此,我尝试用积分对加速度值进行数值积分,将每一步的方向更改为世界坐标中先前的速度,由velocity verlet算法提供: 将numpy导入为np 从数学导入sqrt 从matplotlib导入pyplot作为plt def旋转(a,新X轴): r=newXAxis normX=r/sqrt(np.dot(r.T,r)) normY=[-normX[1],normX[0]] b=n

我想在对象坐标中对二维加速度数据进行双重积分,以获得世界坐标中的二维位置。物体总是指向速度的方向(假设是火车)

因此,我尝试用积分对加速度值进行数值积分,将每一步的方向更改为世界坐标中先前的速度,由velocity verlet算法提供:

将numpy导入为np
从数学导入sqrt
从matplotlib导入pyplot作为plt
def旋转(a,新X轴):
r=newXAxis
normX=r/sqrt(np.dot(r.T,r))
normY=[-normX[1],normX[0]]
b=np.dot(np.array([normX,normY]).T,a)
返回(b)
“”“如果v>1 km/h或给定的任何速度,则返回true”“”
def正在移动(deltaXPosition、deltaYPosition、deltaTime、FasterHankMH=1.0):
x=三角定位
y=三角洲位置
t=德尔塔梯姆
如果t*t==0:
返回错误
如果hasattr(x),“len”:
x=x[0]
如果hasattr(y),“len”:
y=y[0]
如果hasattr(t),“len”:
t=t[0]
速度=浮动(快行程MH)
返回((x*x+y*y)/(t*t)>0.077160*速度*速度)
def velocity_verlet_集成(Xacc、Yacc、,
x0=0,y0=0。,
vx_0=0,vy_0=0,
正向=np.数组([1.0,0.0]):
vx=np.零(len(Xacc))
vy=np.零(len(Xacc))
x=np.0(len(Xacc))
y=np.0(len(Xacc))
x[0]=x0
y[0]=y0
vx[0]=vx_0
vy[0]=vy_0
对于范围内的i(len(Xacc)-1):
dt=Xacc[i+1]-Xacc[i]
a=旋转(Yacc[i,:],向前)
x[i+1]=x[i]+vx[i]*dt+1.0/2.0*a[0]*dt*dt
y[i+1]=y[i]+vy[i]*dt+1.0/2.0*a[1]*dt*dt
如果移动(x[i+1]-x[i],y[i+1]-y[i],dt):
正向=np.数组([x[i+1]-x[i],y[i+1]-y[i]])
aNext=旋转(Yacc[i+1,:],向前)
vx[i+1]=vx[i]+dt*(a[0]+aNext[0])/2
vy[i+1]=vy[i]+dt*(a[1]+aNext[1])/2
返回x,y
通过以下简单的圆周运动来测试这一点:

“测试圆”
向心=-0.2
N=0.01
xCircle=np.array(范围为int(100*10**N))/float(10**N)
yCircle=np.数组([[0.0,向心]表示xCircle中的i])
xvvi,yvvi=速度与积分(xCircle,yCircle,0,0,1,0.)
#策划它
plt.绘图(xvvi,yvvi,“.-”,标签=”带有“velocity verlet”集成的位置)
这会导致向外漂移,因为当前方向基于最后一个速度,这显然是一个糟糕的近似值

有谁能给我指出一个更好的解决办法吗


一些想法:
  • 最佳情况下,我们需要世界坐标系中的最后一个和下一个速度,通过平均(例如相加)这些速度来获得更好的近似值。但在我的方法中,下一个速度取决于世界坐标中的下一个加速度,而下一个加速度又需要下一个方向(追逐自己的尾巴)
  • 如果我用我的方法得到下一个速度的第一个近似值,从而得到下一个方向,我可以用这个来通过上面的想法改进当前方向。现在我可以对下一个速度和下一个方向做一个更好的近似,然后再次使用它来改善当前方向。这可能是一个可行的解决方案,尽管它看起来真的很难看
根据我的想法(在我问题的末尾),我添加了一个难看的解决方案,因此我不会接受它作为答案

def my_集成(t,a_对象,
x0=0,y0=0。,
vx_0=0,vy_0=0,
正向=np.数组([1.0,0.0]):
v=np.零((len(t),2))
p=np.0((len(t),2))
p[0,:]=np.array([x0,y0])
v[0,:]=np.数组([vx_0,vy_0])
v[1,:]=np.数组([vx_0,vy_0])
对于范围内的i(透镜(t)-1):
“这感觉像一个黑客”
对于范围(10)内的j:
dt=t[i+1]-t[i]
a=旋转(a_对象[i,:],v[i,:]+v[i+1,:]))
p[i+1,:]=p[i,:]+v[i,:]*dt+1.0/2.0*a*dt*dt
aNext=旋转(a_对象[i+1,:],v[i,:]+v[i+1,:]))
v[i+1,:]=v[i,:]+dt*(a+aNext)/2。
如果i
对于绘图,添加以下内容:

plt.plot(np.cos(pi*2*np.array(range(21))/20)/向心,
(np.sin(pi*2*np.array(range(21))/20)+1)/向心,
“x”,标签为“地面真相”)
myi=my_积分(t,a,0,0,1,0.)
plt.plot(myi[:,0],myi[:,1],“--”,label='position with my integration')
plt.legend(fontsize='x-small')

您是否有要在某处实现的方程式?比较方程式时,更容易检查代码是否正确。@EdgarH我添加了一个到维基百科的链接,在那里我得到了velocity verlet的方程式。其余的都是我自己做的,因为我还没有找到一个已知的解决方案。不过,这似乎是一个标准问题。一定有答案的。。。我真的认为你应该接受这个答案。第一个解的误差来自于运动方程中高阶项的省略。这正是您通过术语dt*(a+aNext)/2在解决方案中添加的内容。“我不知道怎样才能做得更干净。”不过,我真的希望找到一个标准的解决方案。
dt*(a+aNext)/2
部分也在我的初始解决方案中。主要区别实际上是
旋转部分使用的方向。