Creating a controller (Tkinter)

asked 2019-03-21 16:41:25 -0600

Hyperion gravatar image

Hi people!

Today I was trying to develop a simple GUI interface for controlling the turtle on turtlesim using Tkinter. I have success to develop, but I can't make work the buttons event handlers. In short, I want to press the button and turtle walks indefinitely until I release the button. I tried loops and place all functions inside the same class. Thread I tested, but if I point to function of the button, the dialog of Tkinter spawns multiple instances of the controller... Plz help.

Code:

#!/usr/bin/env python

import rospy
import subprocess
import threading
from tkinter import * 
from geometry_msgs.msg import Twist

PI = 3.1415926535897

class App:

    def __init__(self, master=None):

        self._enable = False

        self.bt_up = Button(master, text="UP", width = 10)
        self.bt_down = Button(master, text="DOWN", width = 10)
        self.bt_r_left = Button(master, text="R-LEFT", width = 10)
        self.bt_r_right = Button(master, text="R-RIGHT", width = 10)
        self.bt_enable_servos = Button(master, text="", width = 2, bg = "red", command = self.servos)
        self.lbl_servos = Label(master, text="servos OFF")

        self.bt_up.bind("<Button-1>", self.btn_exec_up)
        self.bt_down.bind("<Button-1>", self.btn_exec_down)
        self.bt_r_left.bind("<Button-1>", self.btn_exec_c_clockwise)
        self.bt_r_right.bind("<Button-1>", self.btn_exec_clockwise)

        self.bt_up.bind("<ButtonRelease-1>", self.stop_all)
        self.bt_down.bind("<ButtonRelease-1>", self.stop_all)
        self.bt_r_left.bind("<ButtonRelease-1>", self.stop_all)
        self.bt_r_right.bind("<ButtonRelease-1>", self.stop_all)

        self.bt_up.grid(row=0, column=0, columnspan=2, sticky=N)
        self.bt_down.grid(row=2, column=0, columnspan=2, sticky=S)
        self.bt_r_left.grid(row=1, column=0, sticky=W)
        self.bt_r_right.grid(row=1, column=1, sticky=E)
        self.bt_enable_servos.grid(row=0, column=2, rowspan = 2, sticky=N+S)
        self.lbl_servos.grid(row=0, column=3, rowspan = 2, sticky=N+S)

    def servos(self):
       self.state = self.bt_enable_servos["relief"]
       if self.state == RAISED:
          self.bt_enable_servos["relief"] = SUNKEN
          self.bt_enable_servos["bg"] = "green"
          self.lbl_servos.configure(text="servos ON")
          self._enable = True
       else:
          self.bt_enable_servos["relief"] = RAISED
          self.bt_enable_servos["bg"] = "red"
          self.lbl_servos.configure(text="servos OFF")
          self._enable = False

    def btn_exec_up(self, event):
        if self._enable == True:
           self.speed = 2
           self.distance = 1
           self.isForward = True
           move_linear(self.speed, self.distance, self.isForward)

    def btn_exec_down(self, event):

        if self._enable == True:
           self.speed = 2
           self.distance = 1
           self.isForward = False
           move_linear(self.speed, self.distance, self.isForward)

    def btn_exec_clockwise(self, event):

        if self._enable == True:
           self.speed = 100
           self.angle = 1
           self.clockwise = True
           move_rotate(self.speed, self.angle, self.clockwise)

    def btn_exec_c_clockwise(self, event):

        if self._enable == True:
           self.speed = 100
           self.angle = 1
           self.clockwise = False
           move_rotate(self.speed, self.angle, self.clockwise)

    def stop_all(self, event):

        move_linear()
        move_rotate()

def init_system():
    subprocess.call(["rosrun", "tkinter_test", "app2.py"])

def init_ros():
    rospy.init_node("tkinter_robot", anonymous=True)
    global velocity_publisher
    global vel_msg
    velocity_publisher = rospy.Publisher("/turtle1/cmd_vel", Twist, queue_size=10)
    vel_msg = Twist()

def move_linear(speed = 0, distance = 0, isForward = 1):

    if(isForward):
        vel_msg.linear.x = abs(speed)
    else:
        vel_msg.linear.x = -abs(speed)

    # while not rospy.is_shutdown():
    t0 = rospy.Time.now().to_sec()
    current_distance = 0

    while current_distance < distance:
        velocity_publisher.publish(vel_msg)
        t1 = rospy ...
(more)
edit retag flag offensive close merge delete