定义任意打乱的魔方称为随机状态或者初始状态,处于特殊水域的那些状态称为目标状态,目的地为还原状态
初始状态可以看作是由 U,R,F,D,L,B 这 6 个基本转动复合而成的,由这 6 个转动生成的群记为 G = 〈 U , R , F , D , L , B 〉 G=\langle U,R,F,D,L,B \rangleG=〈U,R,F,D,L,B〉
目标状态是只由 U,D,L2,R2,F2,B2 这 6 种转动复合生成的,同样的记为 G 1 = 〈 U , D , L 2 , R 2 , F 2 , B 2 〉
目标状态的性质
棱边有 2 种状态,未翻转(flip)用 0 表示,翻转用 1 表示, 只有 F,B
层的转动能够改变方向
角块有 3 种状态,未扭转(twist)用 0 表示,顺时针扭转用 1 表示,逆时针扭转用 2 表示,只有 U,D
层转动不改变
角块方向
目标状态由 U,D,L2,R2,F2,B2 这 6 种转动生成,而这 6 种转动不会引起角块和棱块方向的变化。因为不论怎么转动,角块拥有的 U 层面或 D 层面始终处于 U 层或者 D 层,所以方向不变。也不会引起棱块方向变化,因为只有 F,B 的转动会引起棱块方向的变化,而像 F2 这样的连续转动两次,翻转再反转棱块相当于未翻转,所以棱块的方向也是不会变化的。这 6 种转动也不会将中层块带到 U 层或者 D 层,所以处于中层的块只能处于中层
棱块角块方向不变,即各自的方向值总和都为 0
还原状态下的中层块处于中层
科先巴的二阶段算法使用的搜索算法是 IDA* 算法,也就是迭代加深搜索算法,而且两个阶段使用的都是 IDA* 算法
#最优化方案:
#在旋转每个面以后,不再进行F层位置还原!在完成本层任务后,函数返回值 1.当前机械位置 2.手爪状态(一般都是闭合)3.魔方当前位姿
#每个面函数,接受 1.机械位置 2.手爪状态 3.魔方当前位姿 并通过判断以上参数,在当前魔方位姿与机械位置条件下进行运动规划
#******考虑 正面的情况 #(魔方位姿相对机械本体) 6*4=24种情况
#******考虑 手腕位置 手腕 现在规定,各手腕有 (1)-270(2)-180(3)-90(4)0 (5)90(6)180(7)270 这样可以提供270延时,但决策复杂
#取代方案:只判断水平或者竖直 问题所在:不能为270度提供精确延时 解决方法:判断完水平还是竖直之后,再预判断转角是否超过软件限位,如果超出,则进行延时补偿
#******考虑 手指状态 现在规定,各手指有 (1)开(2)闭
#******考虑 列表迭代完毕,执行到最后不再复位,直接执行AandBopen()
#当前思路:程序输入为一个大的list,函数中更新list
#真正学习面向对象
机械绝对位置:
#机械绝对位置
A_angle = 0 #A手腕初始化 0度
A_finger = 0 #A手指初始化 关闭 1 open
B_angle = 0 #B手腕初始化 0度
B_finger = 0 #B手指初始化 关闭 1 open
定义其他部分:
#水平 L 竖直 V #bool
A_L = (A_angle == 0 or A_angle == 180 or A_angle == -180 )
A_V = (A_angle == 90 or A_angle == -90 or A_angle == 270 or A_angle == -270)
B_L = (B_angle == 0 or B_angle == 180 or B_angle == -180 )
B_V = (B_angle == 90 or B_angle == -90 or B_angle == 270 or B_angle == -270)
Aopen = (A_finger == 1 )
Aclose = (A_finger == 0 )
Bopen = (B_finger == 1 )
Bclose = (A_finger == 0 )
相对位置:
#魔方相对位置
F_direction = 0 #初始化 F面朝向
U_direction = 3 #初始化 U面朝向
#machine_pos = [A_L, A_finger, B_L, B_finger] #定义机械绝对位置 内容为 A 手腕绝对角度 A 手指开闭 B 手腕绝对角度 B 手指开闭
相对位姿:
cube_pos = [F_direction, U_direction] #定义魔方相对位姿 内容为 魔方正面朝向 元素1:F面 元素2:U面
穷举限位:
def B180(): #有点意思 穷举限位
print('B180...')
global B_angle
B_angle = B_angle + 180 #预判
#if(B_angle != 450 or B_angle != 360)
# time.sleep(0.001)
# ser.write("\x40".encode('utf-8')) #B 180
# time.sleep(time180)
if(B_angle == 450):
#B_angle = 90
time.sleep(0.001)
ser.write("\x40".encode('utf-8')) #B 180
time.sleep(time180)
return
if(B_angle == 360):
#B_angle = 0
time.sleep(0.001)
ser.write("\x40".encode('utf-8')) #B 180
time.sleep(time180)
return
else:
time.sleep(0.001)
ser.write("\x40".encode('utf-8')) #B 180
time.sleep(time180)
return
初代机防止缠绕气管,记录每一次旋转方向,并记录旋转了多少;