找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 48941|回复: 72

EV3教育版解魔方机器人软件研究

    [复制链接]
22 乐币 回复本帖可获得 2 乐币奖励! 每人限 1 次(中奖概率 10%)
发表于 2016-5-29 17:04:20 | 显示全部楼层 |阅读模式
本帖最后由 hmq011212 于 2017-4-3 17:32 编辑

UPDATE: 由于更换电脑的缘故,再加之高中学业繁重(自招考上了),更新会进一步延迟,但是我仍然在继续研究着Mindcub3r,直到帖子完结,然而由于最近占坑太多,并且涉及各种不同的领域,所以时间会比较少,希望大家谅解。
本次更新,删去了乱七八糟的CPP代码,版面更加清爽。
以上。 April 3rd.
另外,删去了Mega网盘的链接,改为大家更为常用的百度网盘(虽然恶心,但是对于大部分人来说,还是比较快的,谁有百度网盘的VIP账号,麻烦分享下,我这里实在是太慢了,请使用PM的形式。):(链接准备中)----------------------------------------------------------------------正文-------------------------------------------------------------------
MindCub3r对于很多玩家来说已经十分熟悉了,当然作为一个新手,也是从搭建错误到不能扫描到成功解魔方过来的,MindCub3r的程序,是一个非常好的研究范本,它不仅仅运用了机械部分的操作,还运用了程序间的通信等高级内容。但是由于采用了Lego方面的编程系统,虽然是开放源代码,但是程序复杂后,就是一个大坑。相信没有人愿意看到这样的程序: 程序.PNG
这也已经是高度模块化的程序了。许多人该打退堂鼓了。

作为一个学生,我当然也希望研究一下,于是就催生出了这篇文章。当然毕竟时间有限,我也不可能一天24小时扑在程序上,只有周末才能来研究一下,不可能每天都来更新帖子、给大家回复,所以大致会每周更新一次,统一回复三次。文章会分为几个章节(具体几个章节没想好),每个章节难度不同。当然由于我LDD技术有限,只能使用官方的搭建图,如果哪位能够提供教育版LDD图纸,那就更好了。我们开始看程序:



第一章  机械部分的初始化
有志者,事竟成。
——引子
一、程序体:
(一)、主程序:
1.     闪烁红色指示灯;
2.     调用Banner子程序,显示Banner;
3.     调用Message子程序,显示信息(参数:Reset scan);
4.     调用ScanCal子程序,使扫描臂复位;
5.     调用Message子程序,显示信息(参数:Reset tilt);
6.     调用TiltCal子程序,使翻动臂复位;
7.     终止程序。
(二)、循环体:
         1.LpMindCub3r(Mindcuber的循环体)
①  测量反射光线强度(端口2,光线传感器);
②  调用CubeAbsent子程序,检测是否放置魔方;
③  测量环境光线强度(端口2,光线传感器);
④  琥珀色指示灯常亮;
⑤  调用CubePresent子程序,检测现有魔方状态;
⑥  判断布尔型变量solve是否为真,为真,则执行ScanAndSolve子程序,为假,则执行Scramble子程序;
⑦  无限循环下去。
2. LpScanCal0(复位扫描臂)
①   C电机旋转0.2s,并测量度数,传入变量a;
②   测量度数,传入变量b;
③   当a大于等于b时,返回真,否则返回假;
④   执行循环,直至返回值为真。
注:此处事实上使电机旋转到“定位点”,方法是不断判断电机是否停止运动,若停止运动,则说明已经到达“定位点”。如下图:
                                                   
定位点.PNG

扫描臂定位点
2. LpScanCal1(复位扫描臂)
①   C电机旋转0.2s,并测量度数,传入变量a;
②   测量度数,传入变量b;
③   当a大于等于b时,返回真,否则返回假;
④   执行循环,直至返回值为真。
     
注:此处事实上使电机旋转到“定位点” ,方法是不断判断电机是否停止运动,若停止运动,则说明已经到达“定位点”。如下图:
扫描臂定位点
    3.     LpTiltCal(复位翻动臂)
