标定记录 2nd

2020.4.27


陀螺仪问题解决


先做线(杜邦线),用2s锂电池单独给陀螺仪供电后问题解决

  • 每次转一圈的数据比较稳定,每转1080°陀螺仪若干数据之间的差不超过20

再次标定


  • 由于陀螺仪数据稳定,需要再次标定,标定后角度经验证比较准确:

    • 每转三圈读取的角度值在1080°±3°之间浮动
  • 角度标准不同后,还需要整体重新标定,结果图示如下:

    • 验证正y轴

      • y方向行进约 1300 mm,x方向偏移量约为 0.7 mm

    • 验证假x轴

      • x方向行进约 1400 mm,y方向偏移量约为 10 mm

    • 验证正y轴转为假x轴后沿正y轴走

      • 这里最终x方向偏移量约 4 mm

  • 根据上图走假x轴的x、y位移数据 acrtan(10.04 / 1373)= 0.4189653°

​ 又推车转角为 89.5257507°

89.5257507° + 0.4189653° = 89.944716° ≈ 90°

​ 在这里再次验证了之前的结论

重复性误差


  • 在这里我推车测试了8条不同的路径(左下角到右上角),并且把每条路径最终的x、y坐标都列了出来,横线代表8个值的平均值,由于条件有限无法知道精确的实际值,所以把平均值当作实际值。

  • 结果发现,在推车直线距离大概 1.5 m的情况下,小车在x、y方向都可能存在5mm内的偏移

旋转误差


  • 这里每次旋转 3 - 4 圈后回到起始点,来观察小车的定位误差情况

  • 顺逆时针都测试了,发现顺时针坐标整体偏移了 5 mm,然而逆时针坐标整体偏移了约 20 mm

为何会有偏移?


  1. 由上图可以发现转三圈的角度值都是1080°左右,说明陀螺仪提供的角度数据没有问题

  2. 旋转算法matlab程序实现是否有问题?

    • 我把程序中 alpha 和 L 的值都设为 0,再次转3圈看结果:

      结论是与旋转算法无关测试结果照样有十几到二十多毫米的偏移

(这里发现路径图中由于是随动中心,会绕中心转圈,是对的,之前是车的中心,所以路径图比较奇怪)

  1. 直行算法matlab程序实现是否有问题?**(由于在家标定时旋转角度方向变了,我改了一部分matlab代码,所以怀疑是不是这个有问题)

    • 我把之前 Adams 的仿真理想数据带入现在的matlab程序,并且在程序里再次分别验证走正y轴,假x轴:正y轴的x方向偏移 0 mm;正x轴的y方向偏移 1.2 mm 比较理想,证明程序无误
  2. 综上,那就意味之标定的系数(8个)还是不准,那就再小心的标定一次

再再次标定


  • 这次标定不一样,电脑不用放在车上了,标定也用蓝牙传数据(这周第一次整体标定电脑还是放在车上的);并且,走一个方向多次重复取平均值。

  • 这一次标定效果如下:

    • 验证正y轴

      • y方向行进约 1400 mm,x方向偏移量约为 0.25 mm

    • 验证假x轴:(这次两边测得正好是90°,没办法每次都测的不一样,这个车有一边有问题)

      • x方向行进约 1400 mm,y方向偏移量约为 1.293 mm

    • 验证正y轴转为假x轴后沿正y轴走

      • 这里最终x方向偏移量约 4 mm,和这周第一次标定的效果

再次看看旋转的误差大小

  • 旋转三圈回到起始点,依然会有 10 - 20 mm的坐标偏移

结论


  考虑到标定时的车身的振动,旋转时车身的振动,自身操作使随动轮前后小幅度摇摆造成回程差等等的条件受到限制。

  这一套系统的精度目前看来就是上述的研究结果。

基于matlab的蓝牙串口通信

一、前言

  用蓝牙做主控串口和电脑通信的想法呢,是因为实践标定的时候需要持续的很稳的推动小车,而且要把jlink将电脑和主控连起来debug看数据又得给主控供5V电(当时忘记充电宝可以供5v电了,一时英明被摧毁),所以无线就没多想了。想过做很长的线、把电脑放在电竞椅上跟着小推车推着走,都不太靠谱,所以在标定的时候还是把电脑架在了小推车上

  标定进度完成了大半,现在得点空,还是想把这个蓝牙无线通信做起来,因为我在想这个方法是不是可以把WLan的网卡看参数替换掉,个人感觉那种Labview结合Matlab🐂是🐂,但是有点太麻烦了,路由器架在车上得自带一个充电宝,主控上的网线插槽老是松,还要先生成调试组文件带入主控更新…我电脑现在也是再也连不上了,所以这个我觉得某种程度上有一些必要


