Skip to content

莆一科协乐高EV3经验教程

By Lily from PTYZ

注意:离开工作室前,关门关灯关电闸!

EV3是LEGO旗下的一款教育用机器人,是现(注:2022年1月2日)莆一科协乐高部的主要设备(2021年曾计划换用纳深机器人设备,奈何学校不给力)。本文的目标受众是未接触过EV3的新手,将由浅入深地讲解笔者的一些关于EV3的经验之谈。仓促之下,内容可能有点粗糙,如有疑问,可以与科协的其他同学探讨。

对所有教育机器人,主要的模块都是这两块:搭建(硬件)和编程(软件)。又因为正规比赛中都是两人一小组,所以一开始就要找好搭档并进行明确的分工,一人主修硬件,为机械师,一人主修软件,为程序员。当然,每个人不仅要掌握自己主修的知识,也要对另一门技术有所了解。笔者的主修是程序员,但机械师搭档不在的时候也负责硬件,所以在机械结构设计上也有一些经验。接下来我们分别讲一讲这两块技术。

一、硬件 机械师的自我修养

\1. 认识主要零件类型:

(1)搭建棒。EV3的搭建棒是具有不同长度、不同颜色、单方向圆形插销孔的硬质棒状零件,是大部分结构的主体。具体来说,可以按形状分类为:n直棒(n为插销孔个数,短的做垫材、短连接,长的撑结构),42(L型,其中两个端点为十字孔),53(L型,由五年高考三年模拟命名),折形(有多种长度,含一个钝角,两端十字孔),二折(两个钝角,两端十字孔,含长槽,总体呈缺直角形,常用于搭建外框),口(长方形,搭建棒变种,同时具有三向插销孔,巨好用,是许多结构的核心零件),井(口的长边向外延伸,也好用)。搭建板是搭建棒的衍生物,用法与搭建棒类似,这里不细表。

(2)十字棒。十字棒是纵截面呈十字形,长度、颜色不一的棍状零件,能穿过十字孔、插销孔,具有单点定线(注:正常情况下,两点确定一直线)、连接结构体、传递电机动力、形成旋转位点等作用。一般情况下,按使用方法,十字棒有两种成结构方式:定十字棒与动十字棒。定十字棒主要用于连接(单点定线、连接结构体),插在十字孔中,不可旋转;动十字棒主要连接电机、齿轮、蜗杆等,一般穿过插销孔,可以旋转,以传递电机动力。使用时常辅以(黄套套,这个是俗名,厚二分之一,用于固定十字棒,防止横移,以其颜色得名,也有灰色的)

(3)插销。插销是能穿过插销孔,用于连接搭建棒的分节圆柱形零件,有二级插销、二级十字插销(一头十字、一头圆)、三级插销、三级十字插销(一头十字、两节圆,稀有)等。注意,每一个插销都有节,拆卸的时候要看清楚节在哪里,不能强拆(血的教训)。这里讲解一下EV3零件的颜色问题。零件的颜色代表其松紧程度,黑色是最紧的,蓝色次之,米黄较松,灰色同理。只需牢记,颜色越深越紧,越浅越松。此外,红色的意思是土豪(价格可以是其他零件的两倍)。黑销是紧固销,米黄色的插销也叫润滑销。紧固销常见于所有结构之中,润滑销一般用于安装齿轮等传动结构。此外,能用三级插销替代多个二级插销的情况下,尽量使用三级插销,使结构更疏松多孔。

(4)传动结构。传动结构主要有齿轮、蜗杆、十字齿轮、链条、链条齿轮、连杆、轮胎等。齿轮是最常用的传动结构,齿轮组具有变速、换向、传动等多种功能。齿轮组设计是技术活,这里暂且不表。蜗杆很少用,它能与齿轮搭配,形成强力、小体积的单向变速结构,但因为这玩意减速太强了,导致速度会很慢,所以少用。十字齿轮是在不需要变速时传动、变向最稳定的选择,效率高,不会跳齿,可以多用。链条由链条齿轮驱动,可以作为履带,但比轮胎慢多了;可以远距离传动,但极其臃肿,故基本不用。链条齿轮挺大个,可以做垫材。连杆的本质是搭建棒与插销的组合,合理运用润滑销可以做到精细而多样的曲线运动,设计时应注意平行四边形与圆形结构。轮胎一般以薄、大、平衡、结实者为上,少用宽轮和小摩托轮,不稳定。

