Example #1
0
    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 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 __init__(self, RDK=None) -> None:
        self.RDK = RDK
        if self.RDK is None:
            self.RDK = Robolink()

        self.root = tk.Tk()

        self.radius = tk.DoubleVar(value=0)
        self.parent_name_text = tk.StringVar(
            value=odt.PARENT.Name() if odt.PARENT is not None else 'Unset')

        odt.loadParameters(self.RDK)

        self.init()
Example #4
0
    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'')
Example #5
0
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 createBox(RDK=None):
    if RDK is None:
        RDK = Robolink()

    global BOX_SIZE_XYZ
    global USE_METRIC
    global PARENT
    global CONV_PARENT

    RDK.Render(False)

    x, y, z = BOX_SIZE_XYZ
    if USE_METRIC:
        new_box = RDK.AddFile(REF_BOX_MM_PATH, PARENT)
        new_box.setName(BOX_ITEM_NAME_MM % (x, y, z))
    else:
        new_box = RDK.AddFile(REF_BOX_IN_PATH, PARENT)
        new_box.setName(BOX_ITEM_NAME_IN % (x, y, z))

    new_box.setPose(eye(4))
    new_box.Scale([x, y, z])
    RDK.Update()

    if CONV_PARENT is not None:
        new_box.setParentStatic(CONV_PARENT)

    new_box.setVisible(True)
    RDK.Render(True)
Example #7
0
    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
Example #8
0
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, '')
Example #9
0
def AttachCamera():
    RDK = Robolink()

    item2station_pose = eye(4)
    view_pose_last = eye(4)
    last_item = None

    RDK.Render()

    run = RunApplication()
    while run.Run():
        # Retrieve user selection
        selected_items = RDK.Selection()
        if len(selected_items) <= 0:
            last_item = None
            continue

        # Use the first selected item to attach the camera
        item = selected_items[0]

        # Prevent selecting programs or instructions or anything that doesn't move
        if item.type == ITEM_TYPE_ROBOT or item.type == ITEM_TYPE_TOOL or item.type == ITEM_TYPE_FRAME or item.type == ITEM_TYPE_OBJECT or item.type == ITEM_TYPE_TARGET:
            item_pose = item.PoseAbs(
            )  # Selected item pose with respect to the station reference
            item2station_pose = item_pose.inv()

            if last_item != item:
                # If it is the first time we select this item: update the relationship camera 2 item pose
                view_pose = RDK.ViewPose(
                )  # View Pose (camera pose with respect to the station reference)
                camera2item_pose = (item2station_pose * view_pose.inv()).inv()
                msg = 'Camera attached to %s' % item.Name()
                print(msg)
                RDK.ShowMessage(msg, False)
                last_item = item

            else:
                # calculate the new view pose and udpate it
                view_pose = camera2item_pose * item2station_pose

                # Only update if the view pose changed
                if view_pose != view_pose_last:
                    view_pose_last = view_pose
                    RDK.setViewPose(view_pose)
                    RDK.Render()
Example #10
0
def objectsInZone(RDK=None):
    if RDK is None:
        RDK = Robolink()

    global RADIUS
    global PARENT

    objects_in_zone = []

    if PARENT is None or not PARENT.Valid():
        return objects_in_zone

    objects = RDK.ItemList(ITEM_TYPE_OBJECT)
    if objects is None or len(objects) < 1:
        return objects_in_zone

    p_abs = PARENT.PoseAbs().Pos()
    for obj in objects:
        if distance(p_abs, obj.PoseAbs().Pos()) < RADIUS:
            objects_in_zone.append(obj)

    return objects_in_zone
Example #11
0
    def __init__(self, RDK=None) -> None:
        self.RDK = RDK
        if self.RDK is None:
            self.RDK = Robolink()

        self.root = tk.Tk()

        self.unit_options = tk.IntVar()
        self.units_format = ''

        self.box_length = tk.DoubleVar(value=0)
        self.box_width = tk.DoubleVar(value=0)
        self.box_height = tk.DoubleVar(value=0)

        self.box_length_text = tk.StringVar(value='')
        self.box_width_text = tk.StringVar(value='')
        self.box_height_text = tk.StringVar(value='')

        self.parent_name_text = tk.StringVar(value='')
        self.conv_parent_name_text = tk.StringVar(value='')

        sbt.loadParameters(self.RDK)

        self.init()
