OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8249|回复: 22

MATLAB 串口显示四轴姿态

[复制链接]

163

主题

1223

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2014-5-21
在线时间
339 小时
发表于 2016-4-19 10:37:36 | 显示全部楼层 |阅读模式
这里先分享一下,我用MATLAB写的一个串口助手小程序



下面是21IC.COM  "" 的帖子分享:

开始做四轴了,一步一步来,东西实在很多,比较杂。先做matlab上位机,主要用来做数据分析,等板子到了可以写飞控的程序了,从底层一层一层开始写。。希望能好好的完成它。。。关于matlab上位机,首先做个姿态显示,然后等板子来了,把板子底层程序写好后,加上matlab的串口接收部分,基本的环境就算搭建好了。。。。

        这个代码写了一天,写到最后出现戏剧性的一幕,实在是太恶心了哈。。开始自己的想法就是通过输入pitch roll yaw三个欧拉角,然后在空间中现实飞机的姿态,为了学习matlab翻了matlab的书,还看了线性代数,为了画这个姿态图,看了高中的立体解析几何,向量运算等。。。都是泪啊,说回正题,首先计算xOy平面中的转动,也就是yaw轴,这个相对比较简单,让三角形的三个点分别在图中的大圆和小圆上,如图所示:

yaw解决了之后就需要解决pitch了,就是俯仰角,约定是以坐标的(0 0 0)点进行旋转的,也是两个圆的圆心,所以算pitch只需要在xOz平面内计算,通过sin(pitch)可以算出来A B C三个点在Z轴上的坐标了,这里需要注意下,A点变换后,相对应的X轴变化是cos(pitch),y轴也是,算到这里会发现一个问题,用matlab算B C连个点的时候,只需算B或者C,解出来是有两个解的,一个B一个C,B和C必须分辨清楚,否则在计算roll的时候因为 B C没有分清楚会导致roll旋转方向不确定,后面再说B C怎么分辨。
        接下来是计算 roll了,需要计算B 点和C点在Z轴上的坐标,因为我们是绕着(0 0 0)转的,而不是绕着BC的终点转,所以无法通过BC的长度乘以sin(roll)计算,所以通过圆心做一条直线与BC平行,假设与AC交与F点,

%          A

%       E  O  F

%   B      D     C
无论pitch和yaw怎么转,OF都是在xOy平面的,方便计算,通过sin(roll)*OF的长度就可以得到F在Z轴的变化,从而通过等比可以的到C在Z轴的变化,B点变化和C是一样的,方向相反,之后将B C的坐标在xOy平面做cos(roll)缩放就可以的到最终的三角形的三个坐标了。
       接着讲BC的分辨问题,想来想去只想到一个比较简单的方法,我们算出来BC并不知道哪个是B,哪个是C,不过我们可以制定一个B‘ 点,那就是我们取一个DB方向的方向向量n,跟随三角形旋转,让它始终指向定义的DB方向,然后可以计算OB OC分别和向量n的内积,因为n与OB为锐角,与OB为钝角,so,n 与OB点乘为负数,与OC点乘为正数,从而区分出B点和C点 。
        上面想法看起来不错,但是怎么让向量n随着yaw角转动呢,灵机一闪,线性代数书的矩阵里面有个旋转矩阵啊,立马拿过来验证,发现可以很好的运行,然后想到一个问题,如果某种情况三角形roll为90度,DB的分量在xOy平面为0,这个方法就无效了啊(其实这个问题应该不会出现,因为我们是线计算yaw 然后计算pitch,在计算pitch的时候分辨BC亮点,压根就还没开始计算roll),那用三维旋转矩阵就可以解决这个问题啊,嗯嗯,又灵机一闪,之前看过捷联惯性导航书上讲了方向旋转矩阵啊,应该可以用。把方向余弦拿过来计算一下,和用xOy平面的旋转举证效果一样,到此忽然想到一个非常十分**的事情,妈蛋,三角形三个点全部用这个方向余弦矩阵旋转就可以了啊,立马改程序,不到十分钟就改完了,程序运行良好,都是泪。。。。。。不过自己的算法不能半途而废啊,后面还是把自己的算法完成,并且也可以很好的运行。。。不过因为用了matlab的符号运算,速度和用方向余弦计算比起来慢很多,后面还是用方向余弦算吧。。。。。。。