(5)连接结构。此类结构种类极为丰富,主要都是些用于特殊连接的小零件,这里以龙骨(可以单链多聚为形似龙骨的零件的总称,有两种,为马形、H形)为例。此类结构的特点是体积小、具有多向的(十字)插销和(十字)插销孔,能方便连接。但大量使用这种零件的弊端是结构不够疏松多孔、不稳定、复杂等,不能多用。

(6)主机(BRICK)是机器人的神经中枢和控制中心,对机器人的程序的写入、执行都由它完成,而所有传感器的数据全部经数据线汇总于它,所有电机也由它经数据线控制。它包含以下结构:电池组、显示屏、六个个控制按钮(上下左右中退,带三色指示灯)、一个充电口、一个USB接口(连接主机与计算机)、四个电机接口(ABCD,接EV3数据线),四个传感器接口(1234,接EV3数据线)。

(7)电机(MOTOR)分为大型电机(大电)和中型电机(中电),需连接主机,是机器人的动力来源。大电主要用于驱动车轮和重型机械臂,中电主要由于一般的机械臂动力。大电的体积大于中电,当然动力也大于中电。注意,电机的机械能会随传动而衰减,所以驱动车轮时,尽量不用额外传动。电机的角度也可以作为电机的返回值,此时电机也相对于传感器。

(8)传感器(SENSER)种类繁多,常见的有颜色传感器(测颜色、灰度)、陀螺仪(测角加速度)、超声波(测距)、触感(测接触)等。传感器相对于机器人的五官,辅助机器人定位、判断,直接影响机器人的行为。同样,传感器需连接主机。关于传感器的知识,我们将在“编程”模块详细讨论。

(9)附:以上三种智能部件均含插销孔,可以通过插销、十字棒、搭建棒等于其他结构相连。学硬件,听学长讲点什么固然可以少走弯路,可是最重要的还是多去工作室,多摸零件,找到对零件的熟悉和设计的感觉。例如你们的学长(笔者)在写这篇教程的时候完全没有参考任何其他教程,也没有零件在手边,全凭对零件的熟悉和自己的经验编写。所以,勤劳最重要。在阅读本教程时,也请找出各个零件,一一比对,加深印象。

\2. 学习结构的方法:

​ 就像学数学需要做例题一样,学搭建也要学样例。打开MINDSTORM EV3,把里面的每一个样例作品都仔细看一看,多观察老学长留下的结构,自己按软件的教程搭一辆小车,感觉就来了。

\3. 搭建的经验谈:

(1)设计结构的三大原则:简约、稳定、高密度。大道至简,过于复杂的结构往往不利于拆装而浪费空间较多、堆料严重;不稳定的结构不合格,否则车开一半散架了会用什么后果,想想都知道;高密度是指在高度有限的空间内尽可能提高空间利用率并不损失稳定性,压缩率高的结构能在更小的空间内实现更多的功能,从而在同样的体积内实现更多的功能。

(2)设计结构的补充原则:模块化、集成化。这也是现代设计的发展趋势。将一个大的结构分解成各个小的模块,将需要实现的功能集成于各个模块中,可以极大地方便改装与记忆结构(大赛的结构要求当场拼装)。相当于:别人用碎屑盖房子,你用砖头盖房子——这不香吗?

(3)如何使结构更稳定?答案是多维固定。如果固定只局限于一维固定(在一个方向上固定),那么结构就无法承受大的扭曲力;如果固定只局限于二维固定,那么结构就无法承受大的剪切力;如果采用三维固定,那么这就基本是无懈可击的稳定结构。此外,堆料行为不可取,堆砌大量垫材在增强稳定性上作用不大,注意用料贵精不贵多。

