相同方程,Pylab和Octave结果不同

8 投票
1 回答
541 浏览
提问于 2025-04-17 05:46

我正在把在Octave中写的代码移植到pylab中。其中一个移植过来的公式在Python中的结果和在Octave中的结果差别很大。

最好的解释方式是展示Octave和pylab用同一个公式生成的图。

下面是Octave中原始公式的一个简化版本。在这个小测试脚本中,保持phi为零,绘制了函数在大约(-π, π)范围内的结果:

clear
clc
close all

L1 = 4.25; % left servo arm length
L2 = 5.75; % left linkage length
L3 = 5.75; % right linkage length
L4 = 4.25; % right servo arm length
L5 = 11/2; % distance from origin to left servo
L6 = 11/2; % distance from origin to right servo

theta_array = [-pi+0.1:0.01:pi-0.1];
phi = 0/180*pi;

for i = 1 : length(theta_array)

theta = theta_array(i);

A(i) = -L3*(-((2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1)-2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1))/(2*L3*sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2))-((2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1)-2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1))*(-(L6+L5-cos(phi)*L4-cos(theta)*L1)^2-(sin(phi)*L4-sin(theta)*L1)^2-L3^2+L2^2))/(4*L3*((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)^(3/2)))/sqrt(1-(-(L6+L5-cos(phi)*L4-cos(theta)*L1)^2-(sin(phi)*L4-sin(theta)*L1)^2-L3^2+L2^2)^2/(4*L3^2*((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)))-((cos(theta)*L1)/sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)-((sin(theta)*L1-sin(phi)*L4)*(2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1)-2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1)))/(2*((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)^(3/2)))/sqrt(1-(sin(theta)*L1-sin(phi)*L4)^2/((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)))*sin(acos((-(L6+L5-cos(phi)*L4-cos(theta)*L1)^2-(sin(phi)*L4-sin(theta)*L1)^2-L3^2+L2^2)/(2*L3*sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)))-asin((sin(theta)*L1-sin(phi)*L4)/sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)^2+(sin(phi)*L4-sin(theta)*L1)^2)));

end

plot(theta_array,A)

生成的Octave图像看起来是这样的:

Octave result

同样的公式被复制粘贴到Python中,进行了以下替换:把'^'换成'**',把'acos'换成'arccos',把'asin'换成'arcsin'。然后在保持phi为零的情况下,绘制了相同范围的theta:

from pylab import *

# physical setup
L1 = 4.25; # left servo arm length
L2 = 5.75; # left linkage length
L3 = 5.75; # right linkage length
L4 = 4.25; # right servo arm length
L5 = 11.0/2.0; # distance from origin to left servo
L6 = 11.0/2.0; # distance from origin to right servo

theta = arange(-pi+0.1,pi-0.1,0.01);
phi = 0/180.0*pi

def func(theta,phi):

A = -L3*(-((2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1)-2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1))/(2*L3*sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2))-((2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1)-2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1))*(-(L6+L5-cos(phi)*L4-cos(theta)*L1)**2-(sin(phi)*L4-sin(theta)*L1)**2-L3**2+L2**2))/(4*L3*((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)**(3/2)))/sqrt(1-(-(L6+L5-cos(phi)*L4-cos(theta)*L1)**2-(sin(phi)*L4-sin(theta)*L1)**2-L3**2+L2**2)**2/(4*L3**2*((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)))-((cos(theta)*L1)/sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin((phi)*L4-sin(theta)*L1)**2)-((sin(theta)*L1-sin(phi)*L4)*(2*sin(theta)*L1*(L6+L5-cos(phi)*L4-cos(theta)*L1)-2*cos(theta)*L1*(sin(phi)*L4-sin(theta)*L1)))/(2*((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)**(3/2)))/sqrt(1-(sin(theta)*L1-sin(phi)*L4)**2/((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)))*sin(arccos((-(L6+L5-cos(phi)*L4-cos(theta)*L1)**2-(sin(phi)*L4-sin(theta)*L1)**2-L3**2+L2**2)/(2*L3*sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)))-arcsin((sin(theta)*L1-sin(phi)*L4)/sqrt((L6+L5-cos(phi)*L4-cos(theta)*L1)**2+(sin(phi)*L4-sin(theta)*L1)**2)))

return A

f = figure();
a = f.add_subplot(111);

a.plot(theta,func(theta,phi))

ginput(1, timeout=-1); # wait for user to click so we dont lose the plot

Python的结果看起来是这样的: Python result

我无法确定造成这些差异的原因,有什么想法吗?

1 个回答

12

试试在代码开头加上 from __future__ import division,这样可以避免因为整数除法而产生的错误。

撰写回答