二、尝试pybluez模块

  之前竞培营的时候买过蓝牙,所以家里留了一个(也是为什么想蓝牙通信)。主控串口连接蓝牙再和电脑通信,问题不在串口,而在电脑是如何接收到的数据?什么形式的数据?怎么处理这类数据成为我想要看到的数据甚至生成动态曲线?由于觉得python无所不能,第一时间想到的就是它,结果在下载pybluez模块时出现问题,电脑提示我没有Microsoft Visual C++ 2014的组件工具,这个我百度了也是很多py模块下载时出现的问题

  有一个解决方法就是在一个国外大学提供实时更新的模块下载网站上先把需要的模块的类似安装包(whl类型文件)下载到本地,之后pip install 安装包绝对地址最后pip install 模块名称,不过这个方法我在尝试的时候仍然出现错误,个人认为是这个pybluez模块版本较老,有一些bug也比较正常

  这条路走不通,以后必须用到的时候再试试把。之后在想wifi也能无线传输数据,而且速率更高,pywifi模块的安装没有问题。不过我手上只有蓝牙模块啊,当务之急是选择什么方法在电脑上得到蓝牙传输的数据


三、Matlab成为选择

  此时,在寻找与蓝牙通信相关的过程中,看到了Matlab的字眼,对啊,之前怎么没想到它呢。说干就干,百度关键词Matlab蓝牙通信,果然就有,不过不多,好在matlab的使用者多,而且内置的help搜索向导非常方便,即使不太了解有的也有官方示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
%Examples
%Find available Bluetooth devices.

instrhwinfo('Bluetooth');
instrhwinfo('Bluetooth', RemoteName);
%Construct a Bluetooth object called b using channel 3 of a Lego Mindstorm robot with RemoteName of NXT.

b = Bluetooth('NXT', 3);
%Connect to the remote device.

fopen(b)
%Send a message to the remote device using the fwrite function.

fwrite(b, uint8([2,0,1,155]));
%Read data from the remote device using the fread function.

name = fread(b,35);
%Disconnect the Bluetooth device.

fclose(b);
%Clean up by deleting and clearing the object.

fclose(b);
clear('b');
  • 结合官方提供的例子,快速入手蓝牙通信,关键在于定义蓝牙的特定变量b = Bluetooth('NXT', 3);,以及fopen(b)来开启蓝牙通信。重点就在于数据的规范、格式。手册上介绍的函数如下:
Matlab蓝牙相关函数

You can read and write both text data (ASCII based) and binary data. For text data, use the fscanf and fprintf functions. For binary data, use the fread and fwrite functions.
你可以借助ASCII码或者二进制数据进行读写操作。对于txt数据使用fscanffprintf函数,对于二进制数据使用freadfwrite函数

  • 以下是目前我脚本中的蓝牙初始化操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
%% 配置蓝牙操作

instrhwinfo('Bluetooth');
instrhwinfo('Bluetooth','col_test');
col_test = Bluetooth('col_test',1);

% col_test.TimerPeriod = 0.1;
% col_test.TimerFcn = {@plotcallback,p};
col_test.Timeout = 10;


%% 开启蓝牙数据监控,同时开启定时器
% fopen(col_test);
try
fopen(col_test);
catch err
disp('col_test蓝牙通道打开失败');
flag = 0;
end

if err_flag
disp('col_test蓝牙通道成功打开');
fwrite(col_test,Command_data);
start(t);
end

通信接口的回调函数

  • 在搜索帮助中有对串口接收数据的中断回调函数,终端的类型我所了解的有
    • 设定接受字节数触发
    • 设定截至字符触发
    • 定时间间隔触发
  • 不过目前没尝试出来,而且我觉得也没有那个必要所以暂时搁置了研究

四、如何有效的接受主控数据

  如果需要监控主控数据,那么每一次就要同时接收数十个浮点数类型的数据。

  1. 接受的方式不可能是直接不停循环接收数据,那么对于高速率传输数据的串口,错误必然存在而且经验证发现错误率不低,所以需要加密再解码确保数据准确。
  2. 其次,由于测试发现fread函数接受蓝牙数据是以字节(8bit)为单位,多个字节数据如何正确转换为float类型我之前没接触过。
  3. 最后蓝牙的速率不出众,那么我也需要测试一下他的速度究竟能有多快?

4.1 报文形式发送与接收

  • 主控上的串口dma接收发送不必多说,使用串口六,定义两个结构体Bluez_TXBluez_RX包含同样的两帧头两帧尾,那么在Matlab脚本中就需要相似的对于报文的解包,这一部分不难,那么我认为matlab接收数据的优点在于in/outputbuf数据一边进另一边出,在读取过程中的操作十分方便。
  • 还有一点就是我的脚本中做到,matlab向主控发送一帧数据,命令主控开始发送数据给蓝牙从而开始数据监控。也有停止命令,非常方便。操作就是在主控中的dma发送函数判断一个标志位(发送函数写在一个任务中)

