【TI-RSLT试用报告】+走迷宫实现过程及学习心得

  [复制链接]

2

主题

8

帖子

97

积分

一粒轻沙

Rank: 1

积分
97
楼主
查看: 20742回复: 14 发表于 2019-3-7 17:11:09   只看该作者
本帖最后由 电赛小编 于 2019-4-11 17:41 编辑

从老师那里得知有这个活动,可以申请学习,没想到真的选上了,非常的高兴能够用这个机会,真的学到了很多东西,现在经过多天折腾终于出了一些成果,实现了预期的基本功能,每一个传感器的探索突破都让我甚是欢喜,感觉自己学的专业好神奇。MSP430的改进版MSP432与之相比在功能上更强大,是EE学生必须掌握的单片机之一。而与之对应的是CCS软件,在这次活动之前,我们团队3人还没有接触过CCS,但是这次活动让我从零开始,TI的课程非常良心,一步一步循序渐进的教我们如何使用CCS软件来对芯片进行编程。在实验操作中,我们也逐步熟悉了这套软件,更是学习到了很多课上学不到的东西。这套器件超赞,TI的这次活动超赞,负责的**姐也超赞。不再多扯,来点详细的干货吧!
成果视频链接:http://www.bilibili.com/video/av45580923?share_medium=android&share_source=copy_link&bbid=XYF6E2EFC491378016967212B3CEB8CBFBD9D&ts=1551942128850

1.  硬件组装
零件的组装对于整个迷宫挑战小车来说是至关重要的一部分,因为稍有不慎,硬件连接错误,会导致整个机器在学习和调试的过程中,受到很大的影响。在我们组装过程中,按照说明指导书,一步一步实现硬件的组装,学习到了各个传感器和驱动装置的硬件连接方法,同样也发现并感慨TI公司在小车设计排版方面的巧妙。尽管已经很认真仔细的组装小车的每一个部分,但是最后调试的时候还是出现了一些小问题,在安装小车右车轮时,因为小车右轮电机的转子并没有调整好插入轮毂的距离,导致调试的时候轮子会晃动,无法走直线,但在我们重新调整完转子之后,完成了正常任务。

