Changes

Jump to navigation Jump to search
m
Line 125: Line 125:  
====Laptop Code for Robot/Laptop Base Communication ====
 
====Laptop Code for Robot/Laptop Base Communication ====
 
<source lang="Python">
 
<source lang="Python">
# -*- coding: utf-8 -*-
+
#!/usr/bin/python3
#author: joel.martin
+
 
#import the modules required here
+
 
 +
import queue
 +
import threading
 +
import time
 +
import itertools
 
import PySimpleGUI as sg
 
import PySimpleGUI as sg
 
import socket
 
import socket
   −
GRAPH_SIZE = (500,400)
+
def worker_thread1(thread_name, gui_queue):
GRAPH_STEP_SIZE = 1
+
    """
 +
    A worker thread that communicates with the GUI
 +
    These threads can call functions that block without affecting the GUI (a good thing)
 +
    Note that this function is the code started as each thread.
 +
    This thread recieves data from the BOT.
 +
    """
 +
    while True:
 +
        message_from_bot = (client.recv(4096)).decode()
 +
        gui_queue.put(message_from_bot)
 +
        #print (message_from_bot)
 +
        #if message_from_bot == "RxAck:Engaging Robot Shutdown" : escape = False
   −
sg.change_look_and_feel('GreenMono') # give our window a spiffy set of colors
+
def worker_thread2(thread_name, run_freq, gui_queue):
# ------ GetFile Window Definition ------ #
+
        gui_queue.put('{} - {}'.format(thread_name))
 
+
       
# ------ Menu Definition ------ #
+
def worker_thread3(thread_name, run_freqgui_queue):
menu_def = [['&File', ['&Open Text File to Transmit', '---', 'Properties', '---','H&alt Everything']],
+
        gui_queue.put('{} - {}'.format(thread_name))
            ['&Help', '&About...'], ]
  −
# ------ Column Definition ------ #
  −
col1 = [   
  −
            [sg.Text('Bot Message response', size=(30, 1))],
  −
            [sg.Output(size=(40, 20), font=('Mono 8'))],
  −
            [sg.Text('Bot Command Single Entry', size=(30, 1))],
  −
            [sg.InputText(size=(30, 0), key='-QUERY-')],
  −
            [sg.Button('Send Command',size=(20,1), button_color=(sg.YELLOWS[0], sg.GREENS[0]), bind_return_key=True)],
  −
            ]   
  −
