49 Commits

Author SHA1 Message Date
guoxy06
2b18d60476 半舵旗舰版 2026-05-26 19:43:23 +08:00
guoxy06
72df1a2654 小陀螺旗舰版 2026-04-29 19:43:54 +08:00
guoxy06
428956e3bd 小陀螺家庭专业版 2026-04-24 21:16:42 +08:00
guoxy06
214971c58b 小陀螺前瞻版 2026-04-22 20:45:40 +08:00
guoxy06
194047605d 小陀螺前瞻版 2026-04-22 20:45:40 +08:00
guoxy06
dc1152e186 底盘正常移动,小陀螺降速方便调 2026-04-22 20:45:40 +08:00
guoxy06
90bdda348e 底盘正常移动,小陀螺降速方便调 2026-04-22 20:45:40 +08:00
guoxy06
e8f4bf3cf2 改底盘(疯2) 2026-04-22 20:45:40 +08:00
guoxy06
e783abf8d6 改底盘(疯2) 2026-04-22 20:45:40 +08:00
guoxy06
579b507e3b 改底盘(疯) 2026-04-22 20:45:40 +08:00
guoxy06
f8282c80b9 改底盘1 2026-04-22 20:45:40 +08:00
guoxy06
47aba369d8 改底盘 2026-04-22 20:45:40 +08:00
fcl
be8f3f38c8 no.second 2026-04-22 20:45:40 +08:00
fcl
8e1e2455e0 no.firsr 2026-04-22 20:45:39 +08:00
Zorua
e66dbb8052 变量名更正 2026-04-22 20:45:39 +08:00
guoxy06
a6c7ccd2a1 1V1用 2026-04-22 20:45:39 +08:00
guoxy06
3d7a4592c4 赛场_v1.2 2026-04-22 20:45:39 +08:00
guoxy06
99bfe7cec7 ui init 2026-04-22 20:45:39 +08:00
guoxy06
69b407db26 方案——赛场_1.1 2026-04-22 20:45:39 +08:00
guoxy06
d1d5698c13 临时方案——赛场 2026-04-22 20:45:39 +08:00
Zorua
31ffd2bde4 救火版本 2026-04-22 20:45:39 +08:00
Zorua
b660cbb9f9 救火版本 2026-04-22 20:45:39 +08:00
Zorua
772ce14ae6 救火版本 2026-04-22 20:45:39 +08:00
guoxy06
0eae0777ca 功率,热量 2026-04-22 20:45:39 +08:00
guoxy06
300048362f 解决键鼠发射,现在键鼠模式小陀螺移动有点问题 2026-04-22 20:45:39 +08:00
Zorua
1f4e8d85b9 键鼠模式底盘方向修正,需优化底盘运动 2026-04-22 20:45:39 +08:00
guoxy06
b355992730 单发模式前几发会连发,后续正常,先急停再启动也会出现相同问题 2026-04-22 20:45:39 +08:00
fcl
e8dde8b825 累计问题解决,拨盘电机仍有问题 2026-04-22 20:45:39 +08:00
fcl
df0e1f4b1f 零点感觉还可以... 2026-04-22 20:45:39 +08:00
fcl
277b3a11c0 all ok but loader reversed 2026-04-22 20:45:39 +08:00
fcl
9e7faaca8b fricok. loader failure 2026-04-22 20:45:39 +08:00
fcl
43b724d7b7 fricok butcant stop instantly.loader failure 2026-04-22 20:45:39 +08:00
guoxy06
a61ed6ff25 摩擦轮,拨盘 driver 2026-04-22 20:45:39 +08:00
Zorua
31eef65a6d 6020pitch driver 2026-04-22 20:45:39 +08:00
Zorua
0235c428c5 damiao motor driver init_1.1 2026-04-22 20:45:39 +08:00
Zorua
4b17e1e193 damiao motor driver init_1 2026-04-22 20:45:39 +08:00
Zorua
9d4e103a01 damiao motor driver init 2026-04-22 20:45:38 +08:00
fcl
082bf3199a changed pid param for steer motor 2026-04-22 20:45:38 +08:00
guoxy06
3add7c5eb2 4310能转,但不受遥控控制 2026-04-22 20:45:38 +08:00
fcl
bd9314aa7a reast 2026-04-22 20:45:38 +08:00
fcl
dc0d98d0a6 Revert "supercap can1"
This reverts commit 69e97cbefa.
2026-04-22 20:45:38 +08:00
fcl
d3c9c04c2a 待测版本(ID修改完成) 2026-04-22 20:45:38 +08:00
fcl
933e86e1bb 待测版本(ID修改完成) 2026-04-22 20:45:38 +08:00
fcl
1a537d7f79 待测版本(ID修改完成) 2026-04-22 20:45:38 +08:00
42c26fa8ac supercap can1 2026-04-22 20:45:38 +08:00
d6c91d7b6f supercap can1 2026-04-22 20:45:38 +08:00
24d718a755 supercap can1 2026-04-22 20:45:38 +08:00
a541614346 supercap 2026-04-22 20:45:38 +08:00
351dfc6b71 !2 delete +3
Merge pull request !2 from TuxMonkey/dev
2026-03-09 18:25:42 +00:00
7 changed files with 99 additions and 189 deletions