2.  碰撞传感器的学习
小车的碰撞传感器就像是猫咪的胡须,它可以摸到前方有没有障碍物,在遇到障碍物时可以让小车做响应的路径调整。由于第一次使用TI-launchpad MSP432,所以最初的探索是从各个功能模块的初始化开始的,但经过不久的摸索发现掌握其基本使用方法还是比较容易的。
RSLK小车的车头装有6个碰撞传感器,连接到TI-launchpad MSP432的P4端口上的其中6位,在碰撞开关没有被按下时传回高电平信号,被按下之后传回低电平信号,进而通过程序控制电机转换工作模式。而要使用P4口作为输入,需要先进行定义。先将P4口的SEL0/SEL1寄存单元置0,定义其为GPIO口,而后使其DIR单元置0定义它为输入口,并且需要激活该端口的内部上拉电阻,保证在没有触发碰撞开关时端口电平为高电平,至此该端口初始化完成,作为碰撞传感器的初始化程序。在主程序中调用碰撞传感器的初始化函数之后,只要调用含有读取P4口状态语句的函数就可以得到传感器传回的实时信息,进而处理使用。
过程 在研究这个碰撞传感器时,我们对CCS这个环境的调试窗口还不够熟悉,不知道到底有没有返回信号,这是一个很实际的问题。后来在学习视频了解到这款Launchpad上设置了强大的调试接口,只要连接上电脑在CCS中下载程序就可以进行逐步的调试,非常的方便,可以看到每一步语句执行后每一个寄存器和I\O口的变化,从刚开始太懂P4口的输入寄存器为何变化到后来可以利用输入的高低电平,我们掌握了通过CCS在线调试的方法和碰撞传感器的使用方法。
3.  循迹传感器的学习
循迹传感器,是迷宫小车的眼睛,也是迷宫循迹中小车最主要的传感器,可以说它的作用非常巨大。在刚开始学习循迹传感器的时候,有些迷茫,一直对于初始化端口的概念模糊不清,于是我们看着教学的课程PPT还有结合课后提供的材料一步一步学会了寻线传感器的初始化。这里重要的是对于P7和P5.3的初始化需要注意顺序和延时时间,因为会有充电的问题。当把传感器正常激活后,我们按照相应的逻辑编写程序,并通过Expressions实时在线看到传感器下的Data值,来调节相应的程序,最后实验Lob6的测试。在后期的迷宫整合中,我们对于传感器的偏移量进行了相应的PID控制方法,使得小车有更好的稳定性,并在线上稳定行驶。对于识别的算法下文会有相应的介绍。
4.  电机的PWM控制   
电机可以说是小车的双腿,怎么走,走多快,都是我们要花心思考虑的问题。而在该闭环的控制系中,需要软件编程运用算法设计控制器实现对执行元件即电机的控制。所以控制算法直接影响到电机的性能。本次使用的小车上装有两个直流减速电机,对于直流电机,微控制系统中最常用的调速方法即为PWM控制——通过脉宽调制来改变直流电机两端的实际电压,进而对电机实现调速控制。
使用TI-Launchpad MSP432生成PWM波需要使用其中的定时器,由于定时器时钟频率非常高,所以要对定时器信号进行分频处理,得到需要的标准低频信号,使用时只需要改变其中的参数即可。MSP432中有四个定时器,分别为TA0、TA1、TA2、TA3,每个定时器都可以输出4个同频率但不同占空比的信号,因此我们使用TA0即可,电机驱动模块的使能端被接在了定时器TA0的3、4口上(即P2.6、P2.7),通过对TA0的第0口的相关寄存器进行设定,控制PWM波的周期,通过对3、4口相关寄存器的设定,控制输出PWM波的占空比。
电机驱动模块上每个电机分配了3个控制端:使能端、方向控制端、休眠控制端,对定时器进行初始化之后,该PWM波就开始在**不断地产生,给到驱动模块的使能端,只要休眠控制端给高电平,电机就会转圈,在程序中改变县级速度时,只需要调用改变3、4口相关寄存器参数的函数即可。
过程 虽然原理比较简单,但是在探索过程中还是遇到了不少困难,因为它不同于51中的定时器,频率高、功能强大、寄存器复杂,单纯对定时器的初始化定义就花了很久的功夫,好在TI在论坛中给这个套件准备的学习视频中有详细的讲解,并且在课件中有实例的程序,稍加改动之后,我们就可以方便的调用。
解决了电机的控制,接下来要解决的就是路线问题了。
5.  走循迹迷宫的算法实现
RSLK套件提供的寻迹传感器共有八个,分别连接P7.0至P7.7。在走迷宫时八个寻迹传感器可以提供更多的信息来决策。走迷宫和循迹的难度差别较大,对算法要求较高。经过小组思考与讨论,我们总结了需要解决的几个关键问题,并提出了解决办法,如果有更好的解决办法,希望大家提出。
要想实现迷宫巡线,就必须了解迷宫的结构。迷宫巡线时要面临以下几种情况如图所示;其中a,b两种无需多说,是迷宫中最简单的路口,只需两边传感器有一边接收到信号并转弯即可,但此时程序写起来并不能按照循迹来写。如果读者学习过《自动控制原理》这门课,便可以了解到按照循迹来写相当于给了这个系统一个很大的干扰,系统回到稳定状态需要的时间比较长,如果不能在下一个路口到来之前快速达到稳态,很可能会影响下一个路口的判断与动作,另外如果连续几个弯道还会造成误差的积累。导致超过系统的调节幅度。

