123

Dependencies:   StationKeeping MPU9250 PID Servo mbed

Committer:
d15321854
Date:
Tue Jul 25 09:11:26 2017 +0000
Revision:
0:4fecb14ffbb8
123

Who changed what in which revision?

UserRevisionLine numberNew contents of line
d15321854 0:4fecb14ffbb8 1 #include "mbed.h"
d15321854 0:4fecb14ffbb8 2 #include "PID.h"
d15321854 0:4fecb14ffbb8 3 #include "Servo.h"
d15321854 0:4fecb14ffbb8 4 #include "MPU9250.h"
d15321854 0:4fecb14ffbb8 5
d15321854 0:4fecb14ffbb8 6 //**************************** PID control para declaration ************************************//
d15321854 0:4fecb14ffbb8 7 #define RATE 0.005
d15321854 0:4fecb14ffbb8 8 #define Kp_1 1.1 //1.1
d15321854 0:4fecb14ffbb8 9 #define Ki_1 0.18 //0.2
d15321854 0:4fecb14ffbb8 10 #define Kd_1 0.001
d15321854 0:4fecb14ffbb8 11 //**************************** Angle Sonsor para declaration ************************************//
d15321854 0:4fecb14ffbb8 12 #define Kp 0.5f // proportional gain governs rate of convergence to accelerometer/magnetometer
d15321854 0:4fecb14ffbb8 13 #define Ki 0.0f//0.005f // integral gain governs rate of convergence of gyroscope biases
d15321854 0:4fecb14ffbb8 14 //**************************** pragram debug declaration ************************************//
d15321854 0:4fecb14ffbb8 15 int index_times = 0;
d15321854 0:4fecb14ffbb8 16 double RunTime =0,lastTime =0;
d15321854 0:4fecb14ffbb8 17 int do_measure_index=0;
d15321854 0:4fecb14ffbb8 18 int Arm_enable_index;
d15321854 0:4fecb14ffbb8 19 DigitalOut Arm_interrupt(D9);
d15321854 0:4fecb14ffbb8 20
d15321854 0:4fecb14ffbb8 21 double t_MeasureAngularVelocity=0.001;
d15321854 0:4fecb14ffbb8 22 double t_PIDcontrol_velocity =0.001;
d15321854 0:4fecb14ffbb8 23 double t_LQR_control = 0.005;
d15321854 0:4fecb14ffbb8 24 double t_MeasureRobotAttitudeAngle = 0.005;
d15321854 0:4fecb14ffbb8 25 double t_quadratureDecoder = 7;
d15321854 0:4fecb14ffbb8 26 double t_TrajectoryTracking_control = 0.1;
d15321854 0:4fecb14ffbb8 27 //**************************** Motor para declaration ************************************//
d15321854 0:4fecb14ffbb8 28 double radius_ball = 0.15;
d15321854 0:4fecb14ffbb8 29 double radius_robot = 0.105;
d15321854 0:4fecb14ffbb8 30 double r_wheel = 0.05;
d15321854 0:4fecb14ffbb8 31 //**************************** Motor declaration ************************************//
d15321854 0:4fecb14ffbb8 32 //DigitalOut ExtInt(PB_7);
d15321854 0:4fecb14ffbb8 33 DigitalOut Break_1(A5);//D15
d15321854 0:4fecb14ffbb8 34 DigitalOut Break_2(A4);//D14
d15321854 0:4fecb14ffbb8 35 DigitalOut Break_3(A3);//D8
d15321854 0:4fecb14ffbb8 36 DigitalOut AR_1(D15);//A5
d15321854 0:4fecb14ffbb8 37 DigitalOut AR_2(D14);//A4
d15321854 0:4fecb14ffbb8 38 DigitalOut AR_3(D8);//A3
d15321854 0:4fecb14ffbb8 39 DigitalOut CW_CCW_1(D7);
d15321854 0:4fecb14ffbb8 40 DigitalOut CW_CCW_2(D6);
d15321854 0:4fecb14ffbb8 41 DigitalOut CW_CCW_3(D5);
d15321854 0:4fecb14ffbb8 42 Servo PWM_Motor_1(D2);
d15321854 0:4fecb14ffbb8 43 Servo PWM_Motor_2(D3);
d15321854 0:4fecb14ffbb8 44 Servo PWM_Motor_3(D4);
d15321854 0:4fecb14ffbb8 45 int control_Brake,control_StopRun=0;
d15321854 0:4fecb14ffbb8 46 int cw_ccw_1=0,cw_ccw_2=0,cw_ccw_3=0;
d15321854 0:4fecb14ffbb8 47 //**************************** Measuremant of angular velocity declaration ************************************//
d15321854 0:4fecb14ffbb8 48 double Angle_1 =0,Angle_2 =0,Angle_3 =0;
d15321854 0:4fecb14ffbb8 49 double LastAngle_1 =0,LastAngle_2 =0,LastAngle_3 =0;
d15321854 0:4fecb14ffbb8 50 double _1_SectionAngle=0,_1_LastSectionAngle,_1_LastSectionAngle_1,_1_LastSectionAngle_2,_1_LastSectionAngle_3,_1_LastSectionAngle_4;
d15321854 0:4fecb14ffbb8 51 double _2_SectionAngle=0,_2_LastSectionAngle,_2_LastSectionAngle_1,_2_LastSectionAngle_2,_2_LastSectionAngle_3,_2_LastSectionAngle_4;
d15321854 0:4fecb14ffbb8 52 double _3_SectionAngle=0,_3_LastSectionAngle,_3_LastSectionAngle_1,_3_LastSectionAngle_2,_3_LastSectionAngle_3,_3_LastSectionAngle_4;
d15321854 0:4fecb14ffbb8 53 double Average_SectionAngle_1,Now_angularVelocity_1=0;
d15321854 0:4fecb14ffbb8 54 double Average_SectionAngle_2,Now_angularVelocity_2=0;
d15321854 0:4fecb14ffbb8 55 double Average_SectionAngle_3,Now_angularVelocity_3=0;
d15321854 0:4fecb14ffbb8 56 double SectionTime =0;
d15321854 0:4fecb14ffbb8 57 double NowTime_measureVelocity=0, LastTime_measureVelocity = 0;
d15321854 0:4fecb14ffbb8 58 //**************************** PID control declaration ************************************//
d15321854 0:4fecb14ffbb8 59 float Now_time_PID,Last_Time_PID;
d15321854 0:4fecb14ffbb8 60 //Command
d15321854 0:4fecb14ffbb8 61 double Command_AngularVel_1=1,Command_AngularVel_2=1,Command_AngularVel_3=1;
d15321854 0:4fecb14ffbb8 62 double command_AngularVel_1=1,command_AngularVel_2=1,command_AngularVel_3=1;
d15321854 0:4fecb14ffbb8 63 //Control
d15321854 0:4fecb14ffbb8 64 double Control_motor_1,Control_motor_2,Control_motor_3;
d15321854 0:4fecb14ffbb8 65 //Control PWM value
d15321854 0:4fecb14ffbb8 66 double Control_Motor_PWM_1,Control_Motor_PWM_2,Control_Motor_PWM_3;
d15321854 0:4fecb14ffbb8 67
d15321854 0:4fecb14ffbb8 68
d15321854 0:4fecb14ffbb8 69 PID Motor_1 (&Now_angularVelocity_1, &Control_motor_1, &Command_AngularVel_1, Kp_1, Ki_1, Kd_1, DIRECT,&Now_time_PID,&Last_Time_PID);
d15321854 0:4fecb14ffbb8 70 PID Motor_2 (&Now_angularVelocity_2, &Control_motor_2, &Command_AngularVel_2, Kp_1, Ki_1, Kd_1, DIRECT,&Now_time_PID,&Last_Time_PID);
d15321854 0:4fecb14ffbb8 71 PID Motor_3 (&Now_angularVelocity_3, &Control_motor_3, &Command_AngularVel_3, Kp_1, Ki_1, Kd_1, DIRECT,&Now_time_PID,&Last_Time_PID);
d15321854 0:4fecb14ffbb8 72 //****************************LQR_control declaration************************************//
d15321854 0:4fecb14ffbb8 73 double Ka = 25; //25.0
d15321854 0:4fecb14ffbb8 74 double Kav = 10.7423; //10.4423
d15321854 0:4fecb14ffbb8 75
d15321854 0:4fecb14ffbb8 76 double Kt = 3.1 ; //3.1
d15321854 0:4fecb14ffbb8 77 double Kt_y = 3.1; //3.98
d15321854 0:4fecb14ffbb8 78 double Kv = 1.0; //1.0
d15321854 0:4fecb14ffbb8 79 double Kv_y = 1.0; //1.1
d15321854 0:4fecb14ffbb8 80
d15321854 0:4fecb14ffbb8 81 double Kz = 0.05; //0.05
d15321854 0:4fecb14ffbb8 82 double Kii = 0.15; //0.2
d15321854 0:4fecb14ffbb8 83
d15321854 0:4fecb14ffbb8 84 double KI_xy = 0.0085; //0.02
d15321854 0:4fecb14ffbb8 85 double KI_xy_y = 0.0085; //0.025
d15321854 0:4fecb14ffbb8 86
d15321854 0:4fecb14ffbb8 87 double Roll_offset = 2.1; //2.88 4.0
d15321854 0:4fecb14ffbb8 88 double Pitch_offset = 1.85; //-0.05 2.1
d15321854 0:4fecb14ffbb8 89 double Diff_Roll,Diff_Pitch,Diff_Yaw;
d15321854 0:4fecb14ffbb8 90 double Integ_Roll,Integ_Pitch;
d15321854 0:4fecb14ffbb8 91 double Integ_x,Integ_y;
d15321854 0:4fecb14ffbb8 92 double Roll_last,Pitch_last;
d15321854 0:4fecb14ffbb8 93 double Vx=0,Vy=0,Wz=0;
d15321854 0:4fecb14ffbb8 94 double d_x=0,d_y=0;
d15321854 0:4fecb14ffbb8 95 double u_x=0,u_y=0;
d15321854 0:4fecb14ffbb8 96 double Point_x;
d15321854 0:4fecb14ffbb8 97 double x_now,y_now;
d15321854 0:4fecb14ffbb8 98 double x_pre_1,y_pre_1;
d15321854 0:4fecb14ffbb8 99 double ax_now,ay_now;
d15321854 0:4fecb14ffbb8 100 double ax_pre_1,ay_pre_1;
d15321854 0:4fecb14ffbb8 101 double ax_pre_2,ay_pre_2;
d15321854 0:4fecb14ffbb8 102 double Vx_pre_1,Vy_pre_1;
d15321854 0:4fecb14ffbb8 103 double Diff_x,Diff_y;
d15321854 0:4fecb14ffbb8 104 double Diff_x_pre,Diff_y_pre;
d15321854 0:4fecb14ffbb8 105 double dot_diff_x,dot_diff_y;
d15321854 0:4fecb14ffbb8 106 //****************************Trajectory Tracking declaration************************************//
d15321854 0:4fecb14ffbb8 107 double x_trajectory,y_trajectory;
d15321854 0:4fecb14ffbb8 108 //****************************Encoder declaration************************************//
d15321854 0:4fecb14ffbb8 109 DigitalIn phaseA_1( PC_3 );
d15321854 0:4fecb14ffbb8 110 DigitalIn phaseB_1( PC_2 );
d15321854 0:4fecb14ffbb8 111 DigitalIn phaseA_2( PH_1 );
d15321854 0:4fecb14ffbb8 112 DigitalIn phaseB_2( PB_7 );
d15321854 0:4fecb14ffbb8 113 DigitalIn phaseA_3( PA_15 );
d15321854 0:4fecb14ffbb8 114 DigitalIn phaseB_3( PA_14 );
d15321854 0:4fecb14ffbb8 115 int encoderClickCount_1=0,previousEncoderState_1=0;
d15321854 0:4fecb14ffbb8 116 int encoderClickCount_2=0,previousEncoderState_2=0;
d15321854 0:4fecb14ffbb8 117 int encoderClickCount_3=0,previousEncoderState_3=0;
d15321854 0:4fecb14ffbb8 118
d15321854 0:4fecb14ffbb8 119 //****************************Angle Sensor declaration************************************//
d15321854 0:4fecb14ffbb8 120 float Times[10] = {0,0,0,0,0,0,0,0,0,0};
d15321854 0:4fecb14ffbb8 121 float control_frequency = 800;//PPM_FREQU; // frequency for the main loop in Hz
d15321854 0:4fecb14ffbb8 122 int counter = 0;
d15321854 0:4fecb14ffbb8 123 int divider = 20;
d15321854 0:4fecb14ffbb8 124 float dt; // time for entire loop
d15321854 0:4fecb14ffbb8 125 float dt_sensors; // time only to read sensors
d15321854 0:4fecb14ffbb8 126 float q0 = 1, q1 = 0, q2 = 0, q3 = 0;
d15321854 0:4fecb14ffbb8 127 float q0_A = 1, q1_A = 0, q2_A = 0, q3_A = 0;
d15321854 0:4fecb14ffbb8 128 float exInt = 0, eyInt = 0, ezInt = 0;
d15321854 0:4fecb14ffbb8 129 float OX = 0, OY = 0, OZ = 0;
d15321854 0:4fecb14ffbb8 130 float Roll_pre_1,Roll_pre_2,Roll_pre_3,Roll_pre_4;
d15321854 0:4fecb14ffbb8 131 float Pitch_pre_1,Pitch_pre_2,Pitch_pre_3,Pitch_pre_4;
d15321854 0:4fecb14ffbb8 132 float Mag_x_pre,Mag_y_pre,Mag_z_pre;
d15321854 0:4fecb14ffbb8 133 float Mag_x_pre_L,Mag_y_pre_L,Mag_z_pre_L;
d15321854 0:4fecb14ffbb8 134 float Mag_x_pre_LL,Mag_y_pre_LL,Mag_z_pre_LL;
d15321854 0:4fecb14ffbb8 135 float Mag_x_pre_LLL,Mag_y_pre_LLL,Mag_z_pre_LLL;
d15321854 0:4fecb14ffbb8 136 float Mag_x_ave,Mag_y_ave,Mag_x_total,Mag_y_total;
d15321854 0:4fecb14ffbb8 137 float Cal_Mag_x_pre_LL,Cal_Mag_x_pre_L,Cal_Mag_x_pre,Cal_Mag_x;
d15321854 0:4fecb14ffbb8 138 float GYRO_z_pre,GYRO_z_pre_L,GYRO_z_pre_LL,GYRO_z_pre_LLL;
d15321854 0:4fecb14ffbb8 139 float GYRO_z_total,GYRO_z_offset,Global_GYRO_z;
d15321854 0:4fecb14ffbb8 140 float Global_mag_vector_angle,Yaw_pre;
d15321854 0:4fecb14ffbb8 141 float Global_mag_x_vector_angle,Mag_x_vector_angle;
d15321854 0:4fecb14ffbb8 142 float Global_mag_y_vector_angle,Mag_y_vector_angle;
d15321854 0:4fecb14ffbb8 143 int Count_mag_check=0;
d15321854 0:4fecb14ffbb8 144 float angle[3];
d15321854 0:4fecb14ffbb8 145 float Roll,Pitch,Yaw;
d15321854 0:4fecb14ffbb8 146 float calibrated_values[3],magCalibrationp[3];
d15321854 0:4fecb14ffbb8 147 float v_index[3];
d15321854 0:4fecb14ffbb8 148 float dest1,dest2;
d15321854 0:4fecb14ffbb8 149 int f=0;
d15321854 0:4fecb14ffbb8 150 int j=0;
d15321854 0:4fecb14ffbb8 151 int k=0;
d15321854 0:4fecb14ffbb8 152 int g=0;
d15321854 0:4fecb14ffbb8 153 int count1=0,count2=0,count3=0,count4=0,count5=0,count6=0,count7=0,count8=0,count9=0,count11=0,count12=0,count14=0;
d15321854 0:4fecb14ffbb8 154 int Rot_index;
d15321854 0:4fecb14ffbb8 155 float mRes = 10.*4912./32760.0;
d15321854 0:4fecb14ffbb8 156
d15321854 0:4fecb14ffbb8 157 int AngleFilter_counter = 0;
d15321854 0:4fecb14ffbb8 158 float Roll_total = 0,Pitch_total = 0;
d15321854 0:4fecb14ffbb8 159
d15321854 0:4fecb14ffbb8 160 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
d15321854 0:4fecb14ffbb8 161 mpu9250_spi imu(spi,SPI_CS); //define the mpu9250 object
d15321854 0:4fecb14ffbb8 162 //****************************Timer declaration************************************//
d15321854 0:4fecb14ffbb8 163 Timer NowTime;
d15321854 0:4fecb14ffbb8 164 //**************************** Filter_IMUupdate ************************************//
d15321854 0:4fecb14ffbb8 165 //**************************** Filter_IMUupdate ************************************//
d15321854 0:4fecb14ffbb8 166 //**************************** Filter_IMUupdate ************************************//
d15321854 0:4fecb14ffbb8 167 //**************************** Filter_IMUupdate ************************************//
d15321854 0:4fecb14ffbb8 168 //**************************** Filter_IMUupdate ************************************//
d15321854 0:4fecb14ffbb8 169 void Filter_IMUupdate(float halfT, float gx, float gy, float gz, float ax, float ay, float az) {
d15321854 0:4fecb14ffbb8 170 float norm;
d15321854 0:4fecb14ffbb8 171 float vx, vy, vz;
d15321854 0:4fecb14ffbb8 172 float ex, ey, ez;
d15321854 0:4fecb14ffbb8 173
d15321854 0:4fecb14ffbb8 174 // normalise the measurements
d15321854 0:4fecb14ffbb8 175 norm = sqrt(ax*ax + ay*ay + az*az);
d15321854 0:4fecb14ffbb8 176 if(norm == 0.0f) return;
d15321854 0:4fecb14ffbb8 177 ax /= norm;
d15321854 0:4fecb14ffbb8 178 ay /= norm;
d15321854 0:4fecb14ffbb8 179 az /= norm;
d15321854 0:4fecb14ffbb8 180
d15321854 0:4fecb14ffbb8 181 // estimated direction of gravity
d15321854 0:4fecb14ffbb8 182 vx = 2*(q1*q3 - q0*q2);
d15321854 0:4fecb14ffbb8 183 vy = 2*(q0*q1 + q2*q3);
d15321854 0:4fecb14ffbb8 184 vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
d15321854 0:4fecb14ffbb8 185
d15321854 0:4fecb14ffbb8 186 // error is sum of cross product between reference direction of field and direction measured by sensor
d15321854 0:4fecb14ffbb8 187 ex = (ay*vz - az*vy);
d15321854 0:4fecb14ffbb8 188 ey = (az*vx - ax*vz);
d15321854 0:4fecb14ffbb8 189 ez = (ax*vy - ay*vx);
d15321854 0:4fecb14ffbb8 190
d15321854 0:4fecb14ffbb8 191 // integral error scaled integral gain
d15321854 0:4fecb14ffbb8 192 exInt += ex*Ki;
d15321854 0:4fecb14ffbb8 193 eyInt += ey*Ki;
d15321854 0:4fecb14ffbb8 194 ezInt += ez*Ki;
d15321854 0:4fecb14ffbb8 195
d15321854 0:4fecb14ffbb8 196 // adjusted gyroscope measurements
d15321854 0:4fecb14ffbb8 197 gx += Kp*ex + exInt;
d15321854 0:4fecb14ffbb8 198 gy += Kp*ey + eyInt;
d15321854 0:4fecb14ffbb8 199 gz += Kp*ez + ezInt;
d15321854 0:4fecb14ffbb8 200
d15321854 0:4fecb14ffbb8 201 // integrate quaternion rate and normalise
d15321854 0:4fecb14ffbb8 202 float q0o = q0; // he did the MATLAB to C error by not thinking of the beginning vector elements already being changed for the calculation of the rest!
d15321854 0:4fecb14ffbb8 203 float q1o = q1;
d15321854 0:4fecb14ffbb8 204 float q2o = q2;
d15321854 0:4fecb14ffbb8 205 float q3o = q3;
d15321854 0:4fecb14ffbb8 206 q0 += (-q1o*gx - q2o*gy - q3o*gz)*halfT;
d15321854 0:4fecb14ffbb8 207 q1 += (q0o*gx + q2o*gz - q3o*gy)*halfT;
d15321854 0:4fecb14ffbb8 208 q2 += (q0o*gy - q1o*gz + q3o*gx)*halfT;
d15321854 0:4fecb14ffbb8 209 q3 += (q0o*gz + q1o*gy - q2o*gx)*halfT;
d15321854 0:4fecb14ffbb8 210
d15321854 0:4fecb14ffbb8 211 // normalise quaternion
d15321854 0:4fecb14ffbb8 212 norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
d15321854 0:4fecb14ffbb8 213 q0 = q0 / norm;
d15321854 0:4fecb14ffbb8 214 q1 = q1 / norm;
d15321854 0:4fecb14ffbb8 215 q2 = q2 / norm;
d15321854 0:4fecb14ffbb8 216 q3 = q3 / norm;
d15321854 0:4fecb14ffbb8 217 }
d15321854 0:4fecb14ffbb8 218 //**************************** Filter_compute ************************************//
d15321854 0:4fecb14ffbb8 219 //**************************** Filter_compute ************************************//
d15321854 0:4fecb14ffbb8 220 //**************************** Filter_compute ************************************//
d15321854 0:4fecb14ffbb8 221 //**************************** Filter_compute ************************************//
d15321854 0:4fecb14ffbb8 222 //**************************** Filter_compute ************************************//
d15321854 0:4fecb14ffbb8 223 void Filter_compute(float dt, const float * Gyro_data, const float * Acc_data, const float * Comp_data)
d15321854 0:4fecb14ffbb8 224 {
d15321854 0:4fecb14ffbb8 225 // IMU/AHRS
d15321854 0:4fecb14ffbb8 226
d15321854 0:4fecb14ffbb8 227 float d_Gyro_angle[3];
d15321854 0:4fecb14ffbb8 228 void get_Acc_angle(const float * Acc_data);
d15321854 0:4fecb14ffbb8 229 // IMU/AHRS (from http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/)
d15321854 0:4fecb14ffbb8 230 float radGyro[3],Gyro_cal_data; // Gyro in radians per second
d15321854 0:4fecb14ffbb8 231
d15321854 0:4fecb14ffbb8 232 for(int i=0; i<3; i++)
d15321854 0:4fecb14ffbb8 233 radGyro[i] = Gyro_data[i] * 3.14159/ 180;
d15321854 0:4fecb14ffbb8 234
d15321854 0:4fecb14ffbb8 235 Filter_IMUupdate(dt/2, radGyro[0], radGyro[1], radGyro[2], Acc_data[0], Acc_data[1], Acc_data[2]);
d15321854 0:4fecb14ffbb8 236 //IMU_AHRSupdate(dt/2, radGyro[0], radGyro[1], radGyro[2], Acc_data[0], Acc_data[1], Acc_data[2], Comp_data[0], Comp_data[1], Comp_data[2]);
d15321854 0:4fecb14ffbb8 237
d15321854 0:4fecb14ffbb8 238 float rangle[3]; // calculate angles in radians from quternion output, formula from Wiki (http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles)
d15321854 0:4fecb14ffbb8 239
d15321854 0:4fecb14ffbb8 240 rangle[0] = atan2(2*q0*q1 + 2*q2*q3, 1 - 2*(q1*q1 + q2*q2));
d15321854 0:4fecb14ffbb8 241 rangle[1] = asin (2*q0*q2 - 2*q3*q1);
d15321854 0:4fecb14ffbb8 242 rangle[2] = atan2(2*q0_A*q3_A + 2*q1_A*q2_A, 1 - 2*(q2_A*q2_A + q3_A*q3_A)); // Z-axis
d15321854 0:4fecb14ffbb8 243
d15321854 0:4fecb14ffbb8 244
d15321854 0:4fecb14ffbb8 245 for(int i=0; i<2; i++){ // angle in degree
d15321854 0:4fecb14ffbb8 246 angle[i] = rangle[i] * 180 / 3.14159;
d15321854 0:4fecb14ffbb8 247 }
d15321854 0:4fecb14ffbb8 248 /*Roll=angle[0]*0.2 + Roll_pre_1*0.2 + Roll_pre_2*0.2 +Roll_pre_3*0.2 + Roll_pre_4*0.2;
d15321854 0:4fecb14ffbb8 249 Roll_pre_4 = Roll_pre_3;
d15321854 0:4fecb14ffbb8 250 Roll_pre_3 = Roll_pre_2;
d15321854 0:4fecb14ffbb8 251 Roll_pre_2 = Roll_pre_1;
d15321854 0:4fecb14ffbb8 252 Roll_pre_1 = Roll;
d15321854 0:4fecb14ffbb8 253
d15321854 0:4fecb14ffbb8 254 Pitch=angle[1]*0.2 + Pitch_pre_1*0.2 + Pitch_pre_2*0.2 + Pitch_pre_3*0.2 + Pitch_pre_4*0.2;
d15321854 0:4fecb14ffbb8 255 Pitch_pre_4 = Pitch_pre_3;
d15321854 0:4fecb14ffbb8 256 Pitch_pre_3 = Pitch_pre_2;
d15321854 0:4fecb14ffbb8 257 Pitch_pre_2 = Pitch_pre_1;
d15321854 0:4fecb14ffbb8 258 Pitch_pre_1 = Pitch;*/
d15321854 0:4fecb14ffbb8 259
d15321854 0:4fecb14ffbb8 260 Roll_total += angle[0];
d15321854 0:4fecb14ffbb8 261 Pitch_total += angle[1];
d15321854 0:4fecb14ffbb8 262 AngleFilter_counter++;
d15321854 0:4fecb14ffbb8 263
d15321854 0:4fecb14ffbb8 264 if( AngleFilter_counter > 1 ){ // The average of the attitude angle for 100 times.
d15321854 0:4fecb14ffbb8 265 Roll = Roll_total / AngleFilter_counter;
d15321854 0:4fecb14ffbb8 266 Pitch = Pitch_total / AngleFilter_counter;
d15321854 0:4fecb14ffbb8 267 AngleFilter_counter = 0;
d15321854 0:4fecb14ffbb8 268 Roll_total = 0;
d15321854 0:4fecb14ffbb8 269 Pitch_total = 0;
d15321854 0:4fecb14ffbb8 270 Roll -= Roll_offset;
d15321854 0:4fecb14ffbb8 271 Pitch -= Pitch_offset;
d15321854 0:4fecb14ffbb8 272 }
d15321854 0:4fecb14ffbb8 273
d15321854 0:4fecb14ffbb8 274 //**************************************************Gyro_data[2] filter start
d15321854 0:4fecb14ffbb8 275 float GYRO_z=0;
d15321854 0:4fecb14ffbb8 276
d15321854 0:4fecb14ffbb8 277 GYRO_z=Gyro_data[2]*0.15 + GYRO_z_pre*0.20 + GYRO_z_pre_L*0.20 + GYRO_z_pre_LL*0.25 + GYRO_z_pre_LLL*0.20;
d15321854 0:4fecb14ffbb8 278 if( count4==1 ){
d15321854 0:4fecb14ffbb8 279 GYRO_z_pre_L=GYRO_z_pre;
d15321854 0:4fecb14ffbb8 280
d15321854 0:4fecb14ffbb8 281 count4=0;
d15321854 0:4fecb14ffbb8 282 }
d15321854 0:4fecb14ffbb8 283 if( count5==2 ){
d15321854 0:4fecb14ffbb8 284 GYRO_z_pre_LL=GYRO_z_pre_L;
d15321854 0:4fecb14ffbb8 285
d15321854 0:4fecb14ffbb8 286 count5=0;
d15321854 0:4fecb14ffbb8 287 }
d15321854 0:4fecb14ffbb8 288 if( count6==3 ){
d15321854 0:4fecb14ffbb8 289 GYRO_z_pre_LLL=GYRO_z_pre_LL;
d15321854 0:4fecb14ffbb8 290
d15321854 0:4fecb14ffbb8 291 count6=0;
d15321854 0:4fecb14ffbb8 292 }
d15321854 0:4fecb14ffbb8 293
d15321854 0:4fecb14ffbb8 294
d15321854 0:4fecb14ffbb8 295
d15321854 0:4fecb14ffbb8 296 count4++;
d15321854 0:4fecb14ffbb8 297 count5++;
d15321854 0:4fecb14ffbb8 298 count6++;
d15321854 0:4fecb14ffbb8 299 GYRO_z_pre=Gyro_data[2];
d15321854 0:4fecb14ffbb8 300 Global_GYRO_z=GYRO_z;
d15321854 0:4fecb14ffbb8 301 /*printf(" GYRO_z:%10.3f ,count8:%10d \n",
d15321854 0:4fecb14ffbb8 302 GYRO_z,
d15321854 0:4fecb14ffbb8 303 count8
d15321854 0:4fecb14ffbb8 304 );*/
d15321854 0:4fecb14ffbb8 305 if((count8>5)&&(count8<=2005)){
d15321854 0:4fecb14ffbb8 306 GYRO_z_total+=GYRO_z;
d15321854 0:4fecb14ffbb8 307 }
d15321854 0:4fecb14ffbb8 308 if( count8==2005 ){
d15321854 0:4fecb14ffbb8 309 GYRO_z_offset=GYRO_z_total/2000;
d15321854 0:4fecb14ffbb8 310 /* printf(" GYRO_z_offset:%10.5f \n ",
d15321854 0:4fecb14ffbb8 311 GYRO_z_offset
d15321854 0:4fecb14ffbb8 312 );*/
d15321854 0:4fecb14ffbb8 313 GYRO_z_total=0;
d15321854 0:4fecb14ffbb8 314 count8=0;
d15321854 0:4fecb14ffbb8 315 }
d15321854 0:4fecb14ffbb8 316
d15321854 0:4fecb14ffbb8 317 count8++;
d15321854 0:4fecb14ffbb8 318 //**************************************************Gyro_data[2]'s average filter : answer=GYRO_Z is roughly = 0.74956
d15321854 0:4fecb14ffbb8 319
d15321854 0:4fecb14ffbb8 320 //************************************************** calculate Yaw
d15321854 0:4fecb14ffbb8 321 if( (count11==35) ){
d15321854 0:4fecb14ffbb8 322 if( abs(Yaw_pre-Yaw)<1 ){
d15321854 0:4fecb14ffbb8 323 Yaw_pre=Yaw_pre;
d15321854 0:4fecb14ffbb8 324 }else{
d15321854 0:4fecb14ffbb8 325 Yaw_pre=Yaw;
d15321854 0:4fecb14ffbb8 326 }
d15321854 0:4fecb14ffbb8 327 count11=0;
d15321854 0:4fecb14ffbb8 328 }
d15321854 0:4fecb14ffbb8 329 count11++;
d15321854 0:4fecb14ffbb8 330
d15321854 0:4fecb14ffbb8 331 if( count12>=20 ){
d15321854 0:4fecb14ffbb8 332 Yaw += (Gyro_data[2]-0.74936) *dt;
d15321854 0:4fecb14ffbb8 333 }
d15321854 0:4fecb14ffbb8 334 count12++;
d15321854 0:4fecb14ffbb8 335 //pc.printf(" Yaw:%10.5f ",
d15321854 0:4fecb14ffbb8 336 //Yaw
d15321854 0:4fecb14ffbb8 337 // );
d15321854 0:4fecb14ffbb8 338 }
d15321854 0:4fecb14ffbb8 339 //**************************** Mag_Complentary_Filter ************************************//
d15321854 0:4fecb14ffbb8 340 //**************************** Mag_Complentary_Filter ************************************//
d15321854 0:4fecb14ffbb8 341 //**************************** Mag_Complentary_Filter ************************************//
d15321854 0:4fecb14ffbb8 342 //**************************** Mag_Complentary_Filter ************************************//
d15321854 0:4fecb14ffbb8 343 //**************************** Mag_Complentary_Filter ************************************//
d15321854 0:4fecb14ffbb8 344 void Mag_Complentary_Filter(float dt, const float * Comp_data)
d15321854 0:4fecb14ffbb8 345 {
d15321854 0:4fecb14ffbb8 346 float Mag_x=0,Mag_y=0,Mag_z=0;
d15321854 0:4fecb14ffbb8 347 Mag_x=Comp_data[0]*0.15 + Mag_x_pre*0.20 + Mag_x_pre_L*0.20 + Mag_x_pre_LL*0.25 + Mag_x_pre_LLL*0.20;
d15321854 0:4fecb14ffbb8 348 Mag_y=Comp_data[1]*0.15 + Mag_y_pre*0.20 + Mag_y_pre_L*0.20 + Mag_y_pre_LL*0.25 + Mag_y_pre_LLL*0.20;
d15321854 0:4fecb14ffbb8 349 Mag_z=Comp_data[2]*0.15 + Mag_z_pre*0.20 + Mag_z_pre_L*0.20 + Mag_z_pre_LL*0.25 + Mag_z_pre_LLL*0.20;
d15321854 0:4fecb14ffbb8 350
d15321854 0:4fecb14ffbb8 351
d15321854 0:4fecb14ffbb8 352 if( count1==1 ){
d15321854 0:4fecb14ffbb8 353 Mag_x_pre_L=Mag_x_pre;
d15321854 0:4fecb14ffbb8 354 Mag_y_pre_L=Mag_y_pre;
d15321854 0:4fecb14ffbb8 355 Mag_z_pre_L=Mag_z_pre;
d15321854 0:4fecb14ffbb8 356 Cal_Mag_x_pre=Cal_Mag_x;
d15321854 0:4fecb14ffbb8 357
d15321854 0:4fecb14ffbb8 358 count1=0;
d15321854 0:4fecb14ffbb8 359 }
d15321854 0:4fecb14ffbb8 360 if( count2==2 ){
d15321854 0:4fecb14ffbb8 361 Mag_x_pre_LL=Mag_x_pre_L;
d15321854 0:4fecb14ffbb8 362 Mag_y_pre_LL=Mag_y_pre_L;
d15321854 0:4fecb14ffbb8 363 Mag_z_pre_LL=Mag_z_pre_L;
d15321854 0:4fecb14ffbb8 364 Cal_Mag_x_pre_L=Cal_Mag_x_pre;
d15321854 0:4fecb14ffbb8 365
d15321854 0:4fecb14ffbb8 366 count2=0;
d15321854 0:4fecb14ffbb8 367 }
d15321854 0:4fecb14ffbb8 368 if( count7==3 ){
d15321854 0:4fecb14ffbb8 369 Mag_x_pre_LLL=Mag_x_pre_LL;
d15321854 0:4fecb14ffbb8 370 Mag_y_pre_LLL=Mag_y_pre_LL;
d15321854 0:4fecb14ffbb8 371 Mag_z_pre_LLL=Mag_z_pre_LL;
d15321854 0:4fecb14ffbb8 372 Cal_Mag_x_pre_LL=Cal_Mag_x_pre_L;
d15321854 0:4fecb14ffbb8 373
d15321854 0:4fecb14ffbb8 374 count7=0;
d15321854 0:4fecb14ffbb8 375 }
d15321854 0:4fecb14ffbb8 376
d15321854 0:4fecb14ffbb8 377
d15321854 0:4fecb14ffbb8 378 count1++;
d15321854 0:4fecb14ffbb8 379 count2++;
d15321854 0:4fecb14ffbb8 380 count7++;
d15321854 0:4fecb14ffbb8 381 Mag_x_pre=Comp_data[0];
d15321854 0:4fecb14ffbb8 382 Mag_y_pre=Comp_data[1];
d15321854 0:4fecb14ffbb8 383 Mag_z_pre=Comp_data[2];
d15321854 0:4fecb14ffbb8 384 if( count14>4 ){
d15321854 0:4fecb14ffbb8 385 Cal_Mag_x=Mag_x;
d15321854 0:4fecb14ffbb8 386 }
d15321854 0:4fecb14ffbb8 387 count14++;
d15321854 0:4fecb14ffbb8 388
d15321854 0:4fecb14ffbb8 389
d15321854 0:4fecb14ffbb8 390 //*************************************Mag_ave calculate
d15321854 0:4fecb14ffbb8 391 if(count3<=20){
d15321854 0:4fecb14ffbb8 392 Mag_x_total+=Mag_x;
d15321854 0:4fecb14ffbb8 393 Mag_y_total+=Mag_y;
d15321854 0:4fecb14ffbb8 394 }
d15321854 0:4fecb14ffbb8 395 if( count3==20){
d15321854 0:4fecb14ffbb8 396 Mag_x_ave=Mag_x_total/21;
d15321854 0:4fecb14ffbb8 397 Mag_y_ave=Mag_y_total/21;
d15321854 0:4fecb14ffbb8 398 /*pc.printf(" Mag_x_ave:%10.5f ,Mag_y_ave:%10.5f ",
d15321854 0:4fecb14ffbb8 399 Mag_x_ave,
d15321854 0:4fecb14ffbb8 400 Mag_y_ave
d15321854 0:4fecb14ffbb8 401 );*/
d15321854 0:4fecb14ffbb8 402 Mag_x_total=0;
d15321854 0:4fecb14ffbb8 403 Mag_y_total=0;
d15321854 0:4fecb14ffbb8 404 count3=0;
d15321854 0:4fecb14ffbb8 405
d15321854 0:4fecb14ffbb8 406
d15321854 0:4fecb14ffbb8 407 }
d15321854 0:4fecb14ffbb8 408 count3++;
d15321854 0:4fecb14ffbb8 409
d15321854 0:4fecb14ffbb8 410 //********************************ROT_check start
d15321854 0:4fecb14ffbb8 411
d15321854 0:4fecb14ffbb8 412 float v_length,v_length_ave,MagVector_angle;
d15321854 0:4fecb14ffbb8 413 v_length=sqrt( Mag_x*Mag_x + Mag_y*Mag_y );
d15321854 0:4fecb14ffbb8 414 v_length_ave=sqrt( Mag_x_ave*Mag_x_ave + Mag_y_ave*Mag_y_ave );
d15321854 0:4fecb14ffbb8 415
d15321854 0:4fecb14ffbb8 416 MagVector_angle=acos(( Mag_x*Mag_x_ave + Mag_y*Mag_y_ave )/(v_length*v_length_ave))*57.3;
d15321854 0:4fecb14ffbb8 417
d15321854 0:4fecb14ffbb8 418 if( count9==3 ){
d15321854 0:4fecb14ffbb8 419 Global_mag_vector_angle=MagVector_angle;
d15321854 0:4fecb14ffbb8 420 count9=0;
d15321854 0:4fecb14ffbb8 421 }
d15321854 0:4fecb14ffbb8 422 count9++;
d15321854 0:4fecb14ffbb8 423
d15321854 0:4fecb14ffbb8 424
d15321854 0:4fecb14ffbb8 425 if( (abs(Global_mag_vector_angle-MagVector_angle)<5) && (abs(Global_GYRO_z)<5) ){
d15321854 0:4fecb14ffbb8 426 Count_mag_check++;
d15321854 0:4fecb14ffbb8 427
d15321854 0:4fecb14ffbb8 428 }else{ Count_mag_check=0; }
d15321854 0:4fecb14ffbb8 429
d15321854 0:4fecb14ffbb8 430 if( Count_mag_check==30 ){
d15321854 0:4fecb14ffbb8 431 Yaw=Yaw_pre;
d15321854 0:4fecb14ffbb8 432 Count_mag_check=0;
d15321854 0:4fecb14ffbb8 433 }
d15321854 0:4fecb14ffbb8 434 float ABS_CHECK=abs(Global_mag_vector_angle-MagVector_angle);
d15321854 0:4fecb14ffbb8 435 //********************************Theta_check end
d15321854 0:4fecb14ffbb8 436 /*pc.printf("ABS_CHECK:%10.3f,Cal_Mag_x_pre_LL:%10.3f,Mag_x:%10.3f,Count_mag_check:%10d ,Yaw_pre:%10.3f,Yaw_filter:%10.3f ",
d15321854 0:4fecb14ffbb8 437 ABS_CHECK,
d15321854 0:4fecb14ffbb8 438 Cal_Mag_x_pre_LL,
d15321854 0:4fecb14ffbb8 439 Mag_x,
d15321854 0:4fecb14ffbb8 440 Count_mag_check,
d15321854 0:4fecb14ffbb8 441 Yaw_pre,
d15321854 0:4fecb14ffbb8 442 Yaw
d15321854 0:4fecb14ffbb8 443 );*/
d15321854 0:4fecb14ffbb8 444
d15321854 0:4fecb14ffbb8 445 }
d15321854 0:4fecb14ffbb8 446 //****************************Motor_run************************************//
d15321854 0:4fecb14ffbb8 447 //****************************Motor_run************************************//
d15321854 0:4fecb14ffbb8 448 //****************************Motor_run************************************//
d15321854 0:4fecb14ffbb8 449 //****************************Motor_run************************************//
d15321854 0:4fecb14ffbb8 450 //****************************Motor_run************************************//
d15321854 0:4fecb14ffbb8 451 int Motor_run(double control_value_PWM_1,double control_value_PWM_2,double control_value_PWM_3,int control_CW_CCW_1,int control_CW_CCW_2,int control_CW_CCW_3,int control_brake ,int control_stopRun){
d15321854 0:4fecb14ffbb8 452
d15321854 0:4fecb14ffbb8 453 Break_1 = 0;
d15321854 0:4fecb14ffbb8 454 Break_2 = 0;
d15321854 0:4fecb14ffbb8 455 Break_3 = 0;
d15321854 0:4fecb14ffbb8 456 //Brake = 1;
d15321854 0:4fecb14ffbb8 457 /*CW_CCW_1 = 1;
d15321854 0:4fecb14ffbb8 458 CW_CCW_2 = 1;
d15321854 0:4fecb14ffbb8 459 CW_CCW_3 = 1;*/
d15321854 0:4fecb14ffbb8 460
d15321854 0:4fecb14ffbb8 461 CW_CCW_1 = control_CW_CCW_1;
d15321854 0:4fecb14ffbb8 462 CW_CCW_2 = control_CW_CCW_2;
d15321854 0:4fecb14ffbb8 463 CW_CCW_3 = control_CW_CCW_3;
d15321854 0:4fecb14ffbb8 464 double Control_value_PWM_1 = 1-control_value_PWM_1;
d15321854 0:4fecb14ffbb8 465 double Control_value_PWM_2 = 1-control_value_PWM_2;
d15321854 0:4fecb14ffbb8 466 double Control_value_PWM_3 = 1-control_value_PWM_3;
d15321854 0:4fecb14ffbb8 467 //printf("Control_value_PWM_2: %f\n",Control_value_PWM_2);
d15321854 0:4fecb14ffbb8 468 //printf("Control_value_PWM_3: %f\n",Control_value_PWM_3);
d15321854 0:4fecb14ffbb8 469 //PWM_Motor_1.write(Control_value_PWM_1);
d15321854 0:4fecb14ffbb8 470 /*control_CW_CCW_1 = 0;
d15321854 0:4fecb14ffbb8 471 control_CW_CCW_2 = 0;
d15321854 0:4fecb14ffbb8 472 control_CW_CCW_3 = 0;
d15321854 0:4fecb14ffbb8 473 AR_1 = 1;
d15321854 0:4fecb14ffbb8 474 AR_2 = 1;
d15321854 0:4fecb14ffbb8 475 AR_3 = 1;
d15321854 0:4fecb14ffbb8 476 CW_CCW_1 = 1;
d15321854 0:4fecb14ffbb8 477 CW_CCW_2 = 1;
d15321854 0:4fecb14ffbb8 478 CW_CCW_3 = 1;
d15321854 0:4fecb14ffbb8 479 PWM_Motor_1.write(0.75);
d15321854 0:4fecb14ffbb8 480 PWM_Motor_2.write(0.75);
d15321854 0:4fecb14ffbb8 481 PWM_Motor_3.write(0.75);*/
d15321854 0:4fecb14ffbb8 482 //wait_ms(0.5);
d15321854 0:4fecb14ffbb8 483 PWM_Motor_1.write(Control_value_PWM_1);
d15321854 0:4fecb14ffbb8 484 PWM_Motor_2.write(Control_value_PWM_2);
d15321854 0:4fecb14ffbb8 485 PWM_Motor_3.write(Control_value_PWM_3);
d15321854 0:4fecb14ffbb8 486
d15321854 0:4fecb14ffbb8 487 }
d15321854 0:4fecb14ffbb8 488 //****************************quadratureDecoder_1************************************//
d15321854 0:4fecb14ffbb8 489 //****************************quadratureDecoder_1************************************//
d15321854 0:4fecb14ffbb8 490 //****************************quadratureDecoder_1************************************//
d15321854 0:4fecb14ffbb8 491 //****************************quadratureDecoder_1************************************//
d15321854 0:4fecb14ffbb8 492 //****************************quadratureDecoder_1************************************//
d15321854 0:4fecb14ffbb8 493 void quadratureDecoder_1( void )
d15321854 0:4fecb14ffbb8 494 {
d15321854 0:4fecb14ffbb8 495 int currentEncoderState_1 = (phaseB_1.read() << 1) + phaseA_1.read();
d15321854 0:4fecb14ffbb8 496
d15321854 0:4fecb14ffbb8 497 //**************************** 1 ************************************//
d15321854 0:4fecb14ffbb8 498 if( currentEncoderState_1 == previousEncoderState_1 )
d15321854 0:4fecb14ffbb8 499 {
d15321854 0:4fecb14ffbb8 500 return;
d15321854 0:4fecb14ffbb8 501 }
d15321854 0:4fecb14ffbb8 502
d15321854 0:4fecb14ffbb8 503 switch( previousEncoderState_1 )
d15321854 0:4fecb14ffbb8 504 {
d15321854 0:4fecb14ffbb8 505 case 0:
d15321854 0:4fecb14ffbb8 506 if( currentEncoderState_1 == 2 )
d15321854 0:4fecb14ffbb8 507 {
d15321854 0:4fecb14ffbb8 508 encoderClickCount_1--;
d15321854 0:4fecb14ffbb8 509
d15321854 0:4fecb14ffbb8 510 }
d15321854 0:4fecb14ffbb8 511 else if( currentEncoderState_1 == 1 )
d15321854 0:4fecb14ffbb8 512 {
d15321854 0:4fecb14ffbb8 513 encoderClickCount_1++;
d15321854 0:4fecb14ffbb8 514
d15321854 0:4fecb14ffbb8 515 }
d15321854 0:4fecb14ffbb8 516 break;
d15321854 0:4fecb14ffbb8 517
d15321854 0:4fecb14ffbb8 518 case 1:
d15321854 0:4fecb14ffbb8 519 if( currentEncoderState_1 == 0 )
d15321854 0:4fecb14ffbb8 520 {
d15321854 0:4fecb14ffbb8 521 encoderClickCount_1--;
d15321854 0:4fecb14ffbb8 522
d15321854 0:4fecb14ffbb8 523 }
d15321854 0:4fecb14ffbb8 524 else if( currentEncoderState_1 == 3 )
d15321854 0:4fecb14ffbb8 525 {
d15321854 0:4fecb14ffbb8 526 encoderClickCount_1++;
d15321854 0:4fecb14ffbb8 527
d15321854 0:4fecb14ffbb8 528 }
d15321854 0:4fecb14ffbb8 529 break;
d15321854 0:4fecb14ffbb8 530
d15321854 0:4fecb14ffbb8 531 case 2:
d15321854 0:4fecb14ffbb8 532 if( currentEncoderState_1 == 3 )
d15321854 0:4fecb14ffbb8 533 {
d15321854 0:4fecb14ffbb8 534 encoderClickCount_1--;
d15321854 0:4fecb14ffbb8 535
d15321854 0:4fecb14ffbb8 536 }
d15321854 0:4fecb14ffbb8 537 else if( currentEncoderState_1 == 0 )
d15321854 0:4fecb14ffbb8 538 {
d15321854 0:4fecb14ffbb8 539 encoderClickCount_1++;
d15321854 0:4fecb14ffbb8 540
d15321854 0:4fecb14ffbb8 541 }
d15321854 0:4fecb14ffbb8 542 break;
d15321854 0:4fecb14ffbb8 543
d15321854 0:4fecb14ffbb8 544 case 3:
d15321854 0:4fecb14ffbb8 545 if( currentEncoderState_1 == 1 )
d15321854 0:4fecb14ffbb8 546 {
d15321854 0:4fecb14ffbb8 547 encoderClickCount_1--;
d15321854 0:4fecb14ffbb8 548
d15321854 0:4fecb14ffbb8 549 }
d15321854 0:4fecb14ffbb8 550 else if( currentEncoderState_1 == 2 )
d15321854 0:4fecb14ffbb8 551 {
d15321854 0:4fecb14ffbb8 552 encoderClickCount_1++;
d15321854 0:4fecb14ffbb8 553
d15321854 0:4fecb14ffbb8 554 }
d15321854 0:4fecb14ffbb8 555 break;
d15321854 0:4fecb14ffbb8 556
d15321854 0:4fecb14ffbb8 557 default:
d15321854 0:4fecb14ffbb8 558 break;
d15321854 0:4fecb14ffbb8 559 }
d15321854 0:4fecb14ffbb8 560 previousEncoderState_1 = currentEncoderState_1;
d15321854 0:4fecb14ffbb8 561
d15321854 0:4fecb14ffbb8 562 }
d15321854 0:4fecb14ffbb8 563 void quadratureDecoder_2( void )
d15321854 0:4fecb14ffbb8 564 {
d15321854 0:4fecb14ffbb8 565 int currentEncoderState_2 = (phaseB_2.read() << 1) + phaseA_2.read();
d15321854 0:4fecb14ffbb8 566
d15321854 0:4fecb14ffbb8 567 //**************************** 2 ************************************//
d15321854 0:4fecb14ffbb8 568 if( currentEncoderState_2 == previousEncoderState_2 )
d15321854 0:4fecb14ffbb8 569 {
d15321854 0:4fecb14ffbb8 570 return;
d15321854 0:4fecb14ffbb8 571 }
d15321854 0:4fecb14ffbb8 572
d15321854 0:4fecb14ffbb8 573 switch( previousEncoderState_2 )
d15321854 0:4fecb14ffbb8 574 {
d15321854 0:4fecb14ffbb8 575 case 0:
d15321854 0:4fecb14ffbb8 576 if( currentEncoderState_2 == 2 )
d15321854 0:4fecb14ffbb8 577 {
d15321854 0:4fecb14ffbb8 578 encoderClickCount_2--;
d15321854 0:4fecb14ffbb8 579
d15321854 0:4fecb14ffbb8 580 }
d15321854 0:4fecb14ffbb8 581 else if( currentEncoderState_2 == 1 )
d15321854 0:4fecb14ffbb8 582 {
d15321854 0:4fecb14ffbb8 583 encoderClickCount_2++;
d15321854 0:4fecb14ffbb8 584
d15321854 0:4fecb14ffbb8 585 }
d15321854 0:4fecb14ffbb8 586 break;
d15321854 0:4fecb14ffbb8 587
d15321854 0:4fecb14ffbb8 588 case 1:
d15321854 0:4fecb14ffbb8 589 if( currentEncoderState_2 == 0 )
d15321854 0:4fecb14ffbb8 590 {
d15321854 0:4fecb14ffbb8 591 encoderClickCount_2--;
d15321854 0:4fecb14ffbb8 592
d15321854 0:4fecb14ffbb8 593 }
d15321854 0:4fecb14ffbb8 594 else if( currentEncoderState_2 == 3 )
d15321854 0:4fecb14ffbb8 595 {
d15321854 0:4fecb14ffbb8 596 encoderClickCount_2++;
d15321854 0:4fecb14ffbb8 597
d15321854 0:4fecb14ffbb8 598 }
d15321854 0:4fecb14ffbb8 599 break;
d15321854 0:4fecb14ffbb8 600
d15321854 0:4fecb14ffbb8 601 case 2:
d15321854 0:4fecb14ffbb8 602 if( currentEncoderState_2 == 3 )
d15321854 0:4fecb14ffbb8 603 {
d15321854 0:4fecb14ffbb8 604 encoderClickCount_2--;
d15321854 0:4fecb14ffbb8 605
d15321854 0:4fecb14ffbb8 606 }
d15321854 0:4fecb14ffbb8 607 else if( currentEncoderState_2 == 0 )
d15321854 0:4fecb14ffbb8 608 {
d15321854 0:4fecb14ffbb8 609 encoderClickCount_2++;
d15321854 0:4fecb14ffbb8 610
d15321854 0:4fecb14ffbb8 611 }
d15321854 0:4fecb14ffbb8 612 break;
d15321854 0:4fecb14ffbb8 613
d15321854 0:4fecb14ffbb8 614 case 3:
d15321854 0:4fecb14ffbb8 615 if( currentEncoderState_2 == 1 )
d15321854 0:4fecb14ffbb8 616 {
d15321854 0:4fecb14ffbb8 617 encoderClickCount_2--;
d15321854 0:4fecb14ffbb8 618
d15321854 0:4fecb14ffbb8 619 }
d15321854 0:4fecb14ffbb8 620 else if( currentEncoderState_2 == 2 )
d15321854 0:4fecb14ffbb8 621 {
d15321854 0:4fecb14ffbb8 622 encoderClickCount_2++;
d15321854 0:4fecb14ffbb8 623
d15321854 0:4fecb14ffbb8 624 }
d15321854 0:4fecb14ffbb8 625 break;
d15321854 0:4fecb14ffbb8 626
d15321854 0:4fecb14ffbb8 627 default:
d15321854 0:4fecb14ffbb8 628 break;
d15321854 0:4fecb14ffbb8 629 }
d15321854 0:4fecb14ffbb8 630 previousEncoderState_2 = currentEncoderState_2;
d15321854 0:4fecb14ffbb8 631 }
d15321854 0:4fecb14ffbb8 632 void quadratureDecoder_3( void )
d15321854 0:4fecb14ffbb8 633 {
d15321854 0:4fecb14ffbb8 634 int currentEncoderState_3 = (phaseB_3.read() << 1) + phaseA_3.read();
d15321854 0:4fecb14ffbb8 635
d15321854 0:4fecb14ffbb8 636 //**************************** 3 ************************************//
d15321854 0:4fecb14ffbb8 637 if( currentEncoderState_3 == previousEncoderState_3 )
d15321854 0:4fecb14ffbb8 638 {
d15321854 0:4fecb14ffbb8 639 return;
d15321854 0:4fecb14ffbb8 640 }
d15321854 0:4fecb14ffbb8 641
d15321854 0:4fecb14ffbb8 642 switch( previousEncoderState_3 )
d15321854 0:4fecb14ffbb8 643 {
d15321854 0:4fecb14ffbb8 644 case 0:
d15321854 0:4fecb14ffbb8 645 if( currentEncoderState_3 == 2 )
d15321854 0:4fecb14ffbb8 646 {
d15321854 0:4fecb14ffbb8 647 encoderClickCount_3--;
d15321854 0:4fecb14ffbb8 648
d15321854 0:4fecb14ffbb8 649 }
d15321854 0:4fecb14ffbb8 650 else if( currentEncoderState_3 == 1 )
d15321854 0:4fecb14ffbb8 651 {
d15321854 0:4fecb14ffbb8 652 encoderClickCount_3++;
d15321854 0:4fecb14ffbb8 653
d15321854 0:4fecb14ffbb8 654 }
d15321854 0:4fecb14ffbb8 655 break;
d15321854 0:4fecb14ffbb8 656
d15321854 0:4fecb14ffbb8 657 case 1:
d15321854 0:4fecb14ffbb8 658 if( currentEncoderState_3 == 0 )
d15321854 0:4fecb14ffbb8 659 {
d15321854 0:4fecb14ffbb8 660 encoderClickCount_3--;
d15321854 0:4fecb14ffbb8 661
d15321854 0:4fecb14ffbb8 662 }
d15321854 0:4fecb14ffbb8 663 else if( currentEncoderState_3 == 3 )
d15321854 0:4fecb14ffbb8 664 {
d15321854 0:4fecb14ffbb8 665 encoderClickCount_3++;
d15321854 0:4fecb14ffbb8 666
d15321854 0:4fecb14ffbb8 667 }
d15321854 0:4fecb14ffbb8 668 break;
d15321854 0:4fecb14ffbb8 669
d15321854 0:4fecb14ffbb8 670 case 2:
d15321854 0:4fecb14ffbb8 671 if( currentEncoderState_3 == 3 )
d15321854 0:4fecb14ffbb8 672 {
d15321854 0:4fecb14ffbb8 673 encoderClickCount_3--;
d15321854 0:4fecb14ffbb8 674
d15321854 0:4fecb14ffbb8 675 }
d15321854 0:4fecb14ffbb8 676 else if( currentEncoderState_3 == 0 )
d15321854 0:4fecb14ffbb8 677 {
d15321854 0:4fecb14ffbb8 678 encoderClickCount_3++;
d15321854 0:4fecb14ffbb8 679
d15321854 0:4fecb14ffbb8 680 }
d15321854 0:4fecb14ffbb8 681 break;
d15321854 0:4fecb14ffbb8 682
d15321854 0:4fecb14ffbb8 683 case 3:
d15321854 0:4fecb14ffbb8 684 if( currentEncoderState_3 == 1 )
d15321854 0:4fecb14ffbb8 685 {
d15321854 0:4fecb14ffbb8 686 encoderClickCount_3--;
d15321854 0:4fecb14ffbb8 687
d15321854 0:4fecb14ffbb8 688 }
d15321854 0:4fecb14ffbb8 689 else if( currentEncoderState_3 == 2 )
d15321854 0:4fecb14ffbb8 690 {
d15321854 0:4fecb14ffbb8 691 encoderClickCount_3++;
d15321854 0:4fecb14ffbb8 692
d15321854 0:4fecb14ffbb8 693 }
d15321854 0:4fecb14ffbb8 694 break;
d15321854 0:4fecb14ffbb8 695
d15321854 0:4fecb14ffbb8 696 default:
d15321854 0:4fecb14ffbb8 697 break;
d15321854 0:4fecb14ffbb8 698 }
d15321854 0:4fecb14ffbb8 699 previousEncoderState_3 = currentEncoderState_3;
d15321854 0:4fecb14ffbb8 700
d15321854 0:4fecb14ffbb8 701 }
d15321854 0:4fecb14ffbb8 702 //****************************getAngular************************************//
d15321854 0:4fecb14ffbb8 703 //****************************getAngular************************************//
d15321854 0:4fecb14ffbb8 704 //****************************getAngular************************************//
d15321854 0:4fecb14ffbb8 705 //****************************getAngular************************************//
d15321854 0:4fecb14ffbb8 706 //****************************getAngular************************************//
d15321854 0:4fecb14ffbb8 707 void getAngular( void )
d15321854 0:4fecb14ffbb8 708 {
d15321854 0:4fecb14ffbb8 709 Angle_1 = (encoderClickCount_1*0.1499)/5;
d15321854 0:4fecb14ffbb8 710 Angle_2 = (encoderClickCount_2*0.1499)/5;
d15321854 0:4fecb14ffbb8 711 Angle_3 = (encoderClickCount_3*0.1499)/5;
d15321854 0:4fecb14ffbb8 712
d15321854 0:4fecb14ffbb8 713
d15321854 0:4fecb14ffbb8 714 _1_SectionAngle = Angle_1 - LastAngle_1;
d15321854 0:4fecb14ffbb8 715 _2_SectionAngle = Angle_2 - LastAngle_2;
d15321854 0:4fecb14ffbb8 716 _3_SectionAngle = Angle_3 - LastAngle_3;
d15321854 0:4fecb14ffbb8 717 Average_SectionAngle_1 = (_1_SectionAngle*0.3 + _1_LastSectionAngle*0.3 + _1_LastSectionAngle_1*0.1 + _1_LastSectionAngle_2*0.1 + _1_LastSectionAngle_3*0.1 + _1_LastSectionAngle_4*0.1)/1;
d15321854 0:4fecb14ffbb8 718 Average_SectionAngle_2 = (_2_SectionAngle*0.3 + _2_LastSectionAngle*0.3 + _2_LastSectionAngle_1*0.1 + _2_LastSectionAngle_2*0.1 + _2_LastSectionAngle_3*0.1 + _2_LastSectionAngle_4*0.1)/1;
d15321854 0:4fecb14ffbb8 719 Average_SectionAngle_3 = (_3_SectionAngle*0.3 + _3_LastSectionAngle*0.3 + _3_LastSectionAngle_1*0.1 + _3_LastSectionAngle_2*0.1 + _3_LastSectionAngle_3*0.1 + _3_LastSectionAngle_4*0.1)/1;
d15321854 0:4fecb14ffbb8 720 NowTime_measureVelocity = NowTime.read();
d15321854 0:4fecb14ffbb8 721 SectionTime = NowTime_measureVelocity - LastTime_measureVelocity;
d15321854 0:4fecb14ffbb8 722 Now_angularVelocity_1 = abs(Average_SectionAngle_1/(SectionTime));
d15321854 0:4fecb14ffbb8 723 Now_angularVelocity_2 = abs(Average_SectionAngle_2/(SectionTime));
d15321854 0:4fecb14ffbb8 724 Now_angularVelocity_3 = abs(Average_SectionAngle_3/(SectionTime));
d15321854 0:4fecb14ffbb8 725
d15321854 0:4fecb14ffbb8 726
d15321854 0:4fecb14ffbb8 727 LastTime_measureVelocity = NowTime_measureVelocity;
d15321854 0:4fecb14ffbb8 728 LastAngle_1 = Angle_1;
d15321854 0:4fecb14ffbb8 729 _1_LastSectionAngle_4 = _1_LastSectionAngle_3;
d15321854 0:4fecb14ffbb8 730 _1_LastSectionAngle_3 = _1_LastSectionAngle_2;
d15321854 0:4fecb14ffbb8 731 _1_LastSectionAngle_2 = _1_LastSectionAngle_1;
d15321854 0:4fecb14ffbb8 732 _1_LastSectionAngle_1 = _1_LastSectionAngle;
d15321854 0:4fecb14ffbb8 733 _1_LastSectionAngle = _1_SectionAngle;
d15321854 0:4fecb14ffbb8 734 LastAngle_2 = Angle_2;
d15321854 0:4fecb14ffbb8 735 _2_LastSectionAngle_4 = _2_LastSectionAngle_3;
d15321854 0:4fecb14ffbb8 736 _2_LastSectionAngle_3 = _2_LastSectionAngle_2;
d15321854 0:4fecb14ffbb8 737 _2_LastSectionAngle_2 = _2_LastSectionAngle_1;
d15321854 0:4fecb14ffbb8 738 _2_LastSectionAngle_1 = _2_LastSectionAngle;
d15321854 0:4fecb14ffbb8 739 _2_LastSectionAngle = _2_SectionAngle;
d15321854 0:4fecb14ffbb8 740 LastAngle_3 = Angle_3;
d15321854 0:4fecb14ffbb8 741 _3_LastSectionAngle_4 = _3_LastSectionAngle_3;
d15321854 0:4fecb14ffbb8 742 _3_LastSectionAngle_3 = _3_LastSectionAngle_2;
d15321854 0:4fecb14ffbb8 743 _3_LastSectionAngle_2 = _3_LastSectionAngle_1;
d15321854 0:4fecb14ffbb8 744 _3_LastSectionAngle_1 = _3_LastSectionAngle;
d15321854 0:4fecb14ffbb8 745 _3_LastSectionAngle = _3_SectionAngle;
d15321854 0:4fecb14ffbb8 746 }
d15321854 0:4fecb14ffbb8 747 //****************************PWM_commmand_transformation************************************//
d15321854 0:4fecb14ffbb8 748 //****************************PWM_commmand_transformation************************************//
d15321854 0:4fecb14ffbb8 749 //****************************PWM_commmand_transformation************************************//
d15321854 0:4fecb14ffbb8 750 //****************************PWM_commmand_transformation************************************//
d15321854 0:4fecb14ffbb8 751 //****************************PWM_commmand_transformation************************************//
d15321854 0:4fecb14ffbb8 752 double PWM_commmand_transformation( double Control_AngVel_Value ){
d15321854 0:4fecb14ffbb8 753 double Control_PWM_Value = 0;
d15321854 0:4fecb14ffbb8 754 //double control_CW_CCW = 0;
d15321854 0:4fecb14ffbb8 755 //printf("*********************Control_AngVel_Value:%.3f\n",Control_AngVel_Value);
d15321854 0:4fecb14ffbb8 756 if( Control_AngVel_Value > 0 ){
d15321854 0:4fecb14ffbb8 757 Control_AngVel_Value = Control_AngVel_Value;
d15321854 0:4fecb14ffbb8 758 //control_CW_CCW = 0;
d15321854 0:4fecb14ffbb8 759
d15321854 0:4fecb14ffbb8 760 }else if( Control_AngVel_Value < 0 ){
d15321854 0:4fecb14ffbb8 761 Control_AngVel_Value = -Control_AngVel_Value;
d15321854 0:4fecb14ffbb8 762 //control_CW_CCW = 1;
d15321854 0:4fecb14ffbb8 763
d15321854 0:4fecb14ffbb8 764 }
d15321854 0:4fecb14ffbb8 765 if( Control_AngVel_Value > 325){
d15321854 0:4fecb14ffbb8 766 if( Control_AngVel_Value < 466 ){
d15321854 0:4fecb14ffbb8 767 if( Control_AngVel_Value < 393 ){
d15321854 0:4fecb14ffbb8 768 Control_PWM_Value = Control_AngVel_Value/651.6 ; //0.5~0.6
d15321854 0:4fecb14ffbb8 769 }else {
d15321854 0:4fecb14ffbb8 770 Control_PWM_Value = Control_AngVel_Value/658.8; //0.6~0.7
d15321854 0:4fecb14ffbb8 771 }
d15321854 0:4fecb14ffbb8 772 }else{
d15321854 0:4fecb14ffbb8 773 if( Control_AngVel_Value < 523 ){
d15321854 0:4fecb14ffbb8 774 Control_PWM_Value = Control_AngVel_Value/658.39; //0.7~0.8
d15321854 0:4fecb14ffbb8 775 }else{
d15321854 0:4fecb14ffbb8 776 if( Control_AngVel_Value < 588 ){
d15321854 0:4fecb14ffbb8 777 Control_PWM_Value = Control_AngVel_Value/652.36; //0.8~0.9
d15321854 0:4fecb14ffbb8 778 }else{
d15321854 0:4fecb14ffbb8 779 Control_PWM_Value = Control_AngVel_Value/655.11; //0.9~1
d15321854 0:4fecb14ffbb8 780 }
d15321854 0:4fecb14ffbb8 781 }
d15321854 0:4fecb14ffbb8 782 }
d15321854 0:4fecb14ffbb8 783 }else if( Control_AngVel_Value < 325){
d15321854 0:4fecb14ffbb8 784 if( Control_AngVel_Value < 40 ){
d15321854 0:4fecb14ffbb8 785 Control_PWM_Value = Control_AngVel_Value/533.3; //0~0.075
d15321854 0:4fecb14ffbb8 786 }else{
d15321854 0:4fecb14ffbb8 787 if( Control_AngVel_Value < 59 ){
d15321854 0:4fecb14ffbb8 788 Control_PWM_Value = Control_AngVel_Value/560.65; //0.1~0.15
d15321854 0:4fecb14ffbb8 789 }else{
d15321854 0:4fecb14ffbb8 790 if( Control_AngVel_Value < 131 ){
d15321854 0:4fecb14ffbb8 791 Control_PWM_Value = Control_AngVel_Value/638.3; //0.15~0.2
d15321854 0:4fecb14ffbb8 792 }else{
d15321854 0:4fecb14ffbb8 793 if( Control_AngVel_Value < 197 ){
d15321854 0:4fecb14ffbb8 794 Control_PWM_Value = Control_AngVel_Value/651.6; //0.2~0.3
d15321854 0:4fecb14ffbb8 795 }else{
d15321854 0:4fecb14ffbb8 796 if( Control_AngVel_Value < 263 ){
d15321854 0:4fecb14ffbb8 797 Control_PWM_Value = Control_AngVel_Value/654.16; //0.3~0.4
d15321854 0:4fecb14ffbb8 798 }else{
d15321854 0:4fecb14ffbb8 799 Control_PWM_Value = Control_AngVel_Value/652.5; //0.4~0.5
d15321854 0:4fecb14ffbb8 800 }
d15321854 0:4fecb14ffbb8 801 }
d15321854 0:4fecb14ffbb8 802 }
d15321854 0:4fecb14ffbb8 803 }
d15321854 0:4fecb14ffbb8 804 }
d15321854 0:4fecb14ffbb8 805 }
d15321854 0:4fecb14ffbb8 806 return Control_PWM_Value;
d15321854 0:4fecb14ffbb8 807 }
d15321854 0:4fecb14ffbb8 808 //****************************PIDcontrol_compute_velocity************************************//
d15321854 0:4fecb14ffbb8 809 //****************************PIDcontrol_compute_velocity************************************//
d15321854 0:4fecb14ffbb8 810 //****************************PIDcontrol_compute_velocity************************************//
d15321854 0:4fecb14ffbb8 811 //****************************PIDcontrol_compute_velocity************************************//
d15321854 0:4fecb14ffbb8 812 //****************************PIDcontrol_compute_velocity************************************//
d15321854 0:4fecb14ffbb8 813 void PIDcontrol_compute_velocity(void){
d15321854 0:4fecb14ffbb8 814 if(command_AngularVel_1 >= 0){
d15321854 0:4fecb14ffbb8 815 cw_ccw_1 = 0;
d15321854 0:4fecb14ffbb8 816 Command_AngularVel_1 = command_AngularVel_1;
d15321854 0:4fecb14ffbb8 817 }else{
d15321854 0:4fecb14ffbb8 818 cw_ccw_1 = 1;
d15321854 0:4fecb14ffbb8 819 Command_AngularVel_1 = -command_AngularVel_1;
d15321854 0:4fecb14ffbb8 820 }
d15321854 0:4fecb14ffbb8 821 if(command_AngularVel_2 >= 0){
d15321854 0:4fecb14ffbb8 822 cw_ccw_2 = 0;
d15321854 0:4fecb14ffbb8 823 Command_AngularVel_2 = command_AngularVel_2;
d15321854 0:4fecb14ffbb8 824 }else{
d15321854 0:4fecb14ffbb8 825 cw_ccw_2 = 1;
d15321854 0:4fecb14ffbb8 826 Command_AngularVel_2 = -command_AngularVel_2;
d15321854 0:4fecb14ffbb8 827 }
d15321854 0:4fecb14ffbb8 828 if(command_AngularVel_3 >= 0){
d15321854 0:4fecb14ffbb8 829 cw_ccw_3 = 0;
d15321854 0:4fecb14ffbb8 830 Command_AngularVel_3 = command_AngularVel_3;
d15321854 0:4fecb14ffbb8 831 }else{
d15321854 0:4fecb14ffbb8 832 cw_ccw_3 = 1;
d15321854 0:4fecb14ffbb8 833 Command_AngularVel_3 = -command_AngularVel_3;
d15321854 0:4fecb14ffbb8 834 }
d15321854 0:4fecb14ffbb8 835 Now_time_PID=NowTime.read();
d15321854 0:4fecb14ffbb8 836 Motor_1.Compute(&Now_time_PID);
d15321854 0:4fecb14ffbb8 837 Motor_2.Compute(&Now_time_PID);
d15321854 0:4fecb14ffbb8 838 Motor_3.Compute(&Now_time_PID);
d15321854 0:4fecb14ffbb8 839 Control_Motor_PWM_1 = PWM_commmand_transformation(Control_motor_1);
d15321854 0:4fecb14ffbb8 840 Control_Motor_PWM_2 = PWM_commmand_transformation(Control_motor_2);
d15321854 0:4fecb14ffbb8 841 Control_Motor_PWM_3 = PWM_commmand_transformation(Control_motor_3);
d15321854 0:4fecb14ffbb8 842 //Control_Motor_PWM_1 = PWM_commmand_transformation(Command_AngularVel_1);
d15321854 0:4fecb14ffbb8 843 //Control_Motor_PWM_2 = PWM_commmand_transformation(Command_AngularVel_2);
d15321854 0:4fecb14ffbb8 844 //Control_Motor_PWM_3 = PWM_commmand_transformation(Command_AngularVel_3);
d15321854 0:4fecb14ffbb8 845 //printf("Command_AngularVel_2: %f\n",Command_AngularVel_2);
d15321854 0:4fecb14ffbb8 846 //printf("Control_motor_2: %f\n",Control_motor_2);
d15321854 0:4fecb14ffbb8 847
d15321854 0:4fecb14ffbb8 848 }
d15321854 0:4fecb14ffbb8 849 //****************************Compute_point************************************//
d15321854 0:4fecb14ffbb8 850 //****************************Compute_point************************************//
d15321854 0:4fecb14ffbb8 851 //****************************Compute_point************************************//
d15321854 0:4fecb14ffbb8 852 //****************************Compute_point************************************//
d15321854 0:4fecb14ffbb8 853 //****************************Compute_point************************************//
d15321854 0:4fecb14ffbb8 854 void LQR_control_compute(void){
d15321854 0:4fecb14ffbb8 855 //Now_point_x = (angle/57.295)*3;
d15321854 0:4fecb14ffbb8 856 //Now_point_x = Angle_1;
d15321854 0:4fecb14ffbb8 857 /*if( Roll > 0.5 ){
d15321854 0:4fecb14ffbb8 858 d_x = Roll*0.01745*radius_ball;
d15321854 0:4fecb14ffbb8 859 Vx = d_x/0.001;
d15321854 0:4fecb14ffbb8 860 }else{
d15321854 0:4fecb14ffbb8 861 Vx = 0;
d15321854 0:4fecb14ffbb8 862 }
d15321854 0:4fecb14ffbb8 863 if(Pitch > 0.5){
d15321854 0:4fecb14ffbb8 864 d_y = Pitch*0.01745*radius_ball;
d15321854 0:4fecb14ffbb8 865 Vy = d_y/0.001;
d15321854 0:4fecb14ffbb8 866 }else{
d15321854 0:4fecb14ffbb8 867 Vy = 0;
d15321854 0:4fecb14ffbb8 868 }
d15321854 0:4fecb14ffbb8 869 if( Yaw > 0 ){
d15321854 0:4fecb14ffbb8 870 Wz = 0;
d15321854 0:4fecb14ffbb8 871 }else{
d15321854 0:4fecb14ffbb8 872 Wz = 0;
d15321854 0:4fecb14ffbb8 873 }*/
d15321854 0:4fecb14ffbb8 874 Diff_Roll = (Roll - Roll_last);
d15321854 0:4fecb14ffbb8 875 Diff_Pitch = (Pitch - Pitch_last);
d15321854 0:4fecb14ffbb8 876 Integ_Roll += Roll;
d15321854 0:4fecb14ffbb8 877 //printf("Diff_Roll:%.3f\n",Diff_Roll);
d15321854 0:4fecb14ffbb8 878 Integ_Pitch += Pitch;
d15321854 0:4fecb14ffbb8 879 Roll_last = Roll;
d15321854 0:4fecb14ffbb8 880 Pitch_last = Pitch;
d15321854 0:4fecb14ffbb8 881
d15321854 0:4fecb14ffbb8 882 //Diff_Roll =0;
d15321854 0:4fecb14ffbb8 883 //Roll -= 2.45;
d15321854 0:4fecb14ffbb8 884 //Pitch -=2.5;
d15321854 0:4fecb14ffbb8 885 Diff_x = x_now - x_trajectory;
d15321854 0:4fecb14ffbb8 886 Diff_y = y_now - y_trajectory;
d15321854 0:4fecb14ffbb8 887 dot_diff_x = Diff_x - Diff_x_pre;
d15321854 0:4fecb14ffbb8 888 dot_diff_y = Diff_y - Diff_y_pre;
d15321854 0:4fecb14ffbb8 889 Integ_x += Diff_x;
d15321854 0:4fecb14ffbb8 890 Integ_y += Diff_y;
d15321854 0:4fecb14ffbb8 891
d15321854 0:4fecb14ffbb8 892 //x_pre_1 = x_now;
d15321854 0:4fecb14ffbb8 893 //y_pre_1 = y_now;
d15321854 0:4fecb14ffbb8 894 Diff_x_pre = Diff_x;
d15321854 0:4fecb14ffbb8 895 Diff_y_pre = Diff_y;
d15321854 0:4fecb14ffbb8 896
d15321854 0:4fecb14ffbb8 897 u_x = Ka*(Roll)+(Integ_Roll*Kii) + Kav*Diff_Roll + Kt*Diff_x + Kv*dot_diff_x + KI_xy*Integ_x;
d15321854 0:4fecb14ffbb8 898 //u_x = Ka*(Roll)+(Integ_Roll*Kii) + Kav*Diff_Roll - Kt*(10) - Kv*0;
d15321854 0:4fecb14ffbb8 899 u_y = Ka*(Pitch)+(Integ_Pitch*Kii) + Kav*Diff_Pitch + Kt_y*Diff_y + Kv_y*dot_diff_y + KI_xy_y*Integ_y;
d15321854 0:4fecb14ffbb8 900 //u_y = Ka*(Pitch)+(Integ_Pitch*Kii) + Kav*Diff_Pitch - Kt*0 - Kv*0;
d15321854 0:4fecb14ffbb8 901 if(u_x > 100 ){u_x = 100;}else if(u_x < -100){u_x = -100;}
d15321854 0:4fecb14ffbb8 902 if(u_y > 100 ){u_y = 100;}else if(u_y < -100){u_y = -100;}
d15321854 0:4fecb14ffbb8 903 Vx = u_x;
d15321854 0:4fecb14ffbb8 904 Vy = u_y;
d15321854 0:4fecb14ffbb8 905 Wz = -Yaw;
d15321854 0:4fecb14ffbb8 906
d15321854 0:4fecb14ffbb8 907 command_AngularVel_1 = (1/radius_ball)*(-Vy*(-0.5)+Kz*Wz);
d15321854 0:4fecb14ffbb8 908 command_AngularVel_2 = (1/radius_ball)*((0.866*Vx+0.5*Vy)*(-0.5)+Kz*Wz);
d15321854 0:4fecb14ffbb8 909 command_AngularVel_3 = (1/radius_ball)*((-0.866*Vx+0.5*Vy)*(-0.5)+Kz*Wz);
d15321854 0:4fecb14ffbb8 910 //printf("Command_AngularVel_2: %f\n",Command_AngularVel_2);
d15321854 0:4fecb14ffbb8 911 //printf("Command_AngularVel_3: %f\n",Command_AngularVel_3);
d15321854 0:4fecb14ffbb8 912
d15321854 0:4fecb14ffbb8 913 /*ax_now = Vx - Vx_pre_1;
d15321854 0:4fecb14ffbb8 914 ay_now = Vy - Vy_pre_1;
d15321854 0:4fecb14ffbb8 915 ax_pre_2 = ax_pre_1;
d15321854 0:4fecb14ffbb8 916 ax_pre_1 = ax_now;
d15321854 0:4fecb14ffbb8 917 ay_pre_2 = ay_pre_1;
d15321854 0:4fecb14ffbb8 918 ay_pre_1 = ay_now;
d15321854 0:4fecb14ffbb8 919 Vx_pre_1 = Vx;
d15321854 0:4fecb14ffbb8 920 Vy_pre_1 = Vy;*/
d15321854 0:4fecb14ffbb8 921
d15321854 0:4fecb14ffbb8 922 }
d15321854 0:4fecb14ffbb8 923 void MeasureRobotAttitudeAngle(void){
d15321854 0:4fecb14ffbb8 924 dt = t_MeasureRobotAttitudeAngle;
d15321854 0:4fecb14ffbb8 925 imu.read_all();
d15321854 0:4fecb14ffbb8 926 Mag_Complentary_Filter(dt,imu.Magnetometer);
d15321854 0:4fecb14ffbb8 927 Filter_compute(dt, imu.gyroscope_data, imu.accelerometer_data, imu.Magnetometer);
d15321854 0:4fecb14ffbb8 928 /*x_now = x_pre_1 + (1/(dt*dt))*(ax_now-2*ax_pre_1+ax_pre_2);
d15321854 0:4fecb14ffbb8 929 y_now = y_pre_1 + (1/(dt*dt))*(ay_now-2*ay_pre_1+ay_pre_2);
d15321854 0:4fecb14ffbb8 930 x_pre_1 = x_now;
d15321854 0:4fecb14ffbb8 931 y_pre_1 = y_now;*/
d15321854 0:4fecb14ffbb8 932 x_now = -((2*r_wheel)/3)*(-1.732*(-Angle_2+Angle_3));
d15321854 0:4fecb14ffbb8 933 y_now = ((2*r_wheel)/3)*((-2*Angle_1+Angle_2+Angle_3)/(-1));
d15321854 0:4fecb14ffbb8 934 do_measure_index++;
d15321854 0:4fecb14ffbb8 935 }
d15321854 0:4fecb14ffbb8 936 void Trajectory_generator(void){
d15321854 0:4fecb14ffbb8 937 double t_trajectory = NowTime.read();
d15321854 0:4fecb14ffbb8 938
d15321854 0:4fecb14ffbb8 939 if( RunTime>=0 &&( RunTime<=10) ){
d15321854 0:4fecb14ffbb8 940 //x_trajectory = t_trajectory * (0.5);
d15321854 0:4fecb14ffbb8 941 x_trajectory = 0;
d15321854 0:4fecb14ffbb8 942 y_trajectory = 0;
d15321854 0:4fecb14ffbb8 943 Arm_enable_index = 0;
d15321854 0:4fecb14ffbb8 944 }else if( RunTime>=10 ){
d15321854 0:4fecb14ffbb8 945 x_trajectory = 0;
d15321854 0:4fecb14ffbb8 946 y_trajectory = 0;
d15321854 0:4fecb14ffbb8 947 Arm_enable_index = 1;
d15321854 0:4fecb14ffbb8 948 }
d15321854 0:4fecb14ffbb8 949 }
d15321854 0:4fecb14ffbb8 950 void Check_Arm_interrupt( double x_Now, double y_Now, double X_trajectory, double Y_trajectory){
d15321854 0:4fecb14ffbb8 951 if( sqrt((x_Now-X_trajectory)*(x_Now-X_trajectory)+(y_Now-Y_trajectory)*(y_Now-Y_trajectory)) < 5 ){
d15321854 0:4fecb14ffbb8 952 if( Arm_enable_index == 1 ){
d15321854 0:4fecb14ffbb8 953 Arm_interrupt = 1;
d15321854 0:4fecb14ffbb8 954 //Roll_offset = 2.0;
d15321854 0:4fecb14ffbb8 955 //Pitch_offset = 2.5;
d15321854 0:4fecb14ffbb8 956 }
d15321854 0:4fecb14ffbb8 957 }
d15321854 0:4fecb14ffbb8 958 }
d15321854 0:4fecb14ffbb8 959 //****************************main function************************************//
d15321854 0:4fecb14ffbb8 960 int main() {
d15321854 0:4fecb14ffbb8 961 Serial pc( USBTX, USBRX );
d15321854 0:4fecb14ffbb8 962 pc.baud(460800);
d15321854 0:4fecb14ffbb8 963 //****************************Angle Sensor initialization************************************//
d15321854 0:4fecb14ffbb8 964 if(imu.init(1,BITS_DLPF_CFG_188HZ)){ //INIT the mpu9250
d15321854 0:4fecb14ffbb8 965 //pc.printf("\nCouldn't initialize MPU9250 via SPI!");
d15321854 0:4fecb14ffbb8 966 }
d15321854 0:4fecb14ffbb8 967 //pc.printf("\nWHOAMI=0x%2x\n",imu.whoami()); //output the I2C address to know if SPI is working, it should be 104
d15321854 0:4fecb14ffbb8 968 imu.whoami();
d15321854 0:4fecb14ffbb8 969 //wait(1);
d15321854 0:4fecb14ffbb8 970 //pc.printf("Gyro_scale=%u\n",imu.set_gyro_scale(BITS_FS_2000DPS)); //Set full scale range for gyros
d15321854 0:4fecb14ffbb8 971 imu.set_gyro_scale(BITS_FS_2000DPS);
d15321854 0:4fecb14ffbb8 972 //wait(1);
d15321854 0:4fecb14ffbb8 973 //pc.printf("Acc_scale=%u\n",imu.set_acc_scale(BITS_FS_16G)); //Set full scale range for accs
d15321854 0:4fecb14ffbb8 974 imu.set_acc_scale(BITS_FS_16G);
d15321854 0:4fecb14ffbb8 975 //wait(1);
d15321854 0:4fecb14ffbb8 976 //pc.printf("AK8963 WHIAM=0x%2x\n",imu.AK8963_whoami());
d15321854 0:4fecb14ffbb8 977 imu.AK8963_whoami();
d15321854 0:4fecb14ffbb8 978 //wait(0.1);
d15321854 0:4fecb14ffbb8 979 imu.AK8963_calib_Magnetometer();
d15321854 0:4fecb14ffbb8 980 //****************************Motor driver declare************************************//
d15321854 0:4fecb14ffbb8 981 //ExtInt = 0; //number high, voltage high.
d15321854 0:4fecb14ffbb8 982 AR_1 = 1;
d15321854 0:4fecb14ffbb8 983 AR_2 = 1;
d15321854 0:4fecb14ffbb8 984 AR_3 = 1;
d15321854 0:4fecb14ffbb8 985 control_Brake = 1; //1:Run 0:Stop
d15321854 0:4fecb14ffbb8 986 //**************************** PWM ************************************//
d15321854 0:4fecb14ffbb8 987 PWM_Motor_1.calibrate(0.02, 0*0.02, 1*0.02);
d15321854 0:4fecb14ffbb8 988 PWM_Motor_2.calibrate(0.02, 0*0.02, 1*0.02);
d15321854 0:4fecb14ffbb8 989 PWM_Motor_3.calibrate(0.02, 0*0.02, 1*0.02);
d15321854 0:4fecb14ffbb8 990 //**************************** Encoder ************************************//
d15321854 0:4fecb14ffbb8 991 phaseA_1.mode( PullUp );
d15321854 0:4fecb14ffbb8 992 phaseB_1.mode( PullUp );
d15321854 0:4fecb14ffbb8 993 phaseA_2.mode( PullUp );
d15321854 0:4fecb14ffbb8 994 phaseB_2.mode( PullUp );
d15321854 0:4fecb14ffbb8 995 phaseA_3.mode( PullUp );
d15321854 0:4fecb14ffbb8 996 phaseB_3.mode( PullUp );
d15321854 0:4fecb14ffbb8 997 //**************************** Ticker ************************************//
d15321854 0:4fecb14ffbb8 998 Ticker Sample_Motor_encoder_1; // create a timer to sample the encoder.
d15321854 0:4fecb14ffbb8 999 Ticker Sample_Motor_encoder_2; // create a timer to sample the encoder.
d15321854 0:4fecb14ffbb8 1000 Ticker Sample_Motor_encoder_3; // create a timer to sample the encoder.
d15321854 0:4fecb14ffbb8 1001 Ticker Sample_robotAngleSonsor; // create a timer to sample the robot attitude.
d15321854 0:4fecb14ffbb8 1002 Ticker MeasureAngularVelocity; // create a timer to measure the motor angular velocity.
d15321854 0:4fecb14ffbb8 1003 Ticker PIDcontrol_velocity; // create a timer to do the motor angular velocity PID control.
d15321854 0:4fecb14ffbb8 1004 Ticker LQR_control; // create a timer to do the position control.
d15321854 0:4fecb14ffbb8 1005 Ticker TrajectoryTracking_control; // create a timer to do the TrajectoryTracking_control.
d15321854 0:4fecb14ffbb8 1006
d15321854 0:4fecb14ffbb8 1007 //**************************** Create the motor encoder sampler. ************************************//
d15321854 0:4fecb14ffbb8 1008 Sample_Motor_encoder_1.attach_us( &quadratureDecoder_1, t_quadratureDecoder );
d15321854 0:4fecb14ffbb8 1009 Sample_Motor_encoder_2.attach_us( &quadratureDecoder_2, t_quadratureDecoder );
d15321854 0:4fecb14ffbb8 1010 Sample_Motor_encoder_3.attach_us( &quadratureDecoder_3, t_quadratureDecoder );
d15321854 0:4fecb14ffbb8 1011 //**************************** Create the motor encoder sampler. ************************************//
d15321854 0:4fecb14ffbb8 1012 Sample_robotAngleSonsor.attach( &MeasureRobotAttitudeAngle, t_MeasureRobotAttitudeAngle );
d15321854 0:4fecb14ffbb8 1013 //**************************** Create the motor angular velocity measurement. ************************************//
d15321854 0:4fecb14ffbb8 1014 MeasureAngularVelocity.attach( &getAngular, t_MeasureAngularVelocity );
d15321854 0:4fecb14ffbb8 1015 //**************************** Create the motor angular velocity PID control. ************************************//
d15321854 0:4fecb14ffbb8 1016 PIDcontrol_velocity.attach( &PIDcontrol_compute_velocity, t_PIDcontrol_velocity );
d15321854 0:4fecb14ffbb8 1017 //**************************** Create the robot LQR control. ************************************//
d15321854 0:4fecb14ffbb8 1018 LQR_control.attach( &LQR_control_compute, t_LQR_control );
d15321854 0:4fecb14ffbb8 1019 //**************************** Create the motor posistion control. ************************************//
d15321854 0:4fecb14ffbb8 1020 TrajectoryTracking_control.attach( &Trajectory_generator, t_TrajectoryTracking_control );
d15321854 0:4fecb14ffbb8 1021 //**************************** Motor settlement ************************************//
d15321854 0:4fecb14ffbb8 1022 Motor_1.SetMode(AUTOMATIC);
d15321854 0:4fecb14ffbb8 1023 Motor_2.SetMode(AUTOMATIC);
d15321854 0:4fecb14ffbb8 1024 Motor_3.SetMode(AUTOMATIC);
d15321854 0:4fecb14ffbb8 1025
d15321854 0:4fecb14ffbb8 1026
d15321854 0:4fecb14ffbb8 1027 Command_AngularVel_1 = 0;
d15321854 0:4fecb14ffbb8 1028 Command_AngularVel_2 = 0;
d15321854 0:4fecb14ffbb8 1029 Command_AngularVel_3 = 0;
d15321854 0:4fecb14ffbb8 1030 //**************************** Timers start ************************************//
d15321854 0:4fecb14ffbb8 1031 NowTime.start();
d15321854 0:4fecb14ffbb8 1032
d15321854 0:4fecb14ffbb8 1033 while( 1 ){
d15321854 0:4fecb14ffbb8 1034
d15321854 0:4fecb14ffbb8 1035 RunTime = NowTime.read();
d15321854 0:4fecb14ffbb8 1036
d15321854 0:4fecb14ffbb8 1037 if( (RunTime-lastTime) > 0.1 ){
d15321854 0:4fecb14ffbb8 1038 index_times++;
d15321854 0:4fecb14ffbb8 1039 lastTime = RunTime;
d15321854 0:4fecb14ffbb8 1040 }
d15321854 0:4fecb14ffbb8 1041
d15321854 0:4fecb14ffbb8 1042 if( index_times >= 0.1 ){
d15321854 0:4fecb14ffbb8 1043 /* pc.printf(" Now_angularVelocity_1 : %.3f ",Now_angularVelocity_1);
d15321854 0:4fecb14ffbb8 1044 pc.printf(" Now_angularVelocity_2 : %.3f ",Now_angularVelocity_2);
d15321854 0:4fecb14ffbb8 1045 pc.printf(" Now_angularVelocity_3 : %.3f\n ",Now_angularVelocity_3);
d15321854 0:4fecb14ffbb8 1046 pc.printf(" Vx : %.3f ",Vx);
d15321854 0:4fecb14ffbb8 1047 pc.printf(" Vy : %.3f ",Vy);
d15321854 0:4fecb14ffbb8 1048 //pc.printf(", Vy : %.3f ",Vy);
d15321854 0:4fecb14ffbb8 1049 pc.printf(", Command_AngularVel_1 : %.3f ",Command_AngularVel_1);
d15321854 0:4fecb14ffbb8 1050 pc.printf(", Command_AngularVel_2 : %.3f ",Command_AngularVel_2);
d15321854 0:4fecb14ffbb8 1051 pc.printf(", Command_AngularVel_3 : %.3f \n",Command_AngularVel_3);*/
d15321854 0:4fecb14ffbb8 1052
d15321854 0:4fecb14ffbb8 1053 /*pc.printf("x_now: %.3f , y_now: %.3f , x_trajectory: %f , u_y: %f ",x_now,y_now,x_trajectory,u_y);
d15321854 0:4fecb14ffbb8 1054 pc.printf(" Roll : %10.3f, Pitch : %10.3f, Yaw : %10.3f \n",
d15321854 0:4fecb14ffbb8 1055 Roll,
d15321854 0:4fecb14ffbb8 1056 Pitch,
d15321854 0:4fecb14ffbb8 1057 Yaw
d15321854 0:4fecb14ffbb8 1058 );*/
d15321854 0:4fecb14ffbb8 1059 pc.printf(" %.3f , %.3f , %.3f , %.3f ",x_now,y_now,x_trajectory,y_trajectory);
d15321854 0:4fecb14ffbb8 1060 pc.printf(", %10.3f, %10.3f, %10.3f , %10.3f \n",
d15321854 0:4fecb14ffbb8 1061 Roll,
d15321854 0:4fecb14ffbb8 1062 Pitch,
d15321854 0:4fecb14ffbb8 1063 Yaw,
d15321854 0:4fecb14ffbb8 1064 RunTime
d15321854 0:4fecb14ffbb8 1065 );
d15321854 0:4fecb14ffbb8 1066 //pc.printf(",Control_motor_1 : %.3f ",Control_motor_1);
d15321854 0:4fecb14ffbb8 1067 //pc.printf(", %.3f ", Command_gularVel_1);
d15321854 0:4fecb14ffbb8 1068
d15321854 0:4fecb14ffbb8 1069 /*pc.printf(", %.3f ",Control_motor_1);*/
d15321854 0:4fecb14ffbb8 1070 //pc.printf(", %.3f\n ",Now_angularVelocity_1);
d15321854 0:4fecb14ffbb8 1071 index_times = 0;
d15321854 0:4fecb14ffbb8 1072 }
d15321854 0:4fecb14ffbb8 1073 Motor_run(Control_Motor_PWM_1,Control_Motor_PWM_2,Control_Motor_PWM_3,cw_ccw_1,cw_ccw_2,cw_ccw_3,control_Brake,control_StopRun);
d15321854 0:4fecb14ffbb8 1074
d15321854 0:4fecb14ffbb8 1075 Check_Arm_interrupt(x_now,y_now,x_trajectory,y_trajectory);
d15321854 0:4fecb14ffbb8 1076
d15321854 0:4fecb14ffbb8 1077 //wait(0.1);
d15321854 0:4fecb14ffbb8 1078 }
d15321854 0:4fecb14ffbb8 1079 }