(4)在拆装零件的过程中,难免会消耗手的耐久。笔者的大拇指、食指都磨出了厚度可观的茧。但是还是不能戴手套:这会大大降低效率。有时一些拼的很结实的结构会让手知难而退:太难拆了。还有一些场合是根本不适合手完成的。这里介绍上古三大神器:金刚之握——钳子,游刃有余——美工刀,铁杵磨针——锉刀。钳子能有力地抓握住裸露的十字棒或插销的末端辅助拆卸“钉子户”;美工刀能“依乎天理,批大郤,导大窾,因其固然”,使零件“謋然已解,如土委地”(出自《庖丁解牛》)。锉刀可以用于缩(bian)短(ji)十字棒的长度,在一些非法搭建(指套路之外的鬼才结构)中用处极大。工具的使用方法请参考通用技术课本,就是注意一下力度,别把零件整坏了(真的有这样的例子,你可以见到不少裂开的插销)。

(5)零件分堆、分类极其重要。毕竟每次想找一个零件都要去零件海里大海捞针,这滋味属实难受。机械师应养成良好的零件分类习惯,每年寒暑假时高二学长学姐应组织高一同学整理零件。

(6)好的结构要保持疏松多孔的良好状态,尽量多空出一些插销孔。疏松多孔的结构,尤其是外框,将极大地方便后续的改装与拓展。切记,切记,切记!还有,设计结构时要注意受力的分配,不能让个别插销、搭建棒承受过多的力,否则机器很有可能会出问题!如果有发现类似的问题,应及时加固主要受力部位,如果缺少改装空间,建议拆了重做。

(7)传动结构的设计。设计传动结构是很难的技术,笔者也不擅长。但学习者可以参考MINDSTORM EV3 EDUCATION的示例项目进行学习,这里列举一些经验性的结论:能用十字棒直接传动的情况就不要使用齿轮组,白白降低机械效率;齿轮能与锯齿棒咬合,搭建类叉车机械臂;部分齿轮上带有额外的插销孔、十字插销孔,是用来搭建连杆结构的,设计者可以酌情考虑。此外,还有一些任务可以不设计带动力的机械臂而直接利用车身的动力,这种机关称为无动力机关。无动力机关在设计上普遍比机械臂简单,且更省时。在解决具体情境的问题时,思路可以适当向无动力机关倾斜。

(8)机体整体的设计应有较低且稳定居中的重心,重心的配置可以在开始时归划(需要经验),也可以在后期增加配重。基础车的体积不宜过大,加上外框后随意,只要不超出基地的范围就行。

二、软件 程序员的血泪史

EV3的编程软件是MINDSTORM EV3,学校用的是白色图标的MINDSTORM EV3 EDUCATION,较家庭版更完善,推荐使用。打开它,恭喜你,一个EV3程序员就此诞生了。进入界面,左侧菜单有五个选项,“模型核心组合”和“模型拓展组合”收录了共十个EV3示例项目的搭建图纸和示例程序,在你学习的时候可以参照它们,以获取宝贵的经验。建议挑一至两个简单的项目进行复制性的搭建,并导入示例程序,这可能会是你的第一个成功的项目。“快速入门”和“Robot Educator”收录的是EV3的官方入门教程。当然,你也可以选择听我继续说。“文件”将是你使用最多的选项,可以新建、打开项目。那么,现在,请新建一个新项目。

右上角是内容编辑器,现在可以暂且不理。右上的工具栏中有“注释”一栏,写注释将是修改程序、检查bug时的好帮手——当然,你也可以不理。右下角是程序块状态栏,当你使用USB或蓝牙接口(我这辈子都没见过的好东西)连接计算机和主机后,这一栏会亮起,你将可以通过它来查看主机状态、下载程序(↓)、读取存储(叠箱图标)等。当你使用USB线连接主机与计算机时,你很可能一时间会失败——这很正常。此时一般是主机与USB接触不良,需要你精细地调整USB插头的位置,既不能插到底,又不能拔太多出来:要有耐心(笔者曾接一次接口花了半个小时)。界面下方是EV3编程所使用的程序块。MINDSTORM EV3采用模块化编程,由每一个特定的模块代表命令行中的语句。可以看见,EV3的模块有以下几种:

