Files
BC1C-firmware/app/by_motion.c

186 lines
4.8 KiB
C
Raw Permalink Normal View History

#include "by_motion.h"
#include <math.h>
#include <string.h>
#include "by_debug.h"
#include "by_can.h"
2024-07-05 08:15:05 +08:00
#define D_X (0.25f) // 底盘 Y 轴上两轮中心的间距
#define D_Y (0.28f) // 底盘 X 轴上两轮中心的间距
#define RX_RY ((D_X + D_Y) / 2.f)
/**********************************************
* v_1 = v_{ty} + v_{tx} - (r_x + r_y) * \omega
* v_2 = v_{ty} - v_{tx} + (r_x + r_y) * \omega
* v_3 = v_{ty} + v_{tx} + (r_x + r_y) * \omega
* v_4 = v_{ty} - v_{tx} - (r_x + r_y) * \omega
**********************************************/
/*** 控制模式 ***/
uint8_t control_mode = 0; // 0-速度模式 1-位置模式
struct by_motion_mode_struct {
uint8_t x;
uint8_t y;
uint8_t w;
} by_motion_mode = {0,0,0};
/*** 位置控制 ***/
uint8_t control_timer = 0; // 位置控制定时器状态
uint32_t control_timer_cnt = 0; // 位置控制计数
/*** 各轮转速,左上角为 1 号,顺时针标号 ***/
float v_wheel[4] = {0.f};
/** 目标速度 **/
motion_speed_type motion_speed_struct;
motion_speed_type motion_speed_struct_last;
motion_time_type motion_time_struct;
/** 下发数据包 **/
int16_t motion_speed_data[4] = {0};
void by_motion_init(void)
{
memset(&motion_speed_struct, 0, sizeof(motion_speed_struct));
memset(&motion_speed_struct_last, 0, sizeof(motion_speed_struct_last));
memset(&motion_time_struct, 0, sizeof(motion_time_struct));
memset(motion_speed_data, 0, sizeof(motion_speed_data));
memset(v_wheel, 0, sizeof(v_wheel));
by_can_send_stdd(0x01, (uint8_t *)&motion_speed_data, 8, 100);
}
void by_motion_update_speed(void)
{
const motion_speed_type *speed = &motion_speed_struct;
v_wheel[0] = speed->v_x + speed->v_y - RX_RY * speed->v_w;
v_wheel[1] = speed->v_x - speed->v_y + RX_RY * speed->v_w;
v_wheel[2] = speed->v_x + speed->v_y + RX_RY * speed->v_w;
v_wheel[3] = speed->v_x - speed->v_y - RX_RY * speed->v_w;
2024-05-05 16:28:11 +08:00
// 根据安装方式调整轮子方向
2024-07-05 08:15:05 +08:00
v_wheel[1] *= -1.0f;
v_wheel[2] *= -1.0f;
2024-05-05 16:28:11 +08:00
for (uint8_t i = 0; i < 4; i++) {
motion_speed_data[i] = (int16_t)v_wheel[i];
LOGD("MOTION#SPD wheel[%d] - %d", i, motion_speed_data[i]);
}
by_can_send_stdd(0x01, (uint8_t *)&motion_speed_data, 8, 100);
LOGD("MOTION#SPD updated");
}
/**
* @brief -
*
*/
void by_motion_loop(void)
{
if (by_motion_mode.x == 0) {
motion_time_struct.t_x = 0;
} else if (by_motion_mode.x == 1 && motion_time_struct.t_x == 0) {
motion_speed_struct.v_x = 0;
}
if (by_motion_mode.y == 0) {
motion_time_struct.t_y = 0;
} else if (by_motion_mode.y == 1 && motion_time_struct.t_y == 0) {
motion_speed_struct.v_y = 0;
}
if (by_motion_mode.w == 0) {
motion_time_struct.t_w = 0;
} else if (by_motion_mode.w == 1 && motion_time_struct.t_w == 0) {
motion_speed_struct.v_w = 0;
}
// if (control_mode == 0) { // 速度控制模式
// memset(&motion_time_struct, 0, sizeof(motion_time_struct));
// } else { // 位置控制模式
// if (0 == motion_time_struct.t_x) {
// motion_speed_struct.v_x = 0;
// }
// if (0 == motion_time_struct.t_y) {
// motion_speed_struct.v_y = 0;
// }
// if (0 == motion_time_struct.t_w) {
// motion_speed_struct.v_w = 0;
// }
// }
if ((motion_speed_struct.v_x != motion_speed_struct_last.v_x) || (motion_speed_struct.v_y != motion_speed_struct_last.v_y) || (motion_speed_struct.v_w != motion_speed_struct_last.v_w)) {
by_motion_update_speed();
memcpy(&motion_speed_struct_last, &motion_speed_struct, sizeof(motion_speed_type));
}
}
/**
* @brief
*
*/
void by_motion_timer_handle(void)
{
// if (control_mode == 0) {
// motion_time_struct.t_x = 0;
// motion_time_struct.t_y = 0;
// motion_time_struct.t_w = 0;
// } else {
// if (motion_time_struct.t_x > 0) {
// motion_time_struct.t_x--;
// }
// if (motion_time_struct.t_y > 0) {
// motion_time_struct.t_y--;
// }
// if (motion_time_struct.t_w > 0) {
// motion_time_struct.t_w--;
// }
// }
if (by_motion_mode.x == 0) {
motion_time_struct.t_x = 0;
} else if(motion_time_struct.t_x > 0) {
motion_time_struct.t_x--;
}
if(by_motion_mode.y == 0) {
motion_time_struct.t_y = 0;
} else if(motion_time_struct.t_y > 0) {
motion_time_struct.t_y--;
}
if(by_motion_mode.w == 0) {
motion_time_struct.t_w = 0;
} else if(motion_time_struct.t_w > 0) {
motion_time_struct.t_w--;
}
}
// /**
// * @brief 设置电机控制模式
// *
// * @param mode 0-速度模式 1-位置模式
// */
// void by_motion_set_mode(uint8_t mode)
// {
// control_mode = mode;
// }
void by_motion_set_mode_x(uint8_t mode)
{
by_motion_mode.x = mode;
}
void by_motion_set_mode_y(uint8_t mode)
{
by_motion_mode.y = mode;
}
void by_motion_set_mode_w(uint8_t mode)
{
by_motion_mode.w = mode;
}