下面贴代码:


[mw_shl_code=golang,true]%%
%2014.7.19 由 sky.zhou 编写
function DrawAttitude(pitch,roll,yaw)
%%
%用于显示飞机姿态,输入为pitch,roll,yaw。
%自己的2B算法算的太慢了,我勒个去。。。还是用方向余弦吧
mode = 2       %标记用那种方法进行计算,1:表示用自己写的2B算法进行计算,2表示用方向余弦矩阵进行计算
   
%pitch = 60;
%roll = 45;
%yaw = 35;
r1 =3;        %大圆半径
r2 = 0.618*r1;    %小圆半径
  
if mode == 2
     pitch = -pitch;   %角度定义不一样,改一下
     roll = -roll;     %角度定义方式不一样,自己习惯改就好,看你希望是以怎样的方向转
end
dc = [cosd(yaw)*cosd(pitch)-sind(yaw)*sind(roll)*sind(pitch)   sind(yaw)*cosd(pitch)+cosd(yaw)*sind(roll)*sind(pitch)   cosd(roll)*(-sind(pitch));
       sind(yaw)*(-cosd(roll))                          cosd(yaw)*cosd(roll)                            sind(roll)        ;
       cosd(yaw)*sind(pitch)+sind(yaw)*sind(roll)*cosd(pitch)   sind(yaw)*sind(pitch)-cosd(yaw)*sind(roll)*cosd(pitch)      cosd(roll)*cosd(pitch) ]
%三角形规约:A为定点,B C为两边的角,具体方位如下
%       A
%     B   C
t_fpa = 35;      %三角形定点角度设置为40度,fpa On behalf of Fixed point angle
t_b = (180 - t_fpa) / 2;
t_c = t_b;
  
if t_fpa > asind((r2/r1))*2
     t_fpa = asind((r2/r1))*2
end
  
%xd,yd,zd存放真是数值,与符号xyz区分开来
%约定 xd yd zd 第 1 2 3 4位分别代表三角形ABC的 A、B、A、C坐标
if mode == 2
    xd=[3 -1.2735;3 -1.2735];
    yd=[0  1.3474;0  -1.3474];
    zd=[0 0;0 0];
    %上面几个初始化的点是根据 定义的。
    %pitch = 0;
    %roll = 0;
    %yaw = 0;
    %r1 =3;        %大圆半径
    %r2 = 0.618*r1;    %小圆半径
else
    xd=[];
    yd=[];
    zd=[];
    tempA =[];     %保存中间计算角度,目前之用来保存角BOA
end
    temp = [];
