抽象力控
This commit is contained in:
parent
5f7c7042bf
commit
493e8082be
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include "mdog_simple_controller/FSM/fsm_state.hpp"
|
||||
|
||||
namespace mdog_simple_controller {
|
||||
@ -12,10 +13,27 @@ public:
|
||||
|
||||
private:
|
||||
bool inited = false;
|
||||
bool if_stand = false;
|
||||
uint16_t joint_reached = 0;
|
||||
float max_speed = 0.001;
|
||||
float pos_threshold = 0.01;
|
||||
float speed_threshold = 0.01;
|
||||
// 默认PD参数
|
||||
std::array<double, 3> kp = {4.5, 4.5, 4.5};
|
||||
std::array<double, 3> kd = {0.05, 0.05, 0.05};
|
||||
|
||||
std::array<std::array<double, 3>, 4> stand_pos;
|
||||
std::array<std::array<double, 3>, 4> stand_foot_pos = {
|
||||
{
|
||||
{0.0, 0.05, -0.25}, // FR
|
||||
{0.0, 0.05, -0.25}, // FL
|
||||
{0.0, 0.05, -0.25}, // RR
|
||||
{0.0, 0.05, -0.25} // RL
|
||||
}
|
||||
};
|
||||
|
||||
std::array<std::array<double, 3>, 4> start_pos;
|
||||
std::array<std::array<double, 3>, 4> target_joint_pos;
|
||||
std::array<std::array<double, 3>, 4> start_joint_pos;
|
||||
std::array<std::array<double, 3>, 4> last_joint_pos;
|
||||
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,8 @@ void real_to_feedback(const MdogControllerData& src, MdogControllerData& dst);
|
||||
// real cmd → 输出 cmd
|
||||
void realcmd_to_cmd(const MdogControllerData& src, MdogControllerData& dst);
|
||||
|
||||
void set_pd_config(MdogControllerData& data, const std::array<float, 3>& kp, const std::array<float, 3>& kd);
|
||||
|
||||
|
||||
double limit_speed(double current, double target, double max_speed);
|
||||
int8_t get_direction(double target, double current);
|
||||
} // namespace mdog_simple_controller
|
@ -68,6 +68,9 @@ public:
|
||||
|
||||
MdogControllerData data_;
|
||||
InputCmd input_cmd_;
|
||||
|
||||
bool if_no_hardware_{false};
|
||||
bool if_debug_{false};
|
||||
private:
|
||||
void fdb_callback(const rc_msgs::msg::LegFdb::SharedPtr msg);
|
||||
void input_callback(const control_input_msgs::msg::Inputs::SharedPtr msg);
|
||||
@ -82,7 +85,7 @@ private:
|
||||
StateBalance state_balance_;
|
||||
StateTroting state_troting_;
|
||||
|
||||
bool if_no_hardware_{false};
|
||||
|
||||
|
||||
rclcpp::Subscription<rc_msgs::msg::LegFdb>::SharedPtr fdb_sub_;
|
||||
rclcpp::Subscription<control_input_msgs::msg::Inputs>::SharedPtr input_sub_;
|
||||
|
@ -1,14 +1,65 @@
|
||||
#include "mdog_simple_controller/FSM/state_stand.hpp"
|
||||
#include "mdog_simple_controller/mdog_simple_controller.hpp"
|
||||
|
||||
#include "mdog_simple_controller/common/kinematics.hpp"
|
||||
#include "mdog_simple_controller/common/user_math.hpp"
|
||||
namespace mdog_simple_controller {
|
||||
|
||||
void StateStand::enter(MdogSimpleController* ctrl) {
|
||||
inited = false;
|
||||
if_stand = false;
|
||||
max_speed = 0.04;
|
||||
joint_reached = 0;
|
||||
pos_threshold = 0.01;
|
||||
speed_threshold = 0.01;
|
||||
|
||||
const auto& hip_signs = kinematics::get_hip_signs();
|
||||
|
||||
for (int leg = 0; leg < 4; ++leg) {
|
||||
kinematics::inverse_kinematics(stand_foot_pos[leg], kinematics::get_leg_link_length(), target_joint_pos[leg]);
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
start_joint_pos[leg][j] = ctrl->data_.feedback_real[leg].pos[j];
|
||||
last_joint_pos[leg][j] = start_joint_pos[leg][j];
|
||||
ctrl->data_.command_real[leg].pos_des[j] = 0;
|
||||
ctrl->data_.command_real[leg].speed_des[j] = 0;
|
||||
ctrl->data_.command_real[leg].torque_des[j] = 0;
|
||||
ctrl->data_.command_real[leg].kp[j] = kp[j];
|
||||
ctrl->data_.command_real[leg].kd[j] = kd[j];
|
||||
|
||||
|
||||
}
|
||||
target_joint_pos[leg][0] *= hip_signs[leg];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StateStand::run(MdogSimpleController* ctrl) {
|
||||
// SAFE状态下的控制逻辑
|
||||
|
||||
if (!if_stand) {
|
||||
for (int leg = 0; leg < 4; ++leg) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
ctrl->data_.command_real[leg].pos_des[j] = limit_speed(ctrl->data_.feedback_real[leg].pos[j], target_joint_pos[leg][j], max_speed);
|
||||
if (!ctrl->if_no_hardware_){
|
||||
if (std::abs(ctrl->data_.feedback_real[leg].pos[j] - target_joint_pos[leg][j]) > pos_threshold) {
|
||||
if (std::abs(ctrl->data_.feedback_real[leg].speed[j]) < speed_threshold) {
|
||||
ctrl->data_.command_real[leg].torque_des[j] += 0.01*get_direction(target_joint_pos[leg][j], ctrl->data_.feedback_real[leg].pos[j]);
|
||||
RCLCPP_INFO(ctrl->get_logger(), "leg %d joint %d torque_des: %f", leg, j, ctrl->data_.command_real[leg].torque_des[j]);
|
||||
|
||||
} else {
|
||||
ctrl->data_.command_real[leg].speed_des[j] = 0;
|
||||
}
|
||||
}
|
||||
if (std::abs(ctrl->data_.feedback_real[leg].pos[j] - target_joint_pos[leg][j]) < 0.01) {
|
||||
//将对应标志位置为1
|
||||
joint_reached |= (1 << (leg * 3 + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (joint_reached == 0b0000111111111111) {
|
||||
if_stand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
realcmd_to_cmd(ctrl->data_, ctrl->data_);
|
||||
}
|
||||
|
||||
void StateStand::exit(MdogSimpleController* ctrl) {
|
||||
|
@ -47,9 +47,40 @@ void realcmd_to_cmd(const MdogControllerData& src, MdogControllerData& dst) {
|
||||
}
|
||||
}
|
||||
|
||||
// 插补函数
|
||||
double interpolate(double start, double end, double alpha) {
|
||||
return (1 - alpha) * start + alpha * end;
|
||||
void set_pd_config(MdogControllerData& data, const std::array<float, 3>& kp, const std::array<float, 3>& kd) {
|
||||
for (int leg = 0; leg < 4; ++leg) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
data.command[leg].kp[j] = kp[j];
|
||||
data.command[leg].kd[j] = kd[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pd计算公式:
|
||||
// u =du + kp * (target - current) + kd * (target_speed - current_speed)
|
||||
|
||||
// double simple_torque_ctrl(double detal_pos, )
|
||||
|
||||
//计算方向
|
||||
int8_t get_direction(double target, double current) {
|
||||
if (target > current) {
|
||||
return 1;
|
||||
} else if (target < current) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 移动速度最大限制器
|
||||
double limit_speed(double current, double target, double max_speed) {
|
||||
double diff = target - current;
|
||||
if (diff > max_speed) {
|
||||
return current + max_speed;
|
||||
} else if (diff < -max_speed) {
|
||||
return current - max_speed;
|
||||
}
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
} // namespace mdog_simple_controller
|
@ -18,6 +18,8 @@ MdogSimpleController::MdogSimpleController() : Node("mdog_simple_controller") {
|
||||
joint_state_pub_ = this->create_publisher<sensor_msgs::msg::JointState>("joint_states", 10);
|
||||
|
||||
if_no_hardware_ = this->declare_parameter<bool>("if_no_hardware", false);
|
||||
if_debug_ = this->declare_parameter<bool>("if_debug", false);
|
||||
|
||||
memset(&data_, 0, sizeof(data_));
|
||||
current_state_ = &state_zero_;
|
||||
current_state_->enter(this);
|
||||
@ -48,7 +50,7 @@ void MdogSimpleController::input_callback(const control_input_msgs::msg::Inputs:
|
||||
input_cmd_.voltage.vx = msg->lx;
|
||||
input_cmd_.voltage.vy = msg->ly;
|
||||
input_cmd_.voltage.wz = msg->rx;
|
||||
// input_cmd_.hight = 0.35;
|
||||
input_cmd_.hight = 0.35;
|
||||
input_cmd_.status = msg->command;
|
||||
}
|
||||
|
||||
@ -62,9 +64,10 @@ void MdogSimpleController::control_loop() {
|
||||
FSMState* target_state = nullptr;
|
||||
switch (input_cmd_.status) {
|
||||
case 0: target_state = &state_safe_; break;
|
||||
case 6: target_state = &state_balance_; break;
|
||||
case 7: target_state = &state_troting_; break;
|
||||
case 8: target_state = &state_walk_; break;
|
||||
// case 5: target_state = &state_balance_; break;
|
||||
// case 6: target_state = &state_troting_; break;
|
||||
// case 7: target_state = &state_walk_; break;
|
||||
case 8: target_state = &state_stand_; break;
|
||||
default: target_state = &state_safe_; break;
|
||||
}
|
||||
if (target_state != current_state_) {
|
||||
@ -75,9 +78,6 @@ void MdogSimpleController::control_loop() {
|
||||
if (if_no_hardware_) {
|
||||
for (int leg = 0; leg < 4; ++leg) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
// data_.feedback[leg].torque[j] = data_.command[leg].torque_des[j];
|
||||
// data_.feedback[leg].speed[j] = data_.command[leg].speed_des[j];
|
||||
// data_.feedback[leg].pos[j] = data_.command[leg].pos_des[j];
|
||||
data_.feedback_real[leg].torque[j] = data_.command_real[leg].torque_des[j];
|
||||
data_.feedback_real[leg].speed[j] = data_.command_real[leg].speed_des[j];
|
||||
data_.feedback_real[leg].pos[j] = data_.command_real[leg].pos_des[j];
|
||||
@ -85,8 +85,7 @@ void MdogSimpleController::control_loop() {
|
||||
data_.feedback[leg].speed[j] = data_.command_real[leg].speed_des[j];
|
||||
}
|
||||
}
|
||||
// feedback_to_real(data_, data_);
|
||||
// real_to_feedback(data_, data_);
|
||||
real_to_feedback(data_, data_);
|
||||
}
|
||||
|
||||
rc_msgs::msg::LegCmd msg;
|
||||
@ -102,23 +101,15 @@ void MdogSimpleController::control_loop() {
|
||||
msg.header.stamp = this->now();
|
||||
msg.header.frame_id = "leg_cmd";
|
||||
cmd_pub_->publish(msg);
|
||||
//打印调试信息
|
||||
|
||||
if (0){
|
||||
RCLCPP_INFO(this->get_logger(), "MdogControllerData:");
|
||||
for (int leg = 0; leg < 4; ++leg) {
|
||||
RCLCPP_INFO(this->get_logger(), "Leg %d:", leg);
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
RCLCPP_INFO(this->get_logger(), "Joint %d: Torque: %f, Speed: %f, Pos: %f",
|
||||
j, data_.feedback[leg].torque[j], data_.feedback[leg].speed[j], data_.feedback[leg].pos[j]);
|
||||
}
|
||||
}
|
||||
RCLCPP_INFO(this->get_logger(), "InputCmd: Voltage: [%f, %f, %f], Height: %f, Status: %d",
|
||||
input_cmd_.voltage.vx, input_cmd_.voltage.vy, input_cmd_.voltage.wz, input_cmd_.hight, input_cmd_.status);
|
||||
}
|
||||
RCLCPP_INFO(this->get_logger(), "InputCmd: Voltage: [%f, %f, %f], Height: %f, Status: %d",
|
||||
input_cmd_.voltage.vx, input_cmd_.voltage.vy, input_cmd_.voltage.wz, input_cmd_.hight, input_cmd_.status);
|
||||
|
||||
sensor_msgs::msg::JointState js_msg;
|
||||
// RCLCPP_INFO(this->get_logger(), "cmd: %f %f %f %f %f %f %f %f %f %f %f %f",
|
||||
// data_.command[0].pos_des[0], data_.command[0].pos_des[1], data_.command[0].pos_des[2],
|
||||
// data_.command[1].pos_des[0], data_.command[1].pos_des[1], data_.command[1].pos_des[2],
|
||||
// data_.command[2].pos_des[0], data_.command[2].pos_des[1], data_.command[2].pos_des[2],
|
||||
// data_.command[3].pos_des[0], data_.command[3].pos_des[1], data_.command[3].pos_des[2]);
|
||||
|
||||
sensor_msgs::msg::JointState js_msg;
|
||||
js_msg.header.stamp = this->now();
|
||||
js_msg.name = {
|
||||
"FR_hip_joint", "FR_thigh_joint", "FR_calf_joint",
|
||||
@ -134,13 +125,6 @@ void MdogSimpleController::control_loop() {
|
||||
}
|
||||
}
|
||||
joint_state_pub_->publish(js_msg);
|
||||
//打印真实数据
|
||||
// for (int leg = 0; leg < 4; ++leg) {
|
||||
// for (int j = 0; j < 3; ++j) {
|
||||
// RCLCPP_INFO(this->get_logger(), "Leg %d Joint %d: Torque: %f, Speed: %f, Pos: %f",
|
||||
// leg, j, data_.feedback_real[leg].torque[j], data_.feedback_real[leg].speed[j], data_.feedback_real[leg].pos[j]);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user