(1)动作(绿色)。包含大电、中电、移动转向、移动槽、显示、声音、指示灯模块。在电机模块中,在左上角选择要控制的电机的端口号,在左下角选择语句类型,可以控制电机功率、按条件开关、结束时是否制动(制动会顿一下,不制动会有惯性滑行)。移动转向和移动槽模块需选择两个电机端口,前者为左轮,后者为右轮。移动转向具有方向参数,可控行车方向,而移动槽直接控制左右两轮的差速,实现转向。实际上,移动转向与移动槽原理相同,本质都是控制左右两轮的差速。显示、声音、指示灯模块用于与人交互,用处不多,也易自学,这里不赘述。

(2)流程控制(橙色)。包含开始(start)、等待(wait)、循环(while)、条件判断(if)、退出循环(break)。熟悉其他编程的同学肯定对其不陌生(不会吧不会吧,这一届不会没有微笙无上计算机协会的人吧)。开始模块主要用于多线程处理,其实没什么用,新建程序会自带;等待模块也具有条件判断的功能,善用者可以之压缩程序;循环和判断是算法的必修课,数学课本里都有教算法初步,不会的自己去看。值得注意的是这几个模块都具有判断功能,可以调用大量其它的信息,要善于活用。循环模块的左端有个小凸起,用鼠标可以拖出一根引线,我们称之为引脚。这根引脚代表的是当前循环的次数(当前正在:第n循环)。每一个循环模块都是有编号的,标注在模块的上方(如:01)。而退出循环模块可以识别特定的循环编号并将其强行终止。橙色模块主要与算法相关,想学更多算法,欢迎学习C、C++、Python等专业编程语言。(真的有用)

(3)传感器(黄色)。总而言之,这里集中了所以用的到的和用不到的传感器的驱动,你可以通过这些模块来控制各个传感器并读取各个传感器的返回值。这里我们就需要详细解释一下关于引脚的概念了。熟悉编程的同学一定对变量不陌生(int a=0;),而定义变量、调用变量、修改变量那简直比吃饭喝水还自然。在EV3,你可以观察到,很多模块都有向拼图一样的凹陷,而这些凹陷都是可以引用其他变量的输入(比如,电机功率60,这里的60就是输入的值,而这个值可以是其他变量);而有些模块又有一些凸起(如上面循环的次数引脚)。由引脚拖出的引线可以连接到模块的凹陷处,这就表示这个凹陷的输入引用的是引脚代表的变量。而引脚又有很多种,圆头引脚代表数字(num),尖头引脚代表逻辑判断(true or false),方头引脚代表文本(text),还有更复杂的双圆角-数组和双尖角-逻辑排列等等,这两个要由高级的程序员使用,普通情况下使用不多(用的好的话可以实现很多高级功能,同样,在这里推荐学习C、C++、Python等专业编程语言)。而大多数传感器模块具有测量、比较、重置三个模式。强烈建议在程序开始是重置所有传感器,强烈建议在程序开始是重置所有传感器,强烈建议在程序开始是重置所有传感器,重要的事情说三遍。测量模式可以获取传感器的返回值用于引用,比较模式相当于集成了判断语句的测量,一开始可以先用,技术好的时候建议使用判断语句,功能更齐全。传感器的返回值一般作为程序的输入,用于矫正机器人的行为。

(4)数据操作(红色)。顾名思义,这就是对数据进行运算的模块,包含定义/引用/修改-变量/常量、数组运算、逻辑运算(交并补之类)、数组运算(加减乘除等)、舍入、比较、区间判断、文本处理、生成随机数等——就是个模块板的“#include”。在这里再推荐学习C、C++、Python等专业编程语言,学了一时,受用一世。变量的名称在变量模块的右上角选择。在这一类模块中,引脚仍然是使用的核心,各种变量引用来引用去,全都是算法层面的事情。算法要自己学、自己设计,才能灵活运用。当然,本教程也会给出一些经典的算法示例。

