def _actuator_handler(self):
        """Sends actuation commands to UR5.

        Waits for `actuator_buffer` being updated. If the connection
        is lost, does not do anything. Otherwise, proceeds with
        sending the command corresponding to the content of
        `actuator_buffer` with an added delay. The delay is randomly
        exponentially distributed with scale set by self._delay attribute."""

        # sleep until ready to send an actuation command
        # the ready condition depends on the `actuator_sync_period`
        while self._actuator_running:
            if self._actuation_sync_period > 0:
                # Synchronized to sensor readings, so check to see if the correct
                # number of readings have been detected to break out of the loop
                self._num_read_lock.acquire()
                if self._num_reads >= self._actuation_sync_period:
                    self._num_reads = 0
                    self._num_read_lock.release()
                    break
                self._num_read_lock.release()
            else:
                if self.actuator_buffer.updated():
                    break
            time.sleep(0.0001)

        # Do not perform an actuation if the socket connection is broken
        # or the actuator should no longer be running
        if self._stop or not self._actuator_running:
            return
        # obtain actuation command if it is ready
        # or a read was just performed and an action needs to be sent
        sent_count = 0
        for entry in self._commands_queue:
            cmd_str, timestamp, delay = entry
            now = time.time()
            if now - timestamp > delay:
                self._last_command = cmd_str
                self._sent_times.append(now)
                if not 'speedj' in str(self._last_command):
                    self._sock.send(cmd_str)
                sent_count += 1
                time.sleep(0.0001)
            else:
                break
        self._commands_queue = self._commands_queue[sent_count:]
        if not self._last_command is None and 'speedj' in str(
                self._last_command):
            self._sock.send(self._last_command)
        if self.actuator_buffer.updated(
        ) or self._actuation_sync_period > 0 or self._delay > 0.0:
            # keep track of the updated flag as it will be set to 0 below
            updated = self.actuator_buffer.updated()
            self._num_read_lock.acquire()
            self._num_reads = 0
            self._num_read_lock.release()
            recent_actuation, time_stamp, _ = self.actuator_buffer.read_update(
            )
            recent_actuation = recent_actuation[0]
            if recent_actuation[0] == ur_utils.COMMANDS['SERVOJ']['id']:
                servoj_values = ur_utils.COMMANDS['SERVOJ']
                cmd = ur_utils.ServoJ(
                    q=recent_actuation[1:1 + servoj_values['size'] - 3],
                    t=servoj_values['default']['t'] if recent_actuation[-3]
                    == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    lookahead_time=servoj_values['default']['lookahead_time']
                    if recent_actuation[-2] == ur_utils.USE_DEFAULT else
                    recent_actuation[-2],
                    gain=servoj_values['default']['gain']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else
                    recent_actuation[-1])
            elif recent_actuation[0] == ur_utils.COMMANDS['SPEEDJ']['id']:
                if time.time() - time_stamp[-1] > self._speedj_timeout:
                    return
                speedj_values = ur_utils.COMMANDS['SPEEDJ']
                cmd = ur_utils.SpeedJ(
                    qd=recent_actuation[1:1 + speedj_values['size'] - 2],
                    a=speedj_values['default']['a'] if recent_actuation[-2]
                    == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    t_min=speedj_values['default']['t_min']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else
                    recent_actuation[-1],
                )
            elif not updated:
                # The commands below this point should only be executed
                # if they are new actuations
                return
            elif recent_actuation[0] == ur_utils.COMMANDS['MOVEL']['id']:
                movel_values = ur_utils.COMMANDS['MOVEL']
                cmd = ur_utils.MoveL(
                    pose=recent_actuation[1:1 + movel_values['size'] - 4],
                    a=movel_values['default']['a'] if recent_actuation[-4]
                    == ur_utils.USE_DEFAULT else recent_actuation[-4],
                    v=movel_values['default']['v'] if recent_actuation[-3]
                    == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    t=movel_values['default']['t'] if recent_actuation[-2]
                    == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    r=movel_values['default']['r'] if recent_actuation[-1]
                    == ur_utils.USE_DEFAULT else recent_actuation[-1],
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['MOVEJ']['id']:
                movej_values = ur_utils.COMMANDS['MOVEJ']
                cmd = ur_utils.MoveJ(
                    q=recent_actuation[1:1 + movej_values['size'] - 4],
                    a=movej_values['default']['a'] if recent_actuation[-4]
                    == ur_utils.USE_DEFAULT else recent_actuation[-4],
                    v=movej_values['default']['v'] if recent_actuation[-3]
                    == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    t=movej_values['default']['t'] if recent_actuation[-2]
                    == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    r=movej_values['default']['r'] if recent_actuation[-1]
                    == ur_utils.USE_DEFAULT else recent_actuation[-1],
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['STOPJ']['id']:
                cmd = ur_utils.StopJ(a=recent_actuation[1])
            elif recent_actuation[0] == ur_utils.COMMANDS['UNLOCK_PSTOP'][
                    'id']:
                print("Unlocking p-stop")
                self._dashboard_sock.send(
                    'unlock protective stop\n'.encode('ascii'))
                return
            elif recent_actuation[0] == ur_utils.COMMANDS['NOTHING']['id']:
                return
            else:
                raise NotImplementedError
            cmd_str = '{}\n'.format(cmd)
            self._commands_queue.append([
                cmd_str.encode('ascii'),
                time.time(),
                np.minimum(
                    int(np.random.exponential(scale=self._delay) / 0.008) *
                    0.008, 0.32)
            ])
예제 #2
0
    def _actuator_handler(self):
        """Sends actuation commands to UR5.

        Waits for `actuator_buffer` being updated.
        If the connection is lost, does not do anything.
        Otherwise, proceeds with sending the command corresponding to
        the content of `actuator_buffer`.
        """

        # sleep until ready to send an actuation command
        # the ready condition depends on the `actuator_sync_period`
        while self._actuator_running:
            if self._actuation_sync_period > 0:
                # Synchronized to sensor readings, so check to see if the correct
                # number of readings have been detected to break out of the loop
                self._num_read_lock.acquire()
                if self._num_reads >= self._actuation_sync_period:
                    self._num_reads = 0
                    self._num_read_lock.release()
                    break
                self._num_read_lock.release()
            else:
                # Not synchronized to sensor readings, so break out of the loop
                # and actuate a command as soon as the buffer is updated
                if self.actuator_buffer.updated():
                    break
            time.sleep(1e-4)

        # Do not perform an actuation if the socket connection is broken
        # or the actuator should no longer be running
        if self._stop or not self._actuator_running:
            return

        # obtain actuation command if it is ready
        # or a read was just performed and an action needs to be sent
        if self.actuator_buffer.updated() or self._actuation_sync_period > 0:
            # keep track of the updated flag as it will be set to 0 below
            updated = self.actuator_buffer.updated()
            self._num_read_lock.acquire()
            self._num_reads = 0
            self._num_read_lock.release()
            recent_actuation, time_stamp, _ = self.actuator_buffer.read_update()
            recent_actuation = recent_actuation[0]
            if recent_actuation[0] == ur_utils.COMMANDS['SERVOJ']['id']:
                servoj_values = ur_utils.COMMANDS['SERVOJ']
                cmd = ur_utils.ServoJ(
                    q=recent_actuation[1:1 + servoj_values['size'] - 3],
                    t=servoj_values['default']['t']
                    if recent_actuation[-3] == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    lookahead_time=servoj_values['default']['lookahead_time']
                    if recent_actuation[-2] == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    gain=servoj_values['default']['gain']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else recent_actuation[-1]
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['SPEEDJ']['id']:
                if time.time() - time_stamp[-1] > self._speedj_timeout:
                    return
                speedj_values = ur_utils.COMMANDS['SPEEDJ']
                cmd = ur_utils.SpeedJ(
                    qd=recent_actuation[1:1 + speedj_values['size'] - 2],
                    a=speedj_values['default']['a']
                    if recent_actuation[-2] == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    t_min=speedj_values['default']['t_min']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else recent_actuation[-1],
                )
            elif not updated:
                # The commands below this point should only be executed
                # if they are new actuations
                return
            elif recent_actuation[0] == ur_utils.COMMANDS['MOVEL']['id']:
                movel_values = ur_utils.COMMANDS['MOVEL']
                cmd = ur_utils.MoveL(
                    pose=recent_actuation[1:1 + movel_values['size'] - 4],
                    a=movel_values['default']['a']
                    if recent_actuation[-4] == ur_utils.USE_DEFAULT else recent_actuation[-4],
                    v=movel_values['default']['v']
                    if recent_actuation[-3] == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    t=movel_values['default']['t']
                    if recent_actuation[-2] == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    r=movel_values['default']['r']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else recent_actuation[-1],
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['MOVEJ']['id']:
                movej_values = ur_utils.COMMANDS['MOVEJ']
                cmd = ur_utils.MoveJ(
                    q=recent_actuation[1:1 + movej_values['size'] - 4],
                    a=movej_values['default']['a']
                    if recent_actuation[-4] == ur_utils.USE_DEFAULT else recent_actuation[-4],
                    v=movej_values['default']['v']
                    if recent_actuation[-3] == ur_utils.USE_DEFAULT else recent_actuation[-3],
                    t=movej_values['default']['t']
                    if recent_actuation[-2] == ur_utils.USE_DEFAULT else recent_actuation[-2],
                    r=movej_values['default']['r']
                    if recent_actuation[-1] == ur_utils.USE_DEFAULT else recent_actuation[-1],
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['STOPJ']['id']:
                cmd = ur_utils.StopJ(
                    a=recent_actuation[1]
                )
            elif recent_actuation[0] == ur_utils.COMMANDS['UNLOCK_PSTOP']['id']:
                print("Unlocking p-stop")
                self._dashboard_sock.send('unlock protective stop\n'.encode('ascii'))
                return
            elif recent_actuation[0] == ur_utils.COMMANDS['NOTHING']['id']:
                return
            else:
                raise NotImplementedError
            cmd_str = '{}\n'.format(cmd)
            self._sock.send(cmd_str.encode('ascii'))