コード例 #1
0
class UAVStatePublisher(QMainWindow):
    def __init__(self):
        super(UAVStatePublisher, self).__init__()

        #Not working: how to set window dimension
        self.height = 300
        self.width = 300
        self.top = 50
        self.left = 50
        font = QFont("Helvetica", 9, QFont.Bold)

        rospy.init_node("uav_state_publisher")
        nodename = rospy.get_name()
        rospy.loginfo("%s started" % nodename)

        self.arm_disarm_req = rospy.ServiceProxy('/mavros/cmd/arming',
                                                 CommandBool)
        self.takeoff_req = rospy.ServiceProxy('/mavros/cmd/takeoff',
                                              CommandTOL)
        self.land_req = rospy.ServiceProxy('/mavros/cmd/land', CommandTOL)
        self.offboard_req = rospy.ServiceProxy('/mavros/set_mode', SetMode)

        rospy.Subscriber("/mavros/local_position/odom", Odometry, self.odomCb)
        rospy.Subscriber("/mavros/state", State, self.stateCb)
        self.state = "Idle"
        self.arm_state = False
        self.local_cmd = ([0.0, 0.0, 0.0])
        self.dx_cmd = 0.0
        self.dy_cmd = 0.0
        self.dz_cmd = 0.0
        self.yaw_cmd = 0.0

        self.ctrl_mode = "position"
        self.setpoint_raw_pub = rospy.Publisher('mavros/setpoint_raw/local',
                                                PositionTarget,
                                                queue_size=1)
        '''
        uint16 IGNORE_PX=1
        uint16 IGNORE_PY=2
        uint16 IGNORE_PZ=4
        uint16 IGNORE_VX=8
        uint16 IGNORE_VY=16
        uint16 IGNORE_VZ=32
        uint16 IGNORE_AFX=64
        uint16 IGNORE_AFY=128
        uint16 IGNORE_AFZ=256
        uint16 FORCE=512
        uint16 IGNORE_YAW=1024
        uint16 IGNORE_YAW_RATE=2048
        '''
        self.pos_raw_msg = PositionTarget()
        self.pos_raw_msg.coordinate_frame = PositionTarget.FRAME_LOCAL_NED
        self.pos_raw_msg.type_mask = PositionTarget.IGNORE_VX + PositionTarget.IGNORE_VY + PositionTarget.IGNORE_VZ + PositionTarget.IGNORE_AFX + PositionTarget.IGNORE_AFY + PositionTarget.IGNORE_AFZ + PositionTarget.IGNORE_YAW + PositionTarget.FORCE

        self.vel_raw_msg = PositionTarget()
        self.vel_raw_msg.coordinate_frame = PositionTarget.FRAME_BODY_NED
        self.vel_raw_msg.type_mask = PositionTarget.IGNORE_PX + PositionTarget.IGNORE_PY + PositionTarget.IGNORE_PZ + PositionTarget.IGNORE_AFX + PositionTarget.IGNORE_AFY + PositionTarget.IGNORE_AFZ + PositionTarget.IGNORE_YAW + PositionTarget.FORCE

        window = QWidget()
        self.layout = QVBoxLayout()

        self.setWindowTitle("UAV State Publisher")

        #Position label
        self.textbox_state = QLabel(self)
        self.textbox_state.move(20, 20)
        self.textbox_state.resize(280, 40)
        self.textbox_state.setFont(font)

        #Position label
        self.textbox_pos = QLabel(self)
        self.textbox_pos.move(20, 20)
        self.textbox_pos.resize(280, 40)

        #Yaw Label
        self.textbox_yaw = QLabel(self)
        self.textbox_yaw.move(20, 20)
        self.textbox_yaw.resize(280, 40)

        #Command position label
        self.textbox_cmd_pos = QLabel(self)
        self.textbox_cmd_pos.move(20, 20)
        self.textbox_cmd_pos.resize(280, 40)

        #Command yaw label
        self.textbox_cmd_yaw = QLabel(self)
        self.textbox_cmd_yaw.move(20, 20)
        self.textbox_cmd_yaw.resize(280, 40)

        #Position control
        self.checkbox_pvcontrol = QCheckBox('Position/velocity control')
        #self.checkbox_vcontrol = QCheckBox('Velocity control')
        self.checkbox_pvcontrol.stateChanged.connect(
            self.select_chkbox_pvcontrol)
        #self.checkbox_vcontrol.stateChanged.connect(self.select_chkbox_vcontrol)

        self.arm_button = QPushButton('Arm / Disarm', self)
        self.arm_button.setToolTip('Start/Stop motor spinning')
        self.arm_button.move(100, 70)
        self.arm_button.clicked.connect(self.on_click_arm)

        self.toff_button = QPushButton('Take-off', self)
        self.toff_button.setToolTip('takeoff the UAV')
        self.toff_button.move(100, 70)
        self.toff_button.clicked.connect(self.on_click_toff)

        self.land_button = QPushButton('Land', self)
        self.land_button.setToolTip('Land the UAV')
        self.land_button.move(100, 70)
        self.land_button.clicked.connect(self.on_click_land)

        self.offboard_button = QPushButton('OFFBOARD', self)
        self.offboard_button.setToolTip('Start offboard mode')
        self.offboard_button.move(100, 70)
        self.offboard_button.clicked.connect(self.on_click_offboard)

        x_cmdlabel = QLabel("Slide to command the x rate (d/s)")
        x_cmdlabel.setFont(font)

        self.cmd_dx_slider = QSlider(Qt.Horizontal, self)
        self.cmd_dx_slider.setGeometry(30, 40, 200, 30)
        self.cmd_dx_slider.valueChanged[int].connect(self.changeValue_dx)
        self.cmd_dx_slider.setRange(-10, 10)
        self.cmd_dx_slider.setValue(0)

        y_cmdlabel = QLabel("Slide to command the y rate (d/s)")
        y_cmdlabel.setFont(font)

        self.cmd_dy_slider = QSlider(Qt.Horizontal, self)
        self.cmd_dy_slider.setGeometry(30, 40, 200, 30)
        self.cmd_dy_slider.valueChanged[int].connect(self.changeValue_dy)
        self.cmd_dy_slider.setRange(-10, 10)
        self.cmd_dy_slider.setValue(0)

        z_cmdlabel = QLabel("Slide to command the z rate (d/s)")
        z_cmdlabel.setFont(font)

        self.cmd_dz_slider = QSlider(Qt.Horizontal, self)
        self.cmd_dz_slider.setGeometry(30, 40, 200, 30)
        self.cmd_dz_slider.valueChanged[int].connect(self.changeValue_dz)
        self.cmd_dz_slider.setRange(-10, 10)
        self.cmd_dz_slider.setValue(0)

        self.center_slider_button = QPushButton('Center', self)
        self.center_slider_button.setToolTip('Put in the middel all sliders')
        self.center_slider_button.move(100, 70)
        self.center_slider_button.clicked.connect(self.on_click_center)

        yaw_cmdlabel = QLabel("Slide to command the yaw rate (d/s)")
        yaw_cmdlabel.setFont(font)

        self.cmd_dyaw_slider = QSlider(Qt.Horizontal, self)
        self.cmd_dyaw_slider.setGeometry(30, 40, 200, 30)
        self.cmd_dyaw_slider.valueChanged[int].connect(self.changeValue_dyaw)
        self.cmd_dyaw_slider.setRange(-60, 60)
        self.cmd_dyaw_slider.setValue(0)

        joy_cmdlabel = QLabel("Click and release buttons to command the UAV")
        joy_cmdlabel.setFont(font)

        self.forward_button = QPushButton('FORWARD', self)
        self.forward_button.setToolTip('Move robot in positive x direction')
        self.forward_button.move(100, 70)
        self.forward_button.pressed.connect(self.on_pres_forward)
        self.forward_button.released.connect(self.on_rel_forward)

        self.back_button = QPushButton('BACKWARD', self)
        self.back_button.setToolTip('Move robot in negative x direction')
        self.back_button.move(100, 70)
        self.back_button.pressed.connect(self.on_pres_back)
        self.back_button.released.connect(self.on_rel_back)

        self.left_button = QPushButton('LEFT', self)
        self.left_button.setToolTip('Move robot in positive y direction')
        self.left_button.move(100, 70)
        self.left_button.pressed.connect(self.on_pres_left)
        self.left_button.released.connect(self.on_rel_left)

        self.right_button = QPushButton('RIGHT', self)
        self.right_button.setToolTip('Move robot in negative y direction')
        self.right_button.move(100, 70)
        self.right_button.pressed.connect(self.on_pres_right)
        self.right_button.released.connect(self.on_rel_right)

        self.up_button = QPushButton('UP', self)
        self.up_button.setToolTip('Move robot in positive z direction')
        self.up_button.move(100, 70)
        self.up_button.pressed.connect(self.on_pres_up)
        self.up_button.released.connect(self.on_rel_up)

        self.down_button = QPushButton('DOWN', self)
        self.down_button.setToolTip('Move robot in negative z direction')
        self.down_button.move(100, 70)
        self.down_button.pressed.connect(self.on_pres_down)
        self.down_button.released.connect(self.on_rel_down)

        self.rot_left_button = QPushButton('ROTATE_LEFT', self)
        self.rot_left_button.setToolTip('rotate robot in left direction')
        self.rot_left_button.move(100, 70)
        self.rot_left_button.pressed.connect(self.on_pres_yawleft)
        self.rot_left_button.released.connect(self.on_rel_yawleft)

        self.rot_right_button = QPushButton('ROTATE_RIGHT', self)
        self.rot_right_button.setToolTip('rotate robot in right direction')
        self.rot_right_button.move(100, 70)
        self.rot_right_button.pressed.connect(self.on_pres_yawright)
        self.rot_right_button.released.connect(self.on_rel_yawright)

        self.layout.addWidget(self.textbox_state)
        self.layout.addWidget(self.textbox_pos)
        self.layout.addWidget(self.textbox_yaw)
        self.layout.addWidget(self.textbox_cmd_pos)
        self.layout.addWidget(self.textbox_cmd_yaw)
        self.layout.addWidget(self.arm_button)
        self.layout.addWidget(self.toff_button)
        self.layout.addWidget(self.land_button)
        self.layout.addWidget(self.offboard_button)

        self.layout.addWidget(self.checkbox_pvcontrol)
        #self.layout.addWidget(self.checkbox_vcontrol)

        self.layout.addWidget(x_cmdlabel)
        self.layout.addWidget(self.cmd_dx_slider)
        self.layout.addWidget(y_cmdlabel)
        self.layout.addWidget(self.cmd_dy_slider)
        self.layout.addWidget(z_cmdlabel)
        self.layout.addWidget(self.cmd_dz_slider)
        self.layout.addWidget(yaw_cmdlabel)
        self.layout.addWidget(self.cmd_dyaw_slider)
        self.layout.addWidget(self.center_slider_button)

        self.layout.addWidget(joy_cmdlabel)
        self.layout.addWidget(self.forward_button)
        self.layout.addWidget(self.back_button)
        self.layout.addWidget(self.left_button)
        self.layout.addWidget(self.right_button)
        self.layout.addWidget(self.up_button)
        self.layout.addWidget(self.down_button)
        self.layout.addWidget(self.rot_left_button)
        self.layout.addWidget(self.rot_right_button)

        self.checkbox_pvcontrol.setChecked(True)

        self.forward_button.setEnabled(False)
        self.back_button.setEnabled(False)
        self.left_button.setEnabled(False)
        self.right_button.setEnabled(False)
        self.up_button.setEnabled(False)
        self.down_button.setEnabled(False)
        self.rot_left_button.setEnabled(False)
        self.rot_right_button.setEnabled(False)

        window.setLayout(self.layout)
        window.show()
        app.exec_()

        sys.exit()
        '''
        self.setWindowTitle("UAV State Publisher")
        font = QFont("Helvetica", 9, QFont.Bold)
        label = QLabel("Yaw")
        label.setFont(font)
        addWidget(label)

        mySlider = QSlider(Qt.Horizontal, self)
        mySlider.setGeometry(30, 40, 200, 30)
        mySlider.valueChanged[int].connect(self.changeValue)

        #self.setGeometry(50,50,320,200)
        self.show()
        '''

    def select_chkbox_pvcontrol(self, state):
        if state == 0:
            self.cmd_dx_slider.setValue(0)
            self.cmd_dy_slider.setValue(0)
            self.cmd_dz_slider.setValue(0)
            self.cmd_dyaw_slider.setValue(0)

            self.center_slider_button.setEnabled(False)
            self.cmd_dx_slider.setEnabled(False)
            self.cmd_dy_slider.setEnabled(False)
            self.cmd_dz_slider.setEnabled(False)
            self.cmd_dyaw_slider.setEnabled(False)

            self.forward_button.setEnabled(True)
            self.back_button.setEnabled(True)
            self.left_button.setEnabled(True)
            self.right_button.setEnabled(True)
            self.up_button.setEnabled(True)
            self.down_button.setEnabled(True)
            self.rot_left_button.setEnabled(True)
            self.rot_right_button.setEnabled(True)
            self.ctrl_mode = "velocity"

        elif state == 2:
            self.cmd_dx_slider.setValue(0)
            self.cmd_dy_slider.setValue(0)
            self.cmd_dz_slider.setValue(0)
            self.cmd_dyaw_slider.setValue(0)

            self.center_slider_button.setEnabled(True)
            self.cmd_dx_slider.setEnabled(True)
            self.cmd_dy_slider.setEnabled(True)
            self.cmd_dz_slider.setEnabled(True)
            self.cmd_dyaw_slider.setEnabled(True)

            self.forward_button.setEnabled(False)
            self.back_button.setEnabled(False)
            self.left_button.setEnabled(False)
            self.right_button.setEnabled(False)
            self.up_button.setEnabled(False)
            self.down_button.setEnabled(False)
            self.rot_left_button.setEnabled(False)
            self.rot_right_button.setEnabled(False)
            self.ctrl_mode = "position"

    #def select_chkbox_pcontrol(self, state):
    #    print("select_chkbox_pcontrol state: ", state)
    #    self.checkbox_vcontrol.setChecked( False )
    #    self.checkbox_pcontrol.setChecked( True )

    #def select_chkbox_vcontrol( self, state ):
    #    print("select_chkbox_vcontrol state: ", state)
    #    self.checkbox_pcontrol.setChecked( False )
    #    self.checkbox_vcontrol.setChecked( True )

    def on_pres_yawleft(self):
        self.yaw_cmd = 0.3

    def on_rel_yawleft(self):
        self.yaw_cmd = 0.0

    def on_pres_yawright(self):
        self.yaw_cmd = -0.3

    def on_rel_yawright(self):
        self.yaw_cmd = 0.0

    def on_pres_forward(self):
        self.dy_cmd = 0.3

    def on_rel_forward(self):
        self.dy_cmd = 0.0

    def on_pres_back(self):
        self.dy_cmd = -0.3

    def on_rel_back(self):
        self.dy_cmd = 0.0

    def on_pres_left(self):
        self.dx_cmd = -0.3

    def on_rel_left(self):
        self.dx_cmd = 0.0

    def on_pres_right(self):
        self.dx_cmd = 0.3

    def on_rel_right(self):
        self.dx_cmd = 0.0

    def on_pres_up(self):
        self.dz_cmd = 0.3

    def on_rel_up(self):
        self.dz_cmd = 0.0

    def on_pres_down(self):
        self.dz_cmd = -0.3

    def on_rel_down(self):
        self.dz_cmd = 0.0

    def on_click_arm(self):
        if self.arm_state == True:
            self.arm_disarm_req(False)
        else:
            self.arm_disarm_req(True)

    def on_click_toff(self):
        print("Request Takeoff")  #Todo
        self.local_cmd[2] = self.local_cmd[2] + 2.0

    def on_click_land(self):
        print("Request Land")  #Todo
        self.land_req(altitude=0, latitude=0, longitude=0, min_pitch=0, yaw=0)

    def on_click_center(self):
        self.cmd_dx_slider.setValue(0)
        self.cmd_dy_slider.setValue(0)
        self.cmd_dz_slider.setValue(0)
        self.cmd_dyaw_slider.setValue(0)

    def on_click_offboard(self):
        self.offboard_req(base_mode=0, custom_mode="OFFBOARD")

    def changeValue_dyaw(self, value):
        self.yaw_cmd = (value * 3.1415) / 180.0

    def changeValue_dx(self, value):
        self.dx_cmd = value / 10.0

    def changeValue_dy(self, value):
        self.dy_cmd = value / 10.0

    def changeValue_dz(self, value):
        self.dz_cmd = value / 10.0

    def stateCb(self, msg):
        self.state = msg.mode
        self.arm_state = msg.armed

    def odomCb(self, msg):

        self.textbox_state.setText("State: " + self.state)

        str_x = str(round(msg.pose.pose.position.x, 2))
        str_y = str(round(msg.pose.pose.position.y, 2))
        str_z = str(round(msg.pose.pose.position.z, 2))
        coords = str_x + " " + str_y + " " + str_z
        self.textbox_pos.setText("Pos: " + coords)

        quaternion = (msg.pose.pose.orientation.x, msg.pose.pose.orientation.y,
                      msg.pose.pose.orientation.z, msg.pose.pose.orientation.w)
        euler = tf.transformations.euler_from_quaternion(quaternion)
        yaw = euler[2]
        self.textbox_yaw.setText("Yaw: " + str(round(yaw, 2)))
        self.pos_raw_msg.header.stamp = rospy.get_rostime()

        if (self.state == "OFFBOARD"):
            if self.ctrl_mode == "position":
                self.local_cmd[0] = self.local_cmd[0] + self.dx_cmd * 0.02
                self.local_cmd[1] = self.local_cmd[1] + self.dy_cmd * 0.02
                self.local_cmd[2] = self.local_cmd[2] + self.dz_cmd * 0.02
            else:
                self.local_cmd[0] = msg.pose.pose.position.x
                self.local_cmd[1] = msg.pose.pose.position.y
                self.local_cmd[2] = msg.pose.pose.position.z
                #self.yaw_cmd = 0.0

        else:
            self.yaw_cmd = yaw
            self.local_cmd[0] = msg.pose.pose.position.x
            self.local_cmd[1] = msg.pose.pose.position.y
            self.local_cmd[2] = msg.pose.pose.position.z

        if self.ctrl_mode == "position":
            self.pos_raw_msg.position.x = self.local_cmd[0]
            self.pos_raw_msg.position.y = self.local_cmd[1]
            self.pos_raw_msg.position.z = self.local_cmd[2]
            self.pos_raw_msg.yaw_rate = self.yaw_cmd
            self.textbox_cmd_pos.setText("Cmd Pos: " +
                                         str(round(self.local_cmd[0], 2)) +
                                         " " +
                                         str(round(self.local_cmd[1], 2)) +
                                         " " +
                                         str(round(self.local_cmd[2], 2)))
            self.textbox_cmd_yaw.setText("Cmd dYaw: " +
                                         str(round(self.yaw_cmd, 2)) +
                                         " rad/s")
            self.setpoint_raw_pub.publish(self.pos_raw_msg)

        elif self.ctrl_mode == "velocity":
            self.vel_raw_msg.velocity.x = self.dx_cmd
            self.vel_raw_msg.velocity.y = self.dy_cmd
            self.vel_raw_msg.velocity.z = self.dz_cmd
            self.vel_raw_msg.yaw_rate = self.yaw_cmd
            self.textbox_cmd_pos.setText("Cmd Vel: " + str(self.dx_cmd) + " " +
                                         str(self.dy_cmd) + " " +
                                         str(self.dz_cmd))
            self.textbox_cmd_yaw.setText("Cmd dYaw: " +
                                         str(round(self.yaw_cmd, 2)) +
                                         " rad/s")
            self.setpoint_raw_pub.publish(self.vel_raw_msg)