(5)高级(蓝色)。包含:文件读写、数据日志(本机)、消息传递、蓝牙连接(多主机)、保持活动(不待机)、原始传感器、未校准电机(原始数值)、电机反转、结束、注释。本机模块在下文介绍,多主机模块用不到,不做介绍,原始数值在普通编程中没有,用在高级算法中可以提高执行效率、减少误差、增强稳定性。其余模块都易自学,不细表。

(6)我的模块(青绿色)。这里存放着学长学姐或你自己打包好的程序模块,可以自定义输入、输出、内容,相当于编程中包装好的函数,可以随时方便地引用。一般需要较高的编程水平才能打包程序。在顶栏工具-我的模块创建器中可以将选中的所有模块打包成单个程序模块并自定义名称、输入、输出。注意打包的时候要注意连接好输入和输出的引线。

在学习各个模块之后,接下来学习一些常见的编程结构。

(1)顺序结构。顺序结构是编程中最简单、最基础的结构,就是按顺序执行预设的一连串指令,贯穿于所有程序之中。常见的顺序结构是电机圈数顺序结构,如:“移动转向,B+C,方向=0,功率=40,1圈,结束制动;移动转向,B+C,方向=90,功率=40,0.6圈,结束制动;”,此类程序编写简单,思路简单,在硬件状态良好、参数选择恰当时经常使用。

(2)判断结构。判断模块可以判断所引用的变量是否满足一定条件,并以此为据选择执行不同的命令。当需要判断多个条件时,既可以通过嵌套判断结构,也可以通过逻辑运算模块实现。判断模块的数字模式可以一次性设置多个判断选项,十分方便好用。

(3)循环结构。循环结构的作用是一直重复执行循环框内的指令,直到触发某个条件后停止。默认的循环模块是“无限循环”,在没有结束循环指令时不会停止,请注意搭配判断模块和结束循环使用并确认编号无误。也可以通过改变循环模块的模式来实现条件循环。

(4)多线程。可以观察到,每一个程序块的右端中部都有一个子弹头的形状,用鼠标可以拖出一根引线,连接在其他程序块的左端子弹头。并且,同一个程序块的右端可以同时用这种方法连接多个程序块,而这些程序块将在这个程序块的命令执行完毕之后同时开始执行,并可以互不干扰。这就是EV3中的多线程处理方法。

(5)变量、文件详解。机器人的主机本质上就是一台计算机,也具有存储、内存、处理器等结构。执行程序时,每定义一个变量,都将向主机的内存申请一块空间,用于临时存放数据。而每一个传感器和读取的文件数据,也将成为变量进入内存,并且每一个变量都具有一个指向它的内存区域的指针。正常情况下这些指针由主程序掌管。引脚引线的调用相当于将一个变量的指针传递给另一个程序块,由它按指针调用相关变量。而将引线跨越判断框或循环框时,需要一个主程序将变量的指针传递给子函数的过程,所以会自动生成一个“注入小块”(俗名)完成这一操作。而要跨越两重框引用变量的话,需要手动中转,即先将其引用到第一层框的一个变量中,在将其引用到第二层框内。而文件是存储在存储器内的数据,程序结束后依然保留。主机内的文件主要包括操作系统(Linux)、可执行文件(程序本体)、用户数据(可通过数据日志或文件读写生成,供用户上传至计算机进行分析、辅助调试或供机器人调用数据)。

接下来提供一些经典的编程思路。

注:接下来的斜体文本将使用“伪代码”来展示程序的算法。伪代码是语法接近代码但完全不可编译的文本,仅用于向人展示算法、思路,在实际编程时读者应使用模块化编程,不必像下文一般写伪代码。又,因为笔者是在微笙学C++出来的,伪代码的风格会比较C化,请包涵。

(1)绿程模式。大量使用绿色的动作模块按照调试好的参数控制电机运动,大面积采用单一的顺序结构。这是适合初学者解决低精密度要求、低应变能力要求的简单方法,而且十分实用。当然,这个思路的调试时间会相对较长,要求有比较好的耐心。例如要使车前安装了框体结构的小车收集一定区域内的物块,可以写出以下程序:

[移动转向,方向=-45,功率=30,距离=0.3**圈];

