Wiki »
Código e implementación¶
Interfaz de usuario (GUI)¶
Código de la interfaz de usuario del proyecto. Permite controlar al robot mediante una conexión wi-fi usando teclas o botones. Posee diversas funciones que incluyen movimiento, utilidad y manejo de conexión con el robot.
#//Project Robot Robo-Cleaner
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
import socket
root = Tk()
root.title("Robo-Cleaner")
root.resizable(False, False)
root.geometry("900x400")
# //Socket Connection & Socket Connection Windows
client = socket.socket()
port = 12345
def get_IP():
vtn_ip = Tk()
vtn_ip.geometry("275x100")
vtn_ip.resizable(False,False)
vtn_ip.title("Ajustes de la Conexión IP")
inform = Label(vtn_ip,text="Dirección IP: ").place(x=10, y=10)
addr = StringVar(vtn_ip)
ip = ttk.Entry(vtn_ip, textvariable = addr).place(x=100, y=10)
boton = Button(vtn_ip, text = "Establecer", command = lambda:[conection(addr.get()+""), vtn_ip.destroy()]).place(x=98, y=50)
print(addr.get())
def conection(addr):
port = 12345
try:
client.connect((addr, port))
messagebox.showinfo("Mensaje Recibido", "El host se conectó al robot: \nDirección IP: {0}\nPuerto: {1}".format(addr,port))
except socket.error:
messagebox.showwarning("Error de conexión", "No se logró realizar la conexión. \nRevise la dirección IP e intentelo nuevamente. \nDirección IP: " + addr)
get_IP()
# //Functions
def Upward(event):
try:
client.send(bytes([ord('i')]))
except BrokenPipeError:
print()
def Backwards(event):
try:
client.send(bytes([ord('k')]))
except BrokenPipeError:
print()
def LeftTurn(event):
try:
client.send(bytes([ord('j')]))
except BrokenPipeError:
print()
def RightTurn(event):
try:
client.send(bytes([ord('l')]))
except BrokenPipeError:
print()
def Rotate(event):
try:
client.send(bytes([ord('p')]))
except BrokenPipeError:
print()
def LeverUp():
try:
client.send(bytes([ord('y')]))
except BrokenPipeError:
messagebox.showerror("Error", "El robot no está conectado")
def LeverDown():
try:
client.send(bytes([ord('h')]))
except BrokenPipeError:
messagebox.showerror("Error", "El robot no está conectado")
def Automatic():
try:
client.send(bytes([ord('a')]))
except BrokenPipeError:
messagebox.showerror("Error", "El robot no está conectado")
def disconection():
try:
client.send(bytes([ord('q')]))
messagebox.showinfo("Información", "El robot se desconectó correctamente")
except BrokenPipeError:
messagebox.showwarning("Advertencia", "No hay un robot conectado a la máquina")
def Halt(event):
try:
client.send(bytes([ord('w')]))
except BrokenPipeError:
messagebox.showerror("Error", "El robot no está conectado")
# //Set own directory for background image
check_photo = PhotoImage(file="checked.png")
exit_photo = PhotoImage(file="exit.png")
automatic_photo = PhotoImage(file="letter-a.png")
root_canvas = Canvas(root, width=900, height=400)
root_canvas.pack(fil="both", expand=True)
root_canvas.create_image(260, 100, image=check_photo, anchor="nw")
root_canvas.create_image(260, 140, image=exit_photo, anchor="nw")
root_canvas.create_image(260, 180, image=automatic_photo, anchor="nw")
# //Buttons of interface tkinter & labels
title_label = Label(root, text="[ Robo-Cleaner Interface ]", font=("Helvetica", 14), width=21, foreground="#757575").place(x=330, y=30)
version_label = Label(root, text="Version 2.0", font=("Helvetica", 12), width=16, foreground="#757575").place(x=120, y=340)
botton_connect = Button(root, text="Conectar", font=("Helvetica", 12), width=12, bg="ForestGreen", foreground="white", command=get_IP).place(x=120, y=100)
botton_disconect = Button(root, text="Desconectar", font=("Helvetica", 12), width=12, bg="FireBrick2", foreground="white", command=disconection).place(x=120, y=140)
botton_automatic = Button(root, text="Automatico", font=("Helvetica", 12), width=12, bg="RoyalBlue1", foreground="white",command=Automatic).place(x=120, y=180)
botton_forward = Button(root, text="Avanzar", font=("Helvetica",12), width=12, bg="SpringGreen3", foreground="DarkGreen")
botton_forward.place(x=550, y=100)
botton_forward.bind('<ButtonPress>',Upward)
botton_forward.bind('<ButtonRelease>',Halt)
botton_rotate = Button(root, text="Rotar Helice", font=("Helvetica", 12), width=12, bg="Chartreuse2", foreground="DarkGreen")
botton_rotate.place(x=550, y=140)
botton_rotate.bind('<ButtonPress>',Rotate)
botton_rotate.bind('<ButtonRelease>',Halt)
botton_rotate_left = Button(root, text="Girar Izq.", font=("Helvetica", 12), width=12, bg="PaleGreen3", foreground="DarkGreen")
botton_rotate_left.place(x=410, y=140)
botton_rotate_left.bind('<ButtonPress>',LeftTurn)
botton_rotate_left.bind('<ButtonRelease>',Halt)
botton_rotate_right = Button(root, text="Girar Der.", font=("Helvetica", 12), width=12, bg="PaleGreen3", foreground="DarkGreen")
botton_rotate_right.place(x=690, y=140)
botton_rotate_right.bind('<ButtonPress>',RightTurn)
botton_rotate_right.bind('<ButtonRelease>',Halt)
botton_backward = Button(root, text="Retroceder", font=("Helvetica", 12), width= 12, bg="SpringGreen3", foreground="DarkGreen")
botton_backward.place(x=550, y=180)
botton_backward.bind('<ButtonPress>',Backwards)
botton_backward.bind('<ButtonRelease>',Halt)
botton_lever_up = Button(root, text="Levantar Pala", font=("Helvetica", 12), width=12, bg="OliveDrab4",foreground="white", command=LeverUp)
botton_lever_up.place(x=480, y=220)
botton_lever_down = Button(root, text="Bajar Pala", font=("Helvetica", 12), width=12, bg="GoldenRod4",foreground="white", command=LeverDown)
botton_lever_down.place(x=620, y=220)
botton_close = Button(root, text=" Salir ", command=root.destroy, font=("Helvetica", 14), width=12, bg="Red3", foreground="white").place(x=700, y=340)
#Protocols & mainloop for root
root.protocol("WM_DELETE_WINDOWS")
root.mainloop()
Parte operacional (código órdenes del robot)¶
Parte del código perteneciente a los movimientos y acciones que puede realizar el robot.El robot mediante sus funciones puede:
- Moverse hacia adelante y hacia atrás
- Girar a la izquierda y derecha
- Accionar el arco giratorio limpiador
- Subir y bajar su pala limpiadora
- Conectarse y desconectarse por wi-fi a un equipo
#!/usr/bin/env python3
from ev3dev2.motor import SpeedPercent, MoveTank, LargeMotor, MediumMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C ,OUTPUT_D
from ev3dev2.sensor import INPUT_1, INPUT_4
from ev3dev2.sensor.lego import UltrasonicSensor, ColorSensor
tank = MoveTank(OUTPUT_A, OUTPUT_D)
mot_rot= MediumMotor(OUTPUT_B)
mot_lev = MediumMotor(OUTPUT_C)
prox = UltrasonicSensor(INPUT_1)
col = ColorSensor(INPUT_4)
def Automatic():
while (col.color != 6):
while (prox.distance_centimeters_continuous > 5):
tank.on(left_speed= 90, right_speed= 90)
if (col.color == 6):
tank.off(brake=True)
break
else:
tank.off(brake=True)
mot_rot.on_for_seconds(speed = 75, seconds = 1, brake=True)
tank.off(brake=True)
def Upward():
tank.on(left_speed= 90, right_speed= 90)
def Backwards():
tank.on(left_speed= -90, right_speed= -90)
def LeftTurn():
tank.on(left_speed= 90, right_speed= 0)
def RightTurn():
tank.on(left_speed= 0, right_speed= 90)
def Rotate():
mot_rot.on(speed = 75, brake=True)
def LeverUp():
mot_lev.on_for_degrees(speed= 18, degrees= 90, brake= True)
def LeverDown():
mot_lev.on_for_degrees(speed= 18, degrees= -90, brake= True)
def Halt():
tank.off(brake=True)
mot_rot.off(brake=True)
Receptor de operaciones (ladrillo EV3)¶
Parte del código perteneciente a la lectura o interpretación de órdenes enviadas desde el PC en el ladrillo EV3.
El Robot-Cleaner es capaz de recibir e interpretar órdenes gracias al uso de la librería socket, que permite el envío de información mediante una conexión establecida.
#!/usr/bin/env python3
import socket
from operations import *
conector = socket.socket()
puerto = 12345
conector.bind(('', puerto))
conector.listen(5)
conexion, addr = conector.accept()
while True:
dato_puro = conexion.recv(1)
key = dato_puro.decode("utf-8")
if (key == 'i'):
Upward()
if (key == 'k'):
Backwards()
if (key == 'j'):
LeftTurn()
if (key == 'l'):
RightTurn()
if (key == 'p'):
Rotate()
if (key == 'y'):
LeverUp()
if (key == 'h'):
LeverDown()
if (key == 'a'):
Automatic()
if (key == 'q'):
break
if (key == 'w'):
Halt()
Contenido:
interfaz1.1.png (37.3 KB) joaquin guarachi, 11/08/2022 08:51 AM
interfazfinal.png (27.2 KB) joaquin guarachi, 12/18/2022 04:46 PM