first commit
This commit is contained in:
commit
5221e95827
|
@ -0,0 +1 @@
|
|||
build
|
|
@ -0,0 +1,35 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(z1_sdk)
|
||||
|
||||
# set(EIGEN_PATH /usr/include/eigen3)
|
||||
|
||||
include_directories(
|
||||
include
|
||||
# ${EIGEN_PATH}
|
||||
)
|
||||
|
||||
link_directories(lib)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -pthread")
|
||||
|
||||
# file(GLOB_RECURSE ADD_SRC_LIST
|
||||
# src/*.cpp
|
||||
# )
|
||||
|
||||
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) # SHARED:CMAKE_LIBRARY_OUTPUT_DIRECTORY STATIC:CMAKE_ARCHIVE_OUTPUT_DIRECTORY
|
||||
# add_library(Z1_SDK_Linux64 SHARED ${ADD_SRC_LIST})
|
||||
|
||||
add_executable(example_lowCmd_send examples/example_lowCmd_send.cpp)
|
||||
target_link_libraries(example_lowCmd_send Z1_SDK_Linux64)
|
||||
|
||||
add_executable(example_state_send examples/example_state_send.cpp)
|
||||
target_link_libraries(example_state_send Z1_SDK_Linux64)
|
||||
|
||||
add_executable(example_state_recv examples/example_state_recv.cpp)
|
||||
target_link_libraries(example_state_recv Z1_SDK_Linux64)
|
||||
|
||||
add_executable(example_keyboard_recv examples/example_keyboard_recv.cpp)
|
||||
target_link_libraries(example_keyboard_recv Z1_SDK_Linux64)
|
||||
|
||||
add_executable(example_keyboard_send examples/example_keyboard_send.cpp)
|
||||
target_link_libraries(example_keyboard_send Z1_SDK_Linux64)
|
|
@ -0,0 +1,76 @@
|
|||
# v3.6.1
|
||||
The z1_sdk is mainly used for communication between z1_controller and command panel(keyboard, joystick, user control panel etc).
|
||||
|
||||
## Notice
|
||||
|
||||
support robot: Z1(v3.6.1)
|
||||
not support robot: Z1(v3.4, v3.5)
|
||||
|
||||
## Dependencies
|
||||
|
||||
- build-essential
|
||||
|
||||
```bash
|
||||
sudo apt install build-essential
|
||||
```
|
||||
|
||||
- Boost (version 1.5.4 or higher)
|
||||
|
||||
```bash
|
||||
dpkg -S /usr/include/boost/version.hpp # check boost version
|
||||
sudo apt install libboost-dev # install boost
|
||||
```
|
||||
|
||||
- CMake (version 2.8.3 or higher)
|
||||
|
||||
```bash
|
||||
cmake --version # check cmake version
|
||||
sudo apt install cmake # install cmake
|
||||
```
|
||||
|
||||
- [Eigen](https://gitlab.com/libeigen/eigen/-/releases/3.3.9) (version 3.3.9 or higher)
|
||||
|
||||
```bash
|
||||
cd eigen-3.3.9
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
sudo make install
|
||||
sudo ln -s /usr/local/include/eigen3 /usr/include/eigen3
|
||||
sudo ln -s /usr/local/include/eigen3/Eigen /usr/local/include/Eigen
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
There are three examples of command panel control based on SDK in this project, you can use it fllowing the steps below.
|
||||
|
||||
### State change
|
||||
|
||||
- First, set(CTRL_PANEL SDK) # z1_ws/src/z1_controller/CMakeList.txt,and then rebuild the z1_ws to generate z1_ctrl, then open a teminal to run z1_ctrl
|
||||
|
||||
```
|
||||
cd /<path to>/z1_controller/build
|
||||
sudo ./z1_ctrl
|
||||
```
|
||||
|
||||
- Sencond, build the z1_sdk, and then open another terminal to run example.
|
||||
|
||||
```
|
||||
cd /<path to>/z1_sdk && mkdir build && cd build
|
||||
cmake ..
|
||||
make -j4
|
||||
./example_state_send
|
||||
```
|
||||
|
||||
### Low level control
|
||||
|
||||
```
|
||||
sudo ./z1_ctrl # Running in a terminal
|
||||
./example_lowCmd_send # Running in another terminal
|
||||
```
|
||||
|
||||
### Keyboard control
|
||||
|
||||
```
|
||||
sudo ./z1_ctrl # Running in a terminal
|
||||
./example_keyboard_send # Running in another terminal
|
||||
```
|
|
@ -0,0 +1,53 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#include "unitree_arm_sdk/unitree_arm_sdk.h"
|
||||
|
||||
bool running = true;
|
||||
|
||||
// over watch the ctrl+c command
|
||||
void ShutDown(int sig){
|
||||
std::cout << "[STATE] stop the controller" << std::endl;
|
||||
running = false;
|
||||
}
|
||||
|
||||
int main(){
|
||||
EmptyAction emptyAction((int)ArmFSMState::INVALID);
|
||||
std::vector<KeyAction*> events;
|
||||
CmdPanel *cmdPanel;
|
||||
events.push_back(new StateAction("`", (int)ArmFSMState::BACKTOSTART));
|
||||
events.push_back(new StateAction("1", (int)ArmFSMState::PASSIVE));
|
||||
events.push_back(new StateAction("2", (int)ArmFSMState::JOINTCTRL));
|
||||
events.push_back(new StateAction("3", (int)ArmFSMState::CARTESIAN));
|
||||
events.push_back(new StateAction("4", (int)ArmFSMState::MOVEJ));
|
||||
events.push_back(new StateAction("5", (int)ArmFSMState::MOVEL));
|
||||
events.push_back(new StateAction("6", (int)ArmFSMState::MOVEC));
|
||||
events.push_back(new StateAction("7", (int)ArmFSMState::TEACH));
|
||||
events.push_back(new StateAction("8", (int)ArmFSMState::TEACHREPEAT));
|
||||
events.push_back(new StateAction("9", (int)ArmFSMState::SAVESTATE));
|
||||
events.push_back(new StateAction("0", (int)ArmFSMState::TOSTATE));
|
||||
events.push_back(new StateAction("-", (int)ArmFSMState::TRAJECTORY));
|
||||
events.push_back(new StateAction("=", (int)ArmFSMState::CALIBRATION));
|
||||
events.push_back(new StateAction("]", (int)ArmFSMState::NEXT));
|
||||
events.push_back(new StateAction("/", (int)ArmFSMState::LOWCMD));
|
||||
|
||||
events.push_back(new ValueAction("q", "a", 1.0));
|
||||
events.push_back(new ValueAction("w", "s", 1.0));
|
||||
events.push_back(new ValueAction("e", "d", 1.0));
|
||||
events.push_back(new ValueAction("r", "f", 1.0));
|
||||
events.push_back(new ValueAction("t", "g", 1.0));
|
||||
events.push_back(new ValueAction("y", "h", 1.0));
|
||||
events.push_back(new ValueAction("down", "up", 1.0));
|
||||
|
||||
|
||||
cmdPanel = new UnitreeKeyboardUDPRecv(events, emptyAction);
|
||||
while(true){
|
||||
std::cout << "state:" << (int)cmdPanel->getState() << std::endl;
|
||||
std::cout << "value:" << cmdPanel->getValues().at(0) << std::endl;
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
delete cmdPanel;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#include "unitree_arm_sdk/unitree_arm_sdk.h"
|
||||
|
||||
bool running = true;
|
||||
|
||||
// over watch the ctrl+c command
|
||||
void ShutDown(int sig){
|
||||
std::cout << "[STATE] stop the controller" << std::endl;
|
||||
running = false;
|
||||
}
|
||||
|
||||
int main(){
|
||||
EmptyAction emptyAction((int)ArmFSMState::INVALID);
|
||||
std::vector<KeyAction*> events;
|
||||
UnitreeKeyboardUDPSend *cmdPanel;
|
||||
|
||||
events.push_back(new StateAction("`", (int)ArmFSMState::BACKTOSTART));
|
||||
events.push_back(new StateAction("1", (int)ArmFSMState::PASSIVE));
|
||||
events.push_back(new StateAction("2", (int)ArmFSMState::JOINTCTRL));
|
||||
events.push_back(new StateAction("3", (int)ArmFSMState::CARTESIAN));
|
||||
events.push_back(new StateAction("4", (int)ArmFSMState::MOVEJ));
|
||||
events.push_back(new StateAction("5", (int)ArmFSMState::MOVEL));
|
||||
events.push_back(new StateAction("6", (int)ArmFSMState::MOVEC));
|
||||
events.push_back(new StateAction("7", (int)ArmFSMState::TEACH));
|
||||
events.push_back(new StateAction("8", (int)ArmFSMState::TEACHREPEAT));
|
||||
events.push_back(new StateAction("9", (int)ArmFSMState::SAVESTATE));
|
||||
events.push_back(new StateAction("0", (int)ArmFSMState::TOSTATE));
|
||||
events.push_back(new StateAction("-", (int)ArmFSMState::TRAJECTORY));
|
||||
events.push_back(new StateAction("=", (int)ArmFSMState::CALIBRATION));
|
||||
events.push_back(new StateAction("]", (int)ArmFSMState::NEXT));
|
||||
events.push_back(new StateAction("/", (int)ArmFSMState::LOWCMD));
|
||||
|
||||
events.push_back(new ValueAction("q", "a", 1.0));
|
||||
events.push_back(new ValueAction("w", "s", 1.0));
|
||||
events.push_back(new ValueAction("e", "d", 1.0));
|
||||
events.push_back(new ValueAction("r", "f", 1.0));
|
||||
events.push_back(new ValueAction("t", "g", 1.0));
|
||||
events.push_back(new ValueAction("y", "h", 1.0));
|
||||
events.push_back(new ValueAction("down", "up", 1.0));
|
||||
|
||||
cmdPanel = new UnitreeKeyboardUDPSend(events, emptyAction);
|
||||
|
||||
while(running){
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
delete cmdPanel;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#include <math.h>
|
||||
#include "unitree_arm_sdk/unitree_arm_sdk.h"
|
||||
|
||||
struct ConfigPD{
|
||||
float K_P[7];
|
||||
float K_W[7];
|
||||
|
||||
virtual void setContrlGain()=0;
|
||||
};
|
||||
|
||||
struct SimulationPD : ConfigPD{
|
||||
|
||||
void setContrlGain(){
|
||||
K_P[0] = 80;
|
||||
K_P[1] = 200;
|
||||
K_P[2] = 200;
|
||||
K_P[3] = 15;
|
||||
K_P[4] = 15;
|
||||
K_P[5] = 15;
|
||||
K_P[6] = 15;
|
||||
|
||||
K_W[0] = 5;
|
||||
K_W[1] = 10;
|
||||
K_W[2] = 10;
|
||||
K_W[3] = 2;
|
||||
K_W[4] = 2;
|
||||
K_W[5] = 2;
|
||||
K_W[6] = 5;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct RealRobotPD : ConfigPD{
|
||||
|
||||
void setContrlGain(){
|
||||
K_P[0] = 20;
|
||||
K_P[1] = 40;
|
||||
K_P[2] = 20;
|
||||
K_P[3] = 160;
|
||||
K_P[4] = 160;
|
||||
K_P[5] = 160;
|
||||
K_P[6] = 20;
|
||||
|
||||
K_W[0] = 6000;
|
||||
K_W[1] = 6000;
|
||||
K_W[2] = 6000;
|
||||
K_W[3] = 6000;
|
||||
K_W[4] = 6000;
|
||||
K_W[5] = 6000;
|
||||
K_W[6] = 3000;
|
||||
}
|
||||
};
|
||||
|
||||
void printUsage() {
|
||||
printf(
|
||||
"Usage: controller [sim-or-robot]\n"
|
||||
"\t sim-or-robot: s for sim, r for robot\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv []){
|
||||
// input number
|
||||
if (argc != 2) {
|
||||
printUsage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// PD config
|
||||
ConfigPD *configPD;
|
||||
if (argv[1][0] == 's') {
|
||||
configPD = new SimulationPD();
|
||||
configPD->setContrlGain();
|
||||
} else if (argv[1][0] == 'r') {
|
||||
configPD = new RealRobotPD();
|
||||
configPD->setContrlGain();
|
||||
} else {
|
||||
printUsage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// UDP object
|
||||
UDPPort udp("127.0.0.1", 8071, 8072, sizeof(RecvState), BlockYN::NO, 500000);
|
||||
|
||||
// Send object
|
||||
SendCmd sendCmd;
|
||||
RecvState recvState;
|
||||
sendCmd = {0};
|
||||
recvState = {0};
|
||||
sendCmd.head[0] = 0xFE;
|
||||
sendCmd.head[1] = 0xFF;
|
||||
|
||||
float deltaTime = 0.004; // s
|
||||
|
||||
// Only Passive state can change to LowCmd state
|
||||
while (recvState.state != ArmFSMState::PASSIVE){
|
||||
sendCmd.state = ArmFSMState::PASSIVE;
|
||||
udp.send((uint8_t*)&sendCmd, sizeof(SendCmd));
|
||||
udp.recv((uint8_t*)&recvState, sizeof(RecvState));
|
||||
usleep(deltaTime*1000000);
|
||||
}
|
||||
|
||||
// LowCmd state
|
||||
sendCmd.state = ArmFSMState::LOWCMD;
|
||||
for(uint8_t i(0); i<7; ++i){
|
||||
sendCmd.valueUnion.jointCmd[i].Pos = 0;
|
||||
sendCmd.valueUnion.jointCmd[i].W = 0;
|
||||
sendCmd.valueUnion.jointCmd[i].T = 0;
|
||||
sendCmd.valueUnion.jointCmd[i].K_P = configPD->K_P[i];
|
||||
sendCmd.valueUnion.jointCmd[i].K_W = configPD->K_W[i];
|
||||
}
|
||||
sendCmd.valueUnion.jointCmd[3].Pos = -M_PI*4.26/180;
|
||||
sendCmd.valueUnion.jointCmd[3].W = 0;
|
||||
sendCmd.valueUnion.jointCmd[3].T = 0;
|
||||
sendCmd.valueUnion.jointCmd[3].K_P = configPD->K_P[3];
|
||||
sendCmd.valueUnion.jointCmd[3].K_W = configPD->K_W[3];
|
||||
|
||||
int count = 0;
|
||||
float velocity = 1; // rad/s
|
||||
|
||||
for(int i(0); i<1000; ++i){
|
||||
if(i<500){
|
||||
// // torque
|
||||
// sendCmd.valueUnion.jointCmd[0].T = 2.5;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = 0;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = 0;
|
||||
|
||||
// // postion
|
||||
// sendCmd.valueUnion.jointCmd[0].Pos += deltaTime*velocity;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = configPD->K_P[0];
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = configPD->K_W[0];
|
||||
|
||||
// // velocity
|
||||
// sendCmd.valueUnion.jointCmd[0].W = velocity;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = 0;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = configPD->K_W[0];
|
||||
|
||||
// Grepper
|
||||
sendCmd.valueUnion.jointCmd[6].Pos -= deltaTime*velocity;
|
||||
sendCmd.valueUnion.jointCmd[6].W = -velocity;
|
||||
sendCmd.valueUnion.jointCmd[6].K_P = configPD->K_P[6];
|
||||
sendCmd.valueUnion.jointCmd[6].K_W = configPD->K_W[6];
|
||||
|
||||
} else{
|
||||
// // torque
|
||||
// sendCmd.valueUnion.jointCmd[0].T = -2.5;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = 0;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = 0;
|
||||
|
||||
// // postion
|
||||
// sendCmd.valueUnion.jointCmd[0].Pos -= deltaTime*velocity;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = configPD->K_P[0];
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = configPD->K_W[0];
|
||||
|
||||
// // velocity
|
||||
// sendCmd.valueUnion.jointCmd[0].W = -velocity;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_P = 0;
|
||||
// sendCmd.valueUnion.jointCmd[0].K_W = configPD->K_W[0];
|
||||
|
||||
// Grepper
|
||||
sendCmd.valueUnion.jointCmd[6].Pos += deltaTime*velocity;
|
||||
sendCmd.valueUnion.jointCmd[6].W = velocity;
|
||||
sendCmd.valueUnion.jointCmd[6].K_P = configPD->K_P[6];
|
||||
sendCmd.valueUnion.jointCmd[6].K_W = configPD->K_W[6];
|
||||
}
|
||||
|
||||
udp.send((uint8_t*)&sendCmd, sizeof(SendCmd));
|
||||
udp.recv((uint8_t*)&recvState, sizeof(RecvState));
|
||||
|
||||
// printf("Pos:%f \n", recvState.jointState[0].Pos);
|
||||
// printf("roll:%f \n", recvState.cartesianState.roll);
|
||||
// printf("pitch:%f \n", recvState.cartesianState.pitch);
|
||||
// printf("yaw:%f \n", recvState.cartesianState.yaw);
|
||||
usleep(deltaTime*1000000);
|
||||
}
|
||||
|
||||
while (recvState.state != ArmFSMState::BACKTOSTART){
|
||||
sendCmd.state = ArmFSMState::BACKTOSTART;
|
||||
udp.send((uint8_t*)&sendCmd, sizeof(SendCmd));
|
||||
udp.recv((uint8_t*)&recvState, sizeof(RecvState));
|
||||
usleep(deltaTime*1000000);
|
||||
}
|
||||
|
||||
delete configPD;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#include "unitree_arm_sdk/unitree_arm_sdk.h"
|
||||
|
||||
int main(){
|
||||
UDPPort udp("127.0.0.1", 8072, 8071, sizeof(SendCmd), BlockYN::NO, 500000);
|
||||
|
||||
SendCmd sendCmd;
|
||||
RecvState recvState;
|
||||
sendCmd = {0};
|
||||
recvState = {0};
|
||||
|
||||
recvState.head[0] = 0xFE;
|
||||
recvState.head[1] = 0xFF;
|
||||
|
||||
bool turn = true;
|
||||
while(true){
|
||||
|
||||
udp.send((uint8_t*)&recvState, sizeof(RecvState));
|
||||
udp.recv((uint8_t*)&sendCmd, sizeof(SendCmd));
|
||||
|
||||
printf("%d \n", (int)sendCmd.state);
|
||||
usleep(2000);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#include "unitree_arm_sdk/unitree_arm_sdk.h"
|
||||
|
||||
|
||||
SendCmd sendCmd;
|
||||
RecvState recvState;
|
||||
UDPPort udp("127.0.0.1", 8071, 8072, sizeof(RecvState), BlockYN::NO, 500000);
|
||||
|
||||
void UDPCommunication(){
|
||||
udp.send((uint8_t*)&sendCmd, sizeof(SendCmd));
|
||||
udp.recv((uint8_t*)&recvState, sizeof(RecvState));
|
||||
}
|
||||
|
||||
int main(){
|
||||
sendCmd = {0};
|
||||
recvState = {0};
|
||||
sendCmd.head[0] = 0xFE;
|
||||
sendCmd.head[1] = 0xFF;
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
|
||||
float deltaTime = 4000; // us
|
||||
|
||||
LoopFunc *udpCommunication;
|
||||
udpCommunication = new LoopFunc("udp", 0.002, boost::bind(&UDPCommunication));
|
||||
udpCommunication->start();
|
||||
|
||||
std::cout << "[PASSIVE]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::PASSIVE;
|
||||
while (recvState.state != ArmFSMState::PASSIVE){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[BACKTOSTART]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::BACKTOSTART;
|
||||
while (recvState.state != ArmFSMState::BACKTOSTART){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[CARTESIAN]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::CARTESIAN;
|
||||
while (recvState.state != ArmFSMState::CARTESIAN){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
for(int i(0); i<2000; ++i){
|
||||
if(i<500){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::E;
|
||||
}
|
||||
else if(i<1000){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::Q;
|
||||
}
|
||||
else if(i<1500){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::D;
|
||||
}
|
||||
else{
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::Q;
|
||||
}
|
||||
|
||||
// printf("------state:%d-------\n", (int)recvState.state);
|
||||
// printf("Pos:%f \n", recvState.jointState[0].Pos);
|
||||
// printf("Pos:%f \n", recvState.jointState[1].Pos);
|
||||
// printf("Pos:%f \n", recvState.jointState[2].Pos);
|
||||
// printf("roll:%f \n", recvState.cartesianState.roll);
|
||||
// printf("pitch:%f \n", recvState.cartesianState.pitch);
|
||||
// printf("yaw:%f \n", recvState.cartesianState.yaw);
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[JOINTCTRL]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::JOINTCTRL;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
for(int i(0); i<1800; ++i){
|
||||
if(i<300){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::Q;
|
||||
}
|
||||
else if(i<600){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::W;
|
||||
}
|
||||
else if(i<900){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::D;
|
||||
}
|
||||
else if(i<1200){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::R;
|
||||
}
|
||||
else if(i<1500){
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::T;
|
||||
}
|
||||
else{
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
sendCmd.value = ArmFSMValue::Y;
|
||||
}
|
||||
|
||||
// printf("------state:%d-------\n", (int)recvState.state);
|
||||
// printf("Pos:%f \n", recvState.jointState[0].Pos);
|
||||
// printf("Pos:%f \n", recvState.jointState[1].Pos);
|
||||
// printf("Pos:%f \n", recvState.jointState[2].Pos);
|
||||
// printf("roll:%f \n", recvState.cartesianState.roll);
|
||||
// printf("pitch:%f \n", recvState.cartesianState.pitch);
|
||||
// printf("yaw:%f \n", recvState.cartesianState.yaw);
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[SAVESTATE]" << std::endl;
|
||||
std::string test = "test";
|
||||
sendCmd.state = ArmFSMState::SAVESTATE;
|
||||
strcpy(sendCmd.valueUnion.saveState, test.c_str());
|
||||
usleep(deltaTime);
|
||||
|
||||
std::cout << "[BACKTOSTART]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::BACKTOSTART;
|
||||
while(recvState.state != ArmFSMState::BACKTOSTART){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
std::cout << "[TOSTATE]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::TOSTATE;
|
||||
strcpy(sendCmd.valueUnion.toState, test.c_str());
|
||||
while (recvState.state != ArmFSMState::TOSTATE){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[BACKTOSTART]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::BACKTOSTART;
|
||||
while (recvState.state != ArmFSMState::BACKTOSTART){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[MoveJ]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::MOVEJ;
|
||||
sendCmd.valueUnion.moveJ.roll = 0;
|
||||
sendCmd.valueUnion.moveJ.pitch = 0;
|
||||
sendCmd.valueUnion.moveJ.yaw = 0;
|
||||
sendCmd.valueUnion.moveJ.x = 0.5;
|
||||
sendCmd.valueUnion.moveJ.y = -0.3;
|
||||
sendCmd.valueUnion.moveJ.z = 0.5;
|
||||
while (recvState.state != ArmFSMState::MOVEJ){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[MoveL]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::MOVEL;
|
||||
sendCmd.valueUnion.moveL.roll = 0;
|
||||
sendCmd.valueUnion.moveL.pitch = 0;
|
||||
sendCmd.valueUnion.moveL.yaw = 0;
|
||||
sendCmd.valueUnion.moveL.x = 0.5;
|
||||
sendCmd.valueUnion.moveL.y = 0.4;
|
||||
sendCmd.valueUnion.moveL.z = 0.3;
|
||||
while (recvState.state != ArmFSMState::MOVEL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[MoveC]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::MOVEC;
|
||||
sendCmd.valueUnion.moveC[0].roll = 0;
|
||||
sendCmd.valueUnion.moveC[0].pitch = 0;
|
||||
sendCmd.valueUnion.moveC[0].yaw = 0;
|
||||
sendCmd.valueUnion.moveC[0].x = 0.5;
|
||||
sendCmd.valueUnion.moveC[0].y = 0;
|
||||
sendCmd.valueUnion.moveC[0].z = 0.5;
|
||||
sendCmd.valueUnion.moveC[1].roll = 0;
|
||||
sendCmd.valueUnion.moveC[1].pitch = 0;
|
||||
sendCmd.valueUnion.moveC[1].yaw = 0;
|
||||
sendCmd.valueUnion.moveC[1].x = 0.5;
|
||||
sendCmd.valueUnion.moveC[1].y = -0.4;
|
||||
sendCmd.valueUnion.moveC[1].z = 0.3;
|
||||
while (recvState.state != ArmFSMState::MOVEC){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
sendCmd.state = ArmFSMState::INVALID;
|
||||
while (recvState.state != ArmFSMState::JOINTCTRL){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
|
||||
std::cout << "[BACKTOSTART]" << std::endl;
|
||||
sendCmd.state = ArmFSMState::BACKTOSTART;
|
||||
while (recvState.state != ArmFSMState::BACKTOSTART){
|
||||
usleep(deltaTime);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#ifndef _UNITREE_ARM_CMDPANEL_H_
|
||||
#define _UNITREE_ARM_CMDPANEL_H_
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include "unitree_arm_sdk/loop.h"
|
||||
#include "unitree_arm_sdk/common/arm_common.h"
|
||||
|
||||
|
||||
enum class KeyPress{
|
||||
RELEASE,
|
||||
PRESS,
|
||||
REPEAT
|
||||
};
|
||||
|
||||
|
||||
enum class ActionType{
|
||||
EMPTY,
|
||||
STATE,
|
||||
VALUE
|
||||
};
|
||||
|
||||
|
||||
struct KeyCmd{
|
||||
std::string c;
|
||||
KeyPress keyPress;
|
||||
};
|
||||
|
||||
|
||||
class KeyAction{
|
||||
public:
|
||||
KeyAction(ActionType type);
|
||||
virtual ~KeyAction(){};
|
||||
ActionType getType(){return _type;}
|
||||
protected:
|
||||
ActionType _type;
|
||||
};
|
||||
|
||||
|
||||
class StateAction : public KeyAction{
|
||||
public:
|
||||
StateAction(std::string c, int state, KeyPress press = KeyPress::PRESS);
|
||||
virtual ~StateAction(){};
|
||||
int getState(){return _state;};
|
||||
bool handleCmd(KeyCmd keyCmd, int &state);
|
||||
protected:
|
||||
int _state;
|
||||
KeyCmd _keyCmdSet;
|
||||
};
|
||||
|
||||
class EmptyAction : public StateAction{
|
||||
public:
|
||||
EmptyAction(int state);
|
||||
~EmptyAction(){};
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
必须为长按, deltaValue为每秒改变量
|
||||
valueAction允许共用按键,例如空格停止
|
||||
但是正反转、停止键不可重复
|
||||
*/
|
||||
class ValueAction : public KeyAction{
|
||||
public:
|
||||
ValueAction(std::string cUp, std::string cDown, double deltaValue, double initValue = 0.0);
|
||||
ValueAction(std::string cUp, std::string cDown, std::string cGoZero, double deltaValue, double initValue = 0.0);
|
||||
ValueAction(std::string cUp, std::string cDown, double deltaValue, double limit1, double limit2, double initValue = 0.0);
|
||||
ValueAction(std::string cUp, std::string cDown, std::string cGoZero, double deltaValue, double limit1, double limit2, double initValue = 0.0);
|
||||
|
||||
~ValueAction(){};
|
||||
bool handleCmd(KeyCmd keyCmd);
|
||||
void setDt(double dt);
|
||||
double getValue();
|
||||
double getDValue();
|
||||
double setValue(double value){_value = value;}
|
||||
private:
|
||||
double _value;
|
||||
double _changeDirection;
|
||||
double _dV = 0.0;
|
||||
double _dt = 0.0;
|
||||
double _dVdt = 0.0;
|
||||
double _lim1, _lim2;
|
||||
bool _hasLim = false;
|
||||
bool _hasGoZero = false;
|
||||
|
||||
KeyCmd _upCmdSet;
|
||||
KeyCmd _downCmdSet;
|
||||
KeyCmd _goZeroCmdSet;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class CmdPanel{
|
||||
public:
|
||||
CmdPanel(std::vector<KeyAction*> events,
|
||||
EmptyAction emptyAction, size_t channelNum = 1, double dt = 0.002);
|
||||
virtual ~CmdPanel();
|
||||
int getState(size_t channelID = 0);
|
||||
std::vector<double> getValues();
|
||||
std::vector<double> getDValues();
|
||||
void setValue(std::vector<double> values);
|
||||
void setValue(double value, size_t id);
|
||||
virtual std::string getString(std::string slogan);
|
||||
virtual std::vector<double> stringToArray(std::string slogan);
|
||||
virtual std::vector<std::vector<double> > stringToMatrix(std::string slogan);
|
||||
|
||||
virtual SendCmd getSendCmd();
|
||||
virtual void getRecvState(RecvState recvState);
|
||||
|
||||
protected:
|
||||
virtual void _read() = 0;
|
||||
void _start();
|
||||
void _run();
|
||||
void _updateState();
|
||||
void _pressKeyboard();
|
||||
void _releaseKeyboard();
|
||||
|
||||
static void* _runStatic(void* obj);
|
||||
static void* _readStatic(void* obj);
|
||||
|
||||
LoopFunc *_runThread;
|
||||
LoopFunc *_readThread;
|
||||
|
||||
std::vector<StateAction> _stateEvents;
|
||||
std::vector<ValueAction> _valueEvents;
|
||||
|
||||
EmptyAction _emptyAction;
|
||||
size_t _actionNum = 0;
|
||||
size_t _stateNum = 0;
|
||||
size_t _valueNum = 0;
|
||||
size_t _channelNum;
|
||||
std::vector<double> _values;
|
||||
std::vector<double> _dValues;
|
||||
int _state;
|
||||
std::vector<std::deque<int>> _stateQueue;
|
||||
std::vector<int> _outputState;
|
||||
std::vector<bool> _getState;
|
||||
double _dt;
|
||||
KeyCmd _keyCmd;
|
||||
std::string _cPast = "";
|
||||
|
||||
bool _running = true;
|
||||
};
|
||||
|
||||
#endif // _UNITREE_ARM_CMDPANEL_H_
|
|
@ -0,0 +1,130 @@
|
|||
#ifndef _UNITREE_ARM_ARM_COMMON_H_
|
||||
#define _UNITREE_ARM_ARM_COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// 4 Byte
|
||||
enum class ArmFSMState{
|
||||
INVALID,
|
||||
PASSIVE,
|
||||
JOINTCTRL,
|
||||
CARTESIAN,
|
||||
MOVEJ,
|
||||
MOVEL,
|
||||
MOVEC,
|
||||
TRAJECTORY,
|
||||
TOSTATE,
|
||||
SAVESTATE,
|
||||
TEACH,
|
||||
TEACHREPEAT,
|
||||
CALIBRATION,
|
||||
DANCE00,
|
||||
DANCE01,
|
||||
DANCE02,
|
||||
DANCE03,
|
||||
DANCE04,
|
||||
DANCE05,
|
||||
DANCE06,
|
||||
DANCE07,
|
||||
DANCE08,
|
||||
DANCE09,
|
||||
BACKTOSTART,
|
||||
GRIPPER_OPEN,
|
||||
GRIPPER_CLOSE,
|
||||
NEXT,
|
||||
LOWCMD
|
||||
};
|
||||
|
||||
// 4 Byte
|
||||
enum class ArmFSMValue{
|
||||
INVALID,
|
||||
Q,A,
|
||||
W,S,
|
||||
E,D,
|
||||
R,F,
|
||||
T,G,
|
||||
Y,H,
|
||||
DOWN,
|
||||
UP
|
||||
};
|
||||
|
||||
// 20 Byte
|
||||
struct JointCmd{
|
||||
float T;
|
||||
float W;
|
||||
float Pos;
|
||||
float K_P;
|
||||
float K_W;
|
||||
};
|
||||
|
||||
// 16 Byte
|
||||
struct JointState{
|
||||
float T;
|
||||
float W;
|
||||
float Acc;
|
||||
float Pos;
|
||||
};
|
||||
|
||||
// 140 Byte
|
||||
union UDPSendCmd{
|
||||
uint8_t checkCmd;
|
||||
JointCmd jointCmd[7];
|
||||
};
|
||||
|
||||
// 16*7=112 Byte
|
||||
union UDPRecvState{
|
||||
uint8_t singleState;
|
||||
uint8_t selfCheck[10];
|
||||
JointState jointState[7];
|
||||
uint8_t errorCheck[16];
|
||||
};
|
||||
|
||||
// 24 Byte
|
||||
struct Posture{
|
||||
float roll;
|
||||
float pitch;
|
||||
float yaw;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
// 48 Byte
|
||||
struct MoveC{
|
||||
Posture middlePosture;
|
||||
Posture endPosture;
|
||||
};
|
||||
|
||||
// 20*7=140 Byte
|
||||
union ValueUnion{
|
||||
Posture moveJ;
|
||||
Posture moveL;
|
||||
Posture moveC[2];
|
||||
char teach[10];
|
||||
char teachRepeat[10];
|
||||
char saveState[10];
|
||||
char toState[10];
|
||||
JointCmd jointCmd[7];
|
||||
};
|
||||
|
||||
// 2+4+4+140 = 150 Byte
|
||||
struct SendCmd{
|
||||
uint8_t head[2];
|
||||
ArmFSMState state;
|
||||
ArmFSMValue value;
|
||||
ValueUnion valueUnion;
|
||||
};
|
||||
|
||||
// 2+4+112+24 = 142 Byte
|
||||
struct RecvState{
|
||||
uint8_t head[2];
|
||||
ArmFSMState state;
|
||||
JointState jointState[7];
|
||||
Posture cartesianState;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _UNITREE_ARM_ARM_MSG_H_
|
|
@ -0,0 +1,214 @@
|
|||
#ifndef _UNITREE_ARM_ARM_MOTOR_COMMON_H_
|
||||
#define _UNITREE_ARM_ARM_MOTOR_COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
typedef int16_t q15_t;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// 发送用单个数据数据结构
|
||||
typedef union{
|
||||
int32_t L;
|
||||
uint8_t u8[4];
|
||||
uint16_t u16[2];
|
||||
uint32_t u32;
|
||||
float F;
|
||||
}COMData32;
|
||||
|
||||
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度分辨率
|
||||
|
||||
int16_t Force16; // 力传感器高16位数据
|
||||
int8_t Force8; // 力传感器低8位数据
|
||||
|
||||
uint8_t FError; // 足端传感器错误标识
|
||||
|
||||
int8_t Res[1]; // 通讯 保留字节
|
||||
|
||||
}ServoComdV3; // 加上数据包的包头 和CRC 78字节(4+70+4)
|
||||
|
||||
typedef struct {
|
||||
// 定义 电机控制命令数据包
|
||||
COMHead head;
|
||||
ServoComdV3 Mdata;
|
||||
|
||||
COMData32 CRCdata;
|
||||
|
||||
}ServoComdDataV3; //发送数据
|
||||
|
||||
// typedef struct {
|
||||
// // 定义 总的485 接受数据包
|
||||
|
||||
// ServoComdDataV3 M[3];
|
||||
// // uint8_t nullbyte1;
|
||||
|
||||
// }DMA485RxDataV3;
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
||||
enum class MotorType{
|
||||
A1Go1, // 4.8M baudrate, K_W x1024
|
||||
B1 // 6.0M baudrate, K_W x512
|
||||
};
|
||||
|
||||
struct MOTOR_send{
|
||||
// 定义 发送格式化数据
|
||||
MasterComdDataV3 motor_send_data; //电机控制数据结构体
|
||||
MotorType motorType = MotorType::A1Go1;
|
||||
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 MOTOR_recv{
|
||||
// 定义 接收数据
|
||||
ServoComdDataV3 motor_recv_data; //电机接收数据结构体
|
||||
MotorType motorType = MotorType::A1Go1;
|
||||
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; //错误码
|
||||
|
||||
float T; // 当前实际电机输出力矩
|
||||
float W; // 当前实际电机速度(高速)
|
||||
float LW; // 当前实际电机速度(低速)
|
||||
int Acc; // 电机转子加速度
|
||||
float Pos; // 当前电机位置(主控0点修正,电机关节还是以编码器0点为准)
|
||||
|
||||
float gyro[3]; // 电机驱动板6轴传感器数据
|
||||
float acc[3];
|
||||
|
||||
int8_t Res;
|
||||
};
|
||||
|
||||
|
||||
extern void modify_data(MOTOR_send* motor_s);
|
||||
extern bool extract_data(MOTOR_recv* motor_r);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/*****************************************************************
|
||||
Copyright (c) 2022, Unitree Robotics.Co.Ltd. All rights reserved.
|
||||
*****************************************************************/
|
||||
#ifndef _UNITREE_ARM_JOYSTICK_COMMON_H_
|
||||
#define _UNITREE_ARM_JOYSTICK_COMMON_H_
|
||||
#include <stdint.h>
|
||||
|
||||
// 16b
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t R1 :1;
|
||||
uint8_t L1 :1;
|
||||
uint8_t start :1;
|
||||
uint8_t select :1;
|
||||
uint8_t R2 :1;
|
||||
uint8_t L2 :1;
|
||||
uint8_t F1 :1;
|
||||
uint8_t F2 :1;
|
||||
uint8_t A :1;
|
||||
uint8_t B :1;
|
||||
uint8_t X :1;
|
||||
uint8_t Y :1;
|
||||
uint8_t up :1;
|
||||
uint8_t right :1;
|
||||
uint8_t down :1;
|
||||
uint8_t left :1;
|
||||
} components;
|
||||
uint16_t value;
|
||||
} xKeySwitchUnion;
|
||||
|
||||
// 40 Byte (now used 24B)
|
||||
typedef struct {
|
||||
uint8_t head[2];
|
||||
xKeySwitchUnion btn;
|
||||
float lx;
|
||||
float rx;
|
||||
float ry;
|
||||
float L2;
|
||||
float ly;
|
||||
uint8_t idle[16];
|
||||
} xRockerBtnDataStruct;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,212 @@
|
|||
#ifndef _UNITREE_ARM_QUADRUPED_COMMON_H_
|
||||
#define _UNITREE_ARM_QUADRUPED_COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <array>
|
||||
|
||||
namespace UNITREE_LEGGED_SDK
|
||||
{
|
||||
|
||||
constexpr int HIGHLEVEL = 0xee;
|
||||
constexpr int LOWLEVEL = 0xff;
|
||||
constexpr int TRIGERLEVEL = 0xf0;
|
||||
constexpr double PosStopF = (2.146E+9f);
|
||||
constexpr double VelStopF = (16000.0f);
|
||||
extern const int HIGH_CMD_LENGTH; // sizeof(HighCmd)
|
||||
extern const int HIGH_STATE_LENGTH; // sizeof(HighState)
|
||||
extern const int LOW_CMD_LENGTH; // shorter than sizeof(LowCmd), bytes compressed LowCmd length
|
||||
extern const int LOW_STATE_LENGTH; // shorter than sizeof(LowState), bytes compressed LowState length
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t off; // off 0xA5
|
||||
std::array<uint8_t, 3> reserve;
|
||||
} BmsCmd;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t version_h;
|
||||
uint8_t version_l;
|
||||
uint8_t bms_status;
|
||||
uint8_t SOC; // SOC 0-100%
|
||||
int32_t current; // mA
|
||||
uint16_t cycle;
|
||||
std::array<int8_t, 8> BQ_NTC; // x1 degrees centigrade
|
||||
std::array<int8_t, 8> MCU_NTC; // x1 degrees centigrade
|
||||
std::array<uint16_t, 30> cell_vol; // cell voltage mV
|
||||
} BmsState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Cartesian;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::array<float, 4> quaternion; // quaternion, normalized, (w,x,y,z)
|
||||
std::array<float, 3> gyroscope; // angular velocity (unit: rad/s) (raw data)
|
||||
std::array<float, 3> accelerometer; // m/(s2) (raw data)
|
||||
std::array<float, 3> rpy; // euler angle(unit: rad)
|
||||
int8_t temperature;
|
||||
} IMU; // when under accelerated motion, the attitude of the robot calculated by IMU will drift.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} LED; // foot led brightness: 0~255
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode; // motor working mode
|
||||
float q; // current angle (unit: radian)
|
||||
float dq; // current velocity (unit: radian/second)
|
||||
float ddq; // current acc (unit: radian/second*second)
|
||||
float tauEst; // current estimated output torque (unit: N.m)
|
||||
float q_raw; // current angle (unit: radian)
|
||||
float dq_raw; // current velocity (unit: radian/second)
|
||||
float ddq_raw;
|
||||
int8_t temperature; // current temperature (temperature conduction is slow that leads to lag)
|
||||
std::array<uint32_t, 2> reserve;
|
||||
} MotorState; // motor feedback
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode; // desired working mode
|
||||
float q; // desired angle (unit: radian)
|
||||
float dq; // desired velocity (unit: radian/second)
|
||||
float tau; // desired output torque (unit: N.m)
|
||||
float Kp; // desired position stiffness (unit: N.m/rad )
|
||||
float Kd; // desired velocity stiffness (unit: N.m/(rad/s) )
|
||||
std::array<uint32_t, 3> reserve;
|
||||
} MotorCmd; // motor control
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::array<uint8_t, 2> head;
|
||||
uint8_t levelFlag;
|
||||
uint8_t frameReserve;
|
||||
|
||||
std::array<uint32_t, 2> SN;
|
||||
std::array<uint32_t, 2> version;
|
||||
uint16_t bandWidth;
|
||||
IMU imu;
|
||||
std::array<MotorState, 20> motorState;
|
||||
BmsState bms;
|
||||
std::array<int16_t, 4> footForce; // force sensors
|
||||
std::array<int16_t, 4> footForceEst; // force sensors
|
||||
uint32_t tick; // reference real-time from motion controller (unit: us)
|
||||
std::array<uint8_t, 40> wirelessRemote; // wireless commands
|
||||
uint32_t reserve;
|
||||
|
||||
uint32_t crc;
|
||||
} LowState; // low level feedback
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::array<uint8_t, 2> head;
|
||||
uint8_t levelFlag;
|
||||
uint8_t frameReserve;
|
||||
|
||||
std::array<uint32_t, 2> SN;
|
||||
std::array<uint32_t, 2> version;
|
||||
uint16_t bandWidth;
|
||||
std::array<MotorCmd, 20> motorCmd;
|
||||
BmsCmd bms;
|
||||
std::array<uint8_t, 40> wirelessRemote;
|
||||
uint32_t reserve;
|
||||
|
||||
uint32_t crc;
|
||||
} LowCmd; // low level control
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::array<uint8_t, 2> head;
|
||||
uint8_t levelFlag;
|
||||
uint8_t frameReserve;
|
||||
|
||||
std::array<uint32_t, 2> SN;
|
||||
std::array<uint32_t, 2> version;
|
||||
uint16_t bandWidth;
|
||||
IMU imu;
|
||||
std::array<MotorState, 20> motorState;
|
||||
BmsState bms;
|
||||
std::array<int16_t, 4> footForce;
|
||||
std::array<int16_t, 4> footForceEst;
|
||||
uint8_t mode;
|
||||
float progress;
|
||||
uint8_t gaitType; // 0.idle 1.trot 2.trot running 3.climb stair 4.trot obstacle
|
||||
float footRaiseHeight; // (unit: m, default: 0.08m), foot up height while walking
|
||||
std::array<float, 3> position; // (unit: m), from own odometry in inertial frame, usually drift
|
||||
float bodyHeight; // (unit: m, default: 0.28m),
|
||||
std::array<float, 3> velocity; // (unit: m/s), forwardSpeed, sideSpeed, rotateSpeed in body frame
|
||||
float yawSpeed; // (unit: rad/s), rotateSpeed in body frame
|
||||
std::array<float, 4> rangeObstacle;
|
||||
std::array<Cartesian, 4> footPosition2Body; // foot position relative to body
|
||||
std::array<Cartesian, 4> footSpeed2Body; // foot speed relative to body
|
||||
std::array<uint8_t, 40> wirelessRemote;
|
||||
uint32_t reserve;
|
||||
|
||||
uint32_t crc;
|
||||
} HighState; // high level feedback
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::array<uint8_t, 2> head;
|
||||
uint8_t levelFlag;
|
||||
uint8_t frameReserve;
|
||||
|
||||
std::array<uint32_t, 2> SN;
|
||||
std::array<uint32_t, 2> version;
|
||||
uint16_t bandWidth;
|
||||
uint8_t mode; // 0. idle, default stand 1. force stand (controlled by dBodyHeight + ypr)
|
||||
// 2. target velocity walking (controlled by velocity + yawSpeed)
|
||||
// 3. target position walking (controlled by position + ypr[0])
|
||||
// 4. path mode walking (reserve for future release)
|
||||
// 5. position stand down.
|
||||
// 6. position stand up
|
||||
// 7. damping mode
|
||||
// 8. recovery stand
|
||||
// 9. backflip
|
||||
// 10. jumpYaw
|
||||
// 11. straightHand
|
||||
// 12. dance1
|
||||
// 13. dance2
|
||||
|
||||
uint8_t gaitType; // 0.idle 1.trot 2.trot running 3.climb stair 4.trot obstacle
|
||||
uint8_t speedLevel; // 0. default low speed. 1. medium speed 2. high speed. during walking, only respond MODE 3
|
||||
float footRaiseHeight; // (unit: m, default: 0.08m), foot up height while walking, delta value
|
||||
float bodyHeight; // (unit: m, default: 0.28m), delta value
|
||||
std::array<float, 2> position; // (unit: m), desired position in inertial frame
|
||||
std::array<float, 3> euler; // (unit: rad), roll pitch yaw in stand mode
|
||||
std::array<float, 2> velocity; // (unit: m/s), forwardSpeed, sideSpeed in body frame
|
||||
float yawSpeed; // (unit: rad/s), rotateSpeed in body frame
|
||||
BmsCmd bms;
|
||||
std::array<LED, 4> led;
|
||||
std::array<uint8_t, 40> wirelessRemote;
|
||||
uint32_t reserve;
|
||||
|
||||
uint32_t crc;
|
||||
} HighCmd; // high level control
|
||||
|
||||
#pragma pack()
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long long TotalCount; // total loop count
|
||||
unsigned long long SendCount; // total send count
|
||||
unsigned long long RecvCount; // total receive count
|
||||
unsigned long long SendError; // total send error
|
||||
unsigned long long FlagError; // total flag error
|
||||
unsigned long long RecvCRCError; // total reveive CRC error
|
||||
unsigned long long RecvLoseError; // total lose package count
|
||||
} UDPState; // UDP communication state
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _UNITREE_ARM_JOYSTICK_H_
|
||||
#define _UNITREE_ARM_JOYSTICK_H_
|
||||
|
||||
#include <vector>
|
||||
#include "unitree_arm_sdk/udp.h"
|
||||
#include "unitree_arm_sdk/cmdPanel.h"
|
||||
#include "unitree_arm_sdk/common/quadruped_common.h"
|
||||
#include "unitree_arm_sdk/common/joystick_common.h"
|
||||
|
||||
using namespace UNITREE_LEGGED_SDK;
|
||||
|
||||
class UnitreeJoystick : public CmdPanel{
|
||||
public:
|
||||
UnitreeJoystick(std::vector<KeyAction*> events,
|
||||
EmptyAction emptyAction, size_t channelNum = 1,
|
||||
double dt = 0.002);
|
||||
~UnitreeJoystick();
|
||||
private:
|
||||
void _read();
|
||||
void _extractCmd();
|
||||
|
||||
xRockerBtnDataStruct _keyData;
|
||||
UDPPort *_udp;
|
||||
HighCmd _udpCmd;
|
||||
HighState _udpState;
|
||||
};
|
||||
|
||||
#endif // _UNITREE_ARM_JOYSTICK_H_
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef _UNITREE_ARM_KEYBOARD_H_
|
||||
#define _UNITREE_ARM_KEYBOARD_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
#include "unitree_arm_sdk/udp.h"
|
||||
#include "unitree_arm_sdk/common/arm_common.h"
|
||||
#include "unitree_arm_sdk/cmdPanel.h"
|
||||
|
||||
class Keyboard : public CmdPanel{
|
||||
public:
|
||||
Keyboard(std::vector<KeyAction*> events,
|
||||
EmptyAction emptyAction, size_t channelNum = 1, double dt = 0.002);
|
||||
~Keyboard();
|
||||
std::string getString(std::string slogan);
|
||||
std::vector<double> stringToArray(std::string slogan);
|
||||
std::vector<std::vector<double> > stringToMatrix(std::string slogan);
|
||||
private:
|
||||
void _read();
|
||||
void _pauseKey();
|
||||
void _startKey();
|
||||
void _extractCmd();
|
||||
|
||||
fd_set _set;
|
||||
char _c = '\0';
|
||||
|
||||
termios _oldSettings;
|
||||
termios _newSettings;
|
||||
timeval _tv;
|
||||
};
|
||||
|
||||
|
||||
class UnitreeKeyboardUDPSend : public CmdPanel{
|
||||
public:
|
||||
UnitreeKeyboardUDPSend(std::vector<KeyAction*> events,
|
||||
EmptyAction emptyAction, size_t channelNum = 1,
|
||||
double dt = 0.002);
|
||||
~UnitreeKeyboardUDPSend();
|
||||
std::string getString(std::string slogan);
|
||||
std::vector<double> stringToArray(std::string slogan);
|
||||
std::vector<std::vector<double> > stringToMatrix(std::string slogan);
|
||||
|
||||
private:
|
||||
// keyboard communication
|
||||
void _read();
|
||||
void _pauseKey();
|
||||
void _startKey();
|
||||
void _extractCmd();
|
||||
|
||||
fd_set _set;
|
||||
char _c = '\0';
|
||||
|
||||
termios _oldSettings;
|
||||
termios _newSettings;
|
||||
timeval _tv;
|
||||
|
||||
// udp communication
|
||||
void _communicationUDP();
|
||||
void _extractCmdKeyboard();
|
||||
|
||||
UDPPort *_udp;
|
||||
SendCmd _sendCmd;
|
||||
RecvState _recvState;
|
||||
std::vector<std::vector<double>> posture;
|
||||
std::string slogan;
|
||||
};
|
||||
|
||||
|
||||
class UnitreeKeyboardUDPRecv : public CmdPanel{
|
||||
public:
|
||||
UnitreeKeyboardUDPRecv(std::vector<KeyAction*> events,
|
||||
EmptyAction emptyAction, size_t channelNum = 1,
|
||||
double dt = 0.002);
|
||||
~UnitreeKeyboardUDPRecv();
|
||||
|
||||
SendCmd getSendCmd(){return _sendCmd;};
|
||||
void getRecvState(RecvState recvState){
|
||||
_recvState = recvState;
|
||||
};
|
||||
|
||||
private:
|
||||
void _read();
|
||||
void _extractCmd();
|
||||
|
||||
UDPPort *_udp;
|
||||
SendCmd _sendCmd;
|
||||
RecvState _recvState;
|
||||
};
|
||||
|
||||
#endif // _UNITREE_ARM_KEYBOARD_H_
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef _UNITREE_ARM_LOOP_H_
|
||||
#define _UNITREE_ARM_LOOP_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <pthread.h>
|
||||
#include <vector>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "unitree_arm_sdk/timer.h"
|
||||
|
||||
// constexpr int THREAD_PRIORITY = 99; // real-time priority
|
||||
|
||||
typedef boost::function<void ()> Callback;
|
||||
|
||||
class Loop {
|
||||
public:
|
||||
Loop(std::string name, float period, int bindCPU = -1);
|
||||
~Loop();
|
||||
void start();
|
||||
void shutdown();
|
||||
virtual void functionCB() = 0;
|
||||
|
||||
private:
|
||||
void entryFunc();
|
||||
|
||||
std::string _name;
|
||||
float _period;
|
||||
int _bindCPU;
|
||||
bool _bind_cpu_flag = false;
|
||||
bool _isrunning = false;
|
||||
std::thread _thread;
|
||||
|
||||
size_t _runTimes = 0;
|
||||
size_t _timeOutTimes = 0;
|
||||
|
||||
AbsoluteTimer *_timer;
|
||||
};
|
||||
|
||||
class LoopFunc : public Loop {
|
||||
public:
|
||||
LoopFunc(std::string name, float period, const Callback& _cb)
|
||||
: Loop(name, period), _fp(_cb){}
|
||||
LoopFunc(std::string name, float period, int bindCPU, const Callback& _cb)
|
||||
: Loop(name, period, bindCPU), _fp(_cb){}
|
||||
void functionCB() { (_fp)(); }
|
||||
private:
|
||||
boost::function<void ()> _fp;
|
||||
};
|
||||
|
||||
#endif // _UNITREE_ARM_LOOP_H_
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef _UNITREE_ARM_TIMER_H_
|
||||
#define _UNITREE_ARM_TIMER_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
//时间戳 微秒级, 需要#include <sys/time.h>
|
||||
inline long long getSystemTime(){
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
return 1000000 * t.tv_sec + t.tv_usec;
|
||||
}
|
||||
//时间戳 秒级, 需要getSystemTime()
|
||||
inline double getTimeSecond(){
|
||||
double time = getSystemTime() * 0.000001;
|
||||
return time;
|
||||
}
|
||||
/*
|
||||
等待函数,微秒级,从startTime开始等待waitTime微秒
|
||||
目前不推荐使用,建议使用AbsoluteTimer类
|
||||
*/
|
||||
inline void absoluteWait(long long startTime, long long waitTime){
|
||||
if(getSystemTime() - startTime > waitTime){
|
||||
std::cout << "[WARNING] The waitTime=" << waitTime << " of function absoluteWait is not enough!" << std::endl
|
||||
<< "The program has already cost " << getSystemTime() - startTime << "us." << std::endl;
|
||||
}
|
||||
while(getSystemTime() - startTime < waitTime){
|
||||
usleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
waitTimeS = 0 means do not care time out
|
||||
*/
|
||||
class AbsoluteTimer{
|
||||
public:
|
||||
AbsoluteTimer(double waitTimeS);
|
||||
~AbsoluteTimer();
|
||||
void start();
|
||||
bool wait();
|
||||
private:
|
||||
void _updateWaitTime(double waitTimeS);
|
||||
int _timerFd;
|
||||
uint64_t _missed;
|
||||
double _waitTime;
|
||||
double _startTime;
|
||||
double _leftTime;
|
||||
double _nextWaitTime;
|
||||
itimerspec _timerSpec;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef _UNITREE_ARM_UDP_H_
|
||||
#define _UNITREE_ARM_UDP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <arpa/inet.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "unitree_arm_sdk/common/arm_motor_common.h"
|
||||
|
||||
enum class BlockYN{
|
||||
YES,
|
||||
NO
|
||||
};
|
||||
|
||||
class IOPort{
|
||||
public:
|
||||
IOPort(BlockYN blockYN, size_t recvLength, size_t timeOutUs){
|
||||
resetIO(blockYN, recvLength, timeOutUs);
|
||||
}
|
||||
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<MOTOR_send> &sendVec, std::vector<MOTOR_recv> &recvVec) = 0;
|
||||
void resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs);
|
||||
protected:
|
||||
BlockYN _blockYN = BlockYN::NO;
|
||||
size_t _recvLength;
|
||||
timeval _timeout;
|
||||
timeval _timeoutSaved;
|
||||
};
|
||||
|
||||
|
||||
class UDPPort : public IOPort{
|
||||
public:
|
||||
UDPPort(std::string toIP, uint toPort, uint ownPort,
|
||||
size_t recvLength = 0,
|
||||
BlockYN blockYN = BlockYN::NO,
|
||||
size_t timeOutUs = 20000);
|
||||
~UDPPort();
|
||||
size_t send(uint8_t *sendMsg, size_t sendMsgLength);
|
||||
size_t recv(uint8_t *recvMsg, size_t recvLength);
|
||||
size_t recv(uint8_t *recvMsg);
|
||||
bool sendRecv(std::vector<MOTOR_send> &sendVec, std::vector<MOTOR_recv> &recvVec);
|
||||
private:
|
||||
size_t _recvBlock(uint8_t *recvMsg, size_t recvLength);
|
||||
size_t _recvUnBlock(uint8_t *recvMsg, size_t recvLength);
|
||||
sockaddr_in _ownAddr, _toAddr, _fromAddr;
|
||||
socklen_t _sockaddrSize;
|
||||
int _sockfd;
|
||||
int _on = 1;
|
||||
size_t _sentLength;
|
||||
|
||||
uint8_t _sendBytes[238]; // 7 motors
|
||||
uint8_t _recvBytes[546]; // 7 motors
|
||||
|
||||
fd_set _rSet;
|
||||
};
|
||||
|
||||
#endif // _UNITREE_ARM_UDP_H_
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _UNITREE_ARM_SDK_H_
|
||||
#define _UNITREE_ARM_SDK_H_
|
||||
|
||||
#include "unitree_arm_sdk/timer.h"
|
||||
#include "unitree_arm_sdk/common/arm_motor_common.h"
|
||||
#include "unitree_arm_sdk/common/arm_common.h"
|
||||
#include "unitree_arm_sdk/common/quadruped_common.h"
|
||||
#include "unitree_arm_sdk/udp.h"
|
||||
#include "unitree_arm_sdk/loop.h"
|
||||
#include "unitree_arm_sdk/joystick.h"
|
||||
#include "unitree_arm_sdk/keyboard.h"
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue