I'm in the process of creating a machine that automatically aligns 2 * 2 * 2 roux book cubes with LEGO by reading the colors with a color sensor.
I tried running a program that solves a 2 * 2 * 2 Rubik's cube with the IDA * algorithm on EV3. However, due to the low CPU performance of EV3 (and my poor understanding of the algorithm), it took nearly 10 minutes to solve the Rubik's cube that can be solved with 9 hands, so using MQTT, I used MQTT.
I will try to make it in the form of. In this article, we will even say, "EV3 sends the state of the Rubik's Cube to the computer, solves it on the computer, and sends the solution to EV3."
MQTT is a lightweight communication protocol based on TCP / IP developed by IBM. Because it is lightweight, it seems that it is often used for IoT devices. Communication is divided into three roles: Publisher (sender), Broker (broker), and Subscriber (receiver). First, the Subscriber decides on a heading for the information it wants to receive and waits. Next, add a headline to the information that Publisher wants to send and send it to the Broker once. The Broker then sends that information to the Subscriber who is trying to receive the information for that heading.
PC OS : Windows10 CPU : Intel Core i5-8600K @ 3.60GHz RAM : 16GB Python : 3.8.0 (Please have pip available)
EV3 OS: EV3 MicroPython (not sure if it's official name) CPU : ARM9 @ 300MHz RAM : 64MB Python : 3.5.3
EV3 MicroPython DL ・ Main usage is from here By the way, this EV3 MicroPython is ev3dev with the Pybricks MicroPython runtime library, so you can use the functions of ev3dev as it is.
Basically, in order to communicate with each other using MQTT, it is necessary to connect the device to the Internet, but since the EV3 does not have a Wi-Fi module in the first place, this time the PC and EV3 are directly connected to the USB cable. Connect and communicate with. If you want to communicate using the Internet, you need to purchase a Wi-Fi dongle separately.
After connecting the EV3 and PC with a cable, the next step is to log in to EV3 from the PC with SSH. If you are using Linux or macOS, you can log in from the terminal with the ssh command (default user ID is'robot', password is'maker'). For Windows, use the software called TeraTerm (for Windows 10 version 1903 or later, you can connect with the ssh command using the software called "Windows Terminal").
When you launch TeraTerm, the following window will appear.
Enter [email protected]
in" Host "and click" OK ". If you use an internet connection, you can use ʻev3dev.localas the IP address (like
[email protected]`).
Next, the "Security Warning" window will appear only when you connect for the first time, so just select "Continue".
You will be asked for a password, type in'maker' and select OK.
If the following is displayed, the SSH connection is complete.
Linux ev3dev 4.14.96-ev3dev-2.3.2-ev3 #1 PREEMPT Sun Jan 27 21:27:35 CST 2019 armv5tejl```
_____ _
_____ _|___ / __| | _____ __
/ _ \ \ / / |_ \ / _` |/ _ \ \ / /
| __/\ V / ___) | (_| | __/\ V /
\___| \_/ |____/ \__,_|\___| \_/
```
Debian stretch on LEGO MINDSTORMS EV3!
Last login: (date and time) from ...
robot@ev3dev:~$
Install a broker for MQTT communication between EV3 and PC. Use mosquitto. You can put it in either PC or EV3, but this time I will install it in EV3. Execute the following command.
robot@ev3dev:~$ sudo apt-get update
robot@ev3dev:~$ sudo apt-get install mosquitto
After installation, check if the broker is running with the following command.
robot@ev3dev:~$ sudo service mosquitto status
● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
Loaded: loaded (/etc/init.d/mosquitto; generated; vendor preset: enabled)
Active: active (running) since (date and time)
Docs: man:systemd-sysv-generator(8)
Process: 1282 ExecStart=/etc/init.d/mosquitto start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/mosquitto.service
mq1289 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
(Date and time) ev3dev systemd [1]: Starting LSB: mosquitto MQTT v3.1 message broker ...
(Date and time) ev3dev mosquitto [1282]: Starting network daemon :: mosquitto.
(Date and time) ev3dev systemd [1]: Started LSB: mosquitto MQTT v3.1 message broker.
● If the part of ʻactive (running)` is green, it has started correctly. The default port number is 1883
If you see the following, it has not started.
robot@ev3dev:~$ sudo service mosquitto status
● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
Loaded: loaded (/etc/init.d/mosquitto; generated; vendor preset: enabled)
Active: inactive (dead)
Docs: man:systemd-sysv-generator(8)
So, execute the following command and check if it is started again.
robot@ev3dev:~$ sudo service mosquitto start
Next, install the library to handle MQTT from Python. Execute the following command on EV3.
robot@ev3dev:~$ sudo pip3 install paho-mqtt
Also, install it on your PC in the same way.
#### **`\Users\(username)>pip install paho-mqtt`**
```c
You are now ready.
main.py
#!/usr/bin/env python3
import paho.mqtt.client as mqtt #Import MQTT library
import subprocess
from time import sleep
get_way = False
def on_connect(client, userdata, flags, rc): #Definition of callback function to be executed when connecting to Broker
print("Connected with result code "+str(rc)) #If the connection is successful, rc is 0
client.subscribe("pc/solve_way") # "pc/solve_way"Read the heading
def on_message(client, userdata, message): #Definition of callback function to be executed when a message is received
print(message.topic + " " + str(message.payload)) #Headline name in topic, message in payload
global get_way
get_way = True
def main():
client = mqtt.Client() #Create an instance of MQTT client
client.on_connect = on_connect #Pass the callback function at the time of connection defined above
client.on_message = on_message #Pass the incoming callback function defined above
client.connect("localhost", 1883, 60) # Broker(myself)Connect to port 1883(Keep Alive is 60 seconds)
client.publish("ev3/cube_state", "5,2,6,3,4,7,1,0:0,0,0,0,0,1,2,0") #Heading in the first argument and taking information in the second argument
# "5,2,6,3,4,7,1,0:0,0,0,0,0,1,2,0"The enumeration of numbers represents the state of the Rubik's cube.
print("published")
client.loop_start() #Start message reception loop
while not get_way:
sleep(0.01)
client.loop_stop() #Stop the receive loop
client.disconnect() #Disconnect
if __name__ == '__main__':
main()
pc-main.py
import paho.mqtt.client as mqtt #Import MQTT library
from time import sleep
import rcSolver as solver # 2*2*2 Program to solve Rubik's cube
get_state = False
solve_way = ""
def on_connect(client, userdata, flags, rc): #Definition of callback function to be executed when connecting to Broker
print("Connected with result code "+str(rc)) #If the connection is successful, rc is 0
client.subscribe("ev3/cube_state") # "ev3/cube_state"Read the heading
def on_message(client, userdata, message): #Definition of callback function to be executed when a message is received
print(message.topic + " " + str(message.payload)) #Headline name in topic, message in payload
cpco_s = message.payload.decode("utf-8").split(":")
cp_s = cpco_s[0].split(",")
co_s = cpco_s[1].split(",")
cp = [int(s) for s in cp_s]
co = [int(s) for s in co_s]
cube_state = solver.State(cp, co) #Stores the state of the Rubik's cube
global solve_way
solve_way = solver.solve(cube_state) #Solve the Rubik's cube and store the solution
print("solve way:", solve_way)
global get_state
get_state = True
def main():
client = mqtt.Client() #Create an instance of MQTT client
client.on_connect = on_connect #Pass the callback function at the time of connection defined above
client.on_message = on_message #Pass the incoming callback function defined above
client.connect("ev3dev.local", 1883, 60) # Broker(EV3)Connect to port 1883(Keep Alive is 60 seconds)
client.loop_start() #Start message reception loop
while not get_state:
sleep(0.01)
client.loop_stop() #Stop the receive loop
sleep(0.5) #Wait for a while as the program on the EV3 side connects to the Broker
client.publish("pc/solve_way", solve_way) #Heading in the first argument and taking information in the second argument
print("published")
client.disconnect() #Disconnect
if __name__ == '__main__':
main()
First, execute pc-main.py
from the PC side.
#### **`\Users\(username)>python pc-main.py`**
```c
Connected with result code 0
If Connected with result code 0
is displayed, also execute main.py
on the EV3 side.
robot@ev3dev:~$ ./main.py
#### **`\Users\(username)>python pc-main.py`**
```c
Connected with result code 0
ev3/cube_state b'5,2,6,3,4,7,1,0:0,0,0,0,0,1,2,0'
solve time: 3.744987964630127
solve way: U2 R2 U R' U2 R' F2 U2 R'
published
robot@ev3dev:~$ ./main.py
published
Connected with result code 0
pc/solve_way b"U2 R2 U R' U2 R' F2 U2 R'"
If you use a PC, you can solve the Rubik's Cube with 9 hands in less than 4 seconds, and the result is also displayed on the EV3!
EV3 --Introduction to Robotics
For how to express the state of the Rubik's cube, I referred to here. [Series] Let's write a program to solve the Rubik's Cube (Part 1)
Recommended Posts