diff --git a/AdvDataPlot.py b/AdvDataPlot.py new file mode 100644 index 0000000000000000000000000000000000000000..97b3c3717ae09ac483d35d7a3fbc226b6bdd94f7 --- /dev/null +++ b/AdvDataPlot.py @@ -0,0 +1,138 @@ +import PySimpleGUI as sg +import os +import pandas as pd +import matplotlib.pyplot as plt + + +sg.theme("SystemDefaultForReal") + +class MainWindow (sg.Window): + + dataframe = [] + dataframe.append(None) + dataframe.append(None) + # Flags to enable the plot of variables in datasets : torque, curent, temperature, command position, measured position + _do_trace = [True, True, True, False, False] + + def __init__ (self, *args, **kwargs): + """ + With __make_layout, generate the pysimplegui window of the GUI + Return : sg.Window + """ + super().__init__("Data Plot", self.__make_layout(), finalize = True, *args, *kwargs) + + def __make_layout (self): + + # plot des variables qu'on veut : combo selon les colonnes du dataframe ouvert + # plot des données d'une seule variable sur un seul axe + self.data = self.def_file_browse('data1') + self.data2 = self.def_file_browse('data2') + + self.do_tq = sg.Checkbox('Motor torque', key='-do_tq-', size=(25, 1), enable_events=True, default=True) + self.do_curr = sg.Checkbox('Motor current', key='-do_curr-', size=(25, 1), enable_events=True, default=True) + self.do_tptr = sg.Checkbox('Motor temperature', key='-do_tprt-', size=(25, 1),enable_events=True, default=True) + self.do_posact = sg.Checkbox('Robot command position', key='-do_posact-', size=(25, 1), enable_events=True, default=False) + self.do_posreal = sg.Checkbox('Robot measured position', key='-do_posreal-', size=(25, 1), enable_events=True, default=False) + self.do_axis = [ sg.Checkbox(f'A{i}', key=f'-do_axis{i}-', enable_events=True, default=True) for i in range(1,7)] + + self._layout = [ + [ self.data ], + [ self.data2 ], + [ sg.Frame("Variables to plot :", border_width=0, layout=[ + [self.do_tq], + [self.do_curr], + [self.do_tptr], + [self.do_posact], + [self.do_posreal] + ]), + ], + [ sg.Text('Axis to plot :'), *self.do_axis ], + [ sg.Button('Trace Selected variables', key='-trace_selvar-', disabled=False, expand_x=True) ] + ] + return self._layout + + def def_file_browse(self, key:str): + data_path = os.path.dirname(os.path.realpath(__file__)) + "/data" + self._input_data = sg.Input(default_text=data_path, key=f'-path_{key}-', size=(130, 1), font=("Consolas", 10)) + self.import_xlsx = sg.FileBrowse("Browse EXCEL",initial_folder=data_path, file_types=(('Excel Files', '*.xlsx'),), key=f'-browse_{key}-') + self.open_xlsx = sg.Button("OPEN", key=f'-open_{key}-') + return [self._input_data, self.import_xlsx, self.open_xlsx] + + def open_xlsx_file (self, path: str, dfnb:int): + """Tries to load a .xslx file collected from the system variables + + Args: + path (str): The path to the file to open + """ + try: + self.dataframe[dfnb-1] = pd.read_excel(path) + if 'TRACE' in path : + self.dataframe[dfnb-1]['Sample_time_s'] = self.dataframe[dfnb-1]['Sample']/1000 + self.enable_var_buttons(True, 'TRACE') + else: + self.dataframe[dfnb-1]['Sample_time_s'] = self.dataframe[dfnb-1]['Sample_time']/1000 + self.enable_var_buttons(True, 'default') + self.update_do() + self.data_col = self.dataframe[dfnb-1].columns + except Exception as e: + self.enable_var_buttons(False) + sg.popup(e) + + def update_do (self): + """_summary_ + Update the state of the variables do_XXX if a checkbox is clicked + """ + i=0 + for checkbox in [self.do_tq, self.do_curr, self.do_tptr, self.do_posact, self.do_posreal]: + self._do_trace[i] = bool(checkbox.get()) and checkbox.Disabled == False + checkbox.update(value = self._do_trace[i]) + i+=1 + + def trace_selected_variables (self, dfnb:int): + plt.close('all') + a = self.get_selected_axis() + if(self._do_trace[0]): + self.dataframe[dfnb-1].plot(x="Sample_time_s",y=[f"Torque_A{i}" for i in a], grid=True),plt.ylabel("Motor Torque (N.m)") + if(self._do_trace[1]): + self.dataframe[dfnb-1].plot(x="Sample_time_s",y=[f"Current_A{i}" for i in a], grid=True),plt.ylabel("Motor Current (%)") + if(self._do_trace[2]): + self.dataframe[dfnb-1].plot(x="Sample_time_s",y=[f"Temperature_A{i}" for i in a], grid=True),plt.ylabel("Motor Temperature (°K)") + if(self._do_trace[3]): + self.dataframe[dfnb-1].plot(x="Sample_time_s",y=[f"Position_Command_A{i}" for i in a], grid=True),plt.ylabel("Robot command position in grid (mm))") + if(self._do_trace[4]): + self.dataframe[dfnb-1].plot(x="Sample_time_s",y=[f"Position_A{i}" for i in a], grid=True),plt.ylabel("Real Robot position in grid (mm))") + plt.pause(0.1) # Alternative to plt.show() that is not blocking + + def get_selected_axis (self): + i=1 + res = [] + for axis in self.do_axis: + if axis.get(): + res.append(i) + i+=1 + return res + + def enable_var_buttons (self, enable:bool, case:str = ''): + e = not(enable and (case == 'TRACE' or case == 'default')) + f = not(enable and case != 'TRACE') + self.do_tq.update(disabled=e) + self.do_curr.update(disabled=e) + self.do_tptr.update(disabled=f) + self.do_posact.update(disabled=f) + self.do_posreal.update(disabled=f) + +window = MainWindow() +while True: + event, values = window.read(100) + if event == sg.WIN_CLOSED: + break + if event == '-open_data1-': + window.open_xlsx_file(values['-path_data1-'], 1) + if event == '-open_data2-': + window.open_xlsx_file(values['-path_data2-'], 2) + if '-do_' in event: + window.update_do() + if event == '-trace_selvar-': + window.trace_selected_variables(1) + +window.close() \ No newline at end of file diff --git a/README.md b/README.md index 042b5e9c9ace33dcab4b6ac272c79684a8e52e0d..b041c3c6ef7e957eeb347e87474c8faaa4871e80 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ This section describes how to deploy the data collection on a cell. ### Global variables -The following declaration must be added in the `System/$config.dat` file +The following declarations must be added in the `System/$config.dat` file on the robot KUKA workspace : ``` @@ -154,7 +154,7 @@ This progam can be found in [`robot/KRL/`](./robot/KRL). Copy the provided configuration files found in [`robot/configurations/`](./robot/configurations) to the `TRACE` folder of the robot. -**Example path** : `\\192.168.1.151\...\TRACE\` +**Example path** : `\\192.168.1.151\roboter\TRACE\` ### The `Axis_Main.src` program diff --git a/main_refactor.py b/main_refactor.py deleted file mode 100644 index 4a4ba6e6f2adfe03786eeb8132d92fcdaf34d782..0000000000000000000000000000000000000000 --- a/main_refactor.py +++ /dev/null @@ -1,340 +0,0 @@ -# Local Imports -from ui import MainWindow, Measure_robot, Measure_latency -from kuka import KUKA_Handler - -# Libs -import traceback -import PySimpleGUI as sg -from threading import Semaphore, Thread -from typing import List, Any -import pandas as pd -import matplotlib.pyplot as plt - -class MainProgram (MainWindow): - """Wrapper for the main program. Classes are more reliable than global variables. - """ - - ### ---- State variables ---- ### - dataframe = None - window_latency = [] - - ### ---- Robots ---- ### - robot_handlers: List[KUKA_Handler] = [ None ] * 3 - robot_windows = [ ] - - ### ---- Sync Mechanism ---- ### - sync_done = 0 - sync_number = 0 - sync_sem = Semaphore(0) - - ### ---- Methods ---- ### - def __init__(self): - super().__init__() - - self.update_disabled_ui() - - def open_cell (self, cell: int): - """Establishes a connection to a robot - - Args: - cell (int): The number of the cell (from 1 to 3) - """ - - handler = KUKA_Handler(f"192.168.1.15{cell}", 7000) - - try: - ok = handler.KUKA_Open() - if not ok: - self.write_event_value(f"-rob_errored:{cell}-", None) - return - except Exception as e: - traceback.print_exception(e) - sg.popup_ok("\n".join(traceback.format_exception(e))) - self.write_event_value(f"-rob_errored:{cell}-", None) - return - - self.robot_handlers[cell - 1] = handler - self.write_event_value(f"-rob_connected:{cell}-", None) - - def update_disabled_ui (self): - """Updates the UI based on the robot connections - """ - - disabled = True - for i in range(len(self.robot_handlers)): - r = self.robot_handlers[i] - disabled = disabled and (r is None) - self.robots[i].disabled = (r is None) - - self.collection_settings.disabled = disabled - self.kukatrace.disabled = disabled - self.latency.disabled = disabled - self.gripper.disabled = disabled - self.data.disabled = disabled - - self.collection_settings.update_robot_buttons() - - def done (self): - """Called when a robot has collected the samples for a run. - Unlocks the syncing mechanism if all robots are done - """ - - self.sync_done += 1 - if self.sync_done == self.sync_number: - self.sync_done = 0 - self.sync_sem.release(self.sync_number) - - def close (self): - """Closes the main program - """ - for r in self.robot_handlers: - if r is not None: - r.KUKA_Close() - plt.close("all") - - super().close() - - def start (self, values: Any): - """Starts the data collection - """ - - # Check inputs - if not self.collection_settings.check_configuration(): - print("Failed to run the collection : invalid configuration") - return - - # Creating the file names - file_path = values["-user_path-"] + "/" + values["-dataset_name-"] - - # Creating the windows used to collect data - self.robot_windows = [ ] - for i in range(len(self.robot_handlers)): - r = self.robot_handlers[i] - if r is not None: - self.robot_windows.append(Measure_robot(r, i + 1, file_path)) - - # Initializing the sync mechanism - self.sync_number = len(self.robot_windows) - self.sync_sem = Semaphore(0) - self.sync_done = 0 - - # Getting the configuration - A_iter = [ values[f'num_of_iter{i}'] for i in range(1,7) ] - speed = self.collection_settings.speed - sampling = values["-Sys_sampling-"] - trace_sampling = values["-Trace_config-"] - - # Running the collection for each robot - for r in self.robot_windows: - - r._poll() # Forces the window to open - - # Reading and writing the files via another thread not to block the main window - t = Thread( - target=r.measure_sequence, - args=[ - A_iter, speed, sampling, trace_sampling, # Collection settings - self.get_category(r.cell), # Sample class - self.sync_sem, lambda: self.done() # Sync mechanism - ], - daemon=False) - t.start() - - # Unlock the robots at the same time - self.sync_sem.release(self.sync_number) - - def measure_latencies (self): - """Runs a latency measurement for each connected robot - """ - - try: - window_latency = [] - for i in range(len(self.robot_handlers)): - r = self.robot_handlers[i] - if r is not None: - w = Measure_latency(f"Latency measurement for Robot {i + 1}") - w._poll() - window_latency.append(w) - t = Thread(target=w.measure_latency, args=[r], daemon=False) - t.start() - - except Exception as e: - sg.popup_ok(traceback.format_exception(e)) - traceback.print_exception(e) - - def toggle_robot (self, cell: int): - """Toggles a robot state - - Args: - cell (int): From 1 to 3, the number of the cell - """ - - # The robot is already connected - if self.robot_handlers[cell - 1] is not None: - print(f"Trying to disconnect from robot {cell}") - self.collection_settings.set_robot_connected(cell - 1, False) - self.robot_handlers[cell - 1].KUKA_Close() - self.robot_handlers[cell - 1] = None - self.update_disabled_ui() - return - - # Connecting to the robot - self.update_disabled_ui() - print(f"Trying to connect to robot {cell}") - self.perform_long_operation(lambda: self.open_cell(cell), "-connect-call-end-") - - def gripper_open (self): - """Tries to open the gripper of the selected robot - """ - - if self.robot_handlers[self.gripper._robot_choice - 1] is not None: - self.robot_handlers[self.gripper._robot_choice - 1].KUKA_WriteVar('PyOPEN_GRIPPER', True) - self.gripper._btn_open.update(disabled=True) - self.gripper._btn_close.update(disabled=False) - - def gripper_close (self): - """Tries to close the gripper of the selected robot - """ - if self.robot_handlers[self.gripper._robot_choice - 1] is not None: - self.robot_handlers[self.gripper._robot_choice - 1].KUKA_WriteVar('PyCLOSE_GRIPPER', True) - self.gripper._btn_open.update(disabled=False) - self.gripper._btn_close.update(disabled=True) - - def open_xlsx (self, path: str): - """Tries to load a .xslx file collected from the system variables - - Args: - path (str): The path to the file to open - """ - try: - self.dataframe = pd.read_excel(path) - self.dataframe['Sample_time_s'] = self.dataframe['Sample_time']/1000 - sg.popup("Done") - self.data.enable_plot_buttons(True) - except Exception as e: - sg.popup(e) - self.data.enable_plot_buttons(False) - - def trace_selected_variables (self): - if(self.collection_settings._do_tq): - self.dataframe.plot(x="Sample_time_s",y=[f"Torque_A{i}" for i in range(1,7,1)], grid=True),plt.ylabel("Motor Torque (N.m)") - if(self.collection_settings._do_curr): - self.dataframe.plot(x="Sample_time_s",y=[f"Current_A{i}" for i in range(1,7,1)], grid=True),plt.ylabel("Motor Current (%)") - if(self.collection_settings._do_temp): - self.dataframe.plot(x="Sample_time_s",y=[f"Temperature_A{i}" for i in range(1,7,1)], grid=True),plt.ylabel("Motor Temperature (°K)") - if(self.collection_settings._do_posact): - self.dataframe.plot(x="Sample_time_s",y=[f"Command_A{i}" for i in range(1,7,1)], grid=True),plt.ylabel("Robot command position in grid (mm))") - if(self.collection_settings._do_posreal): - self.dataframe.plot(x="Sample_time_s",y=[f"Position_A{i}" for i in range(1,7,1)], grid=True),plt.ylabel("Real Robot position in grid (mm))") - plt.pause(0.1) # Alternative to plt.show() that is not blocking - - def trace_sampling (self): - self.dataframe.plot(x="Sample_time_s",y=["Queue_Read", "Queue_Write"], grid=True),plt.ylabel("Samples") - plt.xlabel("Collection execution time (s)") - plt.twinx(), plt.plot(self.dataframe["Sample_time_s"],self.dataframe['Read_time'], alpha=0.05), plt.ylabel("Request time of the sample (ms)") - plt.title("Samples in the buffer and red by Python") - plt.text(10,10,f"Mean ample time : {self.dataframe['Sample_time'].diff().mean()}") - plt.show() - - def trace_latencies (self): - self.dataframe.hist(column='Read_time', grid=True, bins=30) - plt.title("Distribution of the collection time of a sample") - plt.xlabel(f"Request time (ms) : mean = {self.dataframe['Read_time'].mean().__round__(2)}"),plt.ylabel("Number of samples") - plt.show() - - def run (self): - """Runs the main program - """ - - while True: - - event, values = self.read(timeout=10) - - ## ---- Core Events ---- ## - - if event in (sg.WINDOW_CLOSE_ATTEMPTED_EVENT, sg.WIN_CLOSED, 'Exit'): - self.close() - break - - if event == '-equal_iter-': - for i in range(1, 7): - self[f'num_of_iter{i}'].update(value=values['num_of_iter1']) - - if event == '-BTN_start-': - self.start(values) - - if event == "-dataset_auto-name-": - self.collection_settings._input_dataset_name.update(value=self.collection_settings.now()) - - if event == '-BTN_latency-': - self.measure_latencies() - - if event == '-doconst_speed-': - self.collection_settings.update_speed_entry() - - if 'do' in event: - self.collection_settings.update_do() - - ## ---- Robot selector Events ---- ## - if "rob_select" in event: - cell = int(event.split(':')[1][:-1]) - self.toggle_robot(cell) - - if "rob_connected" in event: - cell = int(event.split(':')[1][:-1]) - self.collection_settings.set_robot_connected(cell - 1, True) - self.update_disabled_ui() - - if "rob_errored" in event: - cell = int(event.split(':')[1][:-1]) - self.collection_settings.set_robot_connected(cell - 1, False, True) - self.update_disabled_ui() - - ## ---- Gripper Events ---- ## - if event == '-BTN_open_gripper-': - self.gripper_open() - - if event == '-BTN_close_gripper-': - self.gripper_close() - - ## ---- Trace Events ---- ## - - if event == '-open_xlsx-': - self.open_xlsx(values['-data_path-']) - - if event == '-trace_selvar-': - self.trace_selected_variables() - - if event == '-trace_sample-': - self.trace_sampling() - - if event == '-trace_latency-': - self.trace_latencies() - - - ## ---- Other windows updates ---- ## - - for i in range(len(self.window_latency)): - w = self.window_latency[i] - if w is not None: - if w._poll() is False: - self.window_latency[i] = None - - for i in range(len(self.robot_windows)): - win = self.robot_windows[i] - - # Window closed - if win is None: - continue - - # Window closed - if not win._poll(): - # Récupérer les données - - self.robot_windows[i] = None - continue - -if __name__ == "__main__": - main = MainProgram() - main.run() - main.close() \ No newline at end of file diff --git a/robot/KRL/Data_collector.sub b/robot/KRL/Data_collector.sub new file mode 100644 index 0000000000000000000000000000000000000000..4729910ef41c7d5a2c5992ebfbe4967c202dbbe2 --- /dev/null +++ b/robot/KRL/Data_collector.sub @@ -0,0 +1,213 @@ +&ACCESS RVP +&COMMENT USER specified PLC program +DEF Data_collector( ) + ;FOLD DECLARATIONS + ;FOLD USER DECL + ; Please insert user defined declarations + DECL INT __I + + ;ENDFOLD (USER DECL) + ;ENDFOLD (DECLARATIONS) + ;FOLD INI + ;FOLD USER INIT + ; Please insert user defined initialization commands + ColRUN = FALSE + + FOR __I = 1 TO 36 + __TAB_1[__I] = 0 + ENDFOR + + FOR __I = 1 TO ColBUFFER_SIZE + + ColBUFFER_TQ_A1[__I] = 0 + ColBUFFER_TQ_A2[__I] = 0 + ColBUFFER_TQ_A3[__I] = 0 + ColBUFFER_TQ_A4[__I] = 0 + ColBUFFER_TQ_A5[__I] = 0 + ColBUFFER_TQ_A6[__I] = 0 + ColBUFFER_TEMP_A1[__I] = 0 + ColBUFFER_TEMP_A2[__I] = 0 + ColBUFFER_TEMP_A3[__I] = 0 + ColBUFFER_TEMP_A4[__I] = 0 + ColBUFFER_TEMP_A5[__I] = 0 + ColBUFFER_TEMP_A6[__I] = 0 + ColBUFFER_CURR_A1[__I] = 0 + ColBUFFER_CURR_A2[__I] = 0 + ColBUFFER_CURR_A3[__I] = 0 + ColBUFFER_CURR_A4[__I] = 0 + ColBUFFER_CURR_A5[__I] = 0 + ColBUFFER_CURR_A6[__I] = 0 + ColBUFFER_TIME[__I] = 0 + ColBUFFER_ANALOG[__I] = 0 + ColBUFFER_POS_ACT[__I] = $AXIS_ACT + ColBUFFER_POS_MEAS[__I] = $AXIS_ACT_MEAS + + ENDFOR + + ;ENDFOLD (USER INIT) + ;ENDFOLD (INI) + + LOOP + ;FOLD USER PLC + ;Make your modifications here + IF ColRESET THEN + ColRESET = FALSE + ColRESET_DONE = FALSE + SAMPLE_NUMBER = 1 + ColKEEPING_UP = TRUE + ColRESET_DONE = TRUE + RESET_COMMUNICATION() + IF __PyResetTimer THEN + __PyResetTimer = FALSE + $TIMER[1] = 0 + ENDIF + FOR __I = 1 TO 36 + __TAB_1[__I] = 0 + ENDFOR + ENDIF + + IF ColRUN THEN + $TIMER_STOP[5] = FALSE + IF $TIMER[5] >= ColSAMPLING THEN + $TIMER[5] = 0 + ColBUFFER_TIME[SAMPLE_NUMBER] = $TIMER[1] + ColBUFFER_POS_ACT[SAMPLE_NUMBER] = $AXIS_ACT + ColBUFFER_POS_MEAS[SAMPLE_NUMBER] = $AXIS_ACT_MEAS + + ColBUFFER_TQ_A1[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[1] + ColBUFFER_TQ_A2[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[2] + ColBUFFER_TQ_A3[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[3] + ColBUFFER_TQ_A4[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[4] + ColBUFFER_TQ_A5[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[5] + ColBUFFER_TQ_A6[SAMPLE_NUMBER] = $TORQUE_AXIS_ACT[6] + + ColBUFFER_TEMP_A1[SAMPLE_NUMBER] = $MOT_TEMP[1] + ColBUFFER_TEMP_A2[SAMPLE_NUMBER] = $MOT_TEMP[2] + ColBUFFER_TEMP_A3[SAMPLE_NUMBER] = $MOT_TEMP[3] + ColBUFFER_TEMP_A4[SAMPLE_NUMBER] = $MOT_TEMP[4] + ColBUFFER_TEMP_A5[SAMPLE_NUMBER] = $MOT_TEMP[5] + ColBUFFER_TEMP_A6[SAMPLE_NUMBER] = $MOT_TEMP[6] + + ColBUFFER_CURR_A1[SAMPLE_NUMBER] = $CURR_ACT[1] + ColBUFFER_CURR_A2[SAMPLE_NUMBER] = $CURR_ACT[2] + ColBUFFER_CURR_A3[SAMPLE_NUMBER] = $CURR_ACT[3] + ColBUFFER_CURR_A4[SAMPLE_NUMBER] = $CURR_ACT[4] + ColBUFFER_CURR_A5[SAMPLE_NUMBER] = $CURR_ACT[5] + ColBUFFER_CURR_A6[SAMPLE_NUMBER] = $CURR_ACT[6] + + ColBUFFER_ANALOG[SAMPLE_NUMBER] = $ANOUT[1] + + SAMPLE_NUMBER=SAMPLE_NUMBER+1 + + IF SAMPLE_NUMBER > ColBUFFER_SIZE THEN + SAMPLE_NUMBER = 1 + ENDIF + + ELSE + COMMUNICATION_ROUTINE() + ENDIF + IF $TIMER[5] >= 2 * ColSAMPLING THEN + ColKEEPING_UP = FALSE + ENDIF + ELSE + $TIMER_STOP[5] = TRUE + COMMUNICATION_ROUTINE() + ENDIF + + ;ENDFOLD (USER PLC) + ENDLOOP +END + ;ENDFOLD + ;FOLD USER SUBROUTINE + ;Integrate your user defined subroutines + + ;ENDFOLD (USER SUBROUTINE) + +DEF RESET_COMMUNICATION () + + ;Tabs initialisation + DECL INT __I + FOR __I = 1 TO 36 + __TAB_1[__I] = 0 + ENDFOR + SAMPLE_READ = 1 + __PYTHON_HAS_READ = 0 +END + +DEF COMMUNICATION_ROUTINE () + + WAIT SEC 0 + + ; Check if python read and if data available + IF ((__PYTHON_HAS_READ == (SAMPLE_READ - 1)) OR (__PYTHON_HAS_READ == ColBUFFER_SIZE)) AND (SAMPLE_READ <> SAMPLE_NUMBER) THEN + ; __PYTHON_HAS_READ = FALSE + __TAB_1[35] = 0 ; __PYTHON_DATA_AVAILABLE = FALSE + + ; Make data available + + ; Sample + __TAB_1[1] = ColBUFFER_TIME[SAMPLE_READ] + + ; A1 + __TAB_1[2] = ColBUFFER_POS_ACT[SAMPLE_READ].A1 + __TAB_1[3] = ColBUFFER_POS_MEAS[SAMPLE_READ].A1 + __TAB_1[4] = ColBUFFER_TQ_A1[SAMPLE_READ] + __TAB_1[5] = ColBUFFER_CURR_A1[SAMPLE_READ] + __TAB_1[6] = ColBUFFER_TEMP_A1[SAMPLE_READ] + + ; A2 + __TAB_1[7] = ColBUFFER_POS_ACT[SAMPLE_READ].A2 + __TAB_1[8] = ColBUFFER_POS_MEAS[SAMPLE_READ].A2 + __TAB_1[9] = ColBUFFER_TQ_A2[SAMPLE_READ] + __TAB_1[10] = ColBUFFER_CURR_A2[SAMPLE_READ] + __TAB_1[11] = ColBUFFER_TEMP_A2[SAMPLE_READ] + + ; A3 + __TAB_1[12] = ColBUFFER_POS_ACT[SAMPLE_READ].A3 + __TAB_1[13] = ColBUFFER_POS_MEAS[SAMPLE_READ].A3 + __TAB_1[14] = ColBUFFER_TQ_A3[SAMPLE_READ] + __TAB_1[15] = ColBUFFER_CURR_A3[SAMPLE_READ] + __TAB_1[16] = ColBUFFER_TEMP_A3[SAMPLE_READ] + + + ; A4 + __TAB_1[17] = ColBUFFER_POS_ACT[SAMPLE_READ].A4 + __TAB_1[18] = ColBUFFER_POS_MEAS[SAMPLE_READ].A4 + __TAB_1[19] = ColBUFFER_TQ_A4[SAMPLE_READ] + __TAB_1[20] = ColBUFFER_CURR_A4[SAMPLE_READ] + __TAB_1[21] = ColBUFFER_TEMP_A4[SAMPLE_READ] + + ; A5 + __TAB_1[22] = ColBUFFER_POS_ACT[SAMPLE_READ].A5 + __TAB_1[23] = ColBUFFER_POS_MEAS[SAMPLE_READ].A5 + __TAB_1[24] = ColBUFFER_TQ_A5[SAMPLE_READ] + __TAB_1[25] = ColBUFFER_CURR_A5[SAMPLE_READ] + __TAB_1[26] = ColBUFFER_TEMP_A5[SAMPLE_READ] + + ; A6 + __TAB_1[27] = ColBUFFER_POS_ACT[SAMPLE_READ].A6 + __TAB_1[28] = ColBUFFER_POS_MEAS[SAMPLE_READ].A6 + __TAB_1[29] = ColBUFFER_TQ_A6[SAMPLE_READ] + __TAB_1[30] = ColBUFFER_CURR_A6[SAMPLE_READ] + __TAB_1[31]= ColBUFFER_TEMP_A6[SAMPLE_READ] + + ; System variables + __TAB_1[32] = ColBUFFER_ANALOG[SAMPLE_READ] + __TAB_1[33] = SAMPLE_READ + __TAB_1[34] = SAMPLE_NUMBER + + + SAMPLE_READ = SAMPLE_READ + 1 + IF SAMPLE_READ > ColBUFFER_SIZE THEN + SAMPLE_READ = 1 + ENDIF + + __TAB_1[35] = 1 ; __PYTHON_DATA_AVAILABLE = TRUE + ENDIF + + IF (NOT ColRUN) AND (SAMPLE_NUMBER == SAMPLE_READ) THEN + __TAB_1[36] = 1 ; __READ_DONE + ELSE + __TAB_1[36] = 0 + ENDIF +END \ No newline at end of file diff --git a/robot/KRL/_Axis_MAIN_dataset.src b/robot/KRL/_Axis_MAIN_dataset.src new file mode 100644 index 0000000000000000000000000000000000000000..39738e2aff8d738855b005d4b9d4da6687687d82 --- /dev/null +++ b/robot/KRL/_Axis_MAIN_dataset.src @@ -0,0 +1,90 @@ +&ACCESS RVP +&REL 8 +&PARAM EDITMASK = * +&PARAM TEMPLATE = C:\KRC\Roboter\Template\vorgabe +&PARAM DISKPATH = KRC:\R1\Diagnostika +DEF _Axis_MAIN_dataset ( ) + ;FOLD INI;%{PE} + ;FOLD BASISTECH INI + GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( ) + INTERRUPT ON 3 + BAS (#INITMOV,0 ) + ;ENDFOLD (BASISTECH INI) + ;FOLD USER INI + ;Make your modifications here + + ;ENDFOLD (USER INI) + ;ENDFOLD (INI) + PyRUN=FALSE + PyDONE=FALSE + PySPEED=50 + $ADVANCE = 0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(100), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + LOOP + $ANOUT[1]=0 + WAIT FOR PyRUN + PyDONE = FALSE + ; $TIMER[1]=0 + $TIMER_STOP[1]=FALSE + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=1 + FOR counter = 0 TO PyITER[1]-1 STEP 1 + A1() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=2 + FOR counter = 0 TO PyITER[2]-1 STEP 1 + A2() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=3 + FOR counter = 0 TO PyITER[3]-1 STEP 1 + A3() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=4 + FOR counter = 0 TO PyITER[4]-1 STEP 1 + A4() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=5 + FOR counter = 0 TO PyITER[5]-1 STEP 1 + A5() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + $ANOUT[1]=6 + FOR counter = 0 TO PyITER[6]-1 STEP 1 + A6() + ENDFOR + $ANOUT[1]=0 + ;FOLD domu + SPTP DOMOV WITH $VEL_AXIS[1] = SVEL_JOINT(PySPEED), $TOOL = STOOL2(FP1), $BASE = SBASE(FP1.BASE_NO), $IPO_MODE = SIPO_MODE(FP1.IPO_FRAME), $LOAD = SLOAD(FP1.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PPDAT1), $APO = SAPO_PTP(PPDAT1), $GEAR_JERK[1] = SGEAR_JERK(PPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0) + ;ENDFOLD + WAIT SEC 0 + PyDONE = TRUE + PyRUN = FALSE + ColRUN = FALSE + $TIMER_STOP[1]=TRUE + WAIT SEC 1 + PyDONE = FALSE + ENDLOOP +END \ No newline at end of file diff --git a/robot/KRL/placeholder.txt b/robot/KRL/placeholder.txt deleted file mode 100644 index 22cbe50235f4b1595bcc417bf415dd0f106893a1..0000000000000000000000000000000000000000 --- a/robot/KRL/placeholder.txt +++ /dev/null @@ -1 +0,0 @@ -This file is meant to be removed \ No newline at end of file diff --git a/robot/configurations/$config.dat b/robot/configurations/$config.dat new file mode 100644 index 0000000000000000000000000000000000000000..8a3266af0deaa54498f9753725598293cc31f6d1 --- /dev/null +++ b/robot/configurations/$config.dat @@ -0,0 +1,59 @@ +; Global variables needed for the execution of the data collector ; + +;FOLD ------DIAGNOSTIKA GLOBAL PROMENNE------- +;Program control +DECL BOOL PyRUN=FALSE +DECL BOOL PyDONE=FALSE +DECL INT PySPEED=30 +DECL INT PyITER[6] +DECL BOOL PyOPEN_GRIPPER=FALSE +DECL BOOL PyCLOSE_GRIPPER=FALSE +DECL INT PyKNUCKLE +DECL REAL SPEED + +;Data collection control +DECL BOOL ColRUN=FALSE +DECL BOOL ColRESET=FALSE +DECL BOOL ColBUFFER_FULL=FALSE +DECL BOOL ColKEEPING_UP=FALSE +DECL BOOL ColRESET_DONE=TRUE +DECL INT ColSAMPLING=12 +DECL INT ColBUFFER_SIZE=20000 + +;Data communication buffers and flags +DECL INT SAMPLE_READ=772 +DECL INT SAMPLE_NUMBER=772 +DECL REAL __TAB_1[36] + +DECL INT __PYTHON_HAS_READ=771 ; +DECL BOOL __PyResetTimer=FALSE ; + +;Data collection buffers +DECL REAL ColBUFFER_TQ_A1[20000] +DECL REAL ColBUFFER_TQ_A2[20000] +DECL REAL ColBUFFER_TQ_A3[20000] +DECL REAL ColBUFFER_TQ_A4[20000] +DECL REAL ColBUFFER_TQ_A5[20000] +DECL REAL ColBUFFER_TQ_A6[20000] +DECL REAL ColBUFFER_TEMP_A1[20000] +DECL REAL ColBUFFER_TEMP_A2[20000] +DECL REAL ColBUFFER_TEMP_A3[20000] +DECL REAL ColBUFFER_TEMP_A4[20000] +DECL REAL ColBUFFER_TEMP_A5[20000] +DECL REAL ColBUFFER_TEMP_A6[20000] +DECL REAL ColBUFFER_CURR_A1[20000] +DECL REAL ColBUFFER_CURR_A2[20000] +DECL REAL ColBUFFER_CURR_A3[20000] +DECL REAL ColBUFFER_CURR_A4[20000] +DECL REAL ColBUFFER_CURR_A5[20000] +DECL REAL ColBUFFER_CURR_A6[20000] +DECL REAL ColBUFFER_TIME[20000] +DECL REAL ColBUFFER_ANALOG[20000] + +DECL E6AXIS __LAST_POS_ACT +DECL E6AXIS ColBUFFER_POS_ACT[20000] +DECL E6AXIS __LAST_POS_MEAS +DECL E6AXIS ColBUFFER_POS_MEAS[20000] +;ENDFOLD + +... \ No newline at end of file diff --git a/robot/configurations/placeholder.txt b/robot/configurations/placeholder.txt deleted file mode 100644 index 0d4904a3c93b6274553fe5ba10ad87f053fd14b5..0000000000000000000000000000000000000000 --- a/robot/configurations/placeholder.txt +++ /dev/null @@ -1 +0,0 @@ -This file is meant to be removed later \ No newline at end of file diff --git a/ui/graph_window.py b/ui/graph_window.py index 920bfef18d70c5b1ca50df19eef9910faf6dcedc..2f6db56a6604f89dc38692ea660f16b0d60fb14d 100644 --- a/ui/graph_window.py +++ b/ui/graph_window.py @@ -20,14 +20,8 @@ class CollectionGraphWindow (sg.Window): self._data_latency = [] self._s = 0 - super().__init__(f'Robot {cell}', self.__make_layout(), finalize=True) - def __make_layout (self): - self._title = sg.Text(f'Robot {self.cell}', key="-TITLE-", font='Helvetica 20') - self._subtitle = sg.Text("Collecting sample n°...", key="Subtitle") - self._canvas_elem = sg.Canvas(size=(480,360), key="-CANVAS-") - self._status = sg.Text("",key="-colstatus-",text_color="#000", font="Helvetica 15") - self._exit = sg.Button("Exit", key='-colexit-',font="Helvetica 11", size=(15,1)) + super().__init__(f'Robot {cell}', self.__make_layout(), finalize=True) # Canvas settings self._canvas = self._canvas_elem.TKCanvas @@ -47,6 +41,13 @@ class CollectionGraphWindow (sg.Window): self._fig_agg.draw() self._fig_agg.get_tk_widget().pack(side='top', fill='both', expand=1) + def __make_layout (self): + self._title = sg.Text(f'Robot {self.cell}', key="-TITLE-", font='Helvetica 20') + self._subtitle = sg.Text("Collecting sample n°...", key="Subtitle") + self._canvas_elem = sg.Canvas(size=(480,360), key="-CANVAS-") + self._status = sg.Text("",key="-colstatus-",text_color="#000", font="Helvetica 15") + self._exit = sg.Button("Exit", key='-colexit-',font="Helvetica 11", size=(15,1)) + layout = [ [ sg.Push(), self._title, sg.Push() ], [ sg.Push(), self._subtitle, sg.Push() ], @@ -90,5 +91,7 @@ class CollectionGraphWindow (sg.Window): self._ay.grid() self._ay.plot(range(len(b)), b) + self._figure.tight_layout() + self._fig_agg.draw() self._subtitle.update(f"Collecting sample n°{self._s}") \ No newline at end of file diff --git a/ui/ui_collection_settings.py b/ui/ui_collection_settings.py index a13926cf3457c9e3f049861acd34ca490954f82b..ece5598acd95cc92c08bdb7658310383f3dac80a 100644 --- a/ui/ui_collection_settings.py +++ b/ui/ui_collection_settings.py @@ -29,7 +29,7 @@ class UI_Collection_Settings (sg.Frame): now = self.now() self._input_dataset_name = sg.InputText(now, key='-dataset_name-', size=(30, 1), font=("Consolas", 10)) - dir_path = os.path.dirname(os.path.realpath(__file__)) + "/data" + dir_path = os.getcwd() + "/data" self._input_working_dir = sg.Input(default_text=dir_path, key='-user_path-', size=(40, 1), font=("Consolas", 10)) self._input_browse_dir = sg.FolderBrowse(initial_folder=dir_path, key='-browse-')