好奇魔方机器人的的软件不仅仅适用于上图的搭建,用户通过修改配置文件,可以适用于任何单个NXT驱动的魔方机器人。软件的整体界面如下图4:
图4 好奇解魔法机器人软件
3.1 软件设计原理
好奇软件在复原一个魔方时,首先需要读入魔方的初始状态。当然你也可通过手动输入魔方的初始状态,在读入的过程中,在界面中通过平面和立体两种方式显示出来。通过平面图和立体图对比,你应该很容易分清魔方的前后左右了。在手动输入时,可以通过鼠标右键或者工具条进行输入,两种输入方式只能同时选用一种方式。选用工具条手动输入时,先选定一种颜色,然后直接点击平面图中的色块,就可以将该色块设置为选定的颜色;选用鼠标右键输入时,此时要确保工具条中所有颜色都处于未选定状态,在魔方选定平面图中选定相应的色块,单击鼠标右键,即可弹出右键工具条,选择你要设置的颜色,即可将选定的色块设置为弹出工具条中选定的颜色。由于魔方并不是任意的组装方式都有复原解,本软件并没有对你设置的颜色进行详细校验,注意不要输入错误的状态,否则可能找不到解。输入完成后注意保存初始状态,因为在实际操作中,我发现无论是通过颜色传感器读入还是通过手动输入魔方的初始状态,都是一个痛苦的等待过程。看来下次版本得增加一个通过摄像头输入的过程。
在读入初始状态后,系统通过层先发求解,对于一个一般的魔方,大概需要100多步。据说20步能够复原一个任意三阶魔方,能够写出这个算法的人,应该是神一样的存在了!听说有个美国的学生写了一个28步求解任意三阶魔方,那应该也是大神。我认为写出少于50步求解一个任意三阶魔方的算法,都应该是数学家的干活了。我曾经用递归的方法写了一个求解算法,但是当递归到第三层时感觉有点慢,递归到第6层时,我吃了个午餐,睡了个午觉,还去洗个冷水澡时间还绰绰有余。递归10层时,我最终选择直接将电脑关机……,如果要想等它递归完20层找到最优解法,估计上帝都等不到了。我分析了一下我的算法,魔方旋转的次数=18的n次方(n等于递归的层数)。看来这个工作还真不是一般人能够干得了的,没办法最后只得选用层先发求解,如果哪位大侠有更好的解法,希望不吝赐教。
系统在求解的过程中,将旋转的方式和魔方的所处的状态保存在左边的列表中,用户单击其中的任意一行即可了解到魔方当时处于什么状态。如果你有一个魔方不知道怎么复原,可以通过输入魔方的初始状态,让它给你求解,虽然方法有点笨,但是至少能够达到目的。
在找到魔方的复原解法以后,还不能直接给魔方机器人操作,因为魔方机器人能够操作的只能在水平或者垂直方向对魔法机器人进行翻转,或者对魔法的底部进行旋转,在进行垂直方向的旋转时,一次还只能旋转动90度,所以还必须进行操作转换。
在操作转换后,再可以让机器人操作了,但是在操作之前,你得先打开蓝牙,并且你可能需要先对魔法机器人进行调试。调试时你可以使用调试对话对水平转的3个角度、垂直旋转1个角度(其它两个角度无非就是多转几次),和底部旋转的3个角度,总共7种操作进行调试。当然在读颜色时,你可以定义更多的操作。在调试完成之后你就可以对你的魔方机器人进行复原了,注意魔方的初始状态一定要放对哦,我的方式是将上图2中两个橙色零件中间的连杆贴着的那一面作为正面,该面和模拟图中的正面对应,你也可以选择其它的面作为正面,注意正面的选取是和翻转方式密切相关的,正面的选取不同,则翻转的方式也不相同,在调试时,你要确保魔方的翻转后的状态和模拟的翻转状态保持一致!
在调试完成之后,即可开始试运行了,运行时你可以选择单步执行或者自动执行的方式,注意在暂停后才可以单步执行的。
3.2 配置文件介绍
软件的配置文件主要放在SysConfig.ini文件中。在该文件中定义了颜色传感器的操作,颜色的读取,颜色的区分、马达的操作,程序的操作、魔方的翻转等等。
Motor表示驱动马达,如Motor0表示驱动A口马达,Motor1表示驱动B口马达,Motor2表示驱动C口马达,Motor12表示驱动BC口马达,前面我说了,通过蓝牙直接驱动马达的效果不太理想,建议通过运行NXT中的程序进行间接驱动。
Sleep表示暂停多少毫秒,因为你的电脑的运行速度比机器人的操作速度快很多很多,因此电脑需要暂停等待一定的时间等待机器人操作完成,如果机器人操作还没有完成,就进行下一个驱动,可能导致下面的操作无反应。比如当一个程序运行还没有运行完成时,就驱动下一个程序,则NXT可能直接跳过下一个程序的驱动,还有就是要确保NXT的电池电量是足够的,如果电池报警一次电量不足,也会对驱动程序的操作无响应。
Progr=*** 表示运行NXT中的***程序,建议对于马达的操作都写成*.Rbt程序下装到NXT中,然后通过蓝牙运行该程序来驱动马达。
COMPort表示电脑上蓝牙连接对应的串口。
ColorPort 表示颜色传感器连接到NXT的哪一个端口
串口的链接
[PORT_SET]
COMPort =2
ColorPort=1
魔方的6个面以及旋转
魔方的6个面的定义
F表示前,初始时为蓝色, U表示上,初始为黄色,
B表示后,初始时为绿色 D表示下,初始为白色
L表示左,初始时为橙色 R表示右,初始为红色
F1表示将前面旋转90度,F2表示将前面旋转180,F3表示将前面旋转270度,其它依次类推
颜色的读取区分定义
通过颜色传感器分布发出红、绿、蓝三种颜色来判断读取的是哪一种颜色。由于要进行读取值获取,因此颜色传感器是通过蓝牙进行直接驱动。
控制颜色传感器发出哪种光的颜色的定义为:
LIGHT_COLOR=0表示颜色传感器发出红光,LIGHT_COLOR=1表示颜色传感器发出绿光,LIGHT_COLOR=2表示颜色传感器发出蓝光
六种颜色的定义为:{blue=1,red=2,yellow=3,green=4,white=5,orange=6,black=7}Colors;//7种颜色分别用1~7表示
在软件调试对话框中,有颜色值的比较列表,在打开蓝牙串口之后,将颜色传感器对准魔方中的色块,可以点击最左边的颜色列表中相应的颜色,即可读取该色块的红、绿、蓝值,如图5。
调试对话框
图5 硬件调试对话框
系统后通过三步来区分读到的魔方色块是哪种颜色,每种光够区分出两种颜色。通过蓝光,可以将白色和蓝色其它颜色中挑选出来,再通过红光分辨是白色还是黄色,用绿光在如下的四种颜色中区分出黄、绿两种颜色,然后用红光区分黄、绿;余下的红、橙用绿光区分。
第一步区分:通过蓝光将蓝色和白色从其他颜色中区分开来, COLOR_MIN为发出蓝光时,蓝色和绿色的中间值。再用红光将蓝白区分开来。大的为白色,小的为蓝色。其中COLOR_MID为发出红光时白色和蓝色的中间值
[DISTINGUISH_STEP1]
LIGHT_COLOR1=2
COLOR_MIN=289
LIGHT_COLOR2=0
COLOR_MID=391
LAGER_COLOR=5
SMALLER_COLOR=1
第二步区分:用绿光在如下的四种颜色中区分出黄、绿两种颜色,其中COLOR_MIN为发出绿光时,绿色和橙色的中间值;然后用红光区分黄色和绿色,其中COLOR_MID为为发出红光时,黄色和绿色中间值。
[DISTINGUISH_STEP2]
LIGHT_COLOR1=1
COLOR_MIN=359
LIGHT_COLOR2=0
COLOR_MID=354
LAGER_COLOR=3
SMALLER_COLOR=4
第三步区分:用绿光区分红橙,其中COLOR_MID为发出绿光时,红色和橙色中间值。
[DISTINGUISH_STEP3]
LIGHT_COLOR1=1
COLOR_MID=282
LAGER_COLOR=6
SMALLER_COLOR=2
在读取了六种颜色之后,如果点击“自动配置”,则会根据上面的颜色分辨方式配置颜色识别文件。
机器人操作调试设置
和调试菜单对话框中的下拉菜单对应,左边的和相应的操作定义section对应。如HORIZONTAL1对应section [HORIZONTAL1]的操作。水平转90度未下拉菜单中的下拉名字。
[MOTOR_SECTION]
HORIZONTAL1=水平转90
HORIZONTAL2=水平转180
HORIZONTAL3=水平转270
VERTICAL1=垂直转90
VERTICAL2=垂直转180
VERTICAL3=垂直转270
CATCH1=底部转90
CATCH2=底部转180
CATCH3=底部转270
ReadColor_U=上面颜色读取
;用于对魔方进行底部转90度时的前后操作
CATCH_CUBE = 抓住魔方
RELEASE_CUBE = 释放魔方
魔方的姿态调试设置
将前面调整到底部
[F_D]
HORIZONTAL=3
VERTICAL=1
将魔方的U的位置调整到D的位置
[U_D]
VERTICAL=2
将魔方的B的位置调整到D的位置
[B_D]
HORIZONTAL=1
VERTICAL=1
将魔方的L的位置调整到D的位置
[L_D]
HORIZONTAL=2
VERTICAL=1
将魔方的R的位置调整到D的位置
[R_D]
VERTICAL=1
将魔方的D的位置调整到D的位置 不用操作
[D_D]
读取魔方的颜色定义
读取魔方的颜色,oper表示读魔方之后要对魔方如何翻转,注意此时的翻转不仅仅是魔方实体的翻转,也包含了模拟魔方的翻转,因此不能NXT中的程序代替,NULL表示不用翻转,每次读取9个色块的颜色,由于颜色传感器只能读取上面的颜色,因此读完之后,需要对魔方进行翻转才能读取下一个面的颜色。
[READ_COLOR]
ReadU = ReadColor_U
Oper = VERTICAL1
ReadU = ReadColor_U
Oper = VERTICAL1
ReadU = ReadColor_U
Oper = VERTICAL1
ReadU = ReadColor_U
Oper = HORIZONTAL3
Oper = VERTICAL1
ReadU = ReadColor_U
Oper = VERTICAL2
ReadU = ReadColor_U
读取魔方上面的颜色定义
Motor表示对电机进行操作,在此也可以配置成程序操作。Read = 22表示第一次先读取中间的色块,然后颜色传感器后退一点,读取32的颜色,魔方一面的9个颜色定义用[1-3][1-3]的一个二维数组定义,如图6。注意,读取的颜色具体放在那个块中,也是同你定义的魔方的正面相关的。如图
[ReadColor_U]
Progr=ForLight
Sleep=1500
Read=22
Progr=Back22
Sleep=1500
Read=12
Progr=Turn12
Sleep=1000
Read=13
Progr=Turn13
Sleep=1000
Read=23
Progr=Turn12
Sleep=1000
Read=33
Progr=Turn13
Sleep=1000
Read=32
Progr=Turn12
Sleep=1000
Read=31
Progr=Turn13
Sleep=1000
Read=21
Progr=Turn12
Sleep=1000
Read=11
Progr=BackLight
Sleep=2000
;注意在程序的最后一定要加一个延时,否则在该模块被调用时,可能导致后面的程序模块无响应
图6 魔方编号
魔方水平面上旋转操作
;将魔方在水平面以上面为基准逆时针旋转90°
[HORIZONTAL1]
Progr=H270
Sleep=2500
;将魔方在水平面以上面为基准逆时针旋转180°
[HORIZONTAL2]
Progr=H180
Sleep=5000
;将魔方在水平面以上面为基准逆时针旋转270°
[HORIZONTAL3]
Progr=H90
Sleep=2500
抓住释放魔方的操作
;抓住魔方的动作
[CATCH_CUBE]
Power=70
Motor1=-10
SLEEP=500
;释放魔法的动作
[RELEASE_CUBE]
Power=75
SLEEP=100
Motor0=55
;将魔方中上部不动,从上看,底部顺时针转90度
魔方底部旋转操作
[CATCH1]
Progr=CH90
Sleep=3000
;将魔方中上部不动,从上看,底部顺时针转180度
[CATCH2]
Progr=CH180
Sleep=6000
;将魔方中上部不动,从上看,底部顺时针转270度
[CATCH3]
Progr=CH270
Sleep=3000
魔方垂直方向的旋转操作
;将魔方在垂直面以右面为基准顺时针旋转90°
[VERTICAL1]
Progr=V90
Sleep=2500
;将魔方在垂直面以右面为基准顺时针旋转180°
[VERTICAL2]
Progr=V90
Sleep=2500
Progr=V90
Sleep=2500
;将魔方在垂直面以右面为基准顺时针旋转270°
[VERTICAL3]
Progr=V90
Sleep=2500
Progr=V90
Sleep=2500
Progr=V90
Sleep=2500
魔方的状态保存
;保存魔方的状态,每个面的颜色记录为一个9位数,按照图6中的编号[1][1]、[1][2]、[1][3]、[2][1]、[2][2]、[2][3]、[3][1]、[3][2]、[3][3]的顺序存放,同图4中的左边的列表中存储的数字一致。
[SAVE_CUBE]
UP=333333333
DOWN=555555555
FRONT=222111666
BACK=666444222
LEFT=111666444
RIGHT=444222111