美文网首页
悟空机器人驱动6(没有位姿传感器)

悟空机器人驱动6(没有位姿传感器)

作者: hydro | 来源:发表于2023-04-08 21:44 被阅读0次

    20230409 

    上位机程序,运行环境 python-jupyter lab

    # 继续去除非必要通信数据,

    import serial 

    arduino = serial.Serial('com4', 1000000)  # 打开com x串口,波特率9600

    #  布局  QGridLayout    from  https://realpython.com/python-pyqt-layout/

    # 小部件 QDial QSlider  from  https://blog.csdn.net/MeteorBZ/article/details/105803964

    #coding=utf-8

    import sys

    from PyQt5.QtCore import Qt

    from PyQt5.QtWidgets import (

        QApplication,

        QGridLayout,

        QWidget,

        QLCDNumber,

        QDial,

        QPushButton,

    )

    # int DEFAULTNUMBER = 2000  # debug错误语法

    DEFAULTNUMBER = 100

    class Example(QWidget):

        def __init__(self):

            super().__init__()

            self.setGeometry(30, 50, 800, 500)

            self.setWindowTitle('机器人关节控制')

            lcd5  = QLCDNumber(self)

            lcd5.display( DEFAULTNUMBER  )

            dial5 = QDial(self)

            dial5.setRange(5,250)

            dial5.setValue(DEFAULTNUMBER)

            dial5.valueChanged.connect(lcd5.display)

            dial5.valueChanged.connect(self.dial_changed) ##========================================

            ## <<<<< bug  旋钮的值174 可以.175报错: ValueError: byte must be in range(0, 256)

                ## <<<<< debug  命令 0x01 +  旋钮的值174 + 时间 0x50    = 0xFF, 再大 sumCHK溢出

            lcd6  = QLCDNumber(self)

            lcd6.display( DEFAULTNUMBER  )

            dial6 = QDial(self)

            dial6.setRange(10,200)

            dial6.setValue(DEFAULTNUMBER)

            dial6.valueChanged.connect(lcd6.display)

            lcd7  = QLCDNumber(self)

            lcd7.display( DEFAULTNUMBER  )

            dial7 = QDial(self)

            dial7.setRange(10,4000)

            dial7.setValue(DEFAULTNUMBER)

            dial7.valueChanged.connect(lcd7.display)

            lcd8  = QLCDNumber(self)

            lcd8.display( DEFAULTNUMBER  )

            dial8 = QDial(self)

            dial8.setRange(10,4000)

            dial8.setValue(DEFAULTNUMBER)

            dial8.valueChanged.connect(lcd8.display)

            lcd9  = QLCDNumber(self)

            lcd9.display( DEFAULTNUMBER  )

            dial9 = QDial(self)

            dial9.setRange(10,4000)

            dial9.setValue(DEFAULTNUMBER)

            dial9.valueChanged.connect(lcd9.display)

            lcd10  = QLCDNumber(self)

            lcd10.display( DEFAULTNUMBER  )

            dial10 = QDial(self)

            dial10.setRange(10,4000)

            dial10.setValue(DEFAULTNUMBER)

            dial10.valueChanged.connect(lcd10.display)

            lcd14 = QLCDNumber(self)

            lcd14.display( DEFAULTNUMBER  )

            dial14 = QDial(self)

            dial14.setRange(10,4000)

            dial14.setValue(DEFAULTNUMBER)

            dial14.valueChanged.connect(lcd14.display)

            layout = QGridLayout()

            layout.addWidget( lcd5, 0, 0)

            layout.addWidget( lcd6, 0, 1)

            layout.addWidget( lcd7, 0, 2)

            layout.addWidget( lcd8, 0, 3)

            layout.addWidget( lcd9, 0, 4)

            layout.addWidget(lcd10, 0, 5)

            layout.addWidget(lcd14, 0, 6)

            layout.addWidget( dial5, 1, 0)  #小周期总时间长度,可以超过大周期 #小周期在大周期里开始显示的时间

            layout.addWidget( dial6, 1, 1)

            layout.addWidget( dial7, 1, 2)   

            layout.addWidget( dial8, 1, 3)     

            layout.addWidget( dial9, 1, 4)     

            layout.addWidget(dial10, 1, 5)

            layout.addWidget(dial14, 1, 6)   

            layout.addWidget(QPushButton("右髋"), 2, 0)

            layout.addWidget(QPushButton("右膝"), 2, 1)

            layout.addWidget(QPushButton("右踝"), 2, 2)

            layout.addWidget(QPushButton("左髋"), 2, 3)

            layout.addWidget(QPushButton("左膝"), 2, 4)

            layout.addWidget(QPushButton("左踝"), 2, 5)

            layout.addWidget(QPushButton("腰  "), 2, 6)

            self.setLayout(layout)   

            self.show()

        def dial_changed(self, value):

            #  print(type(value)) # <class 'int'>

            # 构造数据包

            packet =  [0xFA, 0xAF, 0x0, 0x1,    value,0x50,0x0,0x0 ]

            #packet =bytearray( [0xFA, 0xAF, 0, 0x1,    value,0x50,0x0,0x0,    sumCHK,  0xED])

            # 向arduino串口发送数据包

            arduino.write(packet)    # 使用pyserial发送到arduino     

    '''

            layout.addWidget(QPushButton("Tm总长"), 1, 0)

            layout.addWidget(QPushButton("Tm相位"), 1, 1)

            layout.addWidget(QPushButton("Tm起"), 1, 2)

            layout.addWidget(QPushButton("Tm止"), 1, 3)

            layout.addWidget(QPushButton("接续"), 1, 4)

    '''       

    # 适用于Jupyter :使用下面退出 程序,有报错 :Warning: To exit: use 'exit', 'quit', or Ctrl-D.

    # https://www.jianshu.com/p/5a9bf7548fdb 

    if __name__ == '__main__':

        app = QApplication(sys.argv)

        app.aboutToQuit.connect(app.deleteLater)

        ex = Example()

        app.exec_()

    '''

    # 适用于 pycharm

    if __name__ == '__main__':

    app = QApplication(sys.argv)

        ex = Example()

        sys.exit(app.exec_())

    '''

    '''

    # 适用于??

    if __name__ == '__main__':

        app = QApplication(sys.argv)

        app.aboutToQuit.connect(app.deleteLater)

        ex = Example()

        sys.exit(app.exec_())

    '''   

    下位机程序 运行环境--arduino

    // todo bug 虚拟dail拨轮反复转动,串口会挂掉。 这个版本 , 在python上位机中, 精简通讯数据

    // 这个版本 ,  Serial.begin(1000000); 用于PC通信

    //  每次 if (Serial.available() > 0) { }  运行,  Serial.read()都会读入一个字节, 攒够9个输出到舵机。如果半中间读到0xFA,就重置指针,作为头。

    byte readSerialPort[10];                                                            // 构造数据包

    byte angle = 0x70;                                                                  //debug <<<<<<<<<<<<<<<<  正确的语法是byte,而不是 int

    byte sum  =0;                                                                        //debug <<<<<<<<<<<<<<<<  正确的语法是byte  //  计算校验字节,sum(byte 2--byte 7)

    byte SerialMemoPointer =0;

    void setup() {

      Serial.begin(1000000);    // 打开第一条串口,用于通信

      Serial1.begin(1000000);  // 打开第二条串口,用于控制舵机  <<<<<<<<<<<  debug  1MHz频率

    }

    void loop() {

      if (Serial.available() > 0) {                                  // 如果第一条串口有数据

          byte  incomingByte = Serial.read();

          if (  incomingByte == 0xFA    ){

              SerialMemoPointer = 0;                                      //    set 记录器的指针

          }

          readSerialPort[SerialMemoPointer] = incomingByte ;          //  记录 

          //Serial.print("I received: ");    Serial.println(incomingByte );  //  等于  Serial.print("I received: DEC");  Serial.println(incomingByte, DEC);

          //Serial.print("I received: HEX "); Serial.println(incomingByte, HEX);

          if (  SerialMemoPointer == 7  ){                          //    readSerialPort[] 已经填满

              OutPutToServo();                                            //    输出到舵机   

              SerialMemoPointer = 0;                                      //    set 记录器的指针

          }

          SerialMemoPointer ++;                                      //  set 记录器的指针  <<<<<<<<<<<<<<<<<<<<<< debug  这个加一必须放在尾部,不能在中间,否则ED字节读不到

        delay(10);                        //--------------------------------------------------------------------  todo 算短等待时间

      }

    }

    void  OutPutToServo(){

        sum  =0;                                //  计算校验字节,sum(byte 2--byte 7)

        for (int i = 2; i < 8; i++) {

            sum += readSerialPort[i];

            //Serial.print("sum = ");Serial.println(sum, HEX);                //---------------------------------------------------------------

        }

        readSerialPort[8] = sum;

        readSerialPort[9] = 0xED;

        //Serial.print("sum = ");Serial.println(sum, HEX);                //---------------------------------------------------------------

        //Serial.print("END = ");Serial.println( readSerialPort[9], HEX);  //---------------------------------------------------------------

        //Serial.println("outPutToServo================================");

        for (int i = 0; i < 10; i++) {        // 发送数据包

            Serial1.write(readSerialPort[i]);      // 发送 字节数据

            //Serial.println(readSerialPort[i], HEX);

        }

    }

    控制设备 --去头的悟空躯体,12个舵机(悟空共14个舵机,另外的2个舵机在头里)

    相关文章

      网友评论

          本文标题:悟空机器人驱动6(没有位姿传感器)

          本文链接:https://www.haomeiwen.com/subject/ltsyrdtx.html