c、d两种形式的路口相比a,b更复杂一些,对路口判断也较为复杂。该分支在调试时也最容易出现问题,特别是小车驶入图中横向的线路时,如果小车在到达路口时左偏或者右偏很可能导致误判,从而走错道路。
e图为十字路口,难度高于前两种,遍历此路口的所有可能也较为困难。而且在考虑到这种路口的时候,有的读者可能会发现此时选择哪个分支前进也很重要。这就涉及到逻辑问题了。
迷宫实现过程
① 一开始我们拿到小车实现了传感器的功能后,可以实现基本的循迹。此时用的比较基础的方法,即左偏右拐,右偏左拐。但随后我们发现小车与轨迹偏差值会发散震荡,也就是表现为小车在多次左右摇摆之后冲出了跑道。结合自控原理知识,我们降低了小车拐弯的速度,小车效果变好,可以完成循迹。
② 接着我们开始测试直角弯a,b,发现小车偶尔在做出反应之前已经通过了直角弯。所以我们增加了一行程序,当小车左右两边传感器感应到跑道后,旋转90度再继续前进,但由于在走直线时出现的晃动,再加上牛眼轮在地板上出现惯性导致的滑动,偶尔出现脱离跑道的现象。此时我们认识到简单的程序不太容易实现循迹迷宫,因此我们加入了PID算法来计算小车两轮的差速并对1部分的循迹程序进行修改。使得小车可以完成直角弯。并尽量减少了拐弯后小车的晃动幅度。
③ 在对c,d,e三种情况进行思考时我们发现必须对各个路口进行优先级的确定,以便在路口选择合适的一条路。所以我们首先定义右拐为最高优先级,直行次之,左拐最低。通过不断地右拐可以遍历所有可能的路径。但此时我们又遇到了新的问题:小车需要对a,c或b,d进行识别和判断,也需要对c,d,e,f进行识别,所以我们在这些路口进行了多次间隔10ms的检测并综合三次检测的返回数据来确定路口的形状,虽然这样检测给小车带来的晃动更大,但是也实现了我们的预期目标。
④ 除此之外我们还需要考虑死路时的返回,我们采取的方式是转体180度。效果也不错。
⑤ 综上,循迹迷宫需要建立在循迹效果较好的基础上,PID调速可以很好地解决这个问题,相对于单纯的二值调速系统,PID在调节速度与调节效果上都是更加优秀的。