コード例 #2
0
class HardwareUI(Plugin):
    """Backend for the GUI. Receives UDP data and distributes it across all GUI elements."""
    tetrigger = QtCore.pyqtSignal()
    totrigger = QtCore.pyqtSignal()
    votrigger = QtCore.pyqtSignal()
    imutrigger = QtCore.pyqtSignal(Imu)

    def __init__(self, context):
        """Loads up the master.ui GUI file and adds some additional widgets that cannot be added beforehand. Also sets some necessary variables."""
        super(HardwareUI, self).__init__(context)
        self._widget = QMainWindow()

        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('bitbots_hardware_rqt'), 'resource',
                               'master.ui')
        loadUi(ui_file, self._widget, {})

        self.current_tab = 0
        self.current_outer_tab = 0

        self.historydict = []
        self.colorlist = [
        ]  #Holds information about the graph colors, so we can distinguish between the different motors
        self.motornames = [
            'HeadPan', 'HeadTilt', 'LAnklePitch', 'LAnkleRoll', 'LElbow',
            'LHipPitch', 'LHipRoll', 'LHipYaw', 'LKnee', 'LShoulderPitch',
            'LShoulderRoll', 'RAnklePitch', 'RAnkleRoll', 'RElbow',
            'RHipPitch', 'RHipRoll', 'RHipYaw', 'RKnee', 'RShoulderPitch',
            'RShoulderRoll'
        ]  #We need the motor names in alphabetical order for some gui elements
        for i in range(0, 20):
            self.colorlist.append(
                (random.randrange(50, 255), random.randrange(0, 255),
                 random.randrange(0, 255)))

        self.templist = [[] for i in range(20)]
        self.torquelist = [[] for i in range(20)]
        self.voltagelist = [[] for i in range(20)]

        self.crosshair = QLabel()
        self.pixmap = QtGui.QPixmap(
            os.path.join(rp.get_path('bitbots_hardware_rqt'), 'resource',
                         'cross.png'))
        self.crosshair.setPixmap(self.pixmap)
        self.crosshair.setParent(self._widget.label_4)
        self.crosshair.move(187, 187)

        self.crosshair2 = QLabel()
        self.pixmap = QtGui.QPixmap(
            os.path.join(rp.get_path('bitbots_hardware_rqt'), 'resource',
                         'cross.png'))
        self.crosshair2.setPixmap(self.pixmap)
        self.crosshair2.setParent(self._widget.label_11)
        self.crosshair2.move(87, 87)

        self.make_Graphs()

        self.votrigger.connect(lambda: self.update_graph(
            self.voltageplt, self.voltagelist, self.combobox2, 3))
        self.tetrigger.connect(lambda: self.update_graph(
            self.tempplt, self.templist, self.combobox3, 1))
        self.totrigger.connect(lambda: self.update_graph(
            self.torqueplt, self.torquelist, self.combobox, 2))

        #self._robot_ip = [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0]
        self._robot, button_pressed = QInputDialog.getText(self._widget, "Robot?", \
                "Select your Robot. Example: nuc1", QLineEdit.Normal, "")

        self.diagnostics = rospy.Subscriber(
            "/{}/diagnostics".format(self._robot), DiagnosticArray,
            self.set_motor_diagnostics)
        self.joint_states = rospy.Subscriber(
            "/{}/joint_states".format(self._robot), JointState,
            self.set_motor_joint_states)
        self.buttons = rospy.Subscriber("/{}/buttons".format(self._robot),
                                        Buttons, self.set_buttons)
        self.imu = rospy.Subscriber("/{}/imu/data".format(self._robot), Imu,
                                    self.emit_imu_trigger)
        self.state = rospy.Subscriber("/{}/robot_state".format(self._robot),
                                      RobotControlState, self.set_robot_state)

        self.imutrigger.connect(self.set_imu)

        #self.rcvthread = ReceiverThread(self._robot_ip, self._robot_port)
        #self.rcvthread.start()

        self._widget.GraphenView.currentChanged.connect(
            self.current_graph_changed)
        self._widget.tabWidget.currentChanged.connect(
            self.current_outer_tab_changed)

        #self._widget.label_14.setText("IP: "+ [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])

        context.add_widget(self._widget)
        self._widget.show()

    def calcPosInCicle(self, radOrienation):
        """return a position on the circle in the GUI"""
        yPos = -math.cos(radOrienation) * 100 + 87
        xPos = math.sin(radOrienation) * 100 + 87
        return xPos, yPos

    def current_graph_changed(self, change):
        """Handles the changing between tabs, so that only the active tab is updated, to reduce lag"""
        self.current_tab = change

    def current_outer_tab_changed(self, change):
        self.current_outer_tab = change

    def emit_imu_trigger(self, data):
        self.imutrigger.emit(data)

    def set_imu(self, data):
        """Updates the IMU/Gyro widgets."""
        if self.current_outer_tab == 2:
            self._widget.label_8.setText(
                str(math.degrees(data.angular_velocity.x)))
            self._widget.label_9.setText(
                str(math.degrees(data.angular_velocity.y)))
            self._widget.label_10.setText(
                str(math.degrees(data.angular_velocity.z)))

            self.crosshair.move((187+(math.degrees(data.angular_velocity.x)*400/360)), \
                (187+(math.degrees(data.angular_velocity.y)*400/360)))    #To place the crosshair on the circle, circle diametre is 400px, crosshair is 25px wide
            yawx, yawy = self.calcPosInCicle(data.angular_velocity.z)
            self.crosshair2.move(yawx, yawy)

    def set_buttons(self, data):
        """Updates the widgets placed in the topbar"""
        self._widget.checkBox.setCheckState(data.button1)
        self._widget.checkBox.setCheckState(data.button2)

    def set_robot_state(self, data):
        states = {
            0: "CONTROLLABLE",
            1: "FALLING",
            2: "FALLEN",
            3: "GETTING UP",
            4: "ANIMATION RUNNING",
            5: "STARTUP",
            6: "SHUTDOWN",
            7: "PENALTY",
            8: "PENALTY ANIM",
            9: "RECORD",
            10: "WALKING",
            11: "MOTOR OFF",
            12: "HCM OFF",
            13: "HARDWARE PROBLEM",
            14: "PICKED UP"
        }
        self._widget.label_14.setText(states[data.state])

    def set_motor_diagnostics(self, data):
        """Updates the table in the motor overview tab"""
        self.timestamp = data.header.stamp.secs  #setting timestamp here, because this topic should always exist.
        self._widget.label_13.setText(str(self.timestamp))

        self.motorheaderlist = []
        for i in range(len(data.status)):
            if data.status[i].level == 1:
                self.templist[int(data.status[i].hardware_id) - 101].append(
                    float(data.status[i].values[3].value))
                self.voltagelist[int(data.status[i].hardware_id) - 101].append(
                    float(data.status[i].values[1].value))
                if len(self.templist[i]) > 20:
                    self.templist[i].pop(0)
                if len(self.voltagelist[i]) > 20:
                    self.voltagelist[i].pop(0)
                if self.current_tab == 0:
                    if data.status[i].level == 1:
                        if not data.status[i].values[
                                2].value in self.motorheaderlist:
                            self.motorheaderlist.append(
                                data.status[i].values[2].value)
                        for j in range(0, len(self.motorheaderlist)):
                            if j < 10:
                                selected = self._widget.tableWidget
                                k = j
                            else:
                                selected = self._widget.tableWidget_2
                                k = j - 10
                            try:
                                if self.motorheaderlist[j] == data.status[
                                        i].values[2].value:
                                    selected.setItem(
                                        0, k,
                                        QTableWidgetItem(
                                            data.status[i].message))
                                    selected.setItem(
                                        1, k,
                                        QTableWidgetItem(
                                            str(
                                                round(
                                                    float(data.status[i].
                                                          values[3].value),
                                                    2))))
                                    selected.setItem(
                                        3, k,
                                        QTableWidgetItem(
                                            str(
                                                round(
                                                    float(data.status[i].
                                                          values[1].value),
                                                    2))))
                                    selected.setItem(
                                        4, k,
                                        QTableWidgetItem(
                                            data.status[i].values[0].value))
                            except IndexError:
                                rospy.logwarn(
                                    "Received a message that misses some information. Faulty message: "
                                    + data.status[i])

            self._widget.tableWidget.setHorizontalHeaderLabels(
                self.motorheaderlist)
            self._widget.tableWidget_2.setHorizontalHeaderLabels(
                self.motorheaderlist[10:])
            self._widget.tableWidget.reset()
            self._widget.tableWidget_2.reset()
            self._widget.tableWidget.setEditTriggers(
                QTableWidget.NoEditTriggers)

        self.tetrigger.emit()
        self.votrigger.emit()

    def set_motor_joint_states(self, data):
        if self.current_tab == 0:
            self.motorheaderlist = []
            for i in range(0, len(data.name)):
                self.torquelist[i].append(float(data.effort[i]))
                if not data.name[i] in self.motorheaderlist:
                    self.motorheaderlist.append(data.name[i])
                for j in range(0, len(self.motorheaderlist)):
                    if j < 10:
                        selected = self._widget.tableWidget
                        k = j
                    else:
                        selected = self._widget.tableWidget_2
                        k = j - 10
                    for j in self.motorheaderlist:
                        if j == data.name[i]:
                            selected.setItem(
                                2, k,
                                QTableWidgetItem(
                                    str(
                                        round(
                                            float(
                                                math.degrees(
                                                    data.position[i])), 2))))
                            selected.setItem(
                                5, k,
                                QTableWidgetItem(
                                    str(round(float(data.effort[i]), 2))))

            self._widget.tableWidget.setHorizontalHeaderLabels(
                self.motorheaderlist)
            self._widget.tableWidget_2.setHorizontalHeaderLabels(
                self.motorheaderlist[10:])

            self.totrigger.emit()

    def update_graph(self, graph, glist, cbox, number):
        """Updates the graph that displays the motors temperature"""
        if self.current_tab == number:
            graph.clear()
            graph.setXRange(-1, 21)
            for i in range(len(glist)):
                if cbox.currentText() == 'All' or cbox.currentIndex() - 1 == i:
                    path = pg.arrayToQPath(np.arange(len(glist[i])), glist[i])
                    item = QtGui.QGraphicsPathItem(path)
                    item.setPen(pg.mkPen(color=self.colorlist[i]))
                    graph.addItem(item)

    def make_Graphs(self):
        """Method to initialize the different plots.

        Creates a plot with grid and legend, then adds it to the coresponding layout.
        """
        self.tempplt = pg.plot()
        self.tempplt.setYRange(-1, 100)
        self.tempplt.showGrid(x=True, y=True)
        self.tempplt.addLegend()
        for i in range(0, 10):
            self.tempplt.plot(np.zeros(10),
                              np.zeros(10),
                              pen=self.colorlist[i],
                              name=self.motornames[i])
        self.tempplt.addLegend(offset=79)
        #creates a legend by plotting a single point for each motor, just so they show up in the legend.
        #Apparently you are supposed to do it that way...
        for i in range(10, 20):
            self.tempplt.plot(np.zeros(10),
                              np.zeros(10),
                              pen=self.colorlist[i],
                              name=self.motornames[i])
        self.layout_temp = QtGui.QHBoxLayout()
        self.combobox3 = QComboBox()
        self.combobox3.addItem('All')
        for i in self.motornames:
            self.combobox3.addItem(i)
        self._widget.Temperatur.setLayout(self.layout_temp)
        self.layout_temp.addWidget(self.tempplt)
        self.layout_temp.addWidget(self.combobox3)
        self.tempplt.win.hide()

        self.torqueplt = pg.plot()
        self.torqueplt.setYRange(-1, 2)
        self.torqueplt.showGrid(x=True, y=True)
        self.torqueplt.addLegend()
        for i in range(0, 10):
            self.torqueplt.plot(np.zeros(10),
                                np.zeros(10),
                                pen=self.colorlist[i],
                                name=self.motornames[i])
        self.torqueplt.addLegend(offset=79)
        for i in range(10, 20):
            self.torqueplt.plot(np.zeros(10),
                                np.zeros(10),
                                pen=self.colorlist[i],
                                name=self.motornames[i])
        self.layout_torque = QtGui.QHBoxLayout()
        self._widget.Torque.setLayout(self.layout_torque)
        self.layout_torque.addWidget(self.torqueplt)
        self.combobox = QComboBox()
        self.combobox.addItem('All')
        for i in self.motornames:
            self.combobox.addItem(i)
        self.layout_torque.addWidget(self.combobox)
        self.torqueplt.win.hide()

        self.voltageplt = pg.plot()
        self.voltageplt.setYRange(-1, 30)
        self.voltageplt.showGrid(x=True, y=True)
        self.voltageplt.addLegend()
        for i in range(0, 10):
            self.voltageplt.plot(np.zeros(10),
                                 np.zeros(10),
                                 pen=self.colorlist[i],
                                 name=self.motornames[i])
        self.voltageplt.addLegend(offset=79)
        for i in range(10, 20):
            self.voltageplt.plot(np.zeros(10),
                                 np.zeros(10),
                                 pen=self.colorlist[i],
                                 name=self.motornames[i])
        self.layout_voltage = QtGui.QHBoxLayout()
        self.combobox2 = QComboBox()
        self.combobox2.addItem('All')
        for i in self.motornames:
            self.combobox2.addItem(i)
        self._widget.Voltage.setLayout(self.layout_voltage)
        self.layout_voltage.addWidget(self.voltageplt)
        self.layout_voltage.addWidget(self.combobox2)
        self.voltageplt.win.hide()