[移动转向,方向=45,功率=20,距离=0.5**圈];

[移动转向,方向=0,功率=40,距离=0.2**圈];

[移动转向,方向=-45,功率=30,距离=0.35**圈];

[移动转向,方向=0,功率=40,距离=0.25**圈];

[移动转向,方向=-45,功率=30,距离=0.3**圈];

各个移动转向模块的参数要一个一个地调试,使机器人的收集框能扫过目标区域且物块不会因惯性飞出框外。在编写类似的程序时,需要特别注意功率(速度),因为学校的电机在功率大于60的时候精密度会大大降低,而且车速过快不利于精密操作、车速过慢不利于获取时间分。程序员应自己斟酌功率的设定量。

有时,可能需要设计“扫到黑线停止”之类的功能。可以参考如下程序:

初始化 颜色传感器1 颜色模式;

[移动转向,方向=0,**功率=50];

循环{如果(1颜色传感器==黑色){结束循环}}

(2)负反馈调节。这不仅是生物的核心思想,也是机器人编程的重要思想。这里举双颜感巡线(小车利用左右两个颜色传感器沿黑线运动)为例,详细列举负反馈调节的算法原理。

​ *三相调节

让一个没有基础的同学写巡线的程序,他可能会这么设计:

循环{**如果(左比右黑)那么【向左前进】;

如果(右比左黑)那么【向右前进】;

如果(两边差不多)那么【直走】;}

这个程序已经体现了负反馈调节的思想:往哪边偏就朝反方向纠正。但是这个程序拿去实践却会发现效果不佳:车速很慢,轨迹又会呈锯齿状。这是因为这个程序的调节过于僵硬。

*比例调节

于是,这位同学恍然大悟,将程序优化为如下程序:

定义数型变量kp=10,p=0;

循环{p=左颜感灰度-右颜感灰度;

[移动转向,方向=kp*p,**功率=40];}

这个程序的巡线效果会比上一个好得多。为什么呢?如果说上一个程序是机械地反向矫正,那么这个程序会根据偏移量p来指导矫正量。也就是说,偏移得越多,矫正量越大,从而时车的轨迹呈现为阻尼振动图像,更有利于使实际量趋向于目标量。因为这种算法中,矫正量与偏移量成正比,所以它叫作比例调节。kp是比例系数,需要根据实际情况自行调试。

*PID调节

比例调节算法在一般情况下是完全够用的。但是,巡线的精密度要求极高,差之毫厘谬以千里,而阻尼振动的轨迹仍不够理想。在比例调节中,机器人根据“偏了多少”来判断“怎么调整”。那么,我们是不是可以优化一下算法,让它根据“偏了多少”“目前一共偏了多少”和“刚刚少偏了多少”这三个因素综合判断“怎么调整”。以下是这个同学写的程序。

定义数型变量kp=6.5,ki=0.001,kd=14,p=0,i=0,d=0,lp=0;

循环{p=左颜感灰度-右颜感灰度;

i=i+p; d=p-lp;

[移动转向,方向=kp*p+ki*i+kd*d,**功率=40]; lp=p;}

其中p是当前的偏移量,i是累计的偏移量,d是本循环的偏移量与上一循环的偏移量的差,kp、ki、kd分别是p、i、d的比例系数。实际上PID调节的本质就是分别将当前的误差值与其积分和微分乘以各自的比例系数并以其求和为矫正量的参考标准。在这种负反馈调节中,p项主要保证矫正功能的正常实现,i项主要帮助适应连续曲线型变换,d项主要确保在突跃点正常执行程序。如果三个比例系数调试得当,这种算法可以运用于航天器的对接;但相对的,调试这三个系数是一门技术活。总体来讲,要先用比例调节的模型来调整kp,再用对数、指数模型调节ki,最后用折线形模型调节kd。然后,调试这门艺术,最重要的还是耐心,坚持就是胜利。