col2 = [   
  −
            [sg.Text('Bot Jitter Test',font=('Mono 9'), justification="center", size=(48, 1))],
  −
            [sg.Button('<<CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('S2S-F2B',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('Combo',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('CW>>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0]))],
  −
           
  −
            [sg.Text('Bot Rotation',font=('Mono 9'), justification="center", size=(48, 1))],
  −
            [sg.Button('<<180 CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('<180 CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('180 CW>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('180 CW>>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),],
  −
           
  −
            [sg.Button('<<Input CCW',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.InputText(size=(11, 0), justification="center", key='-Rotate-'),
  −
            sg.Button('Input CW>>',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            ],
  −
           
  −
            [sg.Text('IMU',font=('Mono 9'), justification="center", size=(48, 1))],
  −
            [sg.Button('Zero to North',size=(16,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('South',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('East',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),   
  −
            sg.Button('West',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),], 
  −
           
  −
            [sg.Text('Linear Movement',font=('Mono 9'), justification="center", size=(48, 1))],
  −
            [sg.Text('Bot Angle:',font=('Mono 9'), justification="Left", size=(10, 1)),
  −
            sg.InputText(size=(5, 0), justification="center", key='-BotAngle-'),
  −
            sg.Text('Line of Bearing:',font=('Mono 9'), justification="Left", size=(15, 1)),
  −
            sg.InputText(size=(5, 0), justification="center", key='-Bearing-'),],
  −
            [sg.Text('Speed:',font=('Mono 9'), justification="Left", size=(8, 1)),
  −
            sg.Slider(range=(1,255),key='speed', default_value=127, size=(22,15), orientation='horizontal', font=('Helvetica', 12)),],
  −
            [sg.Button('Execute Move',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
  −
            sg.Button('Execute Move with Spin',size=(30,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),],
  −
            ]   
  −
col3 = [
  −
            [sg.Graph(GRAPH_SIZE, (0,0), GRAPH_SIZE, key='-GRAPH-', background_color='lightblue')
  −
            ],
   
          
 
          
            ]
+
def the_gui(gui_queue):
layout = [
+
    GRAPH_SIZE = (400,400)
 +
    GRAPH_STEP_SIZE = 1
 +
    sg.change_look_and_feel('GreenMono') # give our window a spiffy set of colors
 +
    # ------ GetFile Window Definition ------ #
 +
   
 +
    # ------ Menu Definition ------ #
 +
    menu_def = [['&File', ['&Open Text File to Transmit', '---', 'Properties', '---','H&alt Everything']],
 +
                ['&Help', '&About...'], ]
 +
    # ------ Column Definition ------ #
 +
    col1 = [   
 +
                [sg.Text('Bot Message response', size=(30, 1))],
 +
                [sg.Output(size=(40, 20), font=('Mono 8'))],
 +
                [sg.Text('Bot Command Single Entry', size=(30, 1))],
 +
                [sg.InputText(size=(30, 0), key='-QUERY-')],
 +
                [sg.Button('Send Command',size=(20,1), button_color=(sg.YELLOWS[0], sg.GREENS[0]), bind_return_key=True)],
 +
                ]   
 +
    col2 = [   
 +
                [sg.Text('Bot Jitter Test',font=('Mono 9'), justification="center", size=(48, 1))],
 +
                [sg.Button('<<CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('S2S-F2B',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('Combo',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('CW>>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0]))],
 +
               
 +
                [sg.Text('Bot Rotation',font=('Mono 9'), justification="center", size=(48, 1))],
 +
                [sg.Button('<<180 CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('<180 CCW',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('180 CW>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('180 CW>>',size=(10,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),],
 +
               
 +
                [sg.Button('<<Input CCW',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.InputText(size=(11, 0), justification="center", key='-Rotate-'),
 +
                sg.Button('Input CW>>',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                ],
 +
               
 +
                [sg.Text('IMU',font=('Mono 9'), justification="center", size=(48, 1))],
 +
                [sg.Button('Zero to North',size=(16,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('South',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('East',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])), 
 +
                sg.Button('West',size=(8,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),], 
 +
               
 +
                [sg.Text('Linear Movement',font=('Mono 9'), justification="center", size=(48, 1))],
 +
                [sg.Text('Bot Angle:',font=('Mono 9'), justification="Left", size=(10, 1)),
 +
                sg.InputText(size=(5, 0), justification="center", key='-BotAngle-'),
 +
                sg.Text('Line of Bearing:',font=('Mono 9'), justification="Left", size=(15, 1)),
 +
                sg.InputText(size=(5, 0), justification="center", key='-Bearing-'),],
 +
                [sg.Text('Speed:',font=('Mono 9'), justification="Left", size=(8, 1)),
 +
                sg.Slider(range=(1,255),key='speed', default_value=127, size=(22,15), orientation='horizontal', font=('Helvetica', 12)),],
 +
                [sg.Button('Execute Move',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),
 +
                sg.Button('Execute Move with Spin',size=(30,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0])),],
 +
                ]   
 +
    col3 = [
 +
                [sg.Graph(GRAPH_SIZE, (0,0), GRAPH_SIZE, key='-GRAPH-', background_color='lightblue')],
 +
                ]
 +
    col4 = [
 +
                [sg.Button('Gyroscope',size=(15,1),font=('Mono 9'), button_color=(sg.YELLOWS[0], sg.GREENS[0]))],
 +
                [sg.Text('X',font=('Mono 9'), justification="center", size=(5, 1)),
 +
                sg.Text('Y',font=('Mono 9'), justification="center", size=(5, 1)),
 +
                sg.Text('Z',font=('Mono 9'), justification="center", size=(5, 1))],
 +
                ]          
 +
    layout = [
 
           [sg.Menu(menu_def, tearoff=True)],
 
           [sg.Menu(menu_def, tearoff=True)],
 
           [sg.Column(col1, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           [sg.Column(col1, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           sg.Column(col2, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           sg.Column(col2, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           sg.Column(col3, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           sg.Column(col3, pad=((1,1),(1,1)), justification="left", background_color = None),
 +
          sg.Column(col4, pad=((1,1),(1,1)), justification="left", background_color = None),
 
           ]]
 
           ]]
   −
 
+
   
main_window = sg.Window('Crawler Bot Window Control', layout, font=('Helvetica', ' 11'), default_button_element_size=(8, 2))
+
    main_window = sg.Window('Crawler Bot Window Control', layout, font=('Helvetica', ' 11'), default_button_element_size=(8, 2))
 
+
    # --------------------- EVENT LOOP ---------------------
#start executing main here ---------------------------------------
  −
if __name__ == '__main__':
  −
    #sg.Popup('Data!')
  −
    message_from_bot = ''
  −
    #client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  −
    #client.connect(('192.168.1.132', 13000))
   
     escape = True
 
     escape = True
      
+
     message_to_bot = ''
     while escape == True:
+
     while True and escape == True:
         message_from_bot =''
+
         # wait for up to 100 ms for a GUI event
#----------------process all the window events --------------------------
+
         event, values = main_window.read(timeout=100)
         event, value = main_window.read()
+
        if event in (None, 'Exit'):
 +
            break
 
         if event == 'Open Text File to Transmit':
 
         if event == 'Open Text File to Transmit':
 
             text = sg.PopupGetFile("Open the file to transmit",
 
             text = sg.PopupGetFile("Open the file to transmit",
Line 218: Line 241:  
             #transmit line by line to the bot
 
             #transmit line by line to the bot
 
             print ("Transmitting Message")
 
             print ("Transmitting Message")
             #client.send(message_to_bot.encode())
+
             client.send(message_to_bot.encode())
 
         if event == 'Halt Everything':
 
         if event == 'Halt Everything':
 
             message_to_bot = "SRS"
 
             message_to_bot = "SRS"
             #client.send(message_to_bot.encode())
+
             client.send(message_to_bot.encode())
 
             break
 
             break
 +
        if event == 'Gyroscope':
 +
            message_to_bot = "GYR"
 +
            client.send(message_to_bot.encode())
 +
        if event == '<<CCW':
 +
            message_to_bot = "TST"
 +
            client.send(message_to_bot.encode())         
 
         if event == 'Send Command':
 
         if event == 'Send Command':
 
             message_to_bot = value['-QUERY-'].rstrip()
 
             message_to_bot = value['-QUERY-'].rstrip()
             #client.send(message_to_bot.encode())
+
             client.send(message_to_bot.encode())
#-------------------------------------------------------------------------
+
        # --------------- Loop through all messages coming in from threads ---------------
         #message_from_bot = (client.recv(4096)).decode()
+
         while True:                # loop executes until runs out of messages in Queue
        print (message_from_bot)
+
            try:                    # see if something has been posted to Queue
        if message_from_bot == "RxAck:Engaging Robot Shutdown" : escape = False  
+
                message = gui_queue.get_nowait()
       
+
            except queue.Empty:    # get_nowait() will get exception when Queue is empty
 +
                break              # break from the loop if no more messages are queued up
 +
            # if message received from queue, display the message in the Window
 +
            if message:
 +
                #main_window['-QUERY-'].update(message)
 +
                # do a refresh because could be showing multiple messages before next Read
 +
                main_window.refresh()
 +
                print(message)
 +
                if message == "RxAck:Engaging Robot Shutdown" : escape = False
 +
    # if user exits the window, then close the window and exit the GUI func
 
     main_window.close()
 
     main_window.close()
     #client.close()
+
 
 +
if __name__ == '__main__':
 +
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 +
    client.connect(('192.168.1.132', 13000))
 +
    # -- Create a Queue to communicate with GUI --
 +
    # queue used to communicate between the gui and the threads
 +
    gui_queue = queue.Queue()
 +
    # -- Start threads, each taking a different amount of time
 +
    threading.Thread(target=worker_thread1, args=(
 +
        'Thread 1', gui_queue,),  daemon=True).start()
 +
    #threading.Thread(target=worker_thread2, args=(
 +
    #    'Thread 2', 200, gui_queue,),  daemon=True).start()
 +
    #threading.Thread(target=worker_thread3, args=(
 +
     #   'Thread 3', 1000, gui_queue,),  daemon=True).start()
 +
    # -- Start the GUI passing in the Queue --
 +
    the_gui(gui_queue)
 +
 
 +
    client.close()
 
     print ("You ended the Robot Server Session")
 
     print ("You ended the Robot Server Session")
 
</source>
 
</source>
4,000

edits

Navigation menu