总结  初出茅庐,还请大佬们指导,我们写的也非常初级,基本上是小打小闹,但我已经很开心了,下面附上我们的主程序,大家感兴趣的话可以下载试一试,应该是可以用的!
  1. #include <stdint.h>
  2. #include "msp.h"
  3. #include "..\inc\Bump.h"
  4. #include "..\inc\Clock.h"
  5. //#include "..\inc\SysTick.h"
  6. #include "..\inc\CortexM.h"
  7. #include "..\inc\LaunchPad.h"
  8. #include "..\inc\Motor.h"
  9. #include"..\inc\PWM.h"
  10. #include"..\inc\Reflectance.h"

  11. void TimedPause(uint32_t time){
  12.   Clock_Delay1ms(time);          // run for a while and stop
  13.   Motor_Stop();
  14.   //while(LaunchPad_Input()==0);  // wait for touch
  15.   //while(LaunchPad_Input());     // wait for release
  16. }


  17. //reflact
  18. uint8_t Data;
  19. int32_t position;
  20. void reflactance(void){

  21.         Data = Reflectance_Read(1000);
  22.         position = Reflectance_Position(Data);

  23.         if(position==0){
  24.              Motor_Forward(4000,3900);
  25.          }

  26.          else if(position>=237){
  27.                   Motor_Stop();
  28.                   TimedPause(100);
  29.                   Motor_Forward(2000,7000);
  30.                   TimedPause(100);
  31.                       }

  32.               else if(position<=-237){
  33.                   Motor_Stop();
  34.                   TimedPause(100);
  35.                   Motor_Forward(7000,2000);
  36.                   TimedPause(100);
  37.               }
  38.               else if((position>0)&&(position<237)){
  39.                          Motor_Forward((3000-8*position),3700);
  40.                      }
  41.                      //else if((Data == 0x30)||(Data == 0x60)||(Data == 0xC0)){
  42.               else if((position <0)&&(position>-237)){
  43.                          Motor_Forward(3700,(3000+8*position));
  44.                      }

  45.         if(Data == 0xFF){//T型路口
  46.                                  Motor_Forward(4000,3900);
  47.                                           TimedPause(200);
  48.                                                   Motor_Right(4000,3900);
  49.                                                   TimedPause(350);}

  50.         if((Data == 0xF8)||(Data == 0xF0)||(Data == 0xE0)){//直角右转
  51.             Data = Reflectance_Read(1000);
  52.                         TimedPause(10);
  53.              if((Data == 0xF8)||(Data == 0xF0)||(Data == 0xE0)){
  54.                  Data = Reflectance_Read(1000);
  55.                              TimedPause(10);
  56.                 if((Data == 0xF8)||(Data == 0xF0)||(Data == 0xE0)){
  57.              Motor_Forward(4000,3900);
  58.                TimedPause(150);

  59.                        Motor_Right(4000,3900);
  60.                        TimedPause(350);}

  61.                 else;}
  62.                    else;}
  63.                else;


  64.         if((Data == 0x1F)||(Data == 0x0F)||(Data == 0x07)){//直角左转
  65.             Data = Reflectance_Read(1000);
  66.             TimedPause(5);
  67.             if((Data == 0x1F)||(Data == 0x0F)||(Data == 0x07)){
  68.                TimedPause(5);
  69.                 Data = Reflectance_Read(1000);
  70.              if((Data == 0x1F)||(Data == 0x0F)||(Data == 0x07)){
  71.                Motor_Forward(4000,3900);
  72.                TimedPause(150);
  73.             Data = Reflectance_Read(1000);
  74.                        if(Data == 0x00){
  75.                        Motor_Left(4000,3900);
  76.                        TimedPause(400); }
  77.                        else Motor_Forward(4000,3900);
  78.                        }
  79.                 else;}
  80.                 else;}
  81.         //else;



  82.         else if(Data == 0x00){
  83.             Motor_Right(4000,3900);
  84.         }

  85. }



  86. void endstop(void){
  87.     Data = Reflectance_Read(1000);
  88.     if(Data == 0xDB){
  89.         Motor_Stop();
  90.         while(LaunchPad_Input()==0);  // wait for touch
  91.         while(LaunchPad_Input());
  92.     }

  93. }
  94. //bump and driver
  95. void bumprun(void){

  96.         uint8_t numflag = 0;
  97.         numflag = Bump_Read();
  98.         if(numflag == 1){
  99.             TimedPause(500);
  100.             Motor_Left(4000,6000);
  101.             TimedPause(500);//SysTick_Wait10ms(30);
  102.         }
  103.         else if(numflag == 3){
  104.             TimedPause(500);
  105.             Motor_Right(4000,6000);
  106.             TimedPause(500);// SysTick_Wait10ms(30);
  107.         }
  108.         else if(numflag == 2){
  109.             TimedPause(500);
  110.             Motor_Backward(4000,4000);
  111.             TimedPause(500);// SysTick_Wait10ms(30);
  112.             Motor_Right(4000,6000);
  113.             TimedPause(500);// SysTick_Wait10ms(30);
  114.         }
  115.         else if(numflag == 0)
  116.              Motor_Forward(4000,4000);

  117. }

  118. void bumprun1(void){
  119.         uint8_t numflag1 = 0;
  120.         numflag1 = Bump_Read1();
  121.         if ((numflag1 & 0xED)!=0xED){
  122.           Motor_Backward(4000,4000);
  123.          TimedPause(300);// SysTick_Wait10ms(30);
  124.          Motor_Right(4000,3900);
  125.          TimedPause(400);// SysTick_Wait10ms(30);
  126.         }


  127. }
  128.   int main(void){
  129.        Clock_Init48MHz();
  130.        LaunchPad_Init(); // built-in switches and LEDs
  131.        Bump_Init();      // bump switches
  132.        Motor_Init();     // your function
  133.        PWM_Init34(10000, 5000, 7000);
  134.        Reflectance_Init();
  135.        while(LaunchPad_Input()==0);  // wait for touch
  136.        while(LaunchPad_Input());     // wait for release
  137.     // write a main program that uses PWM to move the robot
  138.     // like Program13_1, but uses TimerA1 to periodically
  139.     // check the bump switches, stopping the robot on a collision
  140.   while(1){
  141.      reflactance();
  142.      bumprun1();
  143.      endstop();

  144.   }
  145. }
