我尝试使用Matlab跟踪编码器的旋转对象。 我有一个编码器给我对象的角度位置,然后我将这些信息传递给激光器,但我怎样才能以与物体相同的速度移动激光器?因为现在激光比物体慢,所以它不能很好地跟随它! 我写了这段代码,有没有人有任何建议?
Alpha=pi/2
Positions = [];
t0 = clock;
while etime(clock,t0)<20;
position = data.Position; %here I read the angular position from the encoder
Positions = [Positions position];
A = [floor(Positions/360)];
angPos = position-(floor(position/360))*360;
AngPos = [Positions - A*360];
angRad = angPos*pi/180;
AngRad = [AngPos*pi/180];
Angle = angRad+Alpha;
thetaX = atan(cos(Angle).*(r/d));
thetaY = atan(sin(Angle).*(r/d));
VoltX=-(5/20)*thetaX*180/pi;
VoltY=(5/20)*thetaY*180/pi;
VoltageLimit = 10;
if (max(abs(VoltX))>VoltageLimit) || (max(abs(VoltY))>VoltageLimit)
error('Voltages too large');
end
session.outputSingleScan([VoltX VoltY]); %here I send the laser the angular position obtained before
data = motorA.ReadFromNXT();
end
我知道我应该添加速度,所以我可以用与物体相同的速度移动激光,但我不知道如何给激光器提供速度值!!
sec = etime(clock,t0);
Sec = [Sec sec];
vel=(diff(Positions)/diff(Sec));
Vel = [Vel vel]; %(deg/s);
也许这是一个愚蠢的问题,但我在Matlab中是一个新手! 谢谢!!!
答案 0 :(得分:0)
如何跟踪在输入循环之前初始化为空的某个向量n = 3
中的omega = []
先前角速度。您还应该记住上一次迭代的时间戳prev_t = []
以及之前的角度prev_a = []
,以便执行此操作。
在每次迭代中,您可以通过管理n
之前观察到的速度的向量来更新您对当前角速度的猜测
current_t = clock();
if ~isempty(prev_t)
if length(omega) == n
omega(1) = [];
end
delta_omega = Angle - prev_a;
if delta_omega < 0
delta_omega = delta_omega + 2 * pi;
end
omega = [omega, delta_omega / etime(current_t, prev_t)];
end
prev_t = current_t;
prev_a = Angle;
角速度的估计可能是这些n
先前测量的某些平均值,或许est_omega = median(omega)
对异常值有些稳健。 delta_omega
的重复校正假设角度报告在0到2 pi之间,并且角度随着旋转而增加。如果您的角度不同,则应调整此校正。
然后,在计算VoltX
和VoltY
之前,您可以使用当前角速度的估算来预测更正的Angle = Angle + est_omega * dt;
,其中dt
是您的猜测反馈循环的延迟。你可以凭经验选择。应计算est_omega
,Angle
仅更正if length(omega) == n
。您不想计算空列表的median
。
另外,我看到你分别从一些atan(sin(Angle))
或atan(cos(Angle))
计算x和y电压。我不确定这是否正确。我相信这些电压应该与sin(Angle)
或cos(Angle)
成比例而不应用atan
。
我认为这个解决方案可以很好地工作,但是对于你在这里所做的事情,有大量的控制理论可以用来解决你的问题,以更复杂的方式解决问题。