2024-09-12 13:56:51 +08:00
|
|
|
//
|
|
|
|
// Created by biao on 24-9-12.
|
|
|
|
//
|
|
|
|
|
2024-09-12 20:04:20 +08:00
|
|
|
#include <iostream>
|
2024-09-14 17:54:39 +08:00
|
|
|
#include "unitree_guide_controller/control/CtrlComponent.h"
|
|
|
|
#include "unitree_guide_controller/robot/QuadrupedRobot.h"
|
2024-09-12 13:56:51 +08:00
|
|
|
|
2024-09-20 12:48:45 +08:00
|
|
|
void QuadrupedRobot::init(const std::string &robot_description, const std::vector<std::string> &feet_names) {
|
2024-09-12 13:56:51 +08:00
|
|
|
KDL::Tree robot_tree;
|
|
|
|
kdl_parser::treeFromString(robot_description, robot_tree);
|
|
|
|
|
2024-09-20 12:48:45 +08:00
|
|
|
robot_tree.getChain("base", feet_names[0], fr_chain_);
|
|
|
|
robot_tree.getChain("base", feet_names[1], fl_chain_);
|
|
|
|
robot_tree.getChain("base", feet_names[2], rr_chain_);
|
|
|
|
robot_tree.getChain("base", feet_names[3], rl_chain_);
|
|
|
|
|
2024-09-12 13:56:51 +08:00
|
|
|
|
2024-09-12 20:04:20 +08:00
|
|
|
robot_legs_.resize(4);
|
|
|
|
robot_legs_[0] = std::make_shared<RobotLeg>(fr_chain_);
|
|
|
|
robot_legs_[1] = std::make_shared<RobotLeg>(fl_chain_);
|
|
|
|
robot_legs_[2] = std::make_shared<RobotLeg>(rr_chain_);
|
|
|
|
robot_legs_[3] = std::make_shared<RobotLeg>(rl_chain_);
|
|
|
|
|
2024-09-13 15:00:20 +08:00
|
|
|
current_joint_pos_.resize(4);
|
|
|
|
current_joint_vel_.resize(4);
|
|
|
|
|
2024-09-12 20:04:20 +08:00
|
|
|
std::cout << "robot_legs_.size(): " << robot_legs_.size() << std::endl;
|
2024-09-12 13:56:51 +08:00
|
|
|
|
|
|
|
// calculate total mass from urdf
|
2024-09-12 20:04:20 +08:00
|
|
|
mass_ = 0;
|
2024-09-12 13:56:51 +08:00
|
|
|
for (const auto &[fst, snd]: robot_tree.getSegments()) {
|
2024-09-12 20:04:20 +08:00
|
|
|
mass_ += snd.segment.getInertia().getMass();
|
2024-09-12 13:56:51 +08:00
|
|
|
}
|
2024-09-19 14:00:43 +08:00
|
|
|
feet_pos_normal_stand_ << 0.1881, 0.1881, -0.1881, -0.1881, -0.1300, 0.1300,
|
|
|
|
-0.1300, 0.1300, -0.3200, -0.3200, -0.3200, -0.3200;
|
2024-09-12 13:56:51 +08:00
|
|
|
}
|
|
|
|
|
2024-09-13 15:00:20 +08:00
|
|
|
std::vector<KDL::JntArray> QuadrupedRobot::getQ(const std::vector<KDL::Frame> &pEe_list) const {
|
2024-09-12 13:56:51 +08:00
|
|
|
std::vector<KDL::JntArray> result;
|
|
|
|
result.resize(4);
|
|
|
|
for (int i(0); i < 4; ++i) {
|
2024-09-13 15:00:20 +08:00
|
|
|
result[i] = robot_legs_[i]->calcQ(pEe_list[i], current_joint_pos_[i]);
|
2024-09-12 13:56:51 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-09-18 19:37:01 +08:00
|
|
|
Vec12 QuadrupedRobot::getQ(const Vec34 &vecP) const {
|
|
|
|
Vec12 q;
|
|
|
|
for (int i(0); i < 4; ++i) {
|
|
|
|
KDL::Frame frame;
|
|
|
|
frame.p = KDL::Vector(vecP.col(i)[0], vecP.col(i)[1], vecP.col(i)[2]);
|
2024-09-19 17:16:17 +08:00
|
|
|
frame.M = KDL::Rotation::Identity();
|
2024-09-18 19:37:01 +08:00
|
|
|
q.segment(3 * i, 3) = robot_legs_[i]->calcQ(frame, current_joint_pos_[i]).data;
|
|
|
|
}
|
|
|
|
return q;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vec12 QuadrupedRobot::getQd(const std::vector<KDL::Frame> &pos, const Vec34 &vel) {
|
|
|
|
Vec12 qd;
|
2024-09-19 17:16:17 +08:00
|
|
|
const std::vector<KDL::JntArray> q = getQ(pos);
|
2024-09-18 19:37:01 +08:00
|
|
|
for (int i(0); i < 4; ++i) {
|
|
|
|
Mat3 jacobian = robot_legs_[i]->calcJaco(q[i]).data.topRows(3);
|
|
|
|
qd.segment(3 * i, 3) = jacobian.inverse() * vel.col(i);
|
|
|
|
}
|
|
|
|
return qd;
|
|
|
|
}
|
|
|
|
|
2024-09-16 21:15:34 +08:00
|
|
|
std::vector<KDL::Frame> QuadrupedRobot::getFeet2BPositions() const {
|
2024-09-12 13:56:51 +08:00
|
|
|
std::vector<KDL::Frame> result;
|
|
|
|
result.resize(4);
|
2024-09-12 20:04:20 +08:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2024-09-16 21:15:34 +08:00
|
|
|
result[i] = robot_legs_[i]->calcPEe2B(current_joint_pos_[i]);
|
2024-09-20 12:48:45 +08:00
|
|
|
result[i].M = KDL::Rotation::Identity();
|
2024-09-12 13:56:51 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2024-09-12 20:04:20 +08:00
|
|
|
|
2024-09-13 15:00:20 +08:00
|
|
|
KDL::Frame QuadrupedRobot::getFeet2BPositions(const int index) const {
|
|
|
|
return robot_legs_[index]->calcPEe2B(current_joint_pos_[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDL::Jacobian QuadrupedRobot::getJacobian(const int index) const {
|
|
|
|
return robot_legs_[index]->calcJaco(current_joint_pos_[index]);
|
2024-09-12 20:04:20 +08:00
|
|
|
}
|
|
|
|
|
2024-09-13 15:00:20 +08:00
|
|
|
KDL::JntArray QuadrupedRobot::getTorque(
|
2024-09-17 18:21:04 +08:00
|
|
|
const Vec3 &force, const int index) const {
|
2024-09-17 14:03:08 +08:00
|
|
|
return robot_legs_[index]->calcTorque(current_joint_pos_[index], force);
|
2024-09-12 20:04:20 +08:00
|
|
|
}
|
|
|
|
|
2024-09-17 18:21:04 +08:00
|
|
|
KDL::JntArray QuadrupedRobot::getTorque(const KDL::Vector &force, int index) const {
|
|
|
|
return robot_legs_[index]->calcTorque(current_joint_pos_[index], Vec3(force.data));
|
|
|
|
}
|
|
|
|
|
2024-09-16 13:44:08 +08:00
|
|
|
KDL::Vector QuadrupedRobot::getFeet2BVelocities(const int index) const {
|
2024-09-19 17:16:17 +08:00
|
|
|
const Mat3 jacobian = getJacobian(index).data.topRows(3);
|
|
|
|
Vec3 foot_velocity = jacobian * current_joint_vel_[index].data;
|
2024-09-16 13:44:08 +08:00
|
|
|
return {foot_velocity(0), foot_velocity(1), foot_velocity(2)};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<KDL::Vector> QuadrupedRobot::getFeet2BVelocities() const {
|
|
|
|
std::vector<KDL::Vector> result;
|
|
|
|
result.resize(4);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
result[i] = getFeet2BVelocities(i);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-09-18 13:52:37 +08:00
|
|
|
void QuadrupedRobot::update() {
|
2024-09-16 21:15:34 +08:00
|
|
|
if (mass_ == 0) return;
|
2024-09-13 15:00:20 +08:00
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
KDL::JntArray pos_array(3);
|
2024-09-18 13:52:37 +08:00
|
|
|
pos_array(0) = ctrl_component_.joint_position_state_interface_[i * 3].get().get_value();
|
|
|
|
pos_array(1) = ctrl_component_.joint_position_state_interface_[i * 3 + 1].get().get_value();
|
|
|
|
pos_array(2) = ctrl_component_.joint_position_state_interface_[i * 3 + 2].get().get_value();
|
2024-09-13 15:00:20 +08:00
|
|
|
current_joint_pos_[i] = pos_array;
|
|
|
|
|
|
|
|
KDL::JntArray vel_array(3);
|
2024-09-18 13:52:37 +08:00
|
|
|
vel_array(0) = ctrl_component_.joint_velocity_state_interface_[i * 3].get().get_value();
|
|
|
|
vel_array(1) = ctrl_component_.joint_velocity_state_interface_[i * 3 + 1].get().get_value();
|
|
|
|
vel_array(2) = ctrl_component_.joint_velocity_state_interface_[i * 3 + 2].get().get_value();
|
2024-09-13 15:00:20 +08:00
|
|
|
current_joint_vel_[i] = vel_array;
|
|
|
|
}
|
2024-09-12 20:04:20 +08:00
|
|
|
}
|