①   A电机旋转0.2s,并测量度数,传入变量a;
②   测量度数,传入变量b;
③   当a小于等于b时,返回真,否则返回假;
④   执行循环,直至返回值为真。
注:此处事实上使电机旋转到“定位点” ,方法是不断判断电机是否停止运动,若停止运动,则说明已经到达“定位点”。如下图标黄色的部分,复位完成后,应当在七孔梁的同侧。
定位点2.PNG
翻动臂定位点

(三)、子程序:
1.      Banner(横幅)
①   清屏,用网格状大字在屏幕左上角显示文本“MindCub3r”;
②   在文本“MindCub3r”右上方用像素小字显示文本“v1p9”;
③   调用BannerVariant子程序,在文本“v1p9”下方用像素小字显示文本“Edu”;
④   在该行字符下,绘制填充的矩形,长141px,宽3px;
⑤   在矩形左下,用像素小字显示文本“By David Gilday”;
⑥   在文本“By David Gilday”左下,用像素小字显示文本“mindcuber.com”;
⑦   返回主程序。
2.      Message【信息(状态?)】
①  合并文本,参数A指定为调用子程序时所用的参数;
②  在文本“mindcuber.com”下,将合并后的结果用网格状大字显示;
③  返回主程序;
3.      ScanCal(扫描臂计算)
①   将C端口的电机功率设定为40%;
②   执行循环体LpScanCal0,复位电机;
③   C端口中型电机以40%功率倒转100°,结束时制动;
④   将C端口的电机功率设定为20%;
⑤   执行循环体LpScanCal1,复位电机;
⑥   重置电机度数为0°;
⑦   调用子程序ScanAway,使扫描臂返回工作位置;
⑧   返回主程序。
4.      ScanAway(扫描臂返回工作位置)
①   测量电机旋转度数,传入变量b;
注:由于在LpScanCal1循环体中,已经完成了电机度数的重置,且中途没有退出程序,故此时电机度数为0。
②   计算a-b的值,变量a为常数-340,并使电机以100%的功率转动(a-b)°;
注:此时(a-b)的值为-340。
③   返回主程序。
5.      TiltCal(翻动臂计算)
①   将A端口的电机功率设定为-20%(倒转20%);
②   执行子程序TiltOffset,声明变量bit_offest(偏移量)并赋值;
③   执行循环体LpTiltCal,复位翻动臂;
④   重置电机度数为0°;
⑤   调用子程序TiltAway,使翻动臂返回工作位置;
⑥   返回主程序。
6.      TiltAway(翻动臂返回工作位置)
①   测量电机旋转度数,传入变量a;
注:由于在LpTiltCal循环体中,已经完成了电机度数的重置,且中途没有退出程序,故此时电机度数为0。
②   计算a-b的值,变量b为常数10,并使电机以70%的功率转动(a-b)°;
注:此时(a-b)的值为-10。
③   返回主程序。
2016年5月29日
山东省
(注:这一章是我早期完成的,只是改了改日期,实际完成日期为5月21日,若有不妥之处,敬请PM,文章将会持续更新。)


