x
B题-报告1-程序清单 | ||||
| ||||
B题-报告1-程序清单 (1)PID算法程序 void pid_set_t(PID *pid, float kp, float ti, float td, short t, float smax, float e_isp, short tp) { pid->kp = kp; pid->ki = kp * t / ti; pid->kd = kp * td / t; pid->smax = smax; pid->e_isp = e_isp; pid->type = tp; } void pid_process(PID *pid) { if(pid->type & PID_TYPE_ISP) { if(pid->e < pid->e_isp && pid->e > -pid->e_isp) pid->e_s += pid->e; else pid->e_s /= 2; } else { pid->e_s += pid->e; } //积分限幅 if(pid->e_s > pid->smax) pid->e_s = pid->smax; if(pid->e_s < -pid->smax) pid->e_s = -pid->smax; if(!(pid->type & PID_TYPE_DFB)) { pid->e_d = pid->e - pid->p_e; } pid->p_e = pid->e; if(pid->type & PID_TYPE_DDL) { pid->e_ds += pid->e_d; pid->e_ds /= 2; } else { pid->e_ds = pid->e_d; } pid->o = (float)(pid->kp * pid->e + pid->kd * pid->e_ds + pid->ki * pid->e_s); } (2)画长度大于50cm的直线程序 Q1: motor_set(200, 200, 200, 200); while(1) { int a = tm1638_get_int(); motor_set(a, 0, 0, 0); a = tm1638_get_int(); motor_set(0, a, 0, 0); a = tm1638_get_int(); motor_set(0, 0, a, 0); a = tm1638_get_int(); motor_set(0, 0, 0, a); } (3)画设置角度、设置长度的直线程序 Q2: a_sv = tm1638_get_int(); amp = tm1638_get_int(); tm1638_int2(a_sv, amp); tm1638_disp(); a_sv = 3.1415926f * 2 - a_sv * 3.1415926f / 180.0f; x_sv = 0.4f * arm_cos_f32(a_sv); y_sv = 0.4f * arm_sin_f32(a_sv); while(1) { delay_ms_set(1); //Read Position spi_start(); spi_send(0x0C); for(int i = 0; i < 16; i++) ((unsigned char *)(position_q))[i] = spi_send(0xFF); spi_stop(); quart_multi_q(position_q, position_q_correct); quart_to_eular(position_q, position_e); pid_sta_x.e = x_sv - position_e[0]; if(pid_sta_x.e <0.01f&& pid_sta_x.e >-0.01f) pid_sta_x.e = 0; else if(pid_sta_x.e > 0) pid_sta_x.e -= 0.01f; else pid_sta_x.e += 0.01f; pid_process(&pid_sta_x); motor_ctrl_x = limit(pid_sta_x.o, -1000, 1000); pid_sta_y.e = y_sv - position_e[1]; if(pid_sta_y.e <0.01f&& pid_sta_y.e >-0.01f) pid_sta_y.e = 0; else if(pid_sta_y.e > 0) pid_sta_y.e -= 0.01f; else pid_sta_y.e += 0.01f; pid_process(&pid_sta_y); motor_ctrl_y = limit(pid_sta_y.o, -1000, 1000);
if(time % 20 == 0) { motor_setx(motor_ctrl_x); motor_sety(motor_ctrl_y); } time++; if(time == 1500) goto Q2T; delay_wait(); } (4)快速制动静止程序 Q5: oled_disp_6x8str(80, 6, "Time:"); x_sv = 0; y_sv = 0; while(1) { delay_ms_set(1); //Read Position spi_start(); spi_send(0x0C); for(int i = 0; i < 16; i++) ((unsigned char *)(position_q))[i] = spi_send(0xFF); spi_stop();
quart_multi_q(position_q, position_q_correct); quart_to_eular(position_q, position_e);
pid_sta_x.e = x_sv - position_e[0]; if(pid_sta_x.e <0.01f&& pid_sta_x.e >-0.01f) pid_sta_x.e = 0; else if(pid_sta_x.e > 0) pid_sta_x.e -= 0.01f; else pid_sta_x.e += 0.01f; pid_process(&pid_sta_x); motor_ctrl_x = limit(pid_sta_x.o, -1000, 1000);
pid_sta_y.e = y_sv - position_e[1]; if(pid_sta_y.e <0.01f&& pid_sta_y.e >-0.01f) pid_sta_y.e = 0; else if(pid_sta_y.e > 0) pid_sta_y.e -= 0.01f; else pid_sta_y.e += 0.01f; pid_process(&pid_sta_y); motor_ctrl_y = limit(pid_sta_y.o, -1000, 1000); if(time % 20 == 0) { motor_setx(motor_ctrl_x); motor_sety(motor_ctrl_y); } if(time % 50 == 0) judge(__sqrtf(pid_sta_y.e * pid_sta_y.e + pid_sta_x.e * pid_sta_x.e), 0, 0.03f, 0.001f, 50);
//oled_disp_int(80, 0, position_e[0] * 1000); //oled_disp_int(80, 1, position_e[1] * 1000); time++; delay_wait(); } (5)作半径可设置的圆周运动程序 Q9: oled_disp_6x8str(0, 0, "Radius:"); oled_disp_6x8str(80, 6, "Time:"); disp_en = tm1638_get_int(); pid_init_k(&pid_cir_rr, 250, 0.9f, 50, 20, 0, PID_TYPE_POS); pid_cir_rr.e_s = -5; for(int i = 0; i < 8; i++) pid_init_k(&pid_cir_r[i], 820, 1.2f, 1600, 8, 0, PID_TYPE_POS); r_sv = tm1638_get_int(); gg = 1; if(r_sv > 31) gg = 2; while(1) { delay_ms_set(20); //Read Position spi_start(); spi_send(0x0C); for(int i = 0; i < 16; i++) ((unsigned char *)(position_q))[i] = spi_send(0xFF); spi_stop(); quart_multi_q(position_q, position_q_correct); Quarternion p; quart_set(p, 0, 0, 0, -1); Quarternion qb; qb[0] = position_q[0]; qb[1] = position_q[1]; qb[2] = position_q[2]; qb[3] = position_q[3]; quart_inverse(qb); quart_multi_q(position_q, p); quart_multi_q(position_q, qb); |