复制代码




IMG_20190307_163658.jpg (178.56 KB, 下载次数: 257)

IMG_20190307_163658.jpg

survetrace.zip

1.16 MB, 下载次数: 334, 下载积分: 积分 -1

小车程序

打赏

参与人数 1赫兹币 +5 收起 理由
jason-peng + 5 很给力!

查看全部打赏

2

主题

4

帖子

150

积分

二氧化硅

Rank: 2

积分
150
沙发
发表于 2019-3-7 22:05:51   只看该作者
哎呀不错 赞

3

主题

7

帖子

24

积分

一粒轻沙

Rank: 1

积分
24
板凳
发表于 2019-3-10 14:12:06   只看该作者
你们刚开始是不是利用下载的Lab-12Motor就能让小车先动起来

2

主题

8

帖子

97

积分

一粒轻沙

Rank: 1

积分
97
4#
发表于 2019-3-16 17:09:22   只看该作者
csl 发表于 2019-3-10 14:12
你们刚开始是不是利用下载的Lab-12Motor就能让小车先动起来

是的,就是把实验给的程序框架补充了,就可以转了

3

主题

7

帖子

24

积分

一粒轻沙

Rank: 1

积分
24
5#
发表于 2019-3-19 18:10:14   只看该作者
贾浩林 发表于 2019-3-16 17:09
是的,就是把实验给的程序框架补充了,就可以转了

好的。谢谢

0

主题

1

帖子

152

积分

二氧化硅

Rank: 2

积分
152
6#
发表于 2019-4-2 10:27:02   只看该作者
谢谢楼主的分享,正在学习这个
TI的官方例程 里面的实现步骤都是我们自己加吗?居然没有看到一个比较完整功能性的测试例程:Q

2

主题

8

帖子

97

积分

一粒轻沙

Rank: 1

积分
97
7#
发表于 2019-4-12 20:10:26   只看该作者
魏恒川 发表于 2019-4-2 10:27
谢谢楼主的分享,正在学习这个
TI的官方例程 里面的实现步骤都是我们自己加吗?居然没有看到一个比较完整功 ...

使得 他提供的都是 需要填空的框架,没有可以直接运行的

0

主题

21

帖子

22

积分

一粒轻沙

Rank: 1

积分
22
8#
发表于 2019-7-23 11:47:34   只看该作者
谢谢楼主分享!

0

主题

6

帖子

1

积分

一粒轻沙

Rank: 1

积分
1
9#
发表于 2019-8-7 12:05:37   只看该作者
很给力,感谢分享

0

主题

1

帖子

63

积分

一粒轻沙

Rank: 1

积分
63
10#
发表于 2020-7-21 17:13:53   只看该作者
很棒,感谢分享

0

主题

1

帖子

7

积分

一粒轻沙

Rank: 1

积分
7
11#
发表于 2020-10-9 21:21:16   只看该作者
楼主,msp.h文件在哪里啊,是自己写的吗

0

主题

2

帖子

32

积分

一粒轻沙

Rank: 1

积分
32
12#
发表于 2020-11-19 13:43:53   只看该作者
zhy89895155 发表于 2020-10-9 21:21
楼主,msp.h文件在哪里啊,是自己写的吗

应该可以找到人家厂家给的吧

8

主题

16

帖子

264

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
264
13#
发表于 2020-11-20 10:10:36   只看该作者
zhy89895155 发表于 2020-10-9 21:21
楼主,msp.h文件在哪里啊,是自己写的吗

去匠牛社区的淘宝商城,联系客服她会发送给你的。

0

主题

1

帖子

1

积分

一粒轻沙

Rank: 1

积分
1
14#
发表于 2021-11-26 17:27:55   只看该作者
为什么Bump_Read1()declared implicitly

0

主题

1

帖子

76

积分

一粒轻沙

Rank: 1

积分
76
15#
发表于 2022-6-1 15:08:40   只看该作者
感谢楼主分享
快速回复 返回顶部 返回列表