Example #12
0
    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
Example #13
0
def loadParameters(RDK=None):
    if RDK is None:
        RDK = Robolink()

    global RADIUS
    global PARENT

    radius = RDK.getParam(PARAM_RADIUS, True)
    if radius is not None and radius != '':
        RADIUS = float(radius)

    parent_name = RDK.getParam(PARAM_PARENT_NAME, True)
    if parent_name is not None and parent_name != '':
        item = RDK.Item(parent_name)
        if item.Valid() and item.Name() == parent_name:
            PARENT = item
    if PARENT is None:
        PARENT = RDK.ActiveStation()
Example #14
0
class SpawnBoxEditor:

    SIZE_SPINBOX_FROM = 0.1
    SIZE_SPINBOX_TO = 10000
    SIZE_SPINBOX_INCREMENT = 0.5
    SIZE_SPINBOX_FORMAT = "%0.2f"
    WIDTH_ENTRY = 32
    STICKY = tk.NSEW

    def __init__(self, RDK=None) -> None:
        self.RDK = RDK
        if self.RDK is None:
            self.RDK = Robolink()

        self.root = tk.Tk()

        self.unit_options = tk.IntVar()
        self.units_format = ''

        self.box_length = tk.DoubleVar(value=0)
        self.box_width = tk.DoubleVar(value=0)
        self.box_height = tk.DoubleVar(value=0)

        self.box_length_text = tk.StringVar(value='')
        self.box_width_text = tk.StringVar(value='')
        self.box_height_text = tk.StringVar(value='')

        self.parent_name_text = tk.StringVar(value='')
        self.conv_parent_name_text = tk.StringVar(value='')

        sbt.loadParameters(self.RDK)

        self.init()

    def init(self):
        self.unit_options.set(int(sbt.USE_METRIC))
        self.units_format = '(mm)' if sbt.USE_METRIC else '(in)'

        self.box_length.set(sbt.BOX_SIZE_XYZ[0])
        self.box_width.set(sbt.BOX_SIZE_XYZ[1])
        self.box_height.set(sbt.BOX_SIZE_XYZ[2])

        self.box_length_text.set('Box Length ' + self.units_format)
        self.box_width_text.set('Box Width ' + self.units_format)
        self.box_height_text.set('Box Height ' + self.units_format)

        self.parent_name_text.set(sbt.PARENT.Name() if sbt.PARENT is not None else 'Unset')
        self.conv_parent_name_text.set(sbt.CONV_PARENT.Name() if sbt.CONV_PARENT is not None else 'Unset')

    def switchUnitsFormat(self):

        use_metric = self.unit_options.get() == 1

        if use_metric != sbt.USE_METRIC:
            # Convert units
            factor = 25.4  # in to mm
            if sbt.USE_METRIC and not use_metric:
                factor = 1 / 25.4  # mm to in

            self.box_length.set(self.box_length.get() * factor)
            self.box_width.set(self.box_width.get() * factor)
            self.box_height.set(self.box_height.get() * factor)

        sbt.USE_METRIC = use_metric

    def setBoxDimensions(self):
        sbt.BOX_SIZE_XYZ[0] = self.box_length.get()
        sbt.BOX_SIZE_XYZ[1] = self.box_width.get()
        sbt.BOX_SIZE_XYZ[2] = self.box_height.get()

    def selectParent(self):
        self.RDK.setSelection([])
        choices = self.RDK.ItemList(ITEM_TYPE_FRAME)
        choices.append(self.RDK.ActiveStation())
        parent = self.RDK.ItemUserPick('Select spawning location', choices)
        if parent is not None and parent.Valid():
            sbt.PARENT = parent
            self.parent_name_text.set(sbt.PARENT.Name())

    def selectConvParent(self):
        self.RDK.setSelection([])
        conv_parent = self.RDK.ItemUserPick('Select conveyor relocation', ITEM_TYPE_FRAME)
        if conv_parent is not None and conv_parent.Valid():
            sbt.CONV_PARENT = conv_parent
            self.conv_parent_name_text.set(sbt.CONV_PARENT.Name())

    def clearConvParent(self):
        sbt.CONV_PARENT = None
        self.conv_parent_name_text.set('Unset')

    def saveAndClose(self):
        self.setBoxDimensions()  # This is not called if user entered manually
        sbt.setParameters(self.RDK)
        self.root.destroy()

    def loadDefaults(self):
        sbt.loadDefaults()
        self.init()

    def show(self):

        # Generate the main window
        frame = tk.Frame(self.root)
        frame.pack(side=tk.TOP, fill=tk.X, padx=1, pady=1)
        row = -1

        # Unit selection
        row += 1
        l_units = tk.Label(frame, text='Units', anchor='w')
        rb_box_units_mm = tk.Radiobutton(frame, text='mm', variable=self.unit_options, value=1, command=self.switchUnitsFormat)
        rb_box_units_in = tk.Radiobutton(frame, text='in', variable=self.unit_options, value=0, command=self.switchUnitsFormat)

        l_units.grid(column=0, row=row, sticky=self.STICKY)
        rb_box_units_mm.grid(column=1, columnspan=1, row=row, sticky=tk.NW)
        rb_box_units_in.grid(column=2, columnspan=3, row=row, sticky=tk.NW)

        # Box length (x)
        row += 1
        l_box_length = tk.Label(frame, textvariable=self.box_length_text, anchor='w')
        sb_box_length = tk.Spinbox(
            frame,
            textvariable=self.box_length,
            from_=self.SIZE_SPINBOX_FROM,
            to=self.SIZE_SPINBOX_TO,
            increment=self.SIZE_SPINBOX_INCREMENT,
            format=self.SIZE_SPINBOX_FORMAT,
            command=self.setBoxDimensions,
        )

        l_box_length.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        sb_box_length.grid(column=1, columnspan=3, row=row, sticky=self.STICKY)

        # Box width (y)
        row += 1
        l_box_width = tk.Label(frame, textvariable=self.box_width_text, anchor='w')
        sb_box_width = tk.Spinbox(
            frame,
            textvariable=self.box_width,
            from_=self.SIZE_SPINBOX_FROM,
            to=self.SIZE_SPINBOX_TO,
            increment=self.SIZE_SPINBOX_INCREMENT,
            format=self.SIZE_SPINBOX_FORMAT,
            command=self.setBoxDimensions,
        )

        l_box_width.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        sb_box_width.grid(column=1, columnspan=3, row=row, sticky=self.STICKY)

        # Box height (z)
        row += 1
        l_box_height = tk.Label(frame, textvariable=self.box_height_text, anchor='w')
        sb_box_height = tk.Spinbox(
            frame,
            textvariable=self.box_height,
            from_=self.SIZE_SPINBOX_FROM,
            to=self.SIZE_SPINBOX_TO,
            increment=self.SIZE_SPINBOX_INCREMENT,
            format=self.SIZE_SPINBOX_FORMAT,
            command=self.setBoxDimensions,
        )

        l_box_height.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        sb_box_height.grid(column=1, columnspan=3, row=row, sticky=self.STICKY)

        # Spawn location
        row += 1
        l_parent = tk.Label(frame, text='Spawn location (Item)', anchor='w')
        e_parent = tk.Entry(frame, textvariable=self.parent_name_text, state='readonly', width=self.WIDTH_ENTRY)
        b_parent = tk.Button(frame, text='Select', command=self.selectParent)

        l_parent.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        e_parent.grid(column=1, columnspan=1, row=row, sticky=self.STICKY)
        b_parent.grid(column=2, columnspan=2, row=row, sticky=self.STICKY, padx=1, pady=1)

        # Conveyor remap
        row += 1
        l_conv_parent = tk.Label(frame, text='Conveyor relocation (Item)', anchor='w')
        e_conv_parent = tk.Entry(frame, textvariable=self.conv_parent_name_text, state='readonly', width=self.WIDTH_ENTRY)
        b_conv_parent = tk.Button(frame, text='Select', command=self.selectConvParent)
        b_conv_parent_clr = tk.Button(frame, text='Clear', command=self.clearConvParent)

        l_conv_parent.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        e_conv_parent.grid(column=1, columnspan=1, row=row, sticky=self.STICKY)
        b_conv_parent.grid(column=2, columnspan=1, row=row, sticky=self.STICKY, padx=1, pady=1)
        b_conv_parent_clr.grid(column=3, columnspan=1, row=row, sticky=self.STICKY, padx=1, pady=1)

        # User controls
        control_row = tk.Frame(self.root)
        control_row.pack(side=tk.BOTTOM, padx=1, pady=1)

        # Creating the OK button
        b_ok = tk.Button(control_row, text='OK', command=self.saveAndClose, width=12)
        b_ok.grid(column=0, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Creating the Cancel button
        b_cancel = tk.Button(control_row, text='Cancel', command=self.root.destroy, width=12)
        b_cancel.grid(column=1, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Creating the Default button
        b_defaults = tk.Button(control_row, text='Defaults', command=self.loadDefaults, width=12)
        b_defaults.grid(column=2, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Set window name
        window_title = "Box Spawner Editor"
        self.root.title(window_title)

        # Logo
        icon_path = getPathIcon()
        if os.path.exists(icon_path):
            self.root.iconbitmap(icon_path)

        self.root.resizable(0, 0)
        self.root.mainloop()
Example #15
0
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, '')
Example #16
0
def loadParameters(RDK=None):
    if RDK is None:
        RDK = Robolink()

    global BOX_SIZE_XYZ
    global USE_METRIC
    global PARENT
    global CONV_PARENT

    size_x = RDK.getParam(PARAM_BOX_X, True)
    if size_x is not None and size_x != '':
        BOX_SIZE_XYZ[0] = float(size_x)

    size_y = RDK.getParam(PARAM_BOX_Y, True)
    if size_y is not None and size_y != '':
        BOX_SIZE_XYZ[1] = float(size_y)

    size_z = RDK.getParam(PARAM_BOX_Z, True)
    if size_z is not None and size_z != '':
        BOX_SIZE_XYZ[2] = float(size_z)

    metric = RDK.getParam(PARAM_UNITS, True)
    if metric is not None and metric != '':
        USE_METRIC = bool(metric == 'True')

    parent_name = RDK.getParam(PARAM_PARENT_NAME, True)
    if parent_name is not None and parent_name != '':
        item = RDK.Item(parent_name)
        if item.Valid() and item.Name() == parent_name:
            PARENT = item
    if PARENT is None:
        PARENT = RDK.ActiveStation()

    conv_parent_name = RDK.getParam(PARAM_CONV_PARENT_NAME, True)
    if conv_parent_name is not None and conv_parent_name != '':
        item = RDK.Item(conv_parent_name)
        if item.Valid() and item.Name() == conv_parent_name:
            CONV_PARENT = item
Example #17
0
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
Example #18
0
def RecordProgram():

    # Define the frames per second:
    FRAMES_PER_SECOND = 24

    # Define the video extension (you may need to change the codec)
    #VIDEO_EXTENSION = ".avi"
    VIDEO_EXTENSION = ".mp4"

    # Choose the codec (mp4v, XVID or DIVX)
    #FOURCC = cv2.VideoWriter_fourcc(*'DIVX') # good quality (avi)
    #FOURCC = cv2.VideoWriter_fourcc(*'XVID') # low quality (avi)
    FOURCC = cv2.VideoWriter_fourcc(*'mp4v')  # good quality (mp4)

    # Default screenshot style:
    SNAPSHOT_STYLE = "Snapshot"

    # Other snapshot styles are not recommended, otherwise it will create a delay and a lot of flickering
    # Instead, change the appearance of RoboDK in the menu Tools-Options-Display
    #SNAPSHOT_STYLE = "SnapshotWhite"
    #SNAPSHOT_STYLE = "SnapshotWhiteNoText"
    #SNAPSHOT_STYLE = "SnapshotNoTextNoFrames"

    PREFER_SOCKET = True # If available, prefer socket (usually faster) over temporary file to retrieve the image

    #-------------------------------------------------------------------
    # Use a temporary folder
    with tempfile.TemporaryDirectory(prefix='Record_') as td:

        RDK = Robolink()

        file_video_temp = os.path.join(td, 'RoboDK_Video' + VIDEO_EXTENSION)

        video = None
        frame = None
        use_socket = PREFER_SOCKET  
        render_time_last = 0
        time_per_frame = 1 / FRAMES_PER_SECOND

        app = RunApplication()
        while app.Run():
            tic()

            # There's no need to get a new image if no render as occurred.
            render_time = int(RDK.Command("LastRender"))
            if (render_time_last != render_time):
                render_time_last = render_time

                def getSnapshot(use_socket, tempdir):
                    fallback = False
                    if use_socket:
                        # Socket method. Added in version 5.3.2
                        try:
                            bytes_img = RDK.Cam2D_Snapshot('', None)  # None means station and will throw before version 5.3.2
                            if isinstance(bytes_img, bytes) and bytes_img != b'':
                                return True, cv2.imdecode(np.frombuffer(bytes_img, np.uint8), cv2.IMREAD_UNCHANGED)
                        except Exception:
                            fallback = True
                            pass

                    # Fallback to tempfile method
                    tf = tempdir + '/temp.png'
                    if RDK.Command(SNAPSHOT_STYLE, tf) == 'OK':
                        return not fallback, cv2.imread(tf)

                    return False, None

                # Get the station snapshot
                success, frame = getSnapshot(use_socket, td)
                if not success:
                    if use_socket:
                        use_socket = False
                    else:
                        RDK.ShowMessage("Problems retrieving the RoboDK image buffer", False)
                        break

            # Write the frame to the video file
            if video is None:
                # Requires at least one frame to extract the frame size.
                height, width = frame.shape[:2] 
                video = cv2.VideoWriter(file_video_temp, FOURCC, FRAMES_PER_SECOND, (width, height))
            video.write(frame)

            # Wait some time, if necessary, to have accurate frame rate
            elapsed = toc()
            if elapsed < time_per_frame:
                t_sleep = time_per_frame - elapsed
                print("Waiting for next frame: " + str(t_sleep))
                pause(t_sleep)

        print("Done recording")

        # Check if nothing was saved
        if video is None:
            quit()
        video.release()

        # Save the file
        msg_str = "Saving video recording... "
        print(msg_str)
        RDK.ShowMessage(msg_str, False)

        # Create a suggested file name
        print("Saving video...")
        date_str = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
        path_rdk = RDK.getParam('PATH_DESKTOP')  # or path_rdk = RDK.getParam('PATH_OPENSTATION')
        file_name = "RoboDK-Video-" + date_str + VIDEO_EXTENSION

        # Ask the user to provide a file to save
        file_path = getSaveFileName(path_preference=path_rdk, strfile=file_name, defaultextension=VIDEO_EXTENSION, filetypes=[("Video file", "*" + VIDEO_EXTENSION)])
        if not file_path:
            quit()

        # Save the file
        print("Saving video to: " + file_path)
        if os.path.exists(file_path):
            print("Deleting existing file: " + file_path)
            os.remove(file_path)

        # Move the file
        os.rename(file_video_temp, file_path)

    # Done
    msg_str = "Video recording saved: " + file_path
    print(msg_str)
    RDK.ShowMessage(msg_str, False)
Example #19
0
# Type help("robolink") or help("robodk") for more information
# Press F5 to run the script
# Documentation: https://robodk.com/doc/en/RoboDK-API.html
# Reference:     https://robodk.com/doc/en/PythonAPI/index.html
# Note: It is not required to keep a copy of this file, your python script is saved with the station
from robolink import Robolink  # RoboDK API
import ObjectDeleterTools as odt

RDK = Robolink()
script = RDK.AddFile(odt.LOCAL_PATH + '\ObjectDeleterLoop.py')
script.setName('Object Deleter (loop)')
Example #20
0
def removeParameters(RDK=None):
    if RDK is None:
        RDK = Robolink()

    RDK.setParam(PARAM_RADIUS, b'')
    RDK.setParam(PARAM_PARENT_NAME, b'')
# Type help("robolink") or help("robodk") for more information
# Press F5 to run the script
# Documentation: https://robodk.com/doc/en/RoboDK-API.html
# Reference:     https://robodk.com/doc/en/PythonAPI/index.html
# Note: It is not required to keep a copy of this file, your python script is saved with the station
from robolink import Robolink  # RoboDK API
from robodk import pause
import ObjectDeleterTools as odt

RDK = Robolink()

while True:
    odt.loadParameters(RDK)
    objects = odt.objectsInZone(RDK)
    for obj in objects:
        obj.Delete()
    pause(0.1)
# Type help("robolink") or help("robodk") for more information
# Press F5 to run the script
# Documentation: https://robodk.com/doc/en/RoboDK-API.html
# Reference:     https://robodk.com/doc/en/PythonAPI/index.html
# Note: It is not required to keep a copy of this file, your python script is saved with the station
from robolink import Robolink  # RoboDK API
import SpawnBoxTools as spt

RDK = Robolink()
script = RDK.AddFile(spt.LOCAL_PATH + '\SpawnBox.py')
script.setName('Spawn Box')
class ObjectDeleterEditor:

    SIZE_SPINBOX_FROM = 0.1
    SIZE_SPINBOX_TO = 10000
    SIZE_SPINBOX_INCREMENT = 1
    SIZE_SPINBOX_FORMAT = "%0.2f"
    WIDTH_ENTRY = 32
    STICKY = tk.NSEW

    def __init__(self, RDK=None) -> None:
        self.RDK = RDK
        if self.RDK is None:
            self.RDK = Robolink()

        self.root = tk.Tk()

        self.radius = tk.DoubleVar(value=0)
        self.parent_name_text = tk.StringVar(
            value=odt.PARENT.Name() if odt.PARENT is not None else 'Unset')

        odt.loadParameters(self.RDK)

        self.init()

    def init(self):

        self.radius.set(odt.RADIUS)
        self.parent_name_text.set(
            odt.PARENT.Name() if odt.PARENT is not None else 'Unset')

    def setRadius(self):
        odt.RADIUS = self.radius.get()

    def selectParent(self):
        self.RDK.setSelection([])
        choices = self.RDK.ItemList(ITEM_TYPE_FRAME)
        choices.append(self.RDK.ActiveStation())
        parent = self.RDK.ItemUserPick('Select Deleter location', choices)
        if parent is not None and parent.Valid():
            odt.PARENT = parent
            self.parent_name_text.set(odt.PARENT.Name())

    def saveAndClose(self):
        self.setRadius()
        odt.setParameters(self.RDK)
        self.root.destroy()

    def loadDefaults(self):
        odt.loadDefaults()
        self.init()

    def show(self):

        # Generate the main window
        frame = tk.Frame(self.root)
        frame.pack(side=tk.TOP, fill=tk.X, padx=1, pady=1)
        row = -1

        # Radius
        row += 1
        l_radius = tk.Label(frame, text='Radius (mm)', anchor='w')
        sb_radius = tk.Spinbox(
            frame,
            textvariable=self.radius,
            from_=self.SIZE_SPINBOX_FROM,
            to=self.SIZE_SPINBOX_TO,
            increment=self.SIZE_SPINBOX_INCREMENT,
            format=self.SIZE_SPINBOX_FORMAT,
            command=self.setRadius,
        )

        l_radius.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        sb_radius.grid(column=1, columnspan=3, row=row, sticky=self.STICKY)

        # Delete location
        row += 1
        l_parent = tk.Label(frame, text='Location (Item)', anchor='w')
        e_parent = tk.Entry(frame,
                            textvariable=self.parent_name_text,
                            state='readonly',
                            width=self.WIDTH_ENTRY)
        b_parent = tk.Button(frame,
                             text='Select',
                             command=self.selectParent,
                             padx=1,
                             pady=1)

        l_parent.grid(column=0, columnspan=1, row=row, sticky=self.STICKY)
        e_parent.grid(column=1, columnspan=1, row=row, sticky=self.STICKY)
        b_parent.grid(column=2,
                      columnspan=2,
                      row=row,
                      sticky=self.STICKY,
                      padx=1,
                      pady=1)

        # User controls
        control_row = tk.Frame(self.root)
        control_row.pack(side=tk.BOTTOM, padx=1, pady=1)

        # Creating the OK button
        b_ok = tk.Button(control_row,
                         text='OK',
                         command=self.saveAndClose,
                         width=12)
        b_ok.grid(column=0, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Creating the Cancel button
        b_cancel = tk.Button(control_row,
                             text='Cancel',
                             command=self.root.destroy,
                             width=12)
        b_cancel.grid(column=1, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Creating the Default button
        b_defaults = tk.Button(control_row,
                               text='Defaults',
                               command=self.loadDefaults,
                               width=12)
        b_defaults.grid(column=2, row=0, sticky=self.STICKY, padx=1, pady=1)

        # Set window name
        window_title = "Object Deleter Editor"
        self.root.title(window_title)

        # Logo
        icon_path = getPathIcon()
        if os.path.exists(icon_path):
            self.root.iconbitmap(icon_path)

        self.root.resizable(0, 0)
        self.root.mainloop()