unitree_ros/unitree_legged_real/src/exe/position_mode.cpp

160 lines
5.5 KiB
C++
Raw Normal View History

2020-07-15 11:21:03 +08:00
/************************************************************************
Copyright (c) 2018-2019, Unitree Robotics.Co.Ltd. All rights reserved.
Use of this source code is governed by the MPL-2.0 license, see LICENSE.
************************************************************************/
#include <ros/ros.h>
#include <unitree_legged_msgs/LowCmd.h>
#include <unitree_legged_msgs/LowState.h>
#include "unitree_legged_sdk/unitree_legged_sdk.h"
#include "convert.h"
using namespace UNITREE_LEGGED_SDK;
class Custom
{
public:
Custom() {}
void LCMRecv();
LCM roslcm;
};
void Custom::LCMRecv()
{
roslcm.Recv();
}
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;
}
int main(int argc, char *argv[])
{
std::cout << "WARNING: Control level is set to LOW-level." << std::endl
<< "Make sure the robot is hung up." << std::endl
<< "Press Enter to continue..." << std::endl;
std::cin.ignore();
ros::init(argc, argv, "position_ros_mode");
ros::NodeHandle n;
ros::Rate loop_rate(500);
Custom custom;
SetLevel(LOWLEVEL); // must have this
long motiontime = 0;
int rate_count = 0;
int sin_count = 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};
LowCmd SendLowLCM = {0};
LowState RecvLowLCM = {0};
unitree_legged_msgs::LowCmd SendLowROS;
unitree_legged_msgs::LowState RecvLowROS;
bool initiated_flag = false; // initiate need time
int count = 0;
custom.roslcm.SubscribeState();
LoopFunc loop_lcm("LCM_Recv", 0.002, 3, boost::bind(&Custom::LCMRecv, &custom));
loop_lcm.start();
SendLowROS.levelFlag = LOWLEVEL;
for(int i = 0; i<12; i++){
SendLowROS.motorCmd[i].mode = 0x0A; // motor switch to servo (PMSM) mode
SendLowROS.motorCmd[i].q = PosStopF; // 禁止位置环
SendLowROS.motorCmd[i].Kp = 0;
SendLowROS.motorCmd[i].dq = VelStopF; // 禁止速度环
SendLowROS.motorCmd[i].Kd = 0;
SendLowROS.motorCmd[i].tau = 0;
}
while (ros::ok()){
custom.roslcm.Get(RecvLowLCM);
RecvLowROS = ToRos(RecvLowLCM);
if(initiated_flag == true){
motiontime++;
SendLowROS.motorCmd[FR_0].tau = -0.65f;
SendLowROS.motorCmd[FL_0].tau = +0.65f;
SendLowROS.motorCmd[RR_0].tau = -0.65f;
SendLowROS.motorCmd[RL_0].tau = +0.65f;
// printf("%d\n", motiontime);
// printf("%d %f %f %f\n", FR_0, RecvLowROS.motorState[FR_0].q, RecvLowROS.motorState[FR_1].q, RecvLowROS.motorState[FR_2].q);
// printf("%f %f \n", RecvLowROS.motorState[FR_0].mode, RecvLowROS.motorState[FR_1].mode);
if( motiontime >= 0){
// first, get record initial position
// if( motiontime >= 100 && motiontime < 500){
if( motiontime >= 0 && motiontime < 10){
qInit[0] = RecvLowROS.motorState[FR_0].q;
qInit[1] = RecvLowROS.motorState[FR_1].q;
qInit[2] = RecvLowROS.motorState[FR_2].q;
}
if( motiontime >= 10 && motiontime < 400){
// printf("%f %f %f\n", );
rate_count++;
double rate = rate_count/200.0; // needs count to 200
Kp[0] = 5.0; Kp[1] = 5.0; Kp[2] = 5.0;
Kd[0] = 1.0; Kd[1] = 1.0; Kd[2] = 1.0;
qDes[0] = jointLinearInterpolation(qInit[0], sin_mid_q[0], rate);
qDes[1] = jointLinearInterpolation(qInit[1], sin_mid_q[1], rate);
qDes[2] = jointLinearInterpolation(qInit[2], sin_mid_q[2], rate);
}
double sin_joint1, sin_joint2;
// last, do sine wave
if( motiontime >= 1700){
sin_count++;
sin_joint1 = 0.6 * sin(3*M_PI*sin_count/1000.0);
sin_joint2 = -0.6 * sin(1.8*M_PI*sin_count/1000.0);
qDes[0] = sin_mid_q[0];
qDes[1] = sin_mid_q[1];
qDes[2] = sin_mid_q[2] + sin_joint2;
// qDes[2] = sin_mid_q[2];
}
SendLowROS.motorCmd[FR_0].q = qDes[0];
SendLowROS.motorCmd[FR_0].dq = 0;
SendLowROS.motorCmd[FR_0].Kp = Kp[0];
SendLowROS.motorCmd[FR_0].Kd = Kd[0];
SendLowROS.motorCmd[FR_0].tau = -0.65f;
SendLowROS.motorCmd[FR_1].q = qDes[1];
SendLowROS.motorCmd[FR_1].dq = 0;
SendLowROS.motorCmd[FR_1].Kp = Kp[1];
SendLowROS.motorCmd[FR_1].Kd = Kd[1];
SendLowROS.motorCmd[FR_1].tau = 0.0f;
SendLowROS.motorCmd[FR_2].q = qDes[2];
SendLowROS.motorCmd[FR_2].dq = 0;
SendLowROS.motorCmd[FR_2].Kp = Kp[2];
SendLowROS.motorCmd[FR_2].Kd = Kd[2];
SendLowROS.motorCmd[FR_2].tau = 0.0f;
}
}
SendLowLCM = ToLcm(SendLowROS);
custom.roslcm.Send(SendLowLCM);
ros::spinOnce();
loop_rate.sleep();
count++;
if(count > 10){
count = 10;
initiated_flag = true;
}
}
return 0;
}