[PYTHON] Rubik's Cube Robot Software Updated 7. Key Operations

What is this article?

I am currently developing a robot that solves a 2x2x2 Rubik's cube. This is a collection of commentary articles on the robot program. soltvvo3.jpg I used to write an article collection represented by the article here, but since this time the software has been significantly updated so I will introduce a new program. think.

The corresponding code is available at here.

Related articles

"Let's make a robot that solves the Rubik's cube!"

  1. Overview
  2. Algorithm
  3. Software
  4. Hardware

Updated software for Rubik's Cube Robot

  1. Basic function
  2. Pre-calculation
  3. Solution Search
  4. Status recognition
  5. Machine operation (Python)
  6. Machine operation (Arduino)
  7. Main processing (this article)

This time, we will introduce `` `main.py``` as the main processing.

Module import

Import the module you want to use.

import tkinter
from time import sleep

from basic_functions import *
from solver import solver
from controller import controller, grab_p, release_p, calibration, move_actuator
from detector import detector

Bluetooth settings

This robot can display the elapsed time solved in real time on the screen of another PC via Bluetooth. This is the setting (I don't usually use it).

#What to do if you use bluetooth
bluetoothmode = False
if bluetoothmode:
    subprocess.call(['sh', 'bluetooth_script.sh'])
    PORT = 1
    server_socket=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
    print("connect...")
    server_socket.bind( ("",PORT ))
    server_socket.listen(1)
    client_socket,address = server_socket.accept()
    print("connection success!!")

GUI It is around the screen display. I used tkinter.

#Make a GUI
root = tkinter.Tk()
root.title("Soltvvo")
root.geometry("400x250")

grid = 20
offset = 50

entry = [[None for _ in range(8)] for _ in range(6)]

for i in range(6):
    for j in range(8):
        if 1 < i < 4 or 1 < j < 4:
            entry[i][j] = tkinter.Entry(master=root, width=2, bg='gray')
            entry[i][j].place(x = j * grid + offset, y = i * grid + offset)

inspection = tkinter.Button(root, text="inspection", command=inspection_p)
inspection.place(x=0, y=0)

solutionvar = tkinter.StringVar(master=root, value='')
solution = tkinter.Label(textvariable=solutionvar)
solution.place(x=120, y=0)

solvingtimevar = tkinter.StringVar(master=root, value='')
solvingtime = tkinter.Label(textvariable=solvingtimevar)
solvingtime.place(x=120, y=20)

grab = tkinter.Button(root, text="grab", command=grab_p)
grab.place(x=0, y=150)

release = tkinter.Button(root, text="release", command=release_p)
release.place(x=150, y=150)

calib = tkinter.Button(root, text='calibration', command=calibration)
calib.place(x=300, y=0)

start_slow = tkinter.Button(root, text="slow", command=start_slow_p)
start_slow.place(x=300, y=50)

start_medium = tkinter.Button(root, text="medium", command=start_medium_p)
start_medium.place(x=300, y=90)

start_fast = tkinter.Button(root, text="fast", command=start_fast_p)
start_fast.place(x=300, y=130)

start_superfast = tkinter.Button(root, text="super fast", command=start_superfast_p)
start_superfast.place(x=300, y=170)

root.mainloop()

From puzzle recognition to solution search

It is the recognition of the puzzle, the search for the solution, and the selection of the solution to be adopted. There is one caveat here. This robot spins a puzzle with four arms. Therefore, whether or not it can be solved quickly depends on the direction of the initial puzzle. Omitting the details, you can search for a solution in each of the two appropriately selected directions and adopt a lower cost (faster) solution. I implemented this

'''inspection'''
''' Inspection '''

def inspection_p():
    global solution
    #Initialization
    solution = []
    solutionvar.set('')
    for i in range(6):
        for j in range(8):
            if 1 < i < 4 or 1 < j < 4:
                entry[i][j]['bg'] = 'gray'
    #Get color information in normal orientation, search for solution once
    colors0 = detector()
    for i in range(6):
        for j in range(8):
            if 1 < i < 4 or 1 < j < 4:
                if colors0[i][j] != '':
                    entry[i][j]['bg'] = dic[colors0[i][j]]
                else:
                    entry[i][j]['bg'] = 'gray'
    with open('log.txt', mode='w') as f:
        f.write(str(colors0) + '\n')
    solution0, cost0 = solver(colors0)
    if solution0 == -1:
        print('cannot solve!')
        solutionvar.set('cannot solve!')
        return
    #Rotate the puzzle 90 degrees and search for a solution again
    colors1 = rotate_colors(colors0)
    solution1, cost1 = solver(colors1)
    #Adopt a low-cost solution
    if cost0 <= cost1:
        solution = solution0
        cost = cost0
        with open('log.txt', mode='a') as f:
            f.write('0\n')
    else:
        solution = solution1
        cost = cost1
        with open('log.txt', mode='a') as f:
            f.write('1\n')
        move_actuator(0, 0, -90, 200)
        move_actuator(1, 0, 90, 200)
        sleep(0.3)
    if solution == -1:
        solution = []
        print('cannot solve!')
        solutionvar.set('cannot solve!')
        return
    with open('log.txt', mode='a') as f:
        f.write(str(cost) + '\n')
        f.write(str(solution) + '\n')
    #Display of cost and estimated time
    solutionvar.set('cost: ' + str(cost) + ' ex: ' + str(round(cost * 0.083, 2)) + 's')
    #Preparing to spin the puzzle
    grab = solution[0][0][0] % 2
    for j in range(2):
        move_actuator(j, grab, 1000)
    sleep(0.2)
    for j in range(2):
        move_actuator(j, (grab + 1) % 2, 2000)
    print(solution)

The `` `rotate_colors``` function that came up when rotating the puzzle 90 degrees is: Use this function to replace the color information and represent the rotation of the entire puzzle.

'''Virtually rotate the puzzle'''
''' Rotate puzzle (don't rotate it in real world) '''

def rotate_colors(colors):
    #Replace color information
    replace = [
        [[-1, -1], [-1, -1], [2, 2], [2, 3], [-1, -1], [-1, -1], [-1, -1], [-1, -1]],
        [[-1, -1], [-1, -1], [3, 2], [3, 3], [-1, -1], [-1, -1], [-1, -1], [-1, -1]],
        [[2, 1], [3, 1], [4, 2], [4, 3], [3, 4], [2, 4], [1, 3], [1, 2]],
        [[2, 0], [3, 0], [5, 2], [5, 3], [3, 5], [2, 5], [0, 3], [0, 2]],
        [[-1, -1], [-1, -1], [3, 7], [3, 6], [-1, -1], [-1, -1], [-1, -1], [-1, -1]],
        [[-1, -1], [-1, -1], [2, 7], [2, 6], [-1, -1], [-1, -1], [-1, -1], [-1, -1]]
    ]
    res = [['' for _ in range(8)] for _ in range(6)]
    for i in range(6):
        for j in range(8):
            if 1 < i < 4 or 1 < j < 4:
                res[replace[i][j][0]][replace[i][j][1]] = colors[i][j]
    return res

operation

There are four speed stages for driving. Each function differs only in the argument of controller.

'''operation'''
''' Drive '''

def start_slow_p():
    #safe drive
    # Slow
    global solution
    solutionvar.set(controller(0.15, 0.15, 300, 1.2, solution))
    solution = []

def start_medium_p():
    #Normal operation
    # Medium
    global solution
    solutionvar.set(controller(0.1, 0.1, 400, 1, solution))
    solution = []

def start_fast_p():
    #Fast driving
    # Fast
    global solution
    solutionvar.set(controller(0.095, 0.095, 550, 0.9, solution))
    solution = []

def start_superfast_p():
    #Explosive driving
    # Super Fast
    global solution
    solutionvar.set(controller(0.1, 0.1, 600, 1, solution))
    solution = []

Summary

So far, I have serialized seven articles over a week. Thank you for reading this far. Especially, I think that the article on solution search will be useful for someone. Please comment if you find it helpful or if the program in the article is not very good!

Recommended Posts

Rubik's Cube Robot Software Updated 7. Key Operations
Updated software for Rubik's Cube Robot 2. Pre-calculation
Updated Rubik's Cube Robot software 3. Solution search
Updated Rubik's Cube Robot software 4. Status recognition
Rubik's Cube Robot Software Updated 1. Basic Functions
Updated Rubik's Cube Robot software 6. Machine operation (Arduino)
Rubik's Cube Robot Software Updated 5. Machine Operation (Python)
Let's make a robot that solves the Rubik's Cube! 3 Software
Let's make a robot that solves the Rubik's Cube! 2 Algorithm
Let's make a robot that solves the Rubik's Cube! 1 Overview