if mode == 2
    temp = [xd(1,1) yd(1,1) zd(1,1);
            xd(1,2) yd(1,2) zd(1,2);
            xd(2,2) yd(2,2) zd(2,2)];
    temp = temp*dc;
    xd = [temp(1:2,1)';temp(1,1),temp(3,1)]
    yd = [temp(1:2,2)';temp(1,2),temp(3,2)]
    zd = [temp(1:2,3)';temp(1,3),temp(3,3)]
    %到此位置,方向余弦矩阵已经计算完毕,可以直接用后面的函数进行显示
end
  
if mode == 1      %执行自己的2B算法
%xs ys zs分别问记录方程的解 xs 为sysm缩写
syms x y z r xs ys zs;                                      %x y z 惯性坐标系中三个正交基,r为xOy平面中的大圆和小圆半径
%定义各点的坐标符号参数
syms xa ya za xb yb zb za zb zc ;
  
%%
c1 = sym('x^2+y^2 = r^2');                         %大圆方程
c1 = subs(c1,'r',r1)                               %换成实际数值
  
c2 = sym('x^2+y^2 = r^2');                         %校园方程,可以表达为:c2 = 'x^2+y^2 = r^2',效果是一样的
c2 = subs(c2,'r',r2)
  
l1 = sym('cosd(yaw)*y=sind(yaw)*x')
%l1 = sym('y=tand(yaw)*x')                         %不用这个公式是因为这个公式有零点,90和-90无法使用
%l1 = subs(l1, 'yaw', yaw)                         %换成实际数值,这里不要转成实际数值,为了方便subs的运算
%%
[xs ys] = solve(c1,l1,'x','y')                     %注意,这里算出来的xd yd是符号变量,matlab自动转换了,下面重新对其赋值,可以变回数值变量
   
%双百分号还可以类似于分类的作用,挺好。
temp = subs([xs;ys])
  
%%
%计算A点坐标
if yaw > -90 && yaw < 90                             %判断角度的范围,用来选择在坐标中三角形的顶点是正还是负
     %这个可能有点难理解,角度确定了,就可以知道焦点在x轴的正负,从前两个数值中取对应的X解后,然后取对应的Y的解
     temp = temp([temp(1:2)>0;temp(1:2)>0])
elseif yaw == -90
     temp = [ 0 ;temp(temp<0)]
elseif yaw == 90
     temp = [ 0 ;temp(temp>0)]
else
     temp = temp([temp(1:2)<0;temp(1:2)<0])
end
  
%得到在XOY平面中三角形定点的第一个解
xd = [xd temp(1)]
yd = [yd temp(2)]
  
%%
%计算B点坐标
  
%temp计算出来表示的是 AB段的长度,
%       A
%       O
%    B  D  C
%其中 sind(t_b/2)*r2 表示的是OD段的长度,cosd(t_b/2)*r2是BD段的长度,
%temp计算的最终结果是AB的长度
%利用三角形边与对面角正弦成比例进行运算
%   AB     BC          A0                B0
% ----- = -----       -----     =   ---------
% sin(C)  sin(A)     sin(角ABO)      sin(角OAB)(ps:A的一半)
%   可以求出角ABO,然后通过内角和可以求出角AOB
%   AB                BO         
% -----       =     --------      可以求出AB长度,简化代码如下   
% sin(角AOB)        sin(角OAB)   
% (180 - asind((r1/r2)*sind(t_fpa/2)) - (t_fpa/2)) 为角BOA的大小
tempA = sym('(180 - asind((r1/r2)*sind(t_fpa/2)) - (t_fpa/2))');
temp = sym('(r2/sind(t_fpa/2))*sind(tempA)');
tempA = subs(tempA);
temp = subs(temp);
  
  
%temp = subs(sym('sqrt(((sind(t_b/2)*r2)+r1)^2 + (cosd(t_b/2)*r2)^2)'));
  
%假设 符号 xa ya 为 A点的坐标,x,y为要求的B点坐标
temp = subs(sym('(x-xa)^2 + (y-ya)^2 = temp^2'),'temp',temp);
%将xa和ya换成数值xa和ya,嵌套换的
temp = subs(subs(temp,'xa',xd(1)),'ya',yd(1))
[xs ys] = solve(temp,c2,'x','y')   
  
%通过下面的计算就已经可以得到 B C的坐标了
temp = subs([xs;ys])
  
%下面需要做的是区别哪个点是A,哪个点是B。
%%
%    下面是在xOy平面内的旋转
%    B  
%    D  O  A       yaw=0度的时候三角型在X0Y平面的方位,其中水平位置为x轴竖直方向为Y轴
%    C
%    取一个与DB方向一样的方向向量n(0,1)
%    用旋转矩阵让它跟三角形同步旋转
%    因为n与OB为锐角,与OB为钝角,so,n与OB点乘为负数,与OC点乘为正数,从而区分出B点和C点
%%
%    为了避免roll为90度的时候按照之前的定义方向向量n=(0,0),区分不出来B和C点,所以用方向余弦矩阵进行计算
%方向余弦矩阵定义
%dc = [cosd(yaw)*cosd(pitch)-sind(yaw)*sind(roll)*sind(pitch)   sind(yaw)*cosd(pitch)+cosd(yaw)*sind(roll)*sind(pitch)   cosd(roll)*(-sind(pitch));
%      sind(yaw)*(-cosd(roll))                          cosd(yaw)*cosd(roll)                            sind(roll)        ;
%      cosd(yaw)*sind(pitch)+sind(yaw)*sind(roll)*cosd(pitch)   sind(yaw)*sind(pitch)-cosd(yaw)*sind(roll)*cosd(pitch)      cosd(roll)*cosd(pitch) ]
%%算到这里的时候我发现只要在xOy平面内将三角形的初始化坐标ABC三个点输入后,用方向余弦矩阵算就可以了,然后花了10分钟不到的时间就实现了
%不过这里还是决定把这个方法写完。。。都是泪。。。。。。。。。。。。。。。。。
%%
n  = [0  1  0]                                         %方向向量
n  = n*dc                                               %对方向向量进行旋转
%约定 xd yd zd 第 1 2 3 4位分别代表三角形ABC的 A、B、A、C坐标
n = n*[temp(1);temp(3);0]
if n > 0       %说明夹角是锐角,该角是B点
     xd = [ xd temp(1) xd temp(2)]
     yd = [ yd temp(3) yd temp(4)]
else
     xd = [ xd temp(2) xd temp(1)]
     yd = [ yd temp(4) yd temp(3)]
end
  
%处理成变成矩阵形式
xd = [xd(1:2);xd(3:4)]
yd = [yd(1:2);yd(3:4)]
  
%当存在pitch角度的时候,X坐标做相印调整
xd = xd.*cosd(pitch)
yd = yd.*cosd(pitch)
  
  
%%
%约定 xd yd zd 第 1 2 3 4位分别代表三角形ABC的 A、B、A、C坐标
%计算z中A的坐标,其中B和C是相等的
zd = [zd sind(pitch)*r1]
  
%下面OD的长度,然后可以计算出B和C在Z轴上的坐标,也就是D点的坐标
od = (sind(tempA - 90)*r2)
%zd = [zd temp;zd temp]
  
%计算roll状态下B和C的坐标
%          A
%       E  O  F
%     B    D    C
%    先计算在roll下OF的长度,然后算F在Z轴的高度,然后等比后算B和C在Z轴的高度
%下面计算OF的长度
l2 = tand(t_fpa/2)*r1
%下面计算F在Z轴上的变化高度
l2 = sind(roll)*l2
%下面计算C点在Z轴上的变化高度,通过相似三角形计算
l2 = l2*(r1+od)/r1
  
zd = [zd -l2;zd l2]
%x,y轴根据picth角度缩放
yd(:,2) = yd(:,2).*cosd(roll)
xd(:,2) = xd(:,2).*cosd(roll)
  
%额。。这方法写的心力交瘁。。。。。。。还是方向余弦好。。。四元素再学。。。。。。
  
  
end
surf(xd,yd,zd)
axis([-3 3 -3 3 -3 3])
xlabel('X')
ylabel('Y')
zlabel('Z')
text(xd(1,1),yd(1,1),zd(1,1),'A点')
text(xd(1,2),yd(1,2),zd(1,2),'B点')
text(xd(2,2),yd(2,2),zd(2,2),'C点')
%%
%测试用圆
hold on
alpha=0:pi/20:2*pi;
x=r1*cos(alpha);
y=r1*sin(alpha);
plot(x,y);
  
hold on
x=r2*cos(alpha);
y=r2*sin(alpha);
plot(x,y);
  
hold off
end[/mw_shl_code]


MATLAB编辑界面.jpg

MatLabCOM V1.0 matlab214编写的串口助手.rar

7.18 MB, 下载次数: 2915

彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
160
金钱
160
注册时间
2014-11-28
在线时间
27 小时
发表于 2016-5-6 12:51:14 来自手机 | 显示全部楼层
回复 支持 反对

使用道具 举报

163

主题

1223

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2014-5-21
在线时间
339 小时
 楼主| 发表于 2016-5-6 15:19:31 | 显示全部楼层

这帖子一般都喜欢下载不说话,你是第一个回复的哈哈
彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
回复 支持 反对

使用道具 举报

4

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
160
金钱
160
注册时间
2014-11-28
在线时间
27 小时
发表于 2016-5-10 12:00:02 | 显示全部楼层
cornrn 发表于 2016-5-6 15:19
这帖子一般都喜欢下载不说话,你是第一个回复的哈哈

我喜欢捧人场~~
回复 支持 反对

使用道具 举报

11

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2014-7-29
在线时间
41 小时
发表于 2016-5-11 21:43:42 | 显示全部楼层
厉害、膜拜大神。。
读不在三更五鼓,功只怕一曝十寒。
回复 支持 反对

使用道具 举报

33

主题

481

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
5075
金钱
5075
注册时间
2013-10-4
在线时间
654 小时
发表于 2016-5-13 15:54:53 | 显示全部楼层
顶起
回复 支持 反对

使用道具 举报

4

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2016-5-28
在线时间
14 小时
发表于 2016-5-29 17:42:48 | 显示全部楼层
不管用没用上 都先谢谢啦
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-16
在线时间
48 小时
发表于 2016-6-3 11:53:20 | 显示全部楼层
顶一下 谢谢分享
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-6-16
在线时间
7 小时
发表于 2016-6-22 14:31:00 | 显示全部楼层
回复 支持 反对

使用道具 举报

7

主题

34

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
333
金钱
333
注册时间
2013-3-9
在线时间
32 小时
发表于 2016-6-23 11:08:38 | 显示全部楼层
很值得学习和借鉴的东西
回复 支持 反对

使用道具 举报

26

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
396
金钱
396
注册时间
2014-2-10
在线时间
67 小时
发表于 2016-8-6 23:33:22 | 显示全部楼层
最近正在弄这个,真心感谢楼主
回复 支持 反对

使用道具 举报

163

主题

1223

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2014-5-21
在线时间
339 小时
 楼主| 发表于 2016-8-9 15:11:43 | 显示全部楼层
轩辕zh 发表于 2016-8-6 23:33
最近正在弄这个,真心感谢楼主

不客气,多多分享
彼高丽者,边夷贱类,不足待以仁义,不可责以常礼。古来以鱼鳖畜之,宜从阔略。若必欲绝其种类,恐兽穷则搏。
回复 支持 反对

使用道具 举报

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-8-3
在线时间
6 小时
发表于 2016-8-20 10:07:48 | 显示全部楼层
厉害啊!学习一下。谢谢楼主。
回复 支持 反对

使用道具 举报

3

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
443
金钱
443
注册时间
2016-7-11
在线时间
84 小时
发表于 2016-9-20 18:21:41 | 显示全部楼层
只想说 MTLAB真 强大
回复 支持 反对

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-7-14
在线时间
29 小时
发表于 2016-9-21 09:28:02 | 显示全部楼层
厉害 膜拜
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2017-9-1
在线时间
0 小时
发表于 2017-9-1 09:37:25 | 显示全部楼层
学习一下
回复 支持 反对

使用道具 举报

10

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2014-11-7
在线时间
52 小时
发表于 2017-10-6 21:36:41 | 显示全部楼层
厉害 膜拜
回复 支持 反对

使用道具 举报

10

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
298
金钱
298
注册时间
2016-4-9
在线时间
97 小时
发表于 2018-4-12 21:27:43 | 显示全部楼层
matlab真强大
回复 支持 反对

使用道具 举报

28

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
494
金钱
494
注册时间
2017-10-14
在线时间
76 小时
发表于 2018-4-18 16:26:53 | 显示全部楼层
可以,很6
回复 支持 反对

使用道具 举报

3

主题

144

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
498
金钱
498
注册时间
2018-3-5
在线时间
59 小时
发表于 2018-4-18 16:35:39 | 显示全部楼层
mark,谢谢分享
回复 支持 反对

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2019-8-21
在线时间
12 小时
发表于 2019-10-3 11:25:22 | 显示全部楼层
到此一游
回复 支持 反对

使用道具 举报

4

主题

16

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2019-10-29
在线时间
5 小时
发表于 2019-10-29 17:26:39 | 显示全部楼层
学习楼主,谢谢
回复 支持 反对

使用道具 举报

2

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
162
金钱
162
注册时间
2019-9-27
在线时间
37 小时
发表于 2019-12-4 19:35:20 | 显示全部楼层
dd楼主
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表