4.2 多个单字节与浮点数的转换

  • 已知,主控中的dma发送是将发送结构体变量bluez_tx的头指针作为地址,那么这种方式下浮点数就是按一般的占据4字节进行发送。在Matlab中可以接收到4个字节与该浮点数对应。
1
2
3
raw_data1 = [byte1 byte2 byte3 byte4];
temp = uint8(raw_data1);
stRobot_x(count) = typecast(temp,'single');
  • 通过上述方法进行通信之后的变量类型转换成功

4.3 速率监测

  • 一开始我都是用串口调试助手来研究的,没有用上主控,中间尝试过一次发现主控确实在发送数据,但是Matlab端就是感觉没接收到,很是奇怪。那么我用调试助手时发现,一个包里有单个数据或是多个数据并不影响接收帧率增大串口波特率略微提高解包帧率,但是在发送帧率到达1000fps时,数据的接收帧率只能到650fps左右。
  • 我发现,并不是Matlab没接收到主控的数据,而是没有成功解包,这个问题也一直困扰我,发送结构体变量中的总字节数理论上和实际发的不一样,在帧头和数据之间有两位0x00并不知道从何而来,这样总字节数多了2,dma发送字节数加了2,且在解包过程中多两个字节消耗掉就行了
  • 结果在测试主控与Matlab通信时又发现问题,由于设置的波特率为921600,虽然配置没错但是串口发送的数完全不对,向下减小一些至460800就正常了,看来这种情况波特率有了限制。并且波特率460800时帧数据肉眼可见的概率会发生传输数据错误,说明串口确实不太稳定
  • 最后我一共让主控一帧传输20个数据,能够正常接收,100fps的发送帧率对应100fps的解包帧率。再次说明数据量不影响接受帧率,并且最大帧率在600fps(发送帧率1000fps),不过这种情况在接受10s时间左右程序不再接受蓝牙数据,未找到原因。
  • 另外,如果要在接收过程中画出实时曲线,势必影响接收帧率,我尝试在发送帧率100fps的情况下,每解完一次包绘制两个变量的曲线,结果接受帧率掉到70fps。因此,不画实时图像或者仅绘制1-2张是允许的,不然影响过大。

4.3.1 帧率计算timer

  • Matlab中也有定时器,我通过定时器1s定时来计算每秒钟的接收帧率,特别提醒往往回调函数的函数名的定义变量规范很重要。具体可以查阅帮助,下面是代码部分:
1
2
3
4
5
6
7
t = timer('StartDelay',1,'TimerFcn',@t_TimerFcn,'Period',1,'ExecutionMode','fixedRate');
%StartDelay:开始计时后的延时;TimerFcn:定时中断函数;Period:定时时间周期;ExecutionMode:优先级

start(t)

stop(t)
Delete(t)

4.3.2 打印变量disp()

1
2
string = sprintf('Have received stRobot_x:%d',stRobot_x(count));
disp(string)
  • 类似于format格式化输出,打印在命令行区

标定记录

2020.4.13


  周末测试的定位算法,算是一个阶段性的理解。发现了一些问题并且改正;
其中包括:

  1. 在标定过程中,以近y轴为基准的话,那么旋转来测量x轴行进数据时,需要特别注意旋转方向
    • 以前测量时,全都是顺时针旋转约90°,所有公式都是以顺时针旋转来推导的,原本以为只要规定了正方向,结果应该都一样
    • 但是由于昨天测量时是逆时针,在结算代入数据时发现求出的数据不对,重新推算了一遍发现顺逆时针旋转的算法结算有略微差别
    • 本次差别在于:x轴行进时的A、B轮相对行进方向角度的余弦值,顺逆时针是相反地

下图为两种旋转方向的图示:

逆时针旋转处理
顺时针旋转处理

这里备份了两种相似算法的matlab程序
逆时针算法
顺时针算法


  1. 旋转方法也进行了测试,之前一直没有一个比较具体的有效的验证
    • 首先,采用的验证方法是已知小推车的模型参数,从而得到理论上的几何中心和随动中心的距离L、以及对应夹角
    • 条件是在测完直行标定,并计算出8个变量带入程序并且程序中的L、alpha改成0
    • 其次,操作小推车旋转约180°(顺逆时针皆可)旋转前后都会有一条铝管作为基准边,得到计算出的x、y坐标的变化
    • 带入matlab旋转算法结算程序,求得L与alpha(注意matlab中的alpha为顺时针为正方向计算,程序中需要取负号
    • 将理论和计算出的长度、角度变量比较,发现长度误差1.2mm,角度误差1.2°,考虑到加工精度误差、以及人为操作误差,结果可以接受
旋转算法结果

这里备份了旋转算法的matlab程序    旋转算法

—理论数据—

横间距:37.5 mm

长间距:-29.84 mm

矢量绝对值:47.9236 mm

夹角:-2.24293 rad ( -128.5104 °)

—计算数据—

矢量绝对值:46.698439058181290 mm

夹角:-2.222503658302204 rad ( -127.33 °)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×