I am currently developing a robot that solves a 2x2x2 Rubik's cube. This is a collection of commentary articles on the robot program. 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.
"Let's make a robot that solves the Rubik's cube!"
Updated software for Rubik's Cube Robot
This time, I will introduce `` `controller.py``` as a machine operation (Python) edition.
First, set up serial communication and GPIO.
ser_motor = [None, None]
GPIO.setmode(GPIO.BCM)
GPIO.setup(21,GPIO.IN)
ser_motor[0] = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.01, write_timeout=0)
ser_motor[1] = serial.Serial('/dev/ttyUSB1', 115200, timeout=0.01, write_timeout=0)
An actuator here is a motor. The motor is connected to a self-made Arduino compatible machine, and the actuator is operated by sending a command to Arduino. Here, we will introduce a function that sends commands.
'''Send a command to move the actuator'''
''' Send commands to move actuators '''
def move_actuator(num, arg1, arg2, arg3=None):
if arg3 == None:
com = str(arg1) + ' ' + str(arg2)
else:
com = str(arg1) + ' ' + str(arg2) + ' ' + str(arg3)
ser_motor[num].write((com + '\n').encode())
There are two types of commands to move the actuator, which differ in the number of arguments. So I'm writing a if
statement using arg3 == None
(although I'm talking about separating functions).
Using the previous function, I made a function to grab the puzzle and a function to release it. This is a function for occasional actions.
'''Grab the cube'''
''' Grab arms '''
def grab_p():
for i in range(2):
for j in range(2):
move_actuator(j, i, 1000)
sleep(3)
'''Release the cube'''
''' Release arms '''
def release_p():
for i in range(2):
for j in range(2):
move_actuator(i, j, 2000)
For two Arduino i
, run the two motors `` j``` connected to each.
1000 and 2000 means that if you send 1000, you will grab the puzzle, and if you send 2000, you will release it.
Since the arm is driven by a stepping motor, it is necessary to adjust the position appropriately. The Arduino has a hall sensor (magnetic sensor), and a magnet is attached to the arm. By using this, the position will be adjusted automatically. From Python, you can adjust the position just by sending a command.
'''Arm calibration'''
''' Calibration arms '''
def calibration():
release_p()
sleep(0.1)
for i in range(2):
for j in range(2):
move_actuator(j, i, 0, 500)
It is a function that moves the robot when you enter a solution and other constants.
The robot has an emergency stop button, which is processed first. By the way, the emergency stop button is a pull-up, so even if the connector is disconnected, the operation will stop.
Then, when turning other than the first move, change the puzzle, turn the motor in sequence, and rest for a time proportional to the maximum number of revolutions. Returns the time it took to finally solve.
'''Actually move the robot'''
''' Control robot '''
def controller(slp1, slp2, rpm, ratio, solution):
strt_solv = time()
for i, twist in enumerate(solution):
#Press the emergency stop button to stop
if GPIO.input(21) == GPIO.LOW:
if bluetoothmode:
client_socket.send('emergency\n')
solvingtimevar.set('emergency stop')
print('emergency stop')
return
#Changing puzzles
if i != 0:
grab = twist[0][0] % 2
for j in range(2):
move_actuator(j, grab, 1000)
sleep(slp1)
for j in range(2):
move_actuator(j, (grab + 1) % 2, 2000)
sleep(slp2)
max_turn = 0
for each_twist in twist:
move_actuator(each_twist[0] // 2, each_twist[0] % 2, each_twist[1] * 90, rpm)
max_turn = max(max_turn, abs(each_twist[1]))
#Wait for the puzzle to spin
slptim = 2 * 60 / rpm * max_turn * 90 / 360 * ratio
sleep(slptim)
solv_time = str(int((time() - strt_solv) * 1000) / 1000).ljust(5, '0')
return solv_time
This time, I explained the function that actually moves the robot (although what I am doing is sending commands). Next, I will explain how the motor is operated after receiving the command on the Arduino side.
Recommended Posts