更新V1.4,并增加玩车说明。

This commit is contained in:
myperworld committed 2026-02-05 09:36:10 +08:00
1 parent 1a74f5d323
commit e866a74c9c
13 files changed
+109 -74647

No files matched your search

@@ -119,4 +119,13 @@ ActionStep step_forward[] = {
RobotAction action_step_forward = CREATE_ACTION("action_step_forward", step_forward);
#endif
#endif
// 增加rgb效果
// if (remoteData.btnShare && !last_btnShare && robot_enabled && !isExecutingAction) {
// isExecutingAction = true; // 标记开始执行动作
// currentAction = &action_say_hello; // 指定执行的动作
// stepStartTime = millis(); // 记录第一步开始时间
// currentStepIndex = 0; // 从第一步开始
// }
@@ -6,7 +6,6 @@ char serial_buf[32]; // 存储串口接收数据
uint8_t buf_idx = 0; // 缓冲区索引
// -------------------------- 串口接收处理函数--------------------------
// 修改 serialReceiveProcess 函数以支持两种结束符
void serialReceiveProcess() {
while (Serial.available()) {
char c = Serial.read();
@@ -16,6 +15,8 @@ void serialReceiveProcess() {
// 判断是哪种指令格式
if (strchr(serial_buf, '=') != NULL) {
parseSingleParam(serial_buf); // 处理原格式指令
} else if (strstr(serial_buf, "MODE:") != NULL) {
parseSetRobotMode(serial_buf); // 通过串口设置小车模式
} else if (strstr(serial_buf, "S1:") != NULL && strstr(serial_buf, "S2:") != NULL) {
parseServoAngleCommand(serial_buf); // 处理舵机角度控制指令 S1:90,S2:90;
} else if (strstr(serial_buf, "DX:") != NULL && strstr(serial_buf, "DY:") != NULL) {
@@ -68,6 +69,16 @@ void parseCameraDeviationCommand(char* cmd) {
}
// 添加踢球模式设置函数
void parseSetRobotMode(char* cmd) {
char* modestr = strstr(cmd, "MODE:");
if (modestr == NULL) {
Serial.println("小车模式指令格式错误!请使用\"MODE:模式;\"格式(例如\"MODE:1\")");
return;
}
int mode_id = atoi(modestr + 5); // "MODE:"占5个字符,跳过它们取数值
setRobotMode(mode_id);
}
// -------------------------- 参数解析函数(原逻辑不变)--------------------------
void parseSingleParam(char* cmd) {
@@ -177,6 +188,9 @@ void parseSingleParam(char* cmd) {
} else if (strcmp(param_name, "pitch_adjust") == 0) {
pitch_adjust = param_val;
} else if (strcmp(param_name, "wrobot_height") == 0) {
wrobot_height = param_val;
// } else if (strcmp(param_name, "step_joyx") == 0) {
// step_joyx = param_val;
@@ -20,6 +20,8 @@ extern PIDController pid_yaw_align;
extern float pid_cam_p;
extern float pid_cam_d;
extern int wrobot_height;
extern int chase_ball_s2;
extern int kick_back_s2;
extern int ob_ball_dy;
@@ -69,6 +71,8 @@ void parseServoAngleCommand(char* cmd);
void parseCameraDeviationCommand(char* cmd);
// 踢球相关函数声明
void setRobotMode(int mode_id);
void parseSetRobotMode(char* cmd);
void kick_ball_loop();
void SetKickMode(String mode);
@@ -137,6 +137,8 @@ float original_leg_height_base = leg_height_base ;
#define SERVO0_SPEED 400 // 舵机1速度,不能太快,否则影响其他动作平衡
#define SERVO1_SPEED 400 // 舵机2速度
int wrobot_height_origin = 40;
int wrobot_height = 9999;
int left_height;
int right_height;
float leg_position_add = 0; // roll轴平衡控制量
@@ -252,7 +254,7 @@ float dragon_joyx_factor = 0.8f;
typedef struct
{
int height = 30;
int height = wrobot_height_origin;// 40
int roll;
int jump = 0; // 0=不跳跃 1=跳跃
int joyy;
@@ -421,7 +423,8 @@ void setup()
void loop()
{
serialReceiveProcess(); // 调用串口接收函数(核心修改)
serialReceiveProcess(); // 调用串口接收函数(核心修改)
handleLEDBlink(); // 处理LED闪烁
process_xbox_notif(); // 处理xbox手柄通知
@@ -831,6 +834,9 @@ void leg_loop()
leg_position_add = pid_roll_angle(lpf_roll(roll_angle));
// 左后腿默认等于 wrobot.height
if(wrobot_height != 9999){
wrobot.height = wrobot_height;
}
left_height = wrobot.height;
right_height = wrobot.height;
LegHeightDiff = 0; // 初始化 roll 角度补偿值
@@ -858,7 +864,7 @@ void leg_loop()
// id[0] 正面看右手,id[1] 正面看左手
// 2047是舵机中间位置,8.4是系数,32是默认高度,最高80,最低32
// const int LEG_HEIGHT_BASE 这值越小,机身越高,实测范围 0(最高),52(最低)
Position[0] = 2047 + 8.4 * (left_height - leg_height_base ) - leg_position_add;
Position[0] = 2047 + 8.4 * (left_height - leg_height_base ) + leg_position_add;
Position[1] = 2047 - 8.4 * (right_height - leg_height_base ) - leg_position_add;
// 舵机1:限制在 SERVO0_MIN(下限)~ SERVO0_MAX(上限),和原逻辑一致
@@ -1057,7 +1063,7 @@ void resetZeroPoint() {
* xbox 手柄控制
* ========================================*/
void processControllerData(const XboxControllerNotificationParser& remoteData) {
// String str = String(xboxController.xboxNotif.btnY) + "," + // Y键
// String(xboxController.xboxNotif.btnX) + "," + // X键
// String(xboxController.xboxNotif.btnB) + "," + // B键
@@ -1295,9 +1301,9 @@ void processControllerData(const XboxControllerNotificationParser& remoteData) {
}
// 追逐并转向踢会球模式 @@@@@@
if (remoteData.btnY && !last_btnY && robot_enabled && trace_mode) {
if(kick_mode != "kick_back_mode"){
SetKickMode("kick_back_mode");
}else if(kick_mode == "kick_back_mode"){
if(kick_mode != "kick_run_mode"){
SetKickMode("kick_run_mode");
}else if(kick_mode == "kick_run_mode"){
SetKickMode("kick_place_mode");
}
}
@@ -1568,37 +1574,28 @@ void obstacle_cancel()
void kick_ball_loop(){
if(trace_mode){
if (kick_mode == "kick_run_mode") { // 运动追踪模式
setLEDColor(CRGB::Blue);
}else if(kick_mode == "kick_back_mode") { // 追逐并转向踢会球模式
if(kick_mode == "kick_run_mode") { // 追逐并转向踢会球模式
setLEDColor(CRGB::Red);
}else if(kick_mode == "kick_place_mode"){ // 原地踢球模式
}else if(kick_mode == "kick_place_mode"){ // 原地踢球模式(守门模式)
setLEDColor(CRGB::Green);
}
}else{
// 非踢球模式下,动态调整高度
if(wrobot.joyy == 0 ){
if(current_s1 > 90){ // 打开挡板
leg_height_base = 30.0f;
}else if(current_s1 > 10){
leg_height_base = constrain(current_s1, 15.0f, 30.0f);
}else{
leg_height_base = original_leg_height_base;
}
}
}
// else{
// // 非踢球模式下,动态调整高度
// if(wrobot.joyy == 0 ){
// if(current_s1 > 90){ // 打开挡板
// leg_height_base = 30.0f;
// }else if(current_s1 > 10){
// leg_height_base = constrain(current_s1, 15.0f, 30.0f);
// }else{
// leg_height_base = original_leg_height_base;
// }
// }
// }
}
// 通过偏差deviation 控制摄像头上下左右运动
void kick_ball_main(int dx, int dy) {
// 在运动踢球时,踢好球,需要有一段停止前进时间
// if(kick_over_count > 0 && kick_over_count < kick_over_count_max){
// kick_over_count ++;
// }else{
// kick_over_count = 0;
// }
// Serial.println("kick_over_count: " + String(kick_over_count) );
// 不是追踪模式
if(!trace_mode){
@@ -1641,7 +1638,7 @@ void kick_ball_main(int dx, int dy) {
if(kick_mode == "kick_run_mode"){
cam_aim_ball(dy); // 相机瞄准
if(kick_over_count){ // 踢好球之后阶段
if(kick_over_count){ // 踢好球之后阶段,转到对齐偏航角
if(kick_over_count > 0 && kick_over_count < kick_over_count_max){
kick_over_count ++;
@@ -1727,7 +1724,7 @@ void kick_ball_core(){
void ready_kick_ball(){
if( abs(current_s1 - ready_kick_angel) > 5){
setFrontierServoAngles(ready_kick_angel); // 打开挡板,收到后方
leg_height_base = ready_leg_height_base; // 下降
// leg_height_base = ready_leg_height_base; // 下降
}
}
@@ -1840,17 +1837,65 @@ void cancel_kick_mode(){
setLEDColor(CRGB::Black);
leg_height_base = original_leg_height_base; // 上升
setFrontierServoAngles(0); // s1 前档舵
}
void SetKickMode(String mode){
trace_mode = true;
kick_mode = mode;
yaw_to_joyx = 9999;
// 进入kick_back_mode时,记录当前偏航角作为基准0度
if(mode == "kick_run_mode" || mode == "kick_back_mode"){
// 进入kick_run_mode时,记录当前偏航角作为基准0度
if(mode == "kick_run_mode"){
kick_yaw_zero = mpu6050.getAngleZ(); // 读取当前偏航角(Z轴角度)作为基准
pid_yaw_align.error_prev = 0.0f; // 重置偏航对齐PID状态
}
}
void setRobotMode(int mode_id){
if(mode_id == 11){ // 站起来
robot_enabled = true;
sitting_down = 0; // 清除坐下动作标记
stand_up_count ++; // 站立标志位
pid_trace_joyx.P = 0.25; // 追踪模式
// wrobot_height = 40;
Serial.println("站起来");
}else if(mode_id == 10){ // 坐下
robot_enabled = false;
sitting_down = 1; // 标记开始坐下动作保存当前的角度零点
pid_trace_joyx.P = 0.5; // 追踪模式
sms_sts.EnableTorque(ID[0], 0); // 第一个舵机失能 0 失能,1 使能
sms_sts.EnableTorque(ID[1], 0); // 第二个舵机失能
cancel_kick_mode();
Serial.println("坐下");
}else if(mode_id == 12){ // 还原
roll_adjust = original_roll_adjust;
pitch_adjust = 0.0f;
leg_height_base = original_leg_height_base;
pitch_zeropoint = original_pitch_zeropoint;
Serial.println("还原");
}else if(mode_id == 20){ // 取消踢球
cancel_kick_mode();
Serial.println("取消踢球");
}else if(mode_id == 21){ // 守门模式
SetKickMode("kick_place_mode");
Serial.println("守门模式");
}else if(mode_id == 22){ // 运动踢球模式
SetKickMode("kick_run_mode");
Serial.println("运动踢球模式");
}
}