View File

@@ -26,23 +26,12 @@
#include "referee_UI.h"
#include "arm_math.h"
// =================【功率模型参数】=================
// ⚠️警告:以下参数原本是群星战队为 DJI M3508 电机拟合的。
// 你们的驱动电机是 LK9015,它的扭矩常数、内阻、空载损耗和 M3508 不同!
// 建议后期针对 LK9015 重新拟合这四个参数以达到完美的控制效果。
#define TOQUE_COEFF 1.99688994e-6f
#define K1 1.23e-07f
#define K2 1.453e-07f
#define CONSTANT_POWER 4.081f
#define WARRING_ENERGY_BUFFER 50.0f
// ==================================================
/* 根据robot_def.h中的macro自动计算的参数 */
#define HALF_WHEEL_BASE (WHEEL_BASE / 2.0f) // 半轴距
#define HALF_TRACK_WIDTH (TRACK_WIDTH / 2.0f) // 半轮距
#define PERIMETER_WHEEL (RADIUS_WHEEL * 2 * PI) // 轮子周长
#if defined(CHASSIS_MCNAMEE_WHEEL)
#define CHASSIS_WHEEL_OFFSET 1.0f // 机器人底盘轮子修正偏移量
//#define CHASSIS_WHEEL_OFFSET 1.0f // 机器人底盘轮子修正偏移量
#elif defined(CHASSIS_STEERING_WHEEL)
#define CHASSIS_WHEEL_OFFSET 30.0f // 机器人底盘轮子修正偏移量
//#define CHASSIS_WHEEL_OFFSET 2.0f
@@ -168,12 +157,12 @@ void ChassisInit()
.Ki = 0,
.Kd = 0.1f, // 0.5
.DeadBand = 0.5,
.CoefA = 0.2,
.CoefB = 0.3,
.Improve = PID_Trapezoid_Intergral | PID_DerivativeFilter | PID_DerivativeFilter | PID_Derivative_On_Measurement | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 50, // 200
.MaxOut = 1200,
.Derivative_LPF_RC = 0.01, // 0.01
// .CoefA = 0.2,
// .CoefB = 0.3,
// .Improve = PID_Trapezoid_Intergral | PID_DerivativeFilter | PID_DerivativeFilter | PID_Derivative_On_Measurement | PID_Integral_Limit | PID_Derivative_On_Measurement,
// .IntegralLimit = 50, // 200
.MaxOut = 50,
// .Derivative_LPF_RC = 0.01, // 0.01
};
PIDInit(&chassis_follow_pid, &chassis_follow_pid_conf);
@@ -190,7 +179,7 @@ void ChassisInit()
cap = SuperCapInit(&cap_conf); // 超级电容初始化
// (新增)设置超级电容功率补偿,例如补偿5W,可根据实际需求调整
// SuperCapSetPowerOffset(cap, 5);
SuperCapSetPowerOffset(cap, 5);
// 发布订阅初始化,如果为双板,则需要can comm来传递消息
#ifdef CHASSIS_BOARD
@@ -295,7 +284,8 @@ static void SteeringWheelCalculate()
vt_rf = 0, vt_lb = 0;
} else {
// 生成预计算变量,减少计算量,空间换时间
float w = chassis_cmd_recv.wz * CHASSIS_WHEEL_OFFSET * SQRT2;
//float w = chassis_cmd_recv.wz * CHASSIS_WHEEL_OFFSET * SQRT2;
float w = chassis_cmd_recv.wz * CHASSIS_WHEEL_OFFSET ;
// float temp_x = chassis_vx - w, temp_y = chassis_vy - w;
// arm_sqrt_f32(temp_x * temp_x + temp_y * temp_y, &vt_lf); // lf:y- , x-
// temp_y = chassis_vy + w; // 重复利用变量,temp_x = chassis_vy - w;与上次相同因此注释
@@ -348,102 +338,19 @@ static void SteeringWheelCalculate()
* @brief 根据裁判系统和电容剩余容量对输出进行限制并设置电机参考值
*
*/
/**
* @brief 根据裁判系统和电容剩余容量对输出进行限制,并应用 WJTLU 功率模型
*/
static void LimitChassisOutput()
{
float chassis_max_power = 0;
float chassis_set_power = 90.0f; // 设定的期望功率,可根据需求修改
// 功率限制待添加
// referee_data->PowerHeatData.chassis_power;
// referee_data->PowerHeatData.chassis_power_buffer;
// 获取裁判系统数据
uint16_t referee_power_limit = referee_data->GameRobotState.chassis_power_limit;
float energy_buffer = referee_data->PowerHeatData.chassis_power_buffer;
// 完成功率限制后进行电机参考输入设定
// 1. ============ 超级电容与裁判系统功率统筹 ============
if (SuperCapIsOnline(cap)) {
SuperCap_Msg_s cap_msg = SuperCapGet(cap);
if (cap_msg.ready == READY) {
// 超电正常可用,动态按比例缩放允许功率
if (cap_msg.chassis_power > chassis_set_power) {
chassis_max_power = chassis_set_power * (chassis_set_power / (float)cap_msg.chassis_power);
} else {
chassis_max_power = chassis_set_power;
}
} else {
// 超电保护中,使用裁判系统限制
if (cap_msg.chassis_power > referee_power_limit) {
chassis_max_power = referee_power_limit * ((float)referee_power_limit / (float)cap_msg.chassis_power);
} else {
chassis_max_power = referee_power_limit;
}
}
// LKMotorSetRef( motor_lf , vt_lf );
// LKMotorSetRef( motor_rb , vt_rb );
// 缓冲能量补偿逻辑
uint8_t power_offset = 0;
if (energy_buffer < WARRING_ENERGY_BUFFER) {
power_offset = (uint8_t)((WARRING_ENERGY_BUFFER - energy_buffer) * 0.2f);
}
SuperCapSetPowerOffset(cap, power_offset);
chassis_max_power -= power_offset;
} else {
// 超电离线时逻辑
chassis_max_power = (energy_buffer < WARRING_ENERGY_BUFFER) ?
(referee_power_limit * energy_buffer * 0.02f) : referee_power_limit;
}
// 2. ============ 基于 LK9015 的 WJTLU 二次功率模型限流 ============
float initial_total_power = 0;
float initial_motor_power[2];
LKMotorInstance* motors[2] = {motor_rf, motor_lb}; // 注意舵轮底盘只有两个驱动轮
float current_pid_out[2];
for (int i = 0; i < 2; i++) {
// 修正 1:LK 电机驱动中,speed_PID 是实例的直接成员
current_pid_out[i] = motors[i]->speed_PID.Output;
// 修正 2:LK 的速度单位是 rad/s,WJTLU模型要求 RPM,进行单位转换 (rad/s * 30/pi ≈ RPM)
float rpm = motors[i]->measure.speed_rads * 9.549296f;
initial_motor_power[i] = current_pid_out[i] * TOQUE_COEFF * rpm +
K1 * current_pid_out[i] * current_pid_out[i] +
K2 * rpm * rpm + CONSTANT_POWER;
if (initial_motor_power[i] > 0) initial_total_power += initial_motor_power[i];
}
// 3. 动态修改电机 PID 的 MaxOut 属性
if (initial_total_power > chassis_max_power && initial_total_power > 0) {
float scale = chassis_max_power / initial_total_power;
for (int i = 0; i < 2; i++) {
float scaled_p = initial_motor_power[i] * scale;
if (scaled_p <= CONSTANT_POWER) {
motors[i]->speed_PID.MaxOut = 0; // 该轮分配不到功率
continue;
}
// 同步修正单位
float rpm = motors[i]->measure.speed_rads * 9.549296f;
float b = TOQUE_COEFF * rpm;
float c = K2 * rpm * rpm - scaled_p + CONSTANT_POWER;
float delta = b * b - 4 * K1 * c;
if (delta >= 0) {
// 解方程获得当前允许的最大电流
float out_limit = (-b + sqrtf(delta)) / (2.0f * K1);
// 修正 3:动态限制 LK 电机 speed_PID 的最大输出(LK9015 默认最大输出为 12000)
motors[i]->speed_PID.MaxOut = fminf(out_limit, 12000.0f);
}
}
} else {
// 功率充裕时,恢复电机的默认最大输出
motor_rf->speed_PID.MaxOut = 12000.0f;
motor_lb->speed_PID.MaxOut = 12000.0f;
}
// 4. 下发目标速度(限流操作已通过改变 MaxOut 动态生效)
LKMotorSetRef(motor_rf, vt_rf);
LKMotorSetRef(motor_lb, vt_lb);
LKMotorSetRef( motor_rf , vt_rf );
LKMotorSetRef( motor_lb , vt_lb );
}
/**
@@ -502,53 +409,68 @@ void ChassisTask() {
{
single_round_offset += 360.0f;
}
chassis_cmd_recv.wz = -PIDCalculate(&chassis_follow_pid, single_round_offset, 0)/70.0f;
chassis_cmd_recv.wz = -PIDCalculate(&chassis_follow_pid, single_round_offset, 0)/60.0f;
break;
case CHASSIS_ROTATE: // 自旋,同时保持全向机动;当前wz维持定值,后续增加不规则的变速策略
// chassis_cmd_recv.wz = 0.75;
chassis_cmd_recv.wz = -0.75;//实验版
chassis_cmd_recv.wz = 1.00;//实验版
break;
default:
break;
}
// 根据云台和底盘的角度offset将控制量映射到底盘坐标系上
// 底盘逆时针旋转为角度正方向;云台命令的方向以云台指向的方向为x,采用右手系(x指向正北时y在正东.)
static float sin_theta, cos_theta;
cos_theta = arm_cos_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
sin_theta = arm_sin_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
// chassis_vx = chassis_cmd_recv.vx * cos_theta - chassis_cmd_recv.vy * sin_theta;
// chassis_vy = chassis_cmd_recv.vx * sin_theta + chassis_cmd_recv.vy * cos_theta;
chassis_vy = chassis_cmd_recv.vx * cos_theta - chassis_cmd_recv.vy * sin_theta;//实验版
chassis_vx = chassis_cmd_recv.vx * sin_theta + chassis_cmd_recv.vy * cos_theta;
// ------------------ 【修改部分:加入相位滞后动态补偿】 ------------------
// 提取当前的云台-底盘夹角
float real_offset_angle = chassis_cmd_recv.offset_angle;
// 如果处于小陀螺模式(或者 wz 不为 0),根据旋转速度进行超前补偿
if (chassis_cmd_recv.chassis_mode == CHASSIS_ROTATE )
{
// 补偿系数 K 需要实车微调。
// 根据你的描述 wz=0.95 时偏差约45度,初始 K 值可以设为 45.0 / 0.95 ≈ 47.3f
float lag_compensation_K = 47.3f;//47.3f;45.0f
// 符号(+或-)取决于你的电机正方向、底盘旋转正方向,如果不正就改成减号
real_offset_angle -= (chassis_cmd_recv.wz * lag_compensation_K);
cos_theta = arm_cos_f32(real_offset_angle * DEGREE_2_RAD);
sin_theta = arm_sin_f32(real_offset_angle * DEGREE_2_RAD);
}else if (chassis_cmd_recv.chassis_mode == CHASSIS_FOLLOW_GIMBAL_YAW)
{
cos_theta = arm_cos_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
sin_theta = arm_sin_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
}
// ----------------------------------------------------------------------
chassis_vx = (chassis_cmd_recv.vx * cos_theta + chassis_cmd_recv.vy * sin_theta)/4;
chassis_vy = (-chassis_cmd_recv.vx * sin_theta + chassis_cmd_recv.vy * cos_theta)/4;
// 使用补偿后的角度进行坐标系投影
// static float sin_theta, cos_theta;
// cos_theta = arm_cos_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
// sin_theta = arm_sin_f32(chassis_cmd_recv.offset_angle * DEGREE_2_RAD);
// chassis_vx = (chassis_cmd_recv.vx * cos_theta + chassis_cmd_recv.vy * sin_theta)/4;
// chassis_vy = (-chassis_cmd_recv.vx * sin_theta + chassis_cmd_recv.vy * cos_theta)/4;
// 根据控制模式进行正运动学解算,计算底盘输出
SteeringWheelCalculate();
// MecanumCalculate();
// 根据裁判系统的反馈数据和电容数据对输出限幅并设定闭环参考值
LimitChassisOutput();
// 根据电机的反馈速度和IMU(如果有)计算真实速度
EstimateSpeed();
// // 获取裁判系统数据 建议将裁判系统与底盘分离,所以此处数据应使用消息中心发送
// // 获取裁判系统数据 建议将裁判系统与底盘分离,所以此处数据应使用消息中心发送/
// // 我方颜色id小于7是红色,大于7是蓝色,注意这里发送的是对方的颜色, 0:blue , 1:red
// chassis_feedback_data.enemy_color = referee_data->GameRobotState.robot_id > 7 ? 1 : 0;
// // 当前只做了17mm热量的数据获取,后续根据robot_def中的宏切换双枪管和英雄42mm的情况
// chassis_feedback_data.bullet_speed = referee_data->GameRobotState.shooter_id1_17mm_speed_limit;
// chassis_feedback_data.rest_heat = referee_data->PowerHeatData.shooter_heat0;
// ================== 发送超级电容控制指令 ==================
// 每帧向超电控制板发送最新状态
SuperCap_TxMsg_s cap_tx = {
.Enable = 1,
.Reserved1 = 0, // 可根据需求动态关断充电
.Powerlimit = referee_data->GameRobotState.chassis_power_limit,
.Reserved2 = 0 // PLUS版本忽略此位
};
SuperCapSend(cap, &cap_tx);
// 推送反馈消息
#ifdef ONE_BOARD
PubPushMessage(chassis_pub, (void *)&chassis_feedback_data);

View File

@@ -87,9 +87,17 @@ void RobotCMDInit()
static void CalcOffsetAngle()
{
static float last_offset_angle = 0;
const float smooth_factor = 0.3f; // 平滑因子,0~1之间,值越大平滑效果越明显
//const float smooth_factor = 0.3f; // 平滑因子,
const float deadband = 3.0f; // 死区值
float smooth_factor;
// 小陀螺模式下使用更大的平滑因子,让offset_angle更快跟随云台
if (chassis_cmd_send.chassis_mode == CHASSIS_ROTATE) {
smooth_factor = 0.9f; // 快速响应
} else {
smooth_factor = 0.3f; // 平滑过渡 0~1之间,值越大平滑效果越明显
}
//const float deadband = 3.0f; // 死区值
// 新增:跟踪模式变化,用于重置基准角度
// static chassis_mode_e last_chassis_mode = CHASSIS_NO_FOLLOW;//
//
@@ -111,14 +119,14 @@ static void CalcOffsetAngle()
else if (angle_diff < -180.0f)
new_offset += 360.0f;
/////
// 应用死区
if (fabs(new_offset) < deadband) {
new_offset = 0.0f;
} else if (new_offset > 0) {
new_offset -= deadband;
} else {
new_offset += deadband;
}//////
// // 应用死区
// if (fabs(new_offset) < deadband) {
// new_offset = 0.0f;
// } else if (new_offset > 0) {
// new_offset -= deadband;
// } else {
// new_offset += deadband;
// }//////
chassis_cmd_send.offset_angle = last_offset_angle *(1.0f - smooth_factor) + new_offset * smooth_factor;
last_offset_angle = chassis_cmd_send.offset_angle;
// // 更新模式状态
@@ -187,12 +195,12 @@ static void RemoteControlSet()
// around = 0;
chassis_cmd_send.chassis_mode = CHASSIS_ROTATE;
gimbal_cmd_send.gimbal_mode = GIMBAL_GYRO_MODE;
around= chassis_cmd_send.offset_angle/360;
around= chassis_cmd_send.offset_angle/(-360);
}
else if (switch_is_mid(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[中],底盘和云台分离,底盘保持不转动
{
//gimbal_fetch_data.yaw_motor_total_angle = gimbal_fetch.yaw_motor_total_angle-around*360;
chassis_cmd_send.offset_angle = chassis_cmd_send.offset_angle - 360*around;
chassis_cmd_send.offset_angle = chassis_cmd_send.offset_angle + 360*around;
chassis_cmd_send.chassis_mode = CHASSIS_FOLLOW_GIMBAL_YAW;
gimbal_cmd_send.gimbal_mode = GIMBAL_GYRO_MODE;
}
@@ -200,7 +208,7 @@ static void RemoteControlSet()
// 云台参数,确定云台控制数据
if (switch_is_mid(rc_data[TEMP].rc.switch_left)) // 左侧开关状态为[中],视觉模式
{
// 待添加,视觉会发来和目标的误差,同样将其转化为total angle的增量进行控制
// 待添加,视觉会发来和目标的误差,同样将其转化为total angle的增量进行控制/
// ...
}
// 左侧开关状态为[下],或视觉未识别到目标,纯遥控器拨杆控制
@@ -216,9 +224,9 @@ static void RemoteControlSet()
gimbal_cmd_send.pitch = PITCH_MIN_ANGLE;
// 底盘参数,目前没有加入小陀螺(调试似乎暂时没有必要),系数需要调整
chassis_cmd_send.vx = (0.25f * (float)rc_data[TEMP].rc.rocker_r_); // _水平方向
chassis_cmd_send.vy = (0.25f * (float)rc_data[TEMP].rc.rocker_r1); // 1数值方向 .
chassis_cmd_send.vx = (0.25f * (float)rc_data[TEMP].rc.rocker_r1); // 竖直方向
chassis_cmd_send.vy = (0.25f * (float)rc_data[TEMP].rc.rocker_r_); // 水平方向
//此处如果是右手系,那么x应该是前进方向即竖直方向
// // 发射参数
// if (switch_is_up(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[上],弹舱打开
// ; // 弹舱舵机控制,待添加servo_motor模块,开启

View File

@@ -85,12 +85,12 @@ void GimbalInit()
// },
.controller_param_init_config = {
.angle_PID = {
.Kp = 0.75, //0.55
.Ki = 0.05,//0.05
.Kd = 0.02,//0.02
.Kp = 0.53, //0.55
.Ki = 0.1,//0.05
.Kd = 0.0148,//0.02
.CoefA =0.5,//0.5
.CoefB = 0.6,//0.6
.Output_LPF_RC = 0.01,
.Output_LPF_RC = 0.0068,
.DeadBand = 0.005,//0.02
.Derivative_LPF_RC=0.01,//0.008
.Improve = PID_Trapezoid_Intergral |PID_ChangingIntegrationRate| PID_Integral_Limit |PID_Derivative_On_Measurement | PID_OutputFilter |PID_DerivativeFilter,
@@ -98,15 +98,15 @@ void GimbalInit()
.MaxOut = 600,
},
.speed_PID = {
.Kp = 500,//22000
.Ki = 0,//
.Kd =0.0005,
// .CoefA = 0.8,
// .CoefB = 0.1,
.Kp = 3400,//22000
.Ki = 15,//
.Kd =1,
.CoefA = 0.8,
.CoefB = 0.1,
.Output_LPF_RC = 0.002,//0.002
.Improve = PID_Trapezoid_Intergral |PID_Integral_Limit |PID_Derivative_On_Measurement | PID_OutputFilter,
.IntegralLimit = 5000,
.MaxOut = 20000,
.IntegralLimit = 6000,
.MaxOut = 30000,
},
.other_angle_feedback_ptr = &gimba_IMU_data->Pitch,
// 还需要增加角速度额外反馈指针,注意方向,ins_task.md中有c板的bodyframe坐标系说明

View File

@@ -27,7 +27,7 @@
/* 机器人重要参数定义,注意根据不同机器人进行修改,浮点数需要以.0或f结尾,无符号以u结尾 */
// 云台参数
#define YAW_CHASSIS_ALIGN_ECD -3595 // 云台和底盘对齐指向相同方向时的电机编码器值,若对云台有机械改动需要修改
#define YAW_ECD_GREATER_THAN_4096 0 // ALIGN_ECD值是否大于4096,是为1,否为0;用于计算云台偏转角度
#define YAW_ECD_GREATER_THAN_4096 0 // ALIGN_ECD值是否大于4096,是为1,否为0;用于计算云台偏转角度
#define PITCH_HORIZON_ECD 3412 // 云台处于水平位置时编码器值,若对云台有机械改动需要修改
#define PITCH_MAX_ANGLE 30 // 云台竖直方向最大角度 (注意反馈如果是陀螺仪,则填写陀螺仪的角度)
#define PITCH_MIN_ANGLE -20 // 云台竖直方向最小角度 (注意反馈如果是陀螺仪,则填写陀螺仪的角度)
@@ -35,8 +35,8 @@
// #define CHASSIS_OMNI_WHEEL // 是否为全向轮底盘
// #define CHASSIS_MCNAMEE_WHEEL // 是否为麦克纳姆轮底盘
#define CHASSIS_STEERING_WHEEL // 是否为舵轮
#define STEERING_CHASSIS_ALIGN_ECD_RF 7330 // 舵电机 A 编码器值,若有机械改动需要修改
#define STEERING_CHASSIS_ALIGN_ECD_LB 5099 // 舵电机 D 编码器值,若有机械改动需要修改
#define STEERING_CHASSIS_ALIGN_ECD_RF 7066 // 舵电机 A 编码器值,若有机械改动需要修改
#define STEERING_CHASSIS_ALIGN_ECD_LB 7138 // 舵电机 D 编码器值,若有机械改动需要修改
#define STEERING_CHASSIS_ALIGN_ANGLE_RF STEERING_CHASSIS_ALIGN_ECD_RF / 8192.f * 360.f // 舵轮 A 对齐角度
#define STEERING_CHASSIS_ALIGN_ANGLE_LB STEERING_CHASSIS_ALIGN_ECD_LB / 8192.f * 360.f // 舵轮 D 对齐角度

View File

@@ -40,7 +40,7 @@ static void sbus_to_rc(const uint8_t *sbus_buf)
rc_ctrl[TEMP].rc.rocker_l_ = (((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | (sbus_buf[4] << 10)) & 0x07ff) - RC_CH_VALUE_OFFSET; //!< Channel 2
rc_ctrl[TEMP].rc.rocker_l1 = (((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff) - RC_CH_VALUE_OFFSET; //!< Channel 3
rc_ctrl[TEMP].rc.dial = ((sbus_buf[16] | (sbus_buf[17] << 8)) & 0x07FF) - RC_CH_VALUE_OFFSET;
rc_ctrl[TEMP].rc.rocker_l_= rc_ctrl[TEMP].rc.rocker_l_+2.5;
rc_ctrl[TEMP].rc.rocker_l_= rc_ctrl[TEMP].rc.rocker_l_+5.5;
// 左侧拨轮
RectifyRCjoystick();
// 开关,0左1右

View File

@@ -5,7 +5,6 @@
#include "super_cap.h"
#include "memory.h"
#include "stdlib.h"
#include "bsp_dwt.h" // 【新增】引入获取时间的头文件,或者是 "main.h" 用 HAL_GetTick()
static SuperCapInstance *super_cap_instance = NULL;
@@ -16,9 +15,6 @@ static void SuperCapRxCallback(CANInstance *_instance)
rxbuff = _instance->rx_buff;
Msg = &super_cap_instance->cap_msg;
// 【新增】更新最后一次收到消息的时间戳
super_cap_instance->last_update_tick = DWT_GetTimeline_ms(); // 如果没有DWT,用 HAL_GetTick() 替换
// 按照新协议解析接收数据
Msg->ready = (SuperCapReadyEnum)rxbuff[0];
Msg->state = (SuperCapStateEnum)rxbuff[1];
@@ -28,18 +24,6 @@ static void SuperCapRxCallback(CANInstance *_instance)
Msg->bat_power = rxbuff[5];
}
// 【新增】在线判断函数
uint8_t SuperCapIsOnline(SuperCapInstance *instance)
{
if (instance == NULL) return 0;
// 如果当前时间减去上次接收时间超过 1000ms (1秒),则认为离线
if (DWT_GetTimeline_ms() - instance->last_update_tick > 2000) {
return 0; // 离线
}
return 1; // 在线
}
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config)
{
super_cap_instance = (SuperCapInstance *)malloc(sizeof(SuperCapInstance));
@@ -56,9 +40,9 @@ void SuperCapSend(SuperCapInstance *instance, SuperCap_TxMsg_s *tx_data)
// 按照新协议装载发送数据
txbuff[0] = tx_data->Enable;
txbuff[1] = tx_data->Reserved1;
txbuff[1] = tx_data->Charge;
txbuff[2] = tx_data->Powerlimit - instance->power_offset; // 计算功率补偿
txbuff[3] = tx_data->Reserved2;
txbuff[3] = tx_data->ChargePower;
CANTransmit(instance->can_ins, 1);
}

View File

@@ -44,9 +44,9 @@ typedef struct
/* 需要发送给超级电容的控制信息结构体 */
typedef struct {
uint8_t Enable; // 超级电容使能。1使能,0失能
uint8_t Reserved1; // Reserved 超级电容充电。1充电,0放电
uint8_t Charge; // 超级电容充电。1充电,0放电
uint8_t Powerlimit; // 裁判系统功率限制
uint8_t Reserved2; // Reserved 超级电容充电功率
uint8_t ChargePower; // 超级电容充电功率
} SuperCap_TxMsg_s;
#pragma pack()
@@ -56,7 +56,6 @@ typedef struct
CANInstance *can_ins; // CAN实例
SuperCap_Msg_s cap_msg; // 超级电容接收信息
uint8_t power_offset; // 功率补偿值
uint32_t last_update_tick; // 【新增】上次收到数据的时间戳
} SuperCapInstance;
/* 超级电容初始化配置 */
@@ -70,9 +69,6 @@ typedef struct
*/
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config);
// 【新增】函数声明
uint8_t SuperCapIsOnline(SuperCapInstance *instance);
/**
* @brief 发送超级电容控制信息
*/