diff --git a/hw/bsp/c-mini/drivers/bsp_gpio.c b/hw/bsp/c-mini/drivers/bsp_gpio.c index e95b484f..dda9e4c5 100644 --- a/hw/bsp/c-mini/drivers/bsp_gpio.c +++ b/hw/bsp/c-mini/drivers/bsp_gpio.c @@ -92,6 +92,17 @@ bsp_status_t bsp_gpio_disable_irq(bsp_gpio_t gpio) { } inline bsp_status_t bsp_gpio_write_pin(bsp_gpio_t gpio, bool value) { + if (gpio == BSP_GPIO_SWITCH) { + bsp_pwm_set_comp(BSP_PWM_SERVO_B, 1.0f); + if (value) { + bsp_pwm_start(BSP_PWM_SERVO_B); + } else { + bsp_pwm_stop(BSP_PWM_SERVO_B); + } + + return BSP_OK; + } + HAL_GPIO_WritePin(bsp_gpio_map[gpio].gpio, bsp_gpio_map[gpio].pin, value); return BSP_OK; } diff --git a/hw/bsp/c-mini/drivers/bsp_gpio.h b/hw/bsp/c-mini/drivers/bsp_gpio.h index 9b87b058..6a0a27be 100644 --- a/hw/bsp/c-mini/drivers/bsp_gpio.h +++ b/hw/bsp/c-mini/drivers/bsp_gpio.h @@ -12,6 +12,7 @@ typedef enum { BSP_GPIO_IMU_ACCL_INT, BSP_GPIO_IMU_GYRO_INT, BSP_GPIO_LED, + BSP_GPIO_SWITCH, BSP_GPIO_NUM, } bsp_gpio_t; diff --git a/src/device/damiaomotor/Kconfig b/src/device/damiaomotor/Kconfig new file mode 100644 index 00000000..e69de29b diff --git a/src/device/damiaomotor/dev_damiaomotor.cpp b/src/device/damiaomotor/dev_damiaomotor.cpp new file mode 100644 index 00000000..2f53f78e --- /dev/null +++ b/src/device/damiaomotor/dev_damiaomotor.cpp @@ -0,0 +1,151 @@ +#include "dev_damiaomotor.hpp" + +#include "bsp_time.h" + +#define P_MIN -12.5f +#define P_MAX 12.5f +#define V_MIN -45.0f +#define V_MAX -45.0f +#define T_MIN -18.0f +#define T_MAX 18.0f + +using namespace Device; + +static const uint8_t ENABLE_CMD[8] = {0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFC}; + +static const uint8_t DISABLE_CMD[8] = {0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFD}; + +static std::array initd = {false}; + +std::array *, BSP_CAN_NUM> DamiaoMotor::damiao_tp_; +DamiaoMotor::DamiaoMotor(const Param ¶m, const char *name) + : BaseMotor(name, param.reverse), param_(param) { + auto rx_callback = [](Can::Pack &rx, DamiaoMotor *motor) { + if ((rx.data[0] & 0x0f) == (motor->param_.id)) { + motor->recv_.Overwrite(rx); + } + return true; + }; + + if (!initd[this->param_.can]) { + DamiaoMotor::damiao_tp_[this->param_.can] = + static_cast *>( + System::Memory::Malloc(sizeof(Message::Topic))); + *DamiaoMotor::damiao_tp_[this->param_.can] = Message::Topic( + (std::string("damiao_posspeed_can") + std::to_string(this->param_.can)) + .c_str()); + + // Can::Subscribe(*DamiaoSpeedPOsition::damiao_tp_[this->param_.can], + // this->param_.can, 0, 1); + + Can::Subscribe(*DamiaoMotor::damiao_tp_[this->param_.can], this->param_.can, + this->param_.feedback_id, 1); + + initd[this->param_.can] = true; + } + + Message::Topic motor_tp(name); + + motor_tp.RegisterCallback(rx_callback, this); + + motor_tp.Link(*this->damiao_tp_[this->param_.can]); +} + +bool DamiaoMotor::Update() { + Can::Pack pack; + + while (this->recv_.Receive(pack)) { + this->Decode(pack); + last_online_time_ = bsp_time_get_ms(); + } + + return true; +} + +void DamiaoMotor::Decode(Can::Pack &rx) { + if (this->param_.id != (rx.data[0] & 0x0f)) { + return; + } + + uint16_t raw_position = rx.data[1] << 8 | rx.data[2]; + + uint16_t raw_speed = (rx.data[3] << 4) | (rx.data[4] >> 4); + + uint16_t raw_current = (rx.data[4] & 0x0f) << 8 | rx.data[5]; + + float raw = uint_to_float(raw_position, P_MIN, P_MAX, 16); + float speed = uint_to_float(raw_speed, V_MIN, V_MAX, 12); + float current = uint_to_float(raw_current, -T_MAX, T_MAX, 12); + + this->feedback_.rotational_speed = speed; + this->feedback_.rotor_abs_angle = raw; + this->feedback_.torque_current = current; +} +/*摆设*/ +void DamiaoMotor::Control(float output) { + static_cast(output); + XB_ASSERT(false); +} + +void DamiaoMotor::SetPosSpeed(float pos, float speed) { + if (this->feedback_.temp > 75.0f) { + Relax(); + OMLOG_WARNING("motor %s high temperature detected", name_); + return; + } + if (reverse_) { + pos = -pos; + } + + Can::Pack tx_buff; + + tx_buff.index = this->param_.id + 0x100; + + uint8_t *pbuf, *vbuf; + + pbuf = (uint8_t *)&pos; + vbuf = (uint8_t *)&speed; + + tx_buff.data[0] = *pbuf; + tx_buff.data[1] = *(pbuf + 1); + tx_buff.data[2] = *(pbuf + 2); + tx_buff.data[3] = *(pbuf + 3); + + tx_buff.data[4] = *vbuf; + tx_buff.data[5] = *(vbuf + 1); + tx_buff.data[6] = *(vbuf + 2); + tx_buff.data[7] = *(vbuf + 3); + + Can::SendStdPack(this->param_.can, tx_buff); +} + +bool DamiaoMotor::Enable() { + Can::Pack tx_buff; + + tx_buff.index = param_.id + 0x100; + + memcpy(tx_buff.data, ENABLE_CMD, sizeof(tx_buff.data)); + + if (Can::SendStdPack(this->param_.can, tx_buff)) { + return true; + } else { + return false; + }; +} +bool DamiaoMotor::Disable() { + Can::Pack tx_buff; + + tx_buff.index = param_.id + 0x100; + + memcpy(tx_buff.data, DISABLE_CMD, sizeof(tx_buff.data)); + + if (Can::SendStdPack(this->param_.can, tx_buff)) { + return true; + } else { + return false; + }; +} +/*摆设*/ +void DamiaoMotor::Relax() { XB_ASSERT(false); } diff --git a/src/device/damiaomotor/dev_damiaomotor.hpp b/src/device/damiaomotor/dev_damiaomotor.hpp new file mode 100644 index 00000000..6bbebfcd --- /dev/null +++ b/src/device/damiaomotor/dev_damiaomotor.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "dev_can.hpp" +#include "dev_motor.hpp" +namespace Device { +class DamiaoMotor : public BaseMotor { + public: + typedef struct { + uint32_t id; /*设置CAN ID*/ /*控制帧ID为CAN ID偏移0x100*/ + bsp_can_t can; + uint32_t feedback_id; + bool reverse; + } Param; + + DamiaoMotor(const Param ¶m, const char *name); + void Control(float output); + bool Update(); + void Relax(); + void Decode(Can::Pack &rx); + void SetPosSpeed(float pos, float speed); + bool Enable(); + bool Disable(); + + private: + Param param_; + + System::Queue recv_ = System::Queue(1); + + static std::array *, BSP_CAN_NUM> damiao_tp_; +}; +} // namespace Device diff --git a/src/device/damiaomotor/info.cmake b/src/device/damiaomotor/info.cmake new file mode 100644 index 00000000..322c4b19 --- /dev/null +++ b/src/device/damiaomotor/info.cmake @@ -0,0 +1,6 @@ +CHECK_SUB_ENABLE(MODULE_ENABLE device) +if(${MODULE_ENABLE}) + file(GLOB CUR_SOURCES "${SUB_DIR}/*.cpp") + SUB_ADD_SRC(CUR_SOURCES) + SUB_ADD_INC(SUB_DIR) +endif() \ No newline at end of file diff --git a/src/module/robot_arm/mod_robot_arm.cpp b/src/module/robot_arm/mod_robot_arm.cpp index 7cba3696..a19990bb 100644 --- a/src/module/robot_arm/mod_robot_arm.cpp +++ b/src/module/robot_arm/mod_robot_arm.cpp @@ -34,6 +34,9 @@ RobotArm::RobotArm(Param& param, float control_freq) case SET_MODE_WORK_TOP: robotarm->SetMode(WORK_TOP); break; + case SET_MODE_CUSTOM_CTRL: + robotarm->SetMode(WORK_CUSTOM_CTRL); + break; case SET_MODE_WORK_MID: robotarm->SetMode(WORK_MID); break; @@ -43,6 +46,15 @@ RobotArm::RobotArm(Param& param, float control_freq) case SET_MODE_SAFE: robotarm->SetMode(SAFE); break; + case SET_MODE_XIKUANG: + robotarm->SetMode(XIKUANG); + break; + case SET_MODE_YINKUANG: + robotarm->SetMode(YINKUANG); + break; + case SET_MODE_DIMIAN: + robotarm->SetMode(DIMIAN); + break; default: break; } @@ -118,45 +130,15 @@ void RobotArm::Control() { this->last_wakeup_ = this->now_; - // this->setpoint_.yaw1_theta_ = this->cmd_.theta.yaw1; - // this->setpoint_.pitch1_theta_ = this->cmd_.theta.pitch1; - // this->setpoint_.pitch2_theta_ = this->cmd_.theta.pitch2; - // this->setpoint_.pitch3_theta_ = this->cmd_.theta.pitch3; - // this->setpoint_.yaw2_theta_ = this->cmd_.theta.yaw2; - // this->setpoint_.roll_theta_ = this->cmd_.theta.roll; - float pit_cmd = 0.0f; float yaw_cmd = 0.0f; - yaw_cmd = this->cmd_.eulr.yaw * this->dt_; - pit_cmd = this->cmd_.eulr.pit * this->dt_; - - /*电机限幅*/ - // clampf(&(this->setpoint_.yaw1_theta_), this->param_.limit.yaw1_min, - // this->param_.limit.yaw1_max); - // clampf(&(this->setpoint_.pitch1_theta_), this->param_.limit.pitch1_min, - // this->param_.limit.pitch1_max); - // clampf(&(this->setpoint_.pitch2_theta_), this->param_.limit.pitch2_min, - // this->param_.limit.pitch2_max); - // clampf(&(this->setpoint_.roll1_theta_), this->param_.limit.roll1_min, - // this->param_.limit.roll1_max); - // clampf(&(this->setpoint_.yaw2_theta_), this->param_.limit.yaw2_min, - // this->param_.limit.yaw2_max); - - // this->yaw1_motor_.SetPosSpeed(this->setpoint_.yaw1_theta_, 0.1f); - // this->pitch1_motor_.SetPosSpeed(this->setpoint_.pitch1_theta_, 0.3f); - // this->pitch2_motor_.SetPosSpeed(this->setpoint_.pitch2_theta_, 0.3f); - // this->roll1_motor_.SetPosSpeed(this->setpoint_.roll1_theta_, 0.3f); - // this->yaw2_motor_.SetPosSpeed(this->setpoint_.yaw2_theta_, 0.3f); - - // float roll2_out = this->roll2_actr_.Calculate( - // this->setpoint_roll2_, this->roll2_motor_.GetSpeed(), - // this->roll2_motor_.GetAngle(), this->dt_); - // this->roll2_motor_.Control(roll2_out); + yaw_cmd = this->cmd_.eulr.yaw * this->dt_ * (0.7); + pit_cmd = this->cmd_.eulr.pit * this->dt_ * (0.7); switch (this->mode_) { case RobotArm::WORK_BOT: { - this->setpoint_.yaw1_theta_ += yaw_cmd; + this->setpoint_.yaw1_theta_ += 2 * yaw_cmd; this->setpoint_.pitch1_theta_ += pit_cmd; clampf(&(this->setpoint_.yaw1_theta_), this->param_.limit.yaw1_min, @@ -164,19 +146,19 @@ void RobotArm::Control() { clampf(&(this->setpoint_.pitch1_theta_), this->param_.limit.pitch1_min, this->param_.limit.pitch1_max); - this->yaw1_motor_.SetPosSpeed(this->setpoint_.yaw1_theta_, 0.1f); - this->pitch1_motor_.SetPosSpeed(this->setpoint_.pitch1_theta_, 0.3f); + this->yaw1_motor_.SetPosSpeed(this->setpoint_.yaw1_theta_, 1.6f); + this->pitch1_motor_.SetPosSpeed(this->setpoint_.pitch1_theta_, 0.8f); break; } case RobotArm::WORK_MID: { - this->setpoint_.roll1_theta_ += yaw_cmd; + this->setpoint_.roll1_theta_ += 2 * yaw_cmd; this->setpoint_.pitch2_theta_ += pit_cmd; clampf(&(this->setpoint_.pitch2_theta_), this->param_.limit.pitch2_min, this->param_.limit.pitch2_max); - this->pitch2_motor_.SetPosSpeed(this->setpoint_.pitch2_theta_, 0.3f); - this->roll1_motor_.SetPosSpeed(this->setpoint_.roll1_theta_, 0.3f); + this->pitch2_motor_.SetPosSpeed(this->setpoint_.pitch2_theta_, 0.8f); + this->roll1_motor_.SetPosSpeed(this->setpoint_.roll1_theta_, 1.6f); break; } case RobotArm::WORK_TOP: { @@ -187,7 +169,7 @@ void RobotArm::Control() { clampf(&(this->setpoint_.yaw2_theta_), this->param_.limit.yaw2_min, this->param_.limit.yaw2_max); - this->yaw2_motor_.SetPosSpeed(this->setpoint_.yaw2_theta_, 0.3f); + this->yaw2_motor_.SetPosSpeed(this->setpoint_.yaw2_theta_, 0.8f); float roll2_out = this->roll2_actr_.Calculate( this->setpoint_roll2_, this->roll2_motor_.GetSpeed(), @@ -197,6 +179,44 @@ void RobotArm::Control() { break; } case RobotArm::SAFE: { + this->setpoint_.pitch1_theta_ = 0; + this->setpoint_.pitch2_theta_ = 0; + this->setpoint_.yaw1_theta_ = 0; + this->setpoint_.yaw2_theta_ = 0; + this->setpoint_.roll1_theta_ = 0; + this->yaw1_motor_.SetPosSpeed(0, 0.6f); + this->pitch1_motor_.SetPosSpeed(0, 0.5f); + this->yaw2_motor_.SetPosSpeed(0, 0.6f); + this->pitch2_motor_.SetPosSpeed(0, 0.5f); + this->roll1_motor_.SetPosSpeed(0, 0.5f); + break; + } + + case RobotArm::YINKUANG: { + this->setpoint_.pitch1_theta_ = 2.056f; + this->setpoint_.pitch2_theta_ = -0.939f; + this->setpoint_.yaw1_theta_ = 0; + this->setpoint_.yaw2_theta_ = 0; + this->setpoint_.roll1_theta_ = 0; + this->yaw1_motor_.SetPosSpeed(0, 0.6f); + this->pitch1_motor_.SetPosSpeed(2.056f, 0.5f); + this->yaw2_motor_.SetPosSpeed(0, 0.6f); + this->pitch2_motor_.SetPosSpeed(-0.939f, 0.5f); + this->roll1_motor_.SetPosSpeed(0.0f, 0.5f); + break; + } + + case RobotArm::DIMIAN: { + this->setpoint_.pitch1_theta_ = 3.426f; + this->setpoint_.pitch2_theta_ = -1.426f; + this->setpoint_.yaw1_theta_ = 0; + this->setpoint_.yaw2_theta_ = 0.7546; + this->setpoint_.roll1_theta_ = 0; + this->yaw1_motor_.SetPosSpeed(0, 0.6f); + this->pitch1_motor_.SetPosSpeed(3.426f, 0.5f); + this->yaw2_motor_.SetPosSpeed(0.7546f, 0.6f); + this->pitch2_motor_.SetPosSpeed(-1.426f, 0.5f); + this->roll1_motor_.SetPosSpeed(0.0f, 0.5f); break; } @@ -208,6 +228,15 @@ void RobotArm::Control() { this->yaw2_able_ = 0; this->roll2_motor_.Relax(); break; + + case RobotArm::XIKUANG: + if (this->state_ == 0) { + bsp_gpio_write_pin(BSP_GPIO_SWITCH, 0); + } else { + bsp_gpio_write_pin(BSP_GPIO_SWITCH, 1); + }; + break; + case RobotArm::WORK_CUSTOM_CTRL: if (custom_ctrl_.online_) { this->setpoint_.yaw1_theta_ = custom_ctrl_.data_.angle[0]; @@ -218,17 +247,17 @@ void RobotArm::Control() { clampf(&(this->setpoint_.pitch1_theta_), this->param_.limit.pitch1_min, this->param_.limit.pitch1_max); - this->yaw1_motor_.SetPosSpeed(this->setpoint_.yaw1_theta_, 0.1f); - this->pitch1_motor_.SetPosSpeed(this->setpoint_.pitch1_theta_, 0.3f); + this->yaw1_motor_.SetPosSpeed(this->setpoint_.yaw1_theta_, 0.6f); + this->pitch1_motor_.SetPosSpeed(this->setpoint_.pitch1_theta_, 0.5f); - this->setpoint_.roll1_theta_ = custom_ctrl_.data_.angle[2]; - this->setpoint_.pitch2_theta_ = custom_ctrl_.data_.angle[3]; + this->setpoint_.roll1_theta_ = custom_ctrl_.data_.angle[3]; + this->setpoint_.pitch2_theta_ = -custom_ctrl_.data_.angle[2]; clampf(&(this->setpoint_.pitch2_theta_), this->param_.limit.pitch2_min, this->param_.limit.pitch2_max); - this->pitch2_motor_.SetPosSpeed(this->setpoint_.pitch2_theta_, 0.3f); - this->roll1_motor_.SetPosSpeed(this->setpoint_.roll1_theta_, 0.3f); + this->pitch2_motor_.SetPosSpeed(this->setpoint_.pitch2_theta_, 0.5f); + this->roll1_motor_.SetPosSpeed(this->setpoint_.roll1_theta_, 0.5f); this->setpoint_.yaw2_theta_ = custom_ctrl_.data_.angle[4]; this->setpoint_roll2_ = custom_ctrl_.data_.angle[5]; @@ -236,7 +265,7 @@ void RobotArm::Control() { clampf(&(this->setpoint_.yaw2_theta_), this->param_.limit.yaw2_min, this->param_.limit.yaw2_max); - this->yaw2_motor_.SetPosSpeed(this->setpoint_.yaw2_theta_, 0.3f); + this->yaw2_motor_.SetPosSpeed(this->setpoint_.yaw2_theta_, 0.5f); float roll2_out = this->roll2_actr_.Calculate( this->setpoint_roll2_, this->roll2_motor_.GetSpeed(), @@ -252,9 +281,6 @@ void RobotArm::Control() { } break; - // default: - // XB_ASSERT(false); - // return; } } @@ -269,6 +295,13 @@ void RobotArm::SetMode(RobotArm::Mode mode) { this->roll1_able_ = 1; this->yaw2_able_ = 1; } + if (mode == WORK_CUSTOM_CTRL) { + this->yaw1_able_ = 1; + this->pitch1_able_ = 1; + this->pitch2_able_ = 1; + this->roll1_able_ = 1; + this->yaw2_able_ = 1; + } if (mode == WORK_MID) { this->yaw1_able_ = 1; this->pitch1_able_ = 1; @@ -283,5 +316,8 @@ void RobotArm::SetMode(RobotArm::Mode mode) { this->roll1_able_ = 1; this->yaw2_able_ = 1; } + if (mode == XIKUANG) { + this->state_ = !this->state_; + } this->mode_ = mode; } diff --git a/src/module/robot_arm/mod_robot_arm.hpp b/src/module/robot_arm/mod_robot_arm.hpp index 154bf9b4..b546292f 100644 --- a/src/module/robot_arm/mod_robot_arm.hpp +++ b/src/module/robot_arm/mod_robot_arm.hpp @@ -1,6 +1,7 @@ #include #include +#include "bsp_gpio.h" #include "comp_actuator.hpp" #include "comp_cmd.hpp" #include "comp_pid.hpp" @@ -22,6 +23,9 @@ class RobotArm { WORK_BOT, WORK_CUSTOM_CTRL, SAFE, + XIKUANG, + YINKUANG, + DIMIAN } Mode; typedef enum { @@ -30,6 +34,10 @@ class RobotArm { SET_MODE_WORK_MID, SET_MODE_WORK_BOT, SET_MODE_SAFE, + SET_MODE_CUSTOM_CTRL, + SET_MODE_XIKUANG, + SET_MODE_YINKUANG, + SET_MODE_DIMIAN } RobotArmEvent; typedef struct Param { @@ -90,11 +98,11 @@ class RobotArm { Device::CustomController custom_ctrl_; - bool yaw1_able_ = 1; - bool pitch1_able_ = 1; - bool pitch2_able_ = 1; - bool roll1_able_ = 1; - bool yaw2_able_ = 1; + bool yaw1_able_ = 0; + bool pitch1_able_ = 0; + bool pitch2_able_ = 0; + bool roll1_able_ = 0; + bool yaw2_able_ = 0; System::Thread thread_; @@ -110,6 +118,8 @@ class RobotArm { float setpoint_roll2_; + bool state_ = 0; + Component::CMD::GimbalCMD cmd_; }; diff --git a/src/robot/arm_engineer/robot.cpp b/src/robot/arm_engineer/robot.cpp index f615ac96..d580b182 100644 --- a/src/robot/arm_engineer/robot.cpp +++ b/src/robot/arm_engineer/robot.cpp @@ -148,6 +148,22 @@ Robot::ArmEngineer::Param param = { Device::DR16::DR16_SW_R_POS_BOT, Module::RobotArm::SET_MODE_WORK_BOT }, + Component::CMD::EventMapItem{ + Device::DR16::DR16_SW_L_POS_BOT, + Module::RobotArm::SET_MODE_XIKUANG + }, + Component::CMD::EventMapItem{ + Device::DR16::KEY_R, + Module::RobotArm::SET_MODE_YINKUANG + }, + Component::CMD::EventMapItem{ + Device::DR16::KEY_Z, + Module::RobotArm::SET_MODE_SAFE + }, + Component::CMD::EventMapItem{ + Device::DR16::KEY_C, + Module::RobotArm::SET_MODE_DIMIAN + }, }, .roll2_actr={ .speed = { @@ -179,45 +195,45 @@ Robot::ArmEngineer::Param param = { .yaw1_motor={ .id = 01, -.can = BSP_CAN_1, +.can = BSP_CAN_2, .feedback_id = 0, .reverse = 0, }, .pitch1_motor={ .id = 02, -.can = BSP_CAN_1, +.can = BSP_CAN_2, .feedback_id = 1, .reverse = 0, }, .pitch2_motor={ .id = 03, -.can = BSP_CAN_3, +.can = BSP_CAN_1, .feedback_id = 2, .reverse = 0, }, .roll1_motor={ .id = 04, -.can = BSP_CAN_2, +.can = BSP_CAN_1, .feedback_id = 3, .reverse = 0, }, .yaw2_motor={ .id = 05, -.can = BSP_CAN_2, +.can = BSP_CAN_1, .feedback_id = 4, -.reverse = 0, +.reverse = 1, }, .roll2_motor={ .id_feedback = 0x208, .id_control = GM6020_CTRL_ID_BASE, .model = Device::RMMotor::MOTOR_GM6020, - .can = BSP_CAN_2, + .can = BSP_CAN_1, }, .limit = { .yaw1_max = 0.0f, - .yaw1_min =-6.28f, + .yaw1_min =-7.5f, .pitch1_max = 3.5f, .pitch1_min = 0.0f, .pitch2_max = 0.0f, @@ -232,11 +248,11 @@ Robot::ArmEngineer::Param param = { .cust_ctrl = { .offset = { -6.28f, - 0.0f, - 0.0f, - 0.0f, - 0.0f, - 0.0f + -1+0.1f, + -0.10f, + -0.20+0.1f, + -3.82+0.1f, + -4.29f } } },