然后,既然花了这门长的篇幅讲了这个示例项目,那么我们就顺便用它来讲解一下实际的程序编写。在实际情况下,程序的编写需要考虑多方面因素以及实际使用需求。对于上面这个程序,我们可以看到,它还有很多问题:之前我们说过,调用传感器之前要初始化;可以使用“未校准电机”模块提升运算速度;巡线过程中永远无法退出那个主循环;并且如果小车完全脱线,那么它将会义无反顾地在错误的道路上越走越远;写注释可以优化人的主观视感;再加上巡线完全可以打包成一个模块,在以后项目中可以随时方便的调用……程序优化是几乎无止境的。接下来我们就对上述程序进行优化。

开始;

定义数型变量on,lim=13,kp=3,ki=0.00035,kd=7,p=0,i=0,d=0,lp=0;

初始化 颜色传感器 1,2,3,4 灰度模式;

等待直到(**按键2 被按下);

on=(2颜感灰度 - 3颜感灰度) /2; //on**指在线的灰度

自定义模块 walk(**数型变量 mode,speed,ctype,dist){

lp=0; i=0; //mode:退出条件,0是寻路口,1**是走距离

如果(mode==0且ctype==-1)那么{ //ctype指路口种类,-1左,1**右

循环{如果(1颜感灰度<=5)那么{结束循环} //0**是十字路口

如果(2颜感灰度>=on - 5且3颜感灰度>=on - 5)那么{

[移动转向,方向=0,功率=-20];} //dist**指前进距离

否则{p=2颜感灰度 - 3颜感灰度;

i=i+p; d=p-lp;

[未校准电机B,功率=speed - kp*p - ki*i - kd*d];

[未校准电机C,功率=speed + kp*p + ki*i + kd*d]; lp=p;}}}

如果(mode==0且ctype==1)那么{

循环{如果(4颜感灰度<=5)那么{结束循环}

如果(2颜感灰度>=on - 5且3颜感灰度>=on - 5)那么{

[移动转向,方向=0,功率=-20];}

否则{p=2颜感灰度 - 3颜感灰度;

i=i+p; d=p-lp;

[未校准电机B,功率=speed - kp*p - ki*i - kd*d];

[未校准电机C,功率=speed + kp*p + ki*i + kd*d]; lp=p;}}}

如果(mode==0且ctype==0)那么{

循环{如果(1颜感灰度<=5且4颜感灰度<=5)那么{结束循环}

如果(2颜感灰度>=on - 5且3颜感灰度>=on - 5)那么{

[移动转向,方向=0,功率=-20];}

否则{p=2颜感灰度 - 3颜感灰度;

i=i+p; d=p-lp;

[未校准电机B,功率=speed - kp*p - ki*i - kd*d];

[未校准电机C,功率=speed + kp*p + ki*i + kd*d]; lp=p;}}}

如果(mode==1)那么{数型变量m1=B**电机角度;

循环{如果(2颜感灰度>=on - 5且3颜感灰度>=on - 5)**那么{

[移动转向,方向=0,功率=-20];}

否则{p=2颜感灰度 - 3颜感灰度;

i=i+p; d=p-lp;

[未校准电机B,功率=speed - kp*p - ki*i - kd*d];

[未校准电机C,功率=speed + kp*p + ki*i + kd*d]; lp=p;}

如果(B电机角度>=m1 + dist / 360)那么{**结束循环}}}}

主程序{

... //这里可以自由调用上方的walk模块控制车的移动

}

这个程序看上去就臃肿了不少。它将整个巡线程序打包成一个模块,并实现了初始化、运用了未校准电机、集成了寻路口和走距离的功能、加入了脱线后紧急后撤的功能,并写了一些注释。这样的程序就可以投入实际的机器人使用中,并可以方便继续编写和修改程序。当然,上述只是示例程序,仍然有很大的提升空间,例如可以通过多线程减少代码量,判断的次数也可以减少,脱线紧急后撤的措施也很粗糙,等等。这些,就可以由你来优化。

当然,负反馈调节在机器人中应用极其广泛,不仅是巡线,陀螺仪制导、超声波跟随、机械臂精密动作(接化发(误))等,都可以应用比例调节乃至PID调节实现。

(3)解决设备问题

众所周知,学校的设备大多是老弱病残,不少或多或少带点问题。例如陀螺仪经常出现示数因不明原因暴增的问题。笔者曾对此进行了较深入的研究,结论是应该是陀螺仪内置的角加速度计两端带上了不明原因的电压,导致其示数暴增。当然我们修不好集成电路,我们只能在程序上下功夫。这个问题这里只提供解决思路:

通过数据日志观察故障的陀螺仪的示数曲线特征——找到其中仍可以反映角偏值的变量——通过算法获取该变量——在使用时用该算法矫正陀螺仪的示数。

还有一个待补充的点。经常一辆车的左右大电功率会略有区别。理论来说可以通过电机设置来调整,但笔者不会这项技术,只能通过其他方法(巡线、陀螺仪)矫正。遗憾。

程序员的必修课:

(1)调试。在上述总多文字中,我们多次提到了调试这个名词。调试就是指根据一个程序跑的效果如何来修改算法、微调参数等等。每一个程序在合格之前,都需要经过漫长的调试,从而起到最佳的效果。枯燥的调试真的可以很令人沮丧,那么这里将介绍一些辅助调试的方法。

\1. 二分法。数学课上也教过,从偏小量与偏大量的平均数入手,不断缩小范围,可以快速找到合适的参数。

\2. 数据日志。强烈推荐,尤其是传感器数量多的时候!通过观看数据日志,调试者可以身临其境地感受到机器人看到了什么,做了什么,从而指导调试的方向。数据日志可以直接通过数据日志模块记录,之后通过USB上传到计算机,用软件直接观看。当然,如果需要更复杂的数学处理,可以使用文件读写模块手动写入(各个数据以文本格式写入,在数据中间插入“,”分列,完成一个循环自动换行)生成数据文件,上传到计算机后将后缀名改为.csv后用excel打开,可以进行更复杂的数学处理。

(2)找bug。每写完一个程序,却发现跑不了,这是令无数程序员(包括你和我)心脏骤停的梦魇。这大概率是程序出bug了。由于思维惯性,自己的错误自己很难发觉,这要怎么办呢?这里隆重介绍这款名为“小黄鸭调试法”的神器。具体做法是,将你的程序一句一句非常详细地向你的搭档或桌上的小黄鸭解释,解释一段之后,你可能会这么说:“你看这个是……哦,是这个!哎呀,好了,没事了,我懂了。”然后留下一脸懵逼的搭档或小黄鸭。亲测极其有效!当然,不是每一次都能顺利地找到并修正bug。必须要有耐心,有毅力,坚持就是胜利。

三、解决实际问题的经验谈 开动脑筋,实事求是,精益求精

​ 在实际的任务中,一般是机器人从基地出发,在一个标准比赛台上执行分布在台上的各个任务。任务对象一般是由乐高积木或搭建棒组装成的策略物。通常一个能执行多个任务的机器人由一辆搭载主机、传感器、动力和内框的基础车和用便于拆卸的方式扣在内框上的、搭载机械臂和无动力机关的外框构成。

在设计解决方案时,应主要考虑以下几个问题:

机器人一共要回几次基地?每跑一趟要执行哪些任务?要按照什么顺序?为了执行这些任务,这一趟的外框应搭载哪些机械臂和无动力机关?要怎样将这些部件安装到外框上?机器人要如何定位自己和策略物的位置?

一般来说,回基地的次数应尽可能少,故而一个外框应尽可能多地集成结构;任务的执行顺序应由机器人的前进路线决定;为了精确定位,可以采用巡线、距离等方式定位,但实际上最稳定的定位方式是蹭墙——真正的精准。一般情况下,在大的比赛中很难完成全部任务,所以在设计任务顺序时,允许有所取舍。此外,在设计完成任务的方案时,要尽可能地开拓思维,即使看上去不那么可行的方案也可以试着提出,说不定有惊喜;然后再在众多方案中择优录取。

写在后面:

升到高三了,手打了一万多字,蛮累的,希望学弟学妹可以好好参考,少走一些弯路,多做一些开拓。我们这一代科协发展属实不好,很多精华没有传承下来。现在我在这里将我所学一一列举,期待下一代的后继者能实现科协复兴。

2022年初

Comments