walk-these-ways-go2/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position.cpp

237 lines
6.6 KiB
C++
Raw Normal View History

2024-01-28 17:11:38 +08:00
/*****************************************************************
Copyright (c) 2020, Unitree Robotics.Co.Ltd. All rights reserved.
******************************************************************/
#include "unitree_legged_sdk/unitree_legged_sdk.h"
#include "unitree_legged_sdk/joystick.h"
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <stdint.h>
#include <thread>
#include <lcm/lcm-cpp.hpp>
#include "state_estimator_lcmt.hpp"
#include "leg_control_data_lcmt.hpp"
#include "pd_tau_targets_lcmt.hpp"
#include "rc_command_lcmt.hpp"
using namespace std;
using namespace UNITREE_LEGGED_SDK;
class Custom
{
public:
Custom(uint8_t level): safe(LeggedType::Go1), udp(level, 8090, "192.168.123.10", 8007) {
udp.InitCmdData(cmd);
}
void UDPRecv();
void UDPSend();
void RobotControl();
void init();
void handleActionLCM(const lcm::ReceiveBuffer *rbuf, const std::string & chan, const pd_tau_targets_lcmt * msg);
void _simpleLCMThread();
Safety safe;
UDP udp;
LowCmd cmd = {0};
LowState state = {0};
float qInit[3]={0};
float qDes[3]={0};
float sin_mid_q[3] = {0.0, 1.2, -2.0};
float Kp[3] = {0};
float Kd[3] = {0};
double time_consume = 0;
int rate_count = 0;
int sin_count = 0;
int motiontime = 0;
float dt = 0.002; // 0.001~0.01
lcm::LCM _simpleLCM;
std::thread _simple_LCM_thread;
bool _firstCommandReceived;
bool _firstRun;
state_estimator_lcmt body_state_simple = {0};
leg_control_data_lcmt joint_state_simple = {0};
pd_tau_targets_lcmt joint_command_simple = {0};
rc_command_lcmt rc_command = {0};
xRockerBtnDataStruct _keyData;
int mode = 0;
};
void Custom::init()
{
_simpleLCM.subscribe("pd_plustau_targets", &Custom::handleActionLCM, this);
_simple_LCM_thread = std::thread(&Custom::_simpleLCMThread, this);
_firstCommandReceived = false;
_firstRun = true;
// set nominal pose
for(int i = 0; i < 12; i++){
joint_command_simple.qd_des[i] = 0;
joint_command_simple.tau_ff[i] = 0;
joint_command_simple.kp[i] = 20.;
joint_command_simple.kd[i] = 0.5;
}
joint_command_simple.q_des[0] = -0.3;
joint_command_simple.q_des[1] = 1.2;
joint_command_simple.q_des[2] = -2.721;
joint_command_simple.q_des[3] = 0.3;
joint_command_simple.q_des[4] = 1.2;
joint_command_simple.q_des[5] = -2.721;
joint_command_simple.q_des[6] = -0.3;
joint_command_simple.q_des[7] = 1.2;
joint_command_simple.q_des[8] = -2.721;
joint_command_simple.q_des[9] = 0.3;
joint_command_simple.q_des[10] = 1.2;
joint_command_simple.q_des[11] = -2.721;
printf("SET NOMINAL POSE");
}
void Custom::UDPRecv()
{
udp.Recv();
}
void Custom::UDPSend()
{
udp.Send();
}
double jointLinearInterpolation(double initPos, double targetPos, double rate)
{
double p;
rate = std::min(std::max(rate, 0.0), 1.0);
p = initPos*(1-rate) + targetPos*rate;
return p;
}
void Custom::handleActionLCM(const lcm::ReceiveBuffer *rbuf, const std::string & chan, const pd_tau_targets_lcmt * msg){
(void) rbuf;
(void) chan;
joint_command_simple = *msg;
_firstCommandReceived = true;
}
void Custom::_simpleLCMThread(){
while(true){
_simpleLCM.handle();
}
}
void Custom::RobotControl()
{
motiontime++;
udp.GetRecv(state);
memcpy(&_keyData, &state.wirelessRemote[0], 40);
rc_command.left_stick[0] = _keyData.lx;
rc_command.left_stick[1] = _keyData.ly;
rc_command.right_stick[0] = _keyData.rx;
rc_command.right_stick[1] = _keyData.ry;
rc_command.right_lower_right_switch = _keyData.btn.components.R2;
rc_command.right_upper_switch = _keyData.btn.components.R1;
rc_command.left_lower_left_switch = _keyData.btn.components.L2;
rc_command.left_upper_switch = _keyData.btn.components.L1;
if(_keyData.btn.components.A > 0){
mode = 0;
} else if(_keyData.btn.components.B > 0){
mode = 1;
}else if(_keyData.btn.components.X > 0){
mode = 2;
}else if(_keyData.btn.components.Y > 0){
mode = 3;
}else if(_keyData.btn.components.up > 0){
mode = 4;
}else if(_keyData.btn.components.right > 0){
mode = 5;
}else if(_keyData.btn.components.down > 0){
mode = 6;
}else if(_keyData.btn.components.left > 0){
mode = 7;
}
rc_command.mode = mode;
// publish state to LCM
for(int i = 0; i < 12; i++){
joint_state_simple.q[i] = state.motorState[i].q;
joint_state_simple.qd[i] = state.motorState[i].dq;
joint_state_simple.tau_est[i] = state.motorState[i].tauEst;
}
for(int i = 0; i < 4; i++){
body_state_simple.quat[i] = state.imu.quaternion[i];
}
for(int i = 0; i < 3; i++){
body_state_simple.rpy[i] = state.imu.rpy[i];
body_state_simple.aBody[i] = state.imu.accelerometer[i];
body_state_simple.omegaBody[i] = state.imu.gyroscope[i];
}
for(int i = 0; i < 4; i++){
body_state_simple.contact_estimate[i] = state.footForce[i];
}
_simpleLCM.publish("state_estimator_data", &body_state_simple);
_simpleLCM.publish("leg_control_data", &joint_state_simple);
_simpleLCM.publish("rc_command", &rc_command);
if(_firstRun && joint_state_simple.q[0] != 0){
for(int i = 0; i < 12; i++){
joint_command_simple.q_des[i] = joint_state_simple.q[i];
}
_firstRun = false;
}
for(int i = 0; i < 12; i++){
cmd.motorCmd[i].q = joint_command_simple.q_des[i];
cmd.motorCmd[i].dq = joint_command_simple.qd_des[i];
cmd.motorCmd[i].Kp = joint_command_simple.kp[i];
cmd.motorCmd[i].Kd = joint_command_simple.kd[i];
cmd.motorCmd[i].tau = joint_command_simple.tau_ff[i];
}
safe.PositionLimit(cmd);
int res1 = safe.PowerProtect(cmd, state, 9);
udp.SetSend(cmd);
}
int main(void)
{
std::cout << "Communication level is set to LOW-level." << std::endl
<< "WARNING: Make sure the robot is hung up." << std::endl
<< "Press Enter to continue..." << std::endl;
std::cin.ignore();
Custom custom(LOWLEVEL);
custom.init();
// InitEnvironment();
LoopFunc loop_control("control_loop", custom.dt, boost::bind(&Custom::RobotControl, &custom));
LoopFunc loop_udpSend("udp_send", custom.dt, 3, boost::bind(&Custom::UDPSend, &custom));
LoopFunc loop_udpRecv("udp_recv", custom.dt, 3, boost::bind(&Custom::UDPRecv, &custom));
loop_udpSend.start();
loop_udpRecv.start();
loop_control.start();
while(1){
sleep(10);
};
return 0;
}