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

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个舵机在头里)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容