static void chassis_ramp(void) { if (rc.kb.bit.W) { ramp_calc(&chassis_x_ramp, 1.0f, chassis.keyboard_input, chassis.wheel_max, 0.0f); } else if (rc.kb.bit.S) { ramp_calc(&chassis_x_ramp, 1.0f, -chassis.keyboard_input, 0.0f, -chassis.wheel_max); } else { if (chassis_x_ramp.out > 0) { ramp_calc(&chassis_x_ramp, 1.0f, -chassis.keyboard_input, chassis.wheel_max, 0.0f); } else if (chassis_x_ramp.out < 0) { ramp_calc(&chassis_x_ramp, 1.0f, chassis.keyboard_input, 0.0f, -chassis.wheel_max); } } if (rc.kb.bit.D) { ramp_calc(&chassis_y_ramp, 1.0f, chassis.keyboard_input, chassis.wheel_max, 0.0f); } else if (rc.kb.bit.A) { ramp_calc(&chassis_y_ramp, 1.0f, -chassis.keyboard_input, 0.0f, -chassis.wheel_max); } else { if (chassis_y_ramp.out > 0) { ramp_calc(&chassis_y_ramp, 1.0f, -chassis.keyboard_input, chassis.wheel_max, 0.0f); } else if (chassis_y_ramp.out < 0) { ramp_calc(&chassis_y_ramp, 1.0f, chassis.keyboard_input, 0.0f, -chassis.wheel_max); } } }
时间: 2024-04-17 08:24:00 浏览: 170
这段代码是一个名为 `chassis_ramp` 的函数,它用于根据键盘输入来计算底盘的加速度。
在这段代码中,通过判断键盘输入的状态来决定执行不同的操作:
1. 如果按下了键盘的 W 键,则使用 `ramp_calc` 函数计算底盘在 x 轴上的加速度,并将结果存储在 `chassis_x_ramp` 中。
2. 如果按下了键盘的 S 键,则使用 `ramp_calc` 函数计算底盘在 x 轴上的反向加速度,并将结果存储在 `chassis_x_ramp` 中。
3. 如果没有按下 W 键或 S 键,则根据 `chassis_x_ramp` 的当前输出值进行判断:
- 如果 `chassis_x_ramp.out` 大于 0,则使用 `ramp_calc` 函数计算底盘在 x 轴上的反向加速度,并将结果存储在 `chassis_x_ramp` 中。
- 如果 `chassis_x_ramp.out` 小于 0,则使用 `ramp_calc` 函数计算底盘在 x 轴上的加速度,并将结果存储在 `chassis_x_ramp` 中。
类似地,对于键盘输入的 Y 轴方向,也进行了相同的判断和计算操作。
总之,这段代码根据键盘输入的状态来计算底盘在 x 和 y 轴上的加速度,并使用 `ramp_calc` 函数进行计算和更新。通过这种方式,可以实现底盘的平滑加速和减速操作。
相关问题
位置环写的正确吗? for (i = 0; i < 4; i++) { PID_Calc(&chassis_move_control_loop->motor_speed_pid[i], chassis_move_control_loop->motor_chassis[i].speed, chassis_move_control_loop->motor_chassis[i].speed_set); speed_output = chassis_move_control_loop->motor_speed_pid[i].output; chassis_move_control_loop->motor_position_pid[i].set_point = speed_output; PID_Calc(&chassis_move_control_loop->motor_position_pid[i],chassis_move_control_loop->motor_chassis[i].position, chassis_move_control_loop->motor_chassis[i].position_set); position_output = chassis_move_control_loop->motor_position_pid[i].output; chassis_move_control_loop->motor_chassis[i].output = position_output; }
PID控制器的位置环,应该是在循环中不断更新输出的位置值,而不是不断计算PID值。
例如,以下代码可能更符合位置环的实现方式:
float Setpoint = 50.0; // 目标位置
float Position = 0.0; // 当前位置
float Output = 0.0; // 输出控制值
PID pid(1.0, 0.0, 0.1); // PID控制器对象
// 循环计算输出控制值
while (true) {
Position = read_position_sensor(); // 读取当前位置
Output = pid.Compute(Setpoint - Position); // 计算输出控制值
write_motor(Output); // 输出控制值到电机
delay(10); // 等待一段时间再进行下一次循环
}
以上代码中,使用了一个PID控制器对象pid,其Compute()方法可接受位置偏差作为输入(即目标位置与当前位置的差值),计算对应的输出控制值。在循环中,不断读取当前位置并计算输出控制值,然后输出到电机中进行调节。其中可以加入一些延时操作,确保每次循环的时间间隔相同。
需要注意的是,实际应用中还需要进行一些限幅、积分清零等操作,以确保PID控制器的稳定性和安全性。以上代码仅作为参考,需根据具体场景进行相应的调整和优化。
解释这段代码static void chassis_control_loop(chassis_move_t *chassis_move_control_loop) { fp32 max_vector = 0.0f, vector_rate = 0.0f; fp32 temp = 0.0f; fp32 wheel_speed[4] = {0.0f, 0.0f, 0.0f, 0.0f}; uint8_t i = 0; float position_error, speed_error; float position_output, speed_output; float current_position, current_speed; float target_position, target_speed; chassis_move_control_loop->vx_set=vx_set; chassis_move_control_loop->vy_set=vy_set; chassis_move_control_loop->wz_set=angle_set; chassis_vector_to_mecanum_wheel_speed(chassis_move_control_loop->vx_set, chassis_move_control_loop->vy_set, chassis_move_control_loop->wz_set, wheel_speed); if (chassis_move_control_loop->chassis_mode == CHASSIS_VECTOR_RAW) { for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].give_current = (int16_t)(wheel_speed[i]); } } for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].speed_set = wheel_speed[i]; temp = fabs(chassis_move_control_loop->motor_chassis[i].speed_set); if (max_vector < temp) { max_vector = temp; } } if (max_vector > MAX_WHEEL_SPEED) { vector_rate = MAX_WHEEL_SPEED / max_vector; for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].speed_set *= vector_rate; } } for (i = 0; i < 4; i++) { PID_Calc(&chassis_move_control_loop->motor_speed_pid[i], chassis_move_control_loop->motor_chassis[i].speed, chassis_move_control_loop->motor_chassis[i].speed_set); } for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].give_current = (int16_t)(chassis_move_control_loop->motor_speed_pid[i].out); } }
chassis_move_control_loop->motor_chassis[i].position_pid, chassis_move_control_loop->motor_chassis[i].speed_pid, chassis_move_control_loop->motor_chassis[i].position_get, chassis_move_control_loop->motor_chassis[i].speed_get, chassis_move_control_loop->motor_chassis[i].speed_set, &position_error, &speed_error, &position_output, &speed_output); current_position = chassis_move_control_loop->motor_chassis[i].position_get; current_speed = chassis_move_control_loop->motor_chassis[i].speed_get; target_position = chassis_move_control_loop->motor_chassis[i].position_set; target_speed = speed_output; if(chassis_move_control_loop->motor_chassis[i].position_pid.enable == 1) //PID启动 { chassis_move_control_loop->motor_chassis[i].give_current = PID_Calc(&chassis_move_control_loop->motor_chassis[i].position_pid, current_position, target_position); } else { chassis_move_control_loop->motor_chassis[i].give_current = PID_Calc(&chassis_move_control_loop->motor_chassis[i].speed_pid, current_speed, target_speed); } } }
该函数为底盘控制代码,主要实现底盘的位置和速度控制。
具体实现方法为:
1.根据控制指令,将底盘的速度向量转换为各个驱动电机的速度。
2.根据底盘模式选择不同的控制方式:
如果模式为 CHASSIS_VECTOR_RAW,直接将每个驱动电机的输出电流设置为对应速度。
3.根据电机的最大速度设置,对转换后的速度进行限制。
4.对每个驱动电机进行PID控制,计算出目标位置和目标速度,并根据位置控制或速度控制模式下达电机电流控制指令。
5.将目标速度和目标位置在PID计算中使用,并将计算出的电流控制指令转换为电机的输出电流。
阅读全文