From 8a669dcbe85b443fbe5e96a8a9c72a89d09cac0a Mon Sep 17 00:00:00 2001 From: liang <2303335747@qq.com> Date: Sat, 26 Nov 2022 19:22:07 +0800 Subject: [PATCH] Create a new branch A1B1 --- CMakeLists.txt | 13 +- README.md | 4 +- example/changeID.cpp | 55 ++++++ example/main.cpp | 67 ++++--- include/CRC/crc32.h | 33 ++++ include/IOPort/IOPort.h | 15 +- include/crc/crc_ccitt.h | 67 ------- include/serialPort/SerialPort.h | 30 +-- include/serialPort/include/errorClass.h | 4 +- include/unitreeMotor/include/motor_msg.h | 224 +++++++++++++++-------- include/unitreeMotor/unitreeMotor.h | 136 ++++++++++---- lib/libUnitreeMotorSDK_M80106_Arm64.so | Bin 40936 -> 0 bytes lib/libUnitreeMotorSDK_M80106_Linux64.so | Bin 48536 -> 0 bytes lib/libunitreeMotorSDK_Linux64.so | Bin 0 -> 54944 bytes 14 files changed, 407 insertions(+), 241 deletions(-) create mode 100755 example/changeID.cpp create mode 100755 include/CRC/crc32.h delete mode 100644 include/crc/crc_ccitt.h delete mode 100755 lib/libUnitreeMotorSDK_M80106_Arm64.so delete mode 100755 lib/libUnitreeMotorSDK_M80106_Linux64.so create mode 100755 lib/libunitreeMotorSDK_Linux64.so diff --git a/CMakeLists.txt b/CMakeLists.txt index c840b11..54210d8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,13 @@ -cmake_minimum_required(VERSION 3.10.2) -project(UnitreeMotorSDK_M80106) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") +cmake_minimum_required(VERSION 2.8.3) +project(UnitreeMotorA1B1) + +include_directories( + /home/$ENV{USER}/unitree_actuator_sdk/include/ +) -include_directories("include/") link_directories( lib/ ) -#example add_executable(motorctrl example/main.cpp) -target_link_libraries(motorctrl libUnitreeMotorSDK_M80106_Linux64.so) +target_link_libraries(motorctrl libunitreeMotorSDK_Linux64.so) \ No newline at end of file diff --git a/README.md b/README.md index 5546500..45b6569 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ### Notice -support motor: GO-M8010-6 motor +support motor: A1 motor、 B1 motor -not support motor: A1 motor、 B1 motor (Check A1B1 branch for support) +not support motor: GO-M8010-6 motor (Check GO-M8010-6 branch for support) ### Build ```bash diff --git a/example/changeID.cpp b/example/changeID.cpp new file mode 100755 index 0000000..cc09380 --- /dev/null +++ b/example/changeID.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include "serialPort/SerialPort.h" + +#define BroadAllMotorID 0xBB +#define MotorPulsator 11 + +int main(){ + char serial_name[100]; + + MOTOR_send motor_s; + MOTOR_recv motor_r; + + motor_s.motorType = MotorType::B1; // set the motor type, A1 or B1 + motor_r.motorType = motor_s.motorType; + + printf("Please input the name of serial port.(e.g. Linux:/dev/ttyUSB0, Windows:\\\\.\\COM3)\n"); + scanf("%s",serial_name); + printf("The serial port is %s\n", serial_name); + + memset(static_cast(&motor_s), 0, sizeof(motor_s)); + motor_s.id = BroadAllMotorID; + motor_s.mode = 10; + modify_data(&motor_s); + // printf("The motor ID is: %X\n", motor_s.motor_send_data.head.motorID); + + //进入伺服模式 + SerialPort serial(serial_name); // set the serial port name + serial.send((uint8_t*)&(motor_s.motor_send_data), motor_s.hex_len); + + usleep(100000); //sleep 0.1s + + //进入拨轮模式(修改ID) + motor_s.mode = MotorPulsator; + modify_data(&motor_s); + serial.send((uint8_t*)&(motor_s.motor_send_data), motor_s.hex_len); + + printf("Please turn the motor.\n"); + printf("One time: id=0; Two times: id=1, Three times: id=2\n"); + printf("ID can only be 0, 1, 2\n"); + printf("Once finished, press 'a'\n"); + + // int c; + while(getchar() != (int)'a'); + printf("Turn finished\n"); + + //保存ID + motor_s.mode = 0; + modify_data(&motor_s); + serial.send((uint8_t*)&(motor_s.motor_send_data), motor_s.hex_len); + + return 0; +} diff --git a/example/main.cpp b/example/main.cpp index 513352c..4ab1bb5 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -1,36 +1,49 @@ #include "serialPort/SerialPort.h" -#include +#include -int main() { +int main(){ + // set the serial port name + SerialPort serial("/dev/ttyUSB0"); - SerialPort serial("/dev/ttyUSB0"); - MotorCmd cmd; - MotorData data; + // send message struct + MOTOR_send motor_run, motor_stop; + // receive message struct + MOTOR_recv motor_r; - while(true) { - cmd.motorType = MotorType::GO_M8010_6; - cmd.id = 0; - cmd.mode = 1; - cmd.K_P = 0.0; - cmd.K_W = 0.05; - cmd.Pos = 0.0; - cmd.W = 6.28*6.33; - cmd.T = 0.0; - serial.sendRecv(&cmd,&data); + // set the id of motor + motor_run.id = 0; + // set the motor type, A1 or B1 + motor_run.motorType = MotorType::A1; + motor_run.mode = 5; + motor_run.T = 0.0; + motor_run.W = 0.0; + motor_run.Pos = 0.0; + motor_run.K_P = 0.0; + motor_run.K_W = 0.0; - if(data.correct == true) - { - std::cout << std::endl; - std::cout << "motor.Pos: " << data.Pos << " rad" << std::endl; - std::cout << "motor.Temp: " << data.Temp << " ℃" << std::endl; - std::cout << "motor.W: " << data.W << " rad/s"< + +inline uint32_t crc32_core(uint32_t* ptr, uint32_t len){ + uint32_t xbit = 0; + uint32_t data = 0; + uint32_t CRC32 = 0xFFFFFFFF; + const uint32_t dwPolynomial = 0x04c11db7; + for (uint32_t i = 0; i < len; i++) + { + xbit = 1 << 31; + data = ptr[i]; + for (uint32_t bits = 0; bits < 32; bits++) + { + if (CRC32 & 0x80000000) + { + CRC32 <<= 1; + CRC32 ^= dwPolynomial; + } + else + CRC32 <<= 1; + if (data & xbit) + CRC32 ^= dwPolynomial; + + xbit >>= 1; + } + } + return CRC32; +} + +#endif // CRC32_H \ No newline at end of file diff --git a/include/IOPort/IOPort.h b/include/IOPort/IOPort.h index 173b617..4b5aaa4 100755 --- a/include/IOPort/IOPort.h +++ b/include/IOPort/IOPort.h @@ -1,5 +1,5 @@ -#ifndef __IOPORT_H -#define __IOPORT_H +#ifndef BIANLIB_IOPORT_H +#define BIANLIB_IOPORT_H #include #include @@ -13,20 +13,16 @@ enum class BlockYN{ class IOPort{ public: - IOPort(BlockYN blockYN, size_t recvLength, size_t timeOutUs){ - resetIO(blockYN, recvLength, timeOutUs); - } + IOPort(){} virtual ~IOPort(){} virtual size_t send(uint8_t *sendMsg, size_t sendLength) = 0; - virtual size_t recv(uint8_t *recvMsg, size_t recvLength) = 0; virtual size_t recv(uint8_t *recvMsg) = 0; - virtual bool sendRecv(std::vector &sendVec, std::vector &recvVec) = 0; + virtual bool sendRecv(std::vector &sendVec, std::vector &recvVec) = 0; void resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs); protected: BlockYN _blockYN = BlockYN::NO; size_t _recvLength; timeval _timeout; - timeval _timeoutSaved; }; inline void IOPort::resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs){ @@ -34,8 +30,7 @@ inline void IOPort::resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs _recvLength = recvLength; _timeout.tv_sec = timeOutUs / 1000000; _timeout.tv_usec = timeOutUs % 1000000; - _timeoutSaved = _timeout; } -#endif // z1_lib_IOPORT_H \ No newline at end of file +#endif // BIANLIB_IOPORT_H \ No newline at end of file diff --git a/include/crc/crc_ccitt.h b/include/crc/crc_ccitt.h deleted file mode 100644 index 2930e24..0000000 --- a/include/crc/crc_ccitt.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __CRC_CCITT_H -#define __CRC_CCITT_H - -/* - * This mysterious table is just the CRC of each possible byte. It can be - * computed using the standard bit-at-a-time methods. The polynomial can - * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. - * Add the implicit x^16, and you have the standard CRC-CCITT. - * https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/lib/crc-ccitt.c - */ -uint16_t const crc_ccitt_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - - -static uint16_t crc_ccitt_byte(uint16_t crc, const uint8_t c) -{ - return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff]; -} - -/** - * crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data - * buffer - * @crc: previous CRC value - * @buffer: data pointer - * @len: number of bytes in the buffer - */ -inline uint16_t crc_ccitt(uint16_t crc, uint8_t const *buffer, size_t len) -{ - while (len--) - crc = crc_ccitt_byte(crc, *buffer++); - return crc; -} - - -#endif diff --git a/include/serialPort/SerialPort.h b/include/serialPort/SerialPort.h index 7bfe5e9..880e4c4 100755 --- a/include/serialPort/SerialPort.h +++ b/include/serialPort/SerialPort.h @@ -1,18 +1,20 @@ -#ifndef __SERIALPORT_H -#define __SERIALPORT_H +#ifndef SERIALPORT_H +#define SERIALPORT_H /* High frequency serial communication, Not that common, but useful for motor communication. */ #include +// #include #include + #include #include #include #include #include -#include +#include //serial驱动相关 #include #include @@ -47,20 +49,22 @@ enum class flowcontrol_t{ flowcontrol_hardware }; + + class SerialPort : public IOPort{ public: SerialPort(const std::string &portName, - size_t recvLength = 16, - uint32_t baudrate = 4000000, - size_t timeOutUs = 20000, + size_t recvLength = 78, + uint32_t baudrate = 4800000, + size_t timeOutUs = 20000, BlockYN blockYN = BlockYN::NO, bytesize_t bytesize = bytesize_t::eightbits, parity_t parity = parity_t::parity_none, stopbits_t stopbits = stopbits_t::stopbits_one, flowcontrol_t flowcontrol = flowcontrol_t::flowcontrol_none); virtual ~SerialPort(); - void resetSerial(size_t recvLength = 16, - uint32_t baudrate = 4000000, + void resetSerial(size_t recvLength = 78, + uint32_t baudrate = 4800000, size_t timeOutUs = 20000, BlockYN blockYN = BlockYN::NO, bytesize_t bytesize = bytesize_t::eightbits, @@ -68,17 +72,16 @@ public: stopbits_t stopbits = stopbits_t::stopbits_one, flowcontrol_t flowcontrol = flowcontrol_t::flowcontrol_none); size_t send(uint8_t *sendMsg, size_t sendLength); - size_t recv(uint8_t *recvMsg, size_t recvLength); size_t recv(uint8_t *recvMsg); bool sendRecv(uint8_t *sendMsg, uint8_t *recvMsg, size_t sendLength); - bool sendRecv(MotorCmd* sendMsg, MotorData* recvMsg); - bool sendRecv(std::vector &sendVec, std::vector &recvVec); + bool sendRecv(MOTOR_send* sendMsg, MOTOR_recv* recvMsg); + bool sendRecv(std::vector &sendVec, std::vector &recvVec); private: void _open(); void _set(); void _close(); - size_t _nonBlockRecv(uint8_t *recvMsg, size_t readLen); + size_t _nonBlockRecv(uint8_t *recvMsg, size_t readLen); // only visual in pubSDK std::string _portName; uint32_t _baudrate; bytesize_t _bytesize; @@ -87,12 +90,11 @@ private: flowcontrol_t _flowcontrol; bool _xonxoff; bool _rtscts; + int _fd; fd_set _rSet; }; - - #endif // SERIALPORT_H \ No newline at end of file diff --git a/include/serialPort/include/errorClass.h b/include/serialPort/include/errorClass.h index 48313c3..92af50b 100755 --- a/include/serialPort/include/errorClass.h +++ b/include/serialPort/include/errorClass.h @@ -1,5 +1,5 @@ -#ifndef __ERRORCLASS_H -#define __ERRORCLASS_H +#ifndef ERRORCLASS_H +#define ERRORCLASS_H #include #include diff --git a/include/unitreeMotor/include/motor_msg.h b/include/unitreeMotor/include/motor_msg.h index ef57ff0..168b589 100755 --- a/include/unitreeMotor/include/motor_msg.h +++ b/include/unitreeMotor/include/motor_msg.h @@ -1,90 +1,162 @@ -#ifndef __MOTOR_MSG_H -#define __MOTOR_MSG_H +#ifndef MOTOR_MSG +#define MOTOR_MSG #include -#define CRC_SIZE 2 -#define CTRL_DAT_SIZE sizeof(ControlData_t) - CRC_SIZE -#define DATA_DAT_SIZE sizeof(MotorData_t) - CRC_SIZE +typedef int16_t q15_t; #pragma pack(1) -/** - * @brief 电机模式控制信息 - * - */ -typedef struct -{ - uint8_t id :4; // 电机ID: 0,1...,14 15表示向所有电机广播数据(此时无返回) - uint8_t status :3; // 工作模式: 0.锁定 1.FOC闭环 2.编码器校准 3.保留 - uint8_t none :1; // 保留位 -} RIS_Mode_t; // 控制模式 1Byte +// 发送用单个数据数据结构 +typedef union{ + int32_t L; + uint8_t u8[4]; + uint16_t u16[2]; + uint32_t u32; + float F; +}COMData32; -/** - * @brief 电机状态控制信息 - * - */ -typedef struct -{ - int16_t tor_des; // 期望关节输出扭矩 unit: N.m (q8) - int16_t spd_des; // 期望关节输出速度 unit: rad/s (q8) - int32_t pos_des; // 期望关节输出位置 unit: rad (q15) - uint16_t k_pos; // 期望关节刚度系数 unit: 0.0-1.0 (q15) - uint16_t k_spd; // 期望关节阻尼系数 unit: 0.0-1.0 (q15) +typedef struct { + // 定义 数据包头 + unsigned char start[2]; // 包头 + unsigned char motorID; // 电机ID 0,1,2,3 ... 0xBB 表示向所有电机广播(此时无返回) + unsigned char reserved; +}COMHead; + +#pragma pack() + +#pragma pack(1) + +typedef struct { + + uint8_t fan_d; // 关节上的散热风扇转速 + uint8_t Fmusic; // 电机发声频率 /64*1000 15.625f 频率分度 + uint8_t Hmusic; // 电机发声强度 推荐值4 声音强度 0.1 分度 + uint8_t reserved4; + + uint8_t FRGB[4]; // 足端LED + +}LowHzMotorCmd; + +typedef struct { // 以 4个字节一组排列 ,不然编译器会凑整 + // 定义 数据 + uint8_t mode; // 关节模式选择 + uint8_t ModifyBit; // 电机控制参数修改位 + uint8_t ReadBit; // 电机控制参数发送位 + uint8_t reserved; + + COMData32 Modify; // 电机参数修改 的数据 + //实际给FOC的指令力矩为: + //K_P*delta_Pos + K_W*delta_W + T + q15_t T; // 期望关节的输出力矩(电机本身的力矩)x256, 7 + 8 描述 + q15_t W; // 期望关节速度 (电机本身的速度) x128, 8 + 7描述 + int32_t Pos; // 期望关节位置 x 16384/6.2832, 14位编码器(主控0点修正,电机关节还是以编码器0点为准) + + q15_t K_P; // 关节刚度系数 x2048 4+11 描述 + q15_t K_W; // 关节速度系数 x1024 5+10 描述 + + uint8_t LowHzMotorCmdIndex; // 电机低频率控制命令的索引, 0-7, 分别代表LowHzMotorCmd中的8个字节 + uint8_t LowHzMotorCmdByte; // 电机低频率控制命令的字节 + + COMData32 Res[1]; // 通讯 保留字节 用于实现别的一些通讯内容 + +}MasterComdV3; // 加上数据包的包头 和CRC 34字节 + +typedef struct { + // 定义 电机控制命令数据包 + COMHead head; + MasterComdV3 Mdata; + COMData32 CRCdata; +}MasterComdDataV3;//返回数据 + +// typedef struct { +// // 定义 总得485 数据包 + +// MasterComdData M1; +// MasterComdData M2; +// MasterComdData M3; + +// }DMA485TxDataV3; + +#pragma pack() + +#pragma pack(1) + +typedef struct { // 以 4个字节一组排列 ,不然编译器会凑整 + // 定义 数据 + uint8_t mode; // 当前关节模式 + uint8_t ReadBit; // 电机控制参数修改 是否成功位 + int8_t Temp; // 电机当前平均温度 + uint8_t MError; // 电机错误 标识 + + COMData32 Read; // 读取的当前 电机 的控制数据 + int16_t T; // 当前实际电机输出力矩 7 + 8 描述 + + int16_t W; // 当前实际电机速度(高速) 8 + 7 描述 + float LW; // 当前实际电机速度(低速) + + int16_t W2; // 当前实际关节速度(高速) 8 + 7 描述 + float LW2; // 当前实际关节速度(低速) + + int16_t Acc; // 电机转子加速度 15+0 描述 惯量较小 + int16_t OutAcc; // 输出轴加速度 12+3 描述 惯量较大 + + int32_t Pos; // 当前电机位置(主控0点修正,电机关节还是以编码器0点为准) + int32_t Pos2; // 关节编码器位置(输出编码器) + + int16_t gyro[3]; // 电机驱动板6轴传感器数据 + int16_t acc[3]; + + // 力传感器的数据 + int16_t Fgyro[3]; // + int16_t Facc[3]; + int16_t Fmag[3]; + uint8_t Ftemp; // 8位表示的温度 7位(-28~100度) 1位0.5度分辨率 -} RIS_Comd_t; // 控制参数 12Byte + int16_t Force16; // 力传感器高16位数据 + int8_t Force8; // 力传感器低8位数据 + + uint8_t FError; // 足端传感器错误标识 + + int8_t Res[1]; // 通讯 保留字节 + +}ServoComdV3; // 加上数据包的包头 和CRC 78字节(4+70+4) -/** - * @brief 电机状态反馈信息 - * - */ -typedef struct -{ - int16_t torque; // 实际关节输出扭矩 unit: N.m (q8) - int16_t speed; // 实际关节输出速度 unit: rad/s (q8) - int32_t pos; // 实际关节输出位置 unit: W (q15) - int8_t temp; // 电机温度: -50~127°C 90°C时触发温度保护 - uint8_t MError :3; // 电机错误标识: 0.正常 1.过热 2.过流 3.过压 4.编码器故障 5-7.保留 - uint16_t force :12; // 足端气压传感器数据 12bit (0-4095) - uint8_t none :1; // 保留位 -} RIS_Fbk_t; // 状态数据 11Byte +typedef struct { + // 定义 电机控制命令数据包 + COMHead head; + ServoComdV3 Mdata; + + COMData32 CRCdata; + +}ServoComdDataV3; //发送数据 + +// typedef struct { +// // 定义 总的485 接受数据包 + +// ServoComdDataV3 M[3]; +// // uint8_t nullbyte1; + +// }DMA485RxDataV3; #pragma pack() -#pragma pack(1) - -/** - * @brief 控制数据包格式 - * - */ -typedef struct -{ - uint8_t head[2]; // 包头 2Byte - RIS_Mode_t mode; // 电机控制模式 1Byte - RIS_Comd_t comd; // 电机期望数据 12Byte - uint16_t CRC16; // CRC 2Byte - -} ControlData_t; // 主机控制命令 17Byte - -/** - * @brief 电机反馈数据包格式 - * - */ -typedef struct -{ - uint8_t head[2]; // 包头 2Byte - RIS_Mode_t mode; // 电机控制模式 1Byte - RIS_Fbk_t fbk; // 电机反馈数据 11Byte - uint16_t CRC16; // CRC 2Byte - -} MotorData_t; // 电机返回数据 16Byte - -#pragma pack() - -#endif - - - - +// 00 00 00 00 00 +// 00 00 00 00 00 +// 00 00 00 00 00 +// 00 00 00 +// 数据包默认初始化 +// 主机发送的数据包 +/* + Tx485Data[_FR][i].head.start[0] = 0xFE ; Tx485Data[_FR][i].head.start[1] = 0xEE; // 数据包头 + Tx485Data[_FR][i].Mdata.ModifyBit = 0xFF; Tx485Data[_FR][i].Mdata.mode = 0; // 默认不修改数据 和 电机的默认工作模式 + Tx485Data[_FR][i].head.motorID = i; 0 // 目标电机标号 + Tx485Data[_FR][i].Mdata.T = 0.0f; // 默认目标关节输出力矩 motor1.Extra_Torque = motorRxData[1].Mdata.T*0.390625f; // N.M 转化为 N.CM IQ8描述 + Tx485Data[_FR][i].Mdata.Pos = 0x7FE95C80; // 默认目标关节位置 不启用位置环 14位分辨率 + Tx485Data[_FR][i].Mdata.W = 16000.0f; // 默认目标关节速度 不启用速度环 1+8+7描述 motor1.Target_Speed = motorRxData[1].Mdata.W*0.0078125f; // 单位 rad/s IQ7描述 + Tx485Data[_FR][i].Mdata.K_P = (q15_t)(0.6f*(1<<11)); // 默认关节刚度系数 4+11 描述 motor1.K_Pos = ((float)motorRxData[1].Mdata.K_P)/(1<<11); // 描述刚度的通讯数据格式 4+11 + Tx485Data[_FR][i].Mdata.K_W = (q15_t)(1.0f*(1<<10)); // 默认关节速度系数 5+10 描述 motor1.K_Speed = ((float)motorRxData[1].Mdata.K_W)/(1<<10); // 描述阻尼的通讯数据格式 5+10 +*/ +#endif \ No newline at end of file diff --git a/include/unitreeMotor/unitreeMotor.h b/include/unitreeMotor/unitreeMotor.h index d6deb87..8964299 100755 --- a/include/unitreeMotor/unitreeMotor.h +++ b/include/unitreeMotor/unitreeMotor.h @@ -1,54 +1,116 @@ -#ifndef __UNITREEMOTOR_H -#define __UNITREEMOTOR_H +#ifndef UNITREEMOTOR_H +#define UNITREEMOTOR_H #include "unitreeMotor/include/motor_msg.h" // 电机通信协议 +#include "CRC/crc32.h" // CRC32校验算法 #include #include enum class MotorType{ - GO_M8010_6, + A1, // 4.8M baudrate, K_W x1024 + B1 // 6.0M baudrate, K_W x512 }; -struct MotorCmd{ +struct MOTOR_send{ // 定义 发送格式化数据 - public: - MotorType motorType = MotorType::GO_M8010_6; - int hex_len = 17; - unsigned short id; // 电机ID 0~14 15:广播ID 此时电机无返回 - unsigned short mode; // 电机模式 0:刹车 1:FOC闭环 2:电机标定(发送后等待5sec,期间禁止给电机发送消息) - float T; // 期望关节的输出力矩(电机转子转矩 N.m) 范围: ±127.99 - float W; // 期望关节速度(电机转子转速 rad/s) ±804.00 - float Pos; // 期望关节位置(电机转子位置 rad) ±411774 - float K_P; // 关节刚度系数 0~25.599 - float K_W; // 关节速度系数 0~25.599 - void modify_data(MotorCmd* motor_s); - uint8_t* get_motor_send_data(); - - private: - ControlData_t motor_send_data; //电机控制数据结构体,详见motor_msg.h + MasterComdDataV3 motor_send_data; //电机控制数据结构体,详见motor_msg.h + MotorType motorType = MotorType::A1; + int hex_len = 34; //发送的16进制命令数组长度, 34 + // long long send_time; //发送该命令的时间, 微秒(us) + // 待发送的各项数据 + unsigned short id; //电机ID,0xBB代表全部电机 + unsigned short mode; //0:空闲, 5:开环转动, 10:闭环FOC控制 + //实际给FOC的指令力矩为: + //K_P*delta_Pos + K_W*delta_W + T + float T; //期望关节的输出力矩(电机本身的力矩)(Nm) + float W; //期望关节速度(电机本身的速度)(rad/s) + float Pos; //期望关节位置(rad) + float K_P; //关节刚度系数 + float K_W; //关节速度系数 + COMData32 Res; // 通讯 保留字节 用于实现别的一些通讯内容 }; -struct MotorData{ - // 定义 接收数据 - public: - MotorType motorType = MotorType::GO_M8010_6; - int hex_len = 16; // 接收的命令长度: 16Byte - bool correct = false; // 接收数据是否完整(true完整,false不完整或断联) - unsigned char motor_id; // 电机ID 0~14 15:广播ID 此时电机无返回 - unsigned char mode; // 电机模式 0:刹车 1:FOC闭环 2:电机标定 - int Temp; // 温度 -50~127 ℃ - int MError; // 错误标志 0.正常 1.过热 2.过流 3.过压 4.编码器故障 - float T; // 关节的输出力矩(电机转子转矩 N.m) 范围: ±127.99 - float W; // 关节速度(电机转子转速 rad/s) ±804.00 - float Pos; // 关节位置(电机转子位置 rad) ±411774 - int footForce; // 足端气压传感器接口 ADC原始值 - bool extract_data(MotorData* motor_r); - uint8_t* get_motor_recv_data(); +struct MOTOR_recv{ + // 定义 接收数据 + ServoComdDataV3 motor_recv_data; //电机接收数据结构体,详见motor_msg.h + MotorType motorType = MotorType::A1; + int hex_len = 78; //接收的16进制命令数组长度, 78 + // long long resv_time; //接收该命令的时间, 微秒(us) + bool correct = false; //接收数据是否完整(true完整,false不完整) + //解读得出的电机数据 + unsigned char motor_id; //电机ID + unsigned char mode; //0:空闲, 5:开环转动, 10:闭环FOC控制 + int Temp; //温度 + unsigned char MError; //错误码 - private: - MotorData_t motor_recv_data; //电机接收数据结构体,详见motor_msg.h + float T; // 当前实际电机输出力矩 + float W; // 当前实际电机速度(高速) + float LW; // 当前实际电机速度(低速) + int Acc; // 电机转子加速度 + float Pos; // 当前电机位置(主控0点修正,电机关节还是以编码器0点为准) + float gyro[3]; // 电机驱动板6轴传感器数据 + float acc[3]; }; +inline void modify_data(MOTOR_send* motor_s){ + motor_s->hex_len = 34; + motor_s->motor_send_data.head.start[0] = 0xFE; + motor_s->motor_send_data.head.start[1] = 0xEE; + motor_s->motor_send_data.head.motorID = motor_s->id; + motor_s->motor_send_data.head.reserved = 0x0; + motor_s->motor_send_data.Mdata.mode = motor_s->mode; + motor_s->motor_send_data.Mdata.ModifyBit = 0xFF; + motor_s->motor_send_data.Mdata.ReadBit = 0x0; + motor_s->motor_send_data.Mdata.reserved = 0x0; + motor_s->motor_send_data.Mdata.Modify.L = 0; + motor_s->motor_send_data.Mdata.T = motor_s->T*256; + motor_s->motor_send_data.Mdata.W = motor_s->W*128; + motor_s->motor_send_data.Mdata.Pos = (int)((motor_s->Pos/6.2832)*16384.0); + motor_s->motor_send_data.Mdata.K_P = motor_s->K_P*2048; + + if(motor_s->motorType == MotorType::A1){ + motor_s->motor_send_data.Mdata.K_W = motor_s->K_W*1024; + } + else if(motor_s->motorType == MotorType::B1){ + motor_s->motor_send_data.Mdata.K_W = motor_s->K_W*512; + } + + motor_s->motor_send_data.Mdata.LowHzMotorCmdIndex = 0; + motor_s->motor_send_data.Mdata.LowHzMotorCmdByte = 0; + motor_s->motor_send_data.Mdata.Res[0] = motor_s->Res; + motor_s->motor_send_data.CRCdata.u32 = crc32_core((uint32_t*)(&(motor_s->motor_send_data)), 7); +} + +inline bool extract_data(MOTOR_recv* motor_r){ + if(motor_r->motor_recv_data.CRCdata.u32 != + crc32_core((uint32_t*)(&(motor_r->motor_recv_data)), 18)){ + std::cout << "[WARNING] Receive data CRC error" << std::endl; + motor_r->correct = false; + return motor_r->correct; + }else{ + motor_r->motor_id = motor_r->motor_recv_data.head.motorID; + motor_r->mode = motor_r->motor_recv_data.Mdata.mode; + motor_r->Temp = motor_r->motor_recv_data.Mdata.Temp; + motor_r->MError = motor_r->motor_recv_data.Mdata.MError; + motor_r->T = ((float)motor_r->motor_recv_data.Mdata.T) / 256; + motor_r->W = ((float)motor_r->motor_recv_data.Mdata.W) / 128; + motor_r->LW = motor_r->motor_recv_data.Mdata.LW; + + motor_r->Acc = (int)motor_r->motor_recv_data.Mdata.Acc; + motor_r->Pos = 6.2832*((float)motor_r->motor_recv_data.Mdata.Pos) / 16384; + + motor_r->gyro[0] = ((float)motor_r->motor_recv_data.Mdata.gyro[0]) * 0.00107993176; + motor_r->gyro[1] = ((float)motor_r->motor_recv_data.Mdata.gyro[1]) * 0.00107993176; + motor_r->gyro[2] = ((float)motor_r->motor_recv_data.Mdata.gyro[2]) * 0.00107993176; + + motor_r->acc[0] = ((float)motor_r->motor_recv_data.Mdata.acc[0]) * 0.0023911132; + motor_r->acc[1] = ((float)motor_r->motor_recv_data.Mdata.acc[1]) * 0.0023911132; + motor_r->acc[2] = ((float)motor_r->motor_recv_data.Mdata.acc[2]) * 0.0023911132; + + motor_r->correct = true; + return motor_r->correct; + } +} #endif // UNITREEMOTOR_H \ No newline at end of file diff --git a/lib/libUnitreeMotorSDK_M80106_Arm64.so b/lib/libUnitreeMotorSDK_M80106_Arm64.so deleted file mode 100755 index 576a40a1c467323df7d31ce4fc9714180588c828..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40936 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℘N@B@W$#h&0~Pu< z1wTl^A5ideZJV+WD)_+){SgI!iGpue@D2rkT)_`j@Fx}gFa>{3!CMqO6a9kxf3|{; zQSkJxf;{>vc&9`nO;Yey1#eOCBNY5-1wT^3rz&_&!B0`}mnwKo!H-h#GZg%21)s0r zrz!aP3Vw`&w<~xtdCLCn)%x3SK;7;JLdLym;iq@p}~fWQ9+gg1>8|N9=rVA@x+Sz8Z(W8BK68K#h4lnw4y035NHH{YIu(yU; zOmE5)dAlw$YQDZk#`8EF4LDhW;{azVaBslH3Y-AAL4o@N-l4#Q0Pj`cp@2ITI2o|f z&{hAXfRhz?EZ{5!P61r3z!LyBDDY&!I~4dzzNv_8+fDsijLduJ5b~)^`!LOCkE8OM@4;yH#VW>%9x`ef2F5Zl|4ZD& z*zQhKVoQhV;+8MI^>1;2j+cpMzH7=XQ%)6THlOLI`7W&3FJsh6X1Szs0{Bx*y0GF8 zy1YG^?`g!Qy5txx!!MBE0a=<5%TD#wd^?bLVa48^S#3QU*~#g?EWdw1*z#F=`CGoD zJnA1nyxFnoJ`HX7HDHRNz#$~YG(LpXiWGC}6K&LH&|2S{?sI_lB=pA+SHsa;8GAMP z{K~_b@vGKb&u4CY3G|SCL)P)>zG7b17$_S~e!Fo-hGt-sxNQ5U`@AT_Wjd$%UV(m( zpj{T`EwCG7GDt6^6Ou#5_xFTeBrNsIs*)k>%z4emzz5z07*F{CX<$Er6`U%q$JMDzckdy1iCw?Sv0@z!%pe zFVyc0Xrs0LlE&R+iyq!Xo8Ox5YX|*q&^EzmnfK;%SV>raalPi7gnrW0sby$Jmi|!h z%nUDRCxhe&wZ9jFJk+>mMT7O+3Thm$lP z?h#I~3;rUa(bzR_8HTWgV<@u&^tylO{n-?w+mGya=0;=lSI|G{d!?DxSfW@_B4pXe zSb96!&tEe36W1rA{YCL?w-@bi ziec%i(EfJNe|5pXA8PP8eobaQYW#1)%wp4?&|k@kq29ULG+I#XkWK|?Js)C z$ky*LvRBFHo=5&Bz%LpTPqh2|MbARsz0ux7y4{8~zQyg;zhwsK$j0ra{w){d`YZ4= z8U($c z*U~r0FW%(3zPRNxv{~v(_Kh>}4eA?M(&T-k4YY31J&RNKjRCw5wg4vGOZ_zfCcR4E zRO|0F4QM%OGPOt?#a5zy9c6YvXI|JZw9jZ84aD0pHbb%;Ai%8{-RZ| zbEoh#3-X@<>^EL~!h6h+77OSW;*@%tg6n&P&ottid?sA`(T*UW z`3z+?gZ{#b7n%`2POj0$bAQoezNv-c2KOEK48?37JDB-IrWx@cv6#m2W|XHf;UOa{ za-v@N;Yp@l-B{dLk5gFlEGmxEe54ohLF%`5#HbJnQ;b?Sw^yB>`v`*?nWJ|I^1NC*5+_;h3vR}(jP^TU3(PMnS z_5IN24;$HTJN&pE{lXz){0ry(Tcms)+y?zxQc<=zf(`842D&^Hw?9XjbZQ^;IqgE% z{A3m6qP}Z=V!H1X<~d{wE9Pa8)t5uE4b^;(WJBXH=nl3nlH>Y?^Zo(yT8{B@JePd_ z1ey7mE#?9zQRc#m=lPuKtkcvCWuM%Nll&m*FVlS#7y3g-GzL%~c`G@&u`lLvqyvic zw}Rh3oK27^)8Z{?qU&1LN@J}7u>@n)76ZdrgtFK4Wi=h}l@7!%>L*6C_fR|Nz0j8d z;fV+N6WQ&I)6hs|UquljgJ)1ehZFu2&uYAvu%clxNc$s&JvA%*DV0s~ zmTIl`{%q2*8$n+`Fu_}_wKkw!=Z&nD%C;lV>gk{0U8J>YNo*3kV|BtBwDTD9AN(s@ zKD?eKc*XqB0J)B$jQ<0+{FKw!cqe4h^ZK>CwE7o^EJAno%b~l+Nk{!A+|!?>cRbEo zC0z&T`U|?Y6!@H&^S%B}mycXn@tPjjymuE^j7_yGjcjrI5LQ%9@$|^nf~F`P=N-g~ zFn|{^%c_E=9)fNFE6T&X)iJl=S}U7U7wT^qSwp<)M4k(Ib z7x}!kzJG$r;w><-owZhG8q1EO4&n{nn7j=IS-??W@uDwW1$i3K_f63a3GL63T&6gy zdB_CvZx*w6Q2W!YmD)lwu0p*=^d$z~YnU-^I5SM3K1F=SfrghuUrNIDVWC4auIohG z4Y)28`u_G?(1`1AaD7V9oWpgU@UJt37uR3nx=`@^9M>j$SNo!=ZnW9Tk|vnwnn8ZZ z@fGNv7UetXTGa6Yt~ZLh-=k~6_Z?hY%}Eoeu8E@D8@TQ#XkRD1;PD!+S3i}R5#?{WaNuA@o1#5wCpNBE&VIv>!HTa1MxNu{Vi{g!_V{e!`ZddED=ymKJ>@9EuPvZ&0 zebH`|qcMoa7AqUsSRGVXzm}{c82{R*`(^^)DdY+r=cs)&&b`9Zel62ME5|vShw=Fb z?m1o(`PU$y=A%UOrI6!pRSx^e#<`%OIXlU?Ud?M7(MbGhO#B$EF5-zoS?UA=_+zUPQ9l`TzofZfne+IUG$$ka zxEX5?@$ntk-dhiB`^3=nCC%N|VUEJi7aTr5%3Qe=^TT4Jp_y%n+h$K-zA;Zu_qpO& zYso#C%_a93o5y6b#^yUr=hDrZZ|P9xn}YkqVWz~#*(*%v!8Pp36K15$$tb79QmFb~aOm+YL|vD(nM8*6yO%F?HheU~j@t(K_xDvMW} z)A2CY(l=;x?0avYdK2_P`HPUM^QYsZaw_E4g=00&^## zJB|BFM)y24e}a#aUeB70W6zn)V~>xDs@w@(yn^$S@zIr^AU&~Kdx7TR6#MOnqr;eS zaU0^XZ#eVa3wuysYJks9ejEL!X(ZaxzhyY;ZNq$4zrX0u*A%|$q2KFiSev3Xh0&xt zl$jBgSap1u_o^Le3EEEjEsGjbRR*2G}-Tb{cNmyY2X>+{#S&$0y^bRXTcOz2Kl}8-CZ)dKU9n2YiI=abd-Qou;p84XS_3 z1=P0}a(dB@(EDljP4NBX8_>HQ^S5CvYOxjf(00tphOy|yFX5iqj`407>#^8@Ylq>| zp>~W>(AnY+^npX<_o#>FhIIO~4X2in_`3mdh~~2#c^`bJy-uWbuR?wM4O}~;y|`bc{;sd{%%b{+uv#nTUYlW`M6BID zgL|1(#iP(?a8Cld=RxC0(3aEn&v8w@0bB0sG~ixQ8{PO6aCTusJMPzM9W1erz7EzN zE7rjvOFHOQ;H3N03oA04PZef0pSdx+8SQMOdo+D*DzW7kL<5;RaF0kbksKr!$@DB_ zI}3jzn`{D|E*JV9u1O~(SFs6lwT)`L6FBKxZIEjKJexr8JLlh` zffjmcCBE7z|D;vWy%BR+zX|hl$iD+~+8)qFG)@=J5jaiz*B!bI<$eV@$YwTNH|TzM zFx2ntXM)$u9^+*Ov=pFBXM{2q?yCa=_lj?dGP(btOgmqf>nig!%8-6$pp1NGB4fl? z@JEWxG}gdZeH1gYkTykYzI{0H_SdUUW_%U%gA=RZbHiiV?mb7=9qNaew)KHMUtR$n z99j4Nms^i~{3Yf9iFuA0nzW6bzU{D;vGprizY}?gF0PS9!@RhK2P@nt+`Na|J)5hiNx|jb1x+a|* zM#>;tCt@=7aeP#yF$Vho2)rm((1~YLW93>0!3^sIDopDitI$RxGw}5-Yg^Zv3ej4z zuHrCa+`_u3h8X??c-vt!M==Y`w;tnd!*dR?W-`pDuhmd}Ka~HbF#PWl{A1BJ(v_@d z-8s6q7xLSM{GTfFkLWJ{t>8uNm3*uR(2r^DXpQL{J)_wPo>F%~@_$eMB?^C)_uZlm zQuYO+9)EW1>$vwmcwq(O zu{+qgwn12z#oVHO9`m(XF*k8CpO25prWTr)9KgLUf7UpV;TeIJamHk7g#9vZ!8-+~ z#hk=$G&C+B%UZuNMK#(7G2i`=$<~AUu%3~zvH-DZ7RA@WEl1A!xA^-Qd<`#7_Z>CG zHZn7t=LM}l+q@iW1&6N3+<@(#?z4NhPqlj=oXQ~ozJ{C6eFd4?A7(xc>zqxChM)5< z1bhYLMP3u)a2E9A1<%vjCamLm4-I5l&B?28K1cIV-(u$T8jb6Z{)G8fFG@alg`g!n zHsCy;ZEmz4obHPdjajgB)1r~*KHO(+%z{kEAkQ(U z3GsVK%ZC$jJstC=p1qp=D|_SYgR^h*QOHaFLhUn}yagXl)O?+T4Xq45_TkEe=8oxT zD|ofLb=~;)nKSx=-he(yamUIoYutP$vitM{_T!^rDcjX1l{*m!njTyy(s zW21kcF{1cV_{Xu7B z8?uR&!5+{X>AM3uC0n#_L|xD~%@wKq-LgFFMmC~8+5tVc0e{Riy}2`6^9_f8(7Gu3 z<&H(xbL0AyO2$*PSUmzvFZbx6L1it;Q>3H@%poRKAwejIamU9#%$fiesqVfJuw(NvmcOZ}K z>4n`%1|w`vzK}`20vkUAz0vb~s^=_H@(sG?u?Xdxgg=}_-Y_v<{fjI3mP?cFD4ohyZ4KH8M{jWhl|~YzL8`17Ao@(Vz)gcc3Zw9c25L9((#Xt z-NR-1kl1}K@c)e1{o z6uV<679q}AaPLF0&4T+A8NaVY`AX!6i{D$Q9OC!A;B^OGhs5u9fMa;)fa3Qq(8&0G z6?l?wj;FSUiQlcDRpWOv$r=*BiC<{^ejK=P@%sYsKQeyr3Kzd~!S9F0?-6~q<;g~G zfyL60kZi^po5q$m#IppKIN-BJz^7 z7m_TNp(S|UV3~h!fj47ktpV#B2rRAqo3*87HRBI6NxfSicCVcBHbt{HFZF!>f&Z@Ku?am+msw z$FP{0BM&0IM7ukuzO3GB(PrYiLNnJ4A-IIYJy?&KA8~jghs~^KP(FU|7y`$Iz_CHF z$(}va34Yo2&U!oQ!>=cU;AqRVnJ@GFQjs4Olpkfuo%ty8v+7;-8p>Nv8tdu)`epxJ z1(qb%dMo;-^X@g|Q>`YptCrTUfBx-V3Glzx2XVdDkL!5WO3w;u&F31FapO9Qu7|MJ zTX6kH;)UyFxPG{D8|QV@|JzzB|Jb+41Ft)Ay_4v`i^|CP4D&KRmz6NR&q6-Y_3oje z#Q?k6@76Mk@6j@k)n-@TC|Mv-)I@7PiYy+^~LqB zXSIxy=kZ=2+P&}(TE=Uzm2)pr*su6yEu*YdTb@#1Ro`aSWlf8)fX4tH19(h*dA$Yj%aDuga%p{OeH-e3 z6foIgB<#=x7=Fm@JVN-58Gb{4Bw;7=$?n62-Km|_Ml0H7LHS_@w%Cesz<&4MdPDVN z1@@=1em@-j5_5yl05`26PD(-_AC>yqMK zM7%TQ?bI^tSfg4c)+G<0@^2Xg+Le%lK?Z(L)Q{dZ)a#%zBn$Zs`ufza&^5<)zCP9U zjvhVFnFf0DIYb8TfAaSg>TfIHhwR4Of`WMkKeKdwf$7RC>F4uv>K0l`9px4H1Oq?R zPpMpaB|gG|?-k&y6ib{QOVyH!3QLvSW8t4+(8<}2Kg}$dn>TlQFlYMB{W!~#s$%-Q zk!2~qv4f9GjI#jkDqrfd=-;^D9DY#wW%w|Y#ZzACve0*tet3CNe~AT8$@#|`##xG& zpkZi}&Q0P|*o}onnMJv3t1SEzS{A)YIwyQKN0y@&)Ad++(DyYg_)rtRcO_AjO8W6- z?n>AA>hkd+zjwd9(otSDzOL3ezROZ6&gyDeuE_1SR644bTS{RwOPQmpq{3Baq001M zAzgW8*Y`E3OqOFwNiDv@B6Ti4lVPDRU0LXxSmKa)`dozt->V44>mRg$9|^tSGb}ET zXdlsrx1;=SQ;Mai%w^#pZ79N52rTYW6xE#%Eg-*GN{;BLby@J`hf;i=tg4%Rd1*^| z$yHo5;j|Wal_k3%dz_^N--@sl*SZ&rCRs|{&3gPxU}L`f>*}sY`af z%W094@#|2@^p8RC9-@EJ!CB^VF22%YvsGC}FDol|mRZW{EF*7OGRAWCRTfWKdEMn# zQw^iXgk%dv=gqSOKACoDtDvy5hJ3=!i9{tyIX@&gV*Uts`U zmz~gZ-Wj>(phM{)oE^LGUOF462m zJ^Y7?|NQXX+de*fZdKnH!^Vk&k{`W(-1O&`TwU_Y{n{_zeX-y-pZ&GuRljfPaiev8 zYG32M{VrYj+okC_FI+eC$$h_{|Et#@tUB@0*S8)x^UmtDI7?$flIgK!DW%U8P0fAv zg{&vu*`9yb=iiima^Z;Q6?4`v3;R1BthSh&FP<>!-zU$0?T;Va{Mp;*%hq<>d&}de zp1-{yK6^{eQ2RrPqoba_;>t_^{I{IHd~o6VPe0yjU-!+w*S17E@2XAI9=JAnxbWi;+zS#Ejy57Z`^M_A!W|CU*O_=MsMX z1_JyCVf5!O8z4!F}`EO5M+WEr4^q2N!%pCptp!q#NT3JetAF{H`9B^!)BjlW2Ft2{e|o}> zKQ5R(>+R(?mvsy&>vigyTT*&|^z*NV?BD$6*oPk8HKpNq8>cP)%PmDS-oK&v@)J|5 zd;5mnbvF9%54@51$H#w{+|+t^>gxYkF?Z3M^KZ&Kdex$FUkt79V;F4uNg@V6E8N5W zC%>OzGTQgge*e~J{MH_6dJo2$kd6b*L8KbezOVWHMM&*P>ycI?-Gg)&(tMOpJ?QtZ zr4$ce-$QE0!`rDQ#*X2^m>20uq`Q!6Z~6W0NK23&Gcz{gh~IC)k9bah0RBkrcb&qAI5P>z*ay{sUn}~==Y{; zftxCD7Ni=^-N4O2$})Rf9x!h=Wo=B&_JZXLHusTxfX4W5m>@) zz_~`jSpYwRa~H~MNM#+_8;zR`vrx+$y_p5*12}I&x%o&XP3}hHJShi44f_=5{Qva( zpU`Qv2V%DO$l4gaDJpxj*%9}*_unLDnLRnbBTtPA+P)W{QIq$y;C2E-X4{+(Y(o&yV-bSR|BVaUC!vb zM0v6;ebe+N^c87u@-aFLx8%>}-q&N>7kv$EF!><)ng!<+(9cF{-i8h&{3~apk(2}n z%j}8va7QEBKY{;z(2u~iq=hf$N}CbQNzj}=ivFe0z^(y*C7MK3m5P`7Nw1O*X!0eW z89@IYX9Z~JySru+m+hcA>w%fu^RhS2*fc$R^R#<%v$o`H&Ca%Pow+WprU-;R6# zZ|}bM&R^d?BFzgP#4852+l7~|=v%R7Ja|T(-^Hsl9Iq+hMe(X0c4|Xv{*?2wKM=pY zXV#YJtx>rf<2J=^j=84?*I$qvsVGaa<~;OA-vBnh#mlxE9vHHHaMs2_n+9fYPP%7+ zv4pHDyi-G&{V1~)4+iLSF6J*$CaX8Ek5`pVbxo(5qh^?+@=R4Itk)VnBRY@wHJT=^ zL11Wm7rF!wwB2iXpzroRSsQzA>XoxO{vL=Pw>369YDRQaUQ~9}OmoyM(~Ns#ZhWUO zz-(spEWr?ksT>ufQuoFXE4`>*a?U$*?TMgxbR#S`T2SJQ{bq#n_ zzbxWvR}9UQ{st1>f1Uu{jL*=2;BFGv23!svOvpY(ap?`a4^x>31^ zESrtj$GwTrB4Qr(&v=Xt^Evn#}1mzYvR~3 zljnRazD>QyxHFdB8DriQ%MQetf%-JY49tdD!aNcSJD~hkD8H#EmA@a~(>9rR$FY;9 zO@=4H5)6*SvOO{8{juy^j2Wo=W6i*{#S-QX!611mS>dF?eBQ{w>mYt=VnqMiYBKLJ zu_wULMAgjR-_v}c7kjU#d4DgqHXe2Fj5j~hi?zj@&&9L%;>}O=VyEK~r;qhAukFpe zz0G&_W>54s|Gp19(A)e-ALi|2KG28V-^aYa5Ao~yo*^EQXRDEi6sYW9$GGR6P$z|8n8NWRNmPVs7(eEV zxu5)I-(->BQ{>C~1Q|OnzE?+6K{{yv6gm?1go$MU?0BUgNAQ9c9TI;~G(^f7gZUC2 zv3kN}ec$?Z`7MIpFJLJLrlY)lbA=+X1i@k1PQmV zPS(f>q_-EJ1-{ZUI>%L9?x?b)rKaG+z?V-RBd#nHQYWOPrlrwM`ad{Kh-$PB6nfCt zdSzTu^XO~9GM)tE%}mCfV0;vl{WlmN&1An1#`j<{egxxVn2a;Q_(=Ql#WC40g6XlZ z(-;+_Uz=DwlW|$iHQ{Aci-_03_}+p2B!lsNSiSnuNRes6-T3cIR7(BYgdMcxcYoDf z6CUHrxF3w~+V3V9pNM@myBpGkFYe}xcpgmOKM?1G@!j_^qxtdYA&ESXT~F z;Wbr%7e>Fzr8rysZl_#~GczyM1+hcY9q2K9TFi4?je_)N7U7RK>Ht zA@;o)4T#LAXJCJ>U_M>@ZAtvS{Gz-6NIe|9Oj7FU{YXd;60eDDN#B$s5Fz+be{MrQ z@sao^Lg<;!P+;}7M4}JfH;SHXaQt|kl&=%xQp#fw;Un>FA$X~WwgrJI`GusnObfH?Y9+*KSv9t$|2>kg!FeEpTuH9`YDka(0?Ufa?|MtuyY~fijMEYPKLy> z^(gp{`i0!*ONy%V>BUChC^32}?IrIEWG+1uA%BzjP$_uq^5hT{Jq@Tnp6x}4qP^Xq~>^#1B2 z;K}YXZUf|p&ZqnMa*ES;#}9&@csvO!PxtZbQqUX1jB9$meb}8LekJuU<&^e~q)*9b zPl*0=dA)sDD4zI*^V>ph|L)^>Dd*E&&vgPX`-{B4xeIt>nEAtIj_*ExZR32t@Q04q z^i07(cU2*NxJ%H7j^lbi>ORkT8T7OdVCa5-e--%9{S&|Dc&YWSGyyka;r8hp4tzov zS>S3?1pIW)2REIfKg#>$8#q12osjXRhSPV&TY0~@8u*I>wRK%QBlvj5YPz(`I|AP{ zQKuatihRcLUFGE!t?P$t*HGY-p-(yf&KCtHMxZYMKAfCQ5$KXC|pKIg_pm71pJi|@OJ@E?Umy!J!7Qf9gf$p)xW2Jr+rc7I4Je+kH9An z3lrh|^JldPv_a|)zKAb)~IUiLL{rbxY_<>lU2xs4kz=z{c`*Mb(uaAI#C<6W^ z;K`11KMm>6ha%8hp}=tUPT=_N^R!vOlis{Jdi$mR^?j&8FZu<4wg-|s1fS6TYU8j# z6RzG%fDfmi#S!QmIKC&_FZx}Z7!)1pM%x;q`nC$M
@M|u3CAmp#pS#RczXo=nh5y!BH+K^`0o1%UyT8X^ckv$6~Kq{|7{WQ`vjlR zeU{&gK>tMqd`6$}_2x&wmjZ9;u1?kvf&ShI_)mck=eHNZ;mMAn`xK`OeCYk@9FFfU zP$lr;;(4pUhmNPO0Uu7D6TpXS@7KVGv)3pv2}hp^d^rAh0!ebp`_`L8Q(gf+9RI&Z zz_am7>T1VhXRq-KozC$NN3FALa{A?Xmvu?~Hr@+tMV!KSO2r<7jyj@IHaq>E+d*O*L2T=W{VFHg zQp)RU9oVKUv@UwpnfCe(sY`uLH(k&KkxZXGFDr94c5_=&Y|FESycpV+JOH-VzYkO#$r;@hTt#Uyj zHth1eu)>WZY^-%Gx8bGk+U2aY)=}xQ zl`N^O#4gG<1>)Na2a(!r(+V=@ncqNzppQe!FUbKmUF}0%sF}4D2?r}C3B&(dDEs9=3>v}%&ghD-S#JzTcN7f>e?eP zzfA5;TqrhJ*7zoM`c`zbC*JjHL9vsxPNQ#Rr|EfhocSyWrmwHtC^!&vl!r9o`*`w{%oAh=nd) z6zujVHoI1Z(zhU2G2CS8uEn9-Rk?1+v|4QzgBw6KczML_Oai8Lv2;7jCN@c zZhrVp&ecLG8RS7-d#@JL(9rbu!*sgl-afMYT9@1=L)a?-`M82 zq$0mtD7#+mem_W=xuKd=wo(2E`V4IR48w+O)~akO8_a;VPPWT-8oSZ_$DStvGc_M}Y;{G1dHRJ^1V-I>c!w(^R_7g)Pv(duM31KHAfG8MYG-suH}F$x>kFXtf-58bt%& z^BxAz#eFP#_!Jg(e=%5MHZQ-yFE4Hh*xf+ONrxvR41_u&QNmY5VC6y)i) zgYK1eNAB9KJj|^@aHK-GRQ>0BdVX%XJ|7I`CBgxQyE zpZXvgmQuI85^D@dJ+*pTCa>`OY*z}FgHno@lvk8oUS7gDROYBFV<{!et58x;J+*p{ z_>@2pU_)N5tHMDA#8q{Lho$hfkQ9%r9@qT#Kc&`9KXzs*t}?OiP*#Gn5&~1F)8?vo zx~k=(2FPYSPJudBGOj-_Ckq%!c6_U?;=KL9fr zw0Km4XRP`m-&d3A2!WRg9*+ebDS*DhyQ8wae6LNWCF1!69t-kAu3HO`O~D10+5`2= z_upiS?-}xg>LnhsynN213B0Udz9%PB`93bl_#woRApgA|y&Egb%lGMIdQebG`6Zo9 z>Afg=*H*&vy*rui66HhXmjaaFg7Rc}`F@^E<@>#|{?PVUiSk*3p?r@|rt+xgf$lz4IFDA0Ntn!-DI-F{G`Cgz*LknP8Iq0}8wEP%7TfSd4tziU<0ygulfF@sjNiyx&r*Q$(_#EN?>Nsr{)EAyZL)l!Qe}v~;LxNE3PfXi>hb z9|swYGmCJ_c1yV^ya#00N%`Lmx9dP$f`Y`QtXE?3xF~G-`?ly5@gW65K=%Ita9H}e diff --git a/lib/libUnitreeMotorSDK_M80106_Linux64.so b/lib/libUnitreeMotorSDK_M80106_Linux64.so deleted file mode 100755 index 553fe129de62e03720e4d77d1ec425d7fb2e7477..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48536 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 literal 0 HcmV?d00001