def Load(self, rdk=None): #, stream_data=b''): """Save the class attributes as a RoboDK binary parameter""" # Use a dictionary and the str/eval buit-in conversion attribs_list = self._getAttribsSave() #if len(attribs_list) == 0: # print("Load settings: No attributes to load") # return False print("Loading data from RoboDK station...") if rdk is None: from robolink import Robolink rdk = Robolink() param_backup = self._SETTINGS_PARAM param_backup += "-Backup" bytes_data = rdk.getParam(param_backup, False) if len(bytes_data) > 0: import robodk result = robodk.ShowMessageYesNoCancel( "Something went wrong with the last test.\nRecover lost data?", "Auto recover") if result is None: return False elif not result: bytes_data = b'' # Clear backup data rdk.setParam(param_backup, b'', False) if len(bytes_data) <= 0: bytes_data = rdk.getParam(self._SETTINGS_PARAM, False) if len(bytes_data) <= 0: print("Load settings: No data for " + self._SETTINGS_PARAM) return False import pickle saved_dict = pickle.loads(bytes_data) for key in saved_dict.keys(): # if we have a list of attributes that we want, load it only if it is in the list if len(attribs_list) > 0 and not key in attribs_list: print("Obsolete variable saved (will be deleted): " + key) else: value = saved_dict[key] setattr(self, key, value) return True
class RunApplication: """Class to detect when the terminate signal is emited to stop an action. .. code-block:: python run = RunApplication() while run.Run(): # your main loop to run until the terminate signal is detected ... """ time_last = -1 param_name = None RDK = None def __init__(self, rdk=None): if rdk is None: from robolink import Robolink self.RDK = Robolink() else: self.RDK = rdk self.time_last = time.time() if len(sys.argv) > 0: path = sys.argv[0] folder = os.path.basename(os.path.dirname(path)) file = os.path.basename(path) if file.endswith(".py"): file = file[:-3] elif file.endswith(".exe"): file = file[:-4] self.param_name = file + "_" + folder self.RDK.setParam( self.param_name, "1") # makes sure we can run the file separately in debug mode def Run(self): time_now = time.time() if time_now - self.time_last < 0.25: return True self.time_last = time_now if self.param_name is None: # Unknown start return True keep_running = not (self.RDK.getParam(self.param_name) == 0) return keep_running
def removeParameters(RDK=None): if RDK is None: RDK = Robolink() RDK.setParam(PARAM_BOX_X, b'') RDK.setParam(PARAM_BOX_Y, b'') RDK.setParam(PARAM_BOX_Z, b'') RDK.setParam(PARAM_UNITS, b'') RDK.setParam(PARAM_PARENT_NAME, b'') RDK.setParam(PARAM_CONV_PARENT_NAME, b'')
def Save(self, rdk=None, autorecover=False): # Save the class attributes as a string # Use a dictionary and the str/eval buit-in conversion attribs_list = self._getAttribsSave() if len(attribs_list) <= 0: print("Saving skipped") return print("Saving data to RoboDK station...") dict_data = {} # Important! We must save this but not show it in the UI dict_data['_FIELDS_UI'] = self._FIELDS_UI for key in attribs_list: dict_data[key] = getattr(self, key) #Protocol tips: https://docs.python.org/3/library/pickle.html import pickle bytes_data = pickle.dumps( dict_data, protocol=2 ) # protocol=2: bynary, compatible with python 2.3 and later if rdk is None: from robolink import Robolink rdk = Robolink() param_val = self._SETTINGS_PARAM param_backup = param_val + "-Backup" if autorecover: rdk.setParam(param_backup, bytes_data) else: rdk.setParam(param_val, bytes_data) rdk.setParam(param_backup, b'')
def setParameters(RDK=None): if RDK is None: RDK = Robolink() global RADIUS global PARENT RDK.setParam(PARAM_RADIUS, RADIUS) if PARENT is not None: RDK.setParam(PARAM_PARENT_NAME, PARENT.Name()) else: RDK.setParam(PARAM_PARENT_NAME, '')
def removeParameters(RDK=None): if RDK is None: RDK = Robolink() RDK.setParam(PARAM_RADIUS, b'') RDK.setParam(PARAM_PARENT_NAME, b'')
class robodk_api(driver): ''' This driver uses the RoboDK API to connect to a robot controller. It is based on the Robodk API (https://robodk.com/offline-programming). The driver will always provide access to the robot axis through the variable called "Axis" (float[6]). Optional variable definitions are used to access Station Parameters in RobotDK to be read or written by the driver. controller: str Robot name in RoboDK. Default = '', will take the first that founds. ''' def __init__(self, name: str, pipe: Optional[Pipe] = None): """ :param name: (optional) Name for the driver :param pipe: (optional) Pipe used to communicate with the driver thread. See gateway.py """ # Inherit driver.__init__(self, name, pipe) # Parameters self.controller = '' def connect(self) -> bool: """ Connect driver. : returns: True if connection stablished False if not """ try: #assert ROBODK_API_FOUND, "RoboDK API is not available." self._connection = Robolink() if self._connection: self.robot = self._connection.Item(self.controller) if self.robot: if self.robot.Valid() and self.robot.Type() == ITEM_TYPE_ROBOT: self.sendDebugInfo(f'Driver RoboDK Connected to {self.controller}...') return True else: self.sendDebugInfo(f'Item {self.controller} not found!') else: self.sendDebugInfo(f'Controler not found!') else: self.sendDebugInfo(f'Connection with Robolink not possible.') except Exception as e: self.sendDebugInfo('Exception '+str(e)) return False def disconnect(self): """ Disconnect driver. """ pass def addVariables(self, variables: dict): """ Add variables to the driver. Correctly added variables will be added to internal dictionary 'variables'. Any error adding a variable should be communicated to the server using sendDebugInfo() method. : param variables: Variables to add in a dict following the setup format. (See documentation) """ for var_id, var_data in variables.items(): try: if var_id == 'Axis': var_data['value'] = [None for i in range(var_data['size'])] self.variables[var_id] = var_data continue else: value = self._connection.getParam(var_id) if value is not None: var_data['value'] = None # Force first update self.variables[var_id] = var_data self.sendDebugVarInfo((f'SETUP: Variable found {var_id}', var_id)) continue except: pass self.sendDebugVarInfo((f'SETUP: Variable not found {var_id}', var_id)) def readVariables(self, variables: list) -> list: """ Read given variable values. In case that the read is not possible or generates an error BAD quality should be returned. : param variables: List of variable ids to be read. : returns: list of tupples including (var_id, var_value, VariableQuality) """ res = [] for var_id in variables: try: if var_id == 'Axis': new_value = self.robot.Joints().tr().rows[0] # robot joint rotations [Rax_1, Rax_2, Rax_3, Rax_4, Rax_5, Rax_6] new_value = [round(x,3) for x in new_value] res.append((var_id, new_value, VariableQuality.GOOD)) continue else: new_value = self._connection.getParam(var_id) if new_value is not None: new_value = self.getValueFromString(self.variables[var_id]['datatype'], new_value) res.append((var_id, new_value, VariableQuality.GOOD)) continue except: res.append((var_id, self.variables[var_id]['value'], VariableQuality.BAD)) return res def writeVariables(self, variables: list) -> list: """ Write given variable values. In case that the write is not possible or generates an error BAD quality should be returned. : param variables: List of tupples with variable ids and the values to be written (var_id, var_value). : returns: list of tupples including (var_id, var_value, VariableQuality) """ res = [] # TODO: Possible improvement can be to send multiple at once for (var_id, new_value) in variables: try: self._connection.setParam(var_id, new_value) res.append((var_id, new_value, VariableQuality.GOOD)) except: res.append((var_id, new_value, VariableQuality.BAD)) return res
def setParameters(RDK=None): if RDK is None: RDK = Robolink() global BOX_SIZE_XYZ global USE_METRIC global PARENT global CONV_PARENT RDK.setParam(PARAM_BOX_X, BOX_SIZE_XYZ[0]) RDK.setParam(PARAM_BOX_Y, BOX_SIZE_XYZ[1]) RDK.setParam(PARAM_BOX_Z, BOX_SIZE_XYZ[2]) RDK.setParam(PARAM_UNITS, USE_METRIC) if PARENT is not None: RDK.setParam(PARAM_PARENT_NAME, PARENT.Name()) else: RDK.setParam(PARAM_PARENT_NAME, '') if CONV_PARENT is not None: RDK.setParam(PARAM_CONV_PARENT_NAME, CONV_PARENT.Name()) else: RDK.setParam(PARAM_CONV_PARENT_NAME, '')