今天是6月4日,我们将要进行小中考,时间比较多,更新频率会大些。每次更新也会多些。有一点做阅卷机的想法,这篇文章完成后,将会写下阅卷机的文章,一样持续更新,这是后话。现在是下午17点25分。开始更新。
第二章  隐秘的部分
重要提示:如果第一章都看不懂了,那么请不要继续看第二章!!!
-——引子
这仅仅是开个玩笑,这一部分难度增加了,但是也不是最难的一部分。这一部分你几乎看不见,但是后面还是会用到。所以,这一章还是比较重要的。
首先,我们要引入一些概念,这也是我们第一章结束的原因。这些概念,我都会用最最通俗的语言来叙述。
1. 变量:所谓变量,其实就是“可变的量”,你可以把它想象成一个缸,在这个缸里面放上水,它就叫“水缸”,在这个缸里面放上米,它就叫“米缸”,这个“缸”里放上什么,它里面就有什么,缸里的物质是可以改变的。在编程中,常用来存储可变的量,在程序执行过程中,变量的量是可变的,它存储于内存中。在C++中常用的定义变量的方式为“数据类型 变量名”;
2. 数组(排列):数组也叫排列。所谓数组,其实就是一个变量,只不过这个变量中含有多个元素,怎么理解呢?变量是个缸,缸里放上米,这个缸里每一粒米都是这个缸的“元素”,这个缸就是一个数组,它也存储在内存里。在C++中常用的定义数组的方式为“数据类型 数组名[数组宽度]”,这个“数组宽度”,就是数组的大小;
3. 数据类型:所谓数据类型,实际上就是指这个数据是什么一类东西,比如“abc”是字符型(char)数据[又称“文本型(text)数据”];比如“123”是整数型(int)数据;比如“123.456”是单精度小数型(float)数据;比如“3.1415926535”是双精度小数型(double)数据,以上整数型、单双精度小数型数据,在EV3的编程系统中,统称为“数字型数据”。当然,有一个特例,布尔型(bool)数据,只有“真”与“假”两种状态,被称为“逻辑型数据”。在EV3编程系统中,可用的只有这几种数据类型。
4. 函数:函数不同于数学中的函数,它是由一组命令组成的,你也可以把它视作“模块”,一个模块完成一项任务,函数组合在一起,就是一个程序,在EV3编程系统中,被称为“模块”。
5. 参数:参数与函数有关,就是函数执行时所需要的数据。
(原混乱的代码已删除。)
一、函数
1.  InitTables函数(变量表)
① 定义变量dbg,并赋值为0;
② 定义数组imap,并插入元素{0,1,2,3,4,5,0,3,2,1,5,4,2,4,5,3,1,0,5,2,4,1,3,1,0,3,2,5,4,1,2,3,0,4,5,1,4,3,5,0,2,1,5,3,4,2,0,2,1,0,3,5,4,2,3,0,1,4,5,2,4,0,5,1,3,2,5,0,4,3,1,3,0,1,2,4,5,3,2,1,0,5,4,3,4,1,5,2,0,3,5,1,4,0,2,4,0,5,2,1,3,4,1,5,3,2,0,4,2,5,0,3,1,4,3,5,1,0,2,5,0,4,2,3,1,5,1,4,3,0,2,5,2,4,0,1,3,5,3,4,1,2,0};
③ 定义数组edge0_tab并插入元素{1,7,5,3,43,31,23,35,21,11,19,17};
④ 定义数组……并插入元素……(我不写了,有需要的自己翻阅上述内容,总之就是定义变量);
⑤ 调用Message函数,显示文本“Find solver”。
⑥ 调用SolverCommand函数,参数cmd=2 [有些类似EV3Messager的做法,若想了解详情,请访问http://bbs.cmnxt.com/thread-12655-1-1.html与http://ev3messenger.codeplex.com/(需梯子)];
⑦ 执行循环LpInitTables,判断Solver是否响应(此处就是卡在Find solver的循环);
⑧ 播放音调(1000Hz,0.1s,音量100%,播放一次);
⑨ 定义数字型变量pattern,并赋值为0;
⑩ 定义数字型变量pattern_mode,并赋值为0;
⑪  调用GetPattern函数,返回name, faces, turns, number;
⑫  调用SetPattern函数,参数faces, turns均使用GetPattern中的返回值;
⑬  调用CubeDetect函数,检测魔方;
⑭  返回主程序。
2.  △SolverCommand函数(给Solver发信息)
① 删除mc3cmd文件;
② 创建mc3cmd文件,并写入cmd;
③ 关闭mc3cmd文件,返回主程序。
3.  △SolverResponse函数(检测Solver是否响应)
①  读取mc3cmd文件,并将其值返回为resp,Mod2后判断是否与1相等,若相等返回done为真,否则返回done为假;
②  关闭mc3cmd文件。
4.  GetPattern函数(取解魔方模式函数)
①  判断传入的number值:
⑴ 若为0,则返回name为Solve;
⑵ 若为1,则返回name为CheckerBoard(棋盘形),定义数组checkboard_faces,并添加元素{0,2,1,3,4,5},定义数组checkboard_turns,并添加元素{2,2,2,2,2,2};
(3) 若为2,则返回name为Cube-in-cube(魔方套魔方),定义数组cubes_faces,并添加元素{0,4,2,1,4,0,4,0,4,0,4,5,2,5,1,2,4},定义数组cubes_turns,并添加元素{-1,1,-1,-1,1,2,2,-1,-1,1,2,1,-1,-1,2,2,-1},返回faces为cubes_faces,返回turns为cubes_turns;
(4) 若为3,则返回name为Six-spot(蓝点),定义数组spot_faces,并添加元素{4,5,1,3,0,2,4,5},定义数组spot_turns,并添加元素{1,-1,1,-1,1,-1,1,-1},返回faces为spot_faces,返回turns为spot_turns;
(5) 若为4,则返回name为snake(S形),定义数组snake_faces,并添加元素{1,5,0,5,3,0,3,5,0,5,1,5,0,1},定义数组snake_turns,并添加元素{-1,-1,1,1,2,1,2,1,-1,1,-1,2,-1,2},返回faces为snake_faces,返回turns为snake_turns;
(6) 若为5,则返回name为Superflip(翻棱),定义数组superflip_faces,并添加元素{0,1,4,0,4,2,1,3,0,1,4,5,1,2,3,4,1,2,1,2},定义数组superflip_turns,并添加元素{-1,2,-1,2,2,2,1,-1,-1,2,1,1,-1,2,-1,2,-1,2,-1,-1},返回faces为superflip_faces,返回turns为superflip_turns;
(6) 若为-1,则返回name为All(所有),返回faces为空数组,返回turns为空数组;
(7) 若为-2,则返回name为Random(随机),返回faces为空数组,返回turns为空数组;
(8) 若为-3,则返回name为Scramble(打乱),返回faces为空数组,返回turns为空数组;
②  返回number为5;
③  返回InitTables函数。
(注:初始状态为-1,即All。吐槽:本来是一个switch语句,结果搞得这么复杂,我想念写两个函数直接return faces,然后再return turns的时代,还有乐高公司麻烦出个全局变/常量和局部变/常量吧,看“*量表”眼花啊,顺便把变量值加进去……
还有所谓“结构化编程”对于ev3来说就是个笑话,你这是图形化编程,易学倒是易学,对开发大工程来说就是噩梦……)
5.  SetPatten函数(设置魔方模式函数)
①  删除文件mc3dat;
②  取数组faces的长度,判断是否介于1-100之间;
⑴  若介于1-100之间,则向mc3dat中写入数组faces的长度,执行LpSetPattern0循环,继续顺次写入faces、turns数组的各个值;
⑵  若不介于1-100之间,则向mc3dat中写入0;
③  关闭mc3dat文件;
④  执行SolverCommand函数,参数cmd=8;
⑤  执行LpSetPattern循环,判断解魔方程序是否响应;
⑴  等待0.1秒;
⑵  执行SolverResponse函数,检测是否响应;
⑶  若响应,返回InitTables程序;
⑷  若无响应,继续执行循环。
6.  CubeDetect函数(检测魔方函数)
①  调用1号端口的超声波传感器测量距离;
②  判断6-10厘米处是否有物体,若有物体返回真,否则返回假。



下载地址见图片

下载地址见图片

评分

参与人数 1乐币 +50 收起 理由
ntwuhui + 50 中文乐高有你更精彩:)

查看全部评分

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2016-5-29 17:57:08 | 显示全部楼层
非常棒,期待其他章节
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-5-29 20:06:20 | 显示全部楼层
学习
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-5-31 14:02:58 | 显示全部楼层
好贴,一直想学习,这会可以看到详细的解释了,期待更新。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-5-31 19:03:10 | 显示全部楼层
真是肯钻研,赞
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-6-1 12:37:42 | 显示全部楼层
不错,多谢分享
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-6-5 15:34:57 | 显示全部楼层
太厉害了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-2 19:20:03 | 显示全部楼层

回帖奖励 +2 乐币

好帖
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-2 19:20:20 | 显示全部楼层
学习学习
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-16 13:59:30 | 显示全部楼层
牛逼
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-17 10:00:37 | 显示全部楼层

回帖奖励 +2 乐币

牛逼
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-31 16:44:31 | 显示全部楼层
666
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-7-31 21:52:26 | 显示全部楼层
学习
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-8-3 11:41:28 | 显示全部楼层
学习了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2016-8-6 15:58:17 | 显示全部楼层
高手就是境界不同,学习了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-3-29 04:28 , Processed in 0.343996 second(s), 28 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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