20181105

Dependencies:   MX28 mbed

Fork of LSM9DS1_project_5_zerotorque by Chen Wei Ting

Committer:
JJting
Date:
Sat Aug 11 04:58:46 2018 +0000
Revision:
6:f48c51662e27
Parent:
5:4dbed091ec5a
Child:
7:5cb292622961
speed control can work but still some bugs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JJting 0:c23e915f255b 1 #include "mbed.h"
JJting 0:c23e915f255b 2 #include "encoder.h"
JJting 0:c23e915f255b 3 #include "Mx28.h"
JJting 0:c23e915f255b 4 #include "PID.h"
JJting 4:f19e7669d1b5 5 #include "LSM9DS1.h"
JJting 0:c23e915f255b 6
JJting 0:c23e915f255b 7 //********************* Dynamxiel ******************************
JJting 0:c23e915f255b 8 #define SERVO_ID 0x01 // ID of which we will set Dynamixel too
JJting 0:c23e915f255b 9 #define SERVO_ControlPin A2 // Control pin of buffer chip, NOTE: this does not matter becasue we are not using a half to full contorl buffer.
JJting 0:c23e915f255b 10 #define SERVO_SET_Baudrate 1000000 // Baud rate speed which the Dynamixel will be set too (1Mbps)
JJting 0:c23e915f255b 11 #define TxPin A0
JJting 0:c23e915f255b 12 #define RxPin A1
JJting 0:c23e915f255b 13 #define CW_LIMIT_ANGLE 1 // lowest clockwise angle is 1, as when set to 0 it set servo to wheel mode
JJting 0:c23e915f255b 14 #define CCW_LIMIT_ANGLE 4095 // Highest anit-clockwise angle is 0XFFF, as when set to 0 it set servo to wheel mode
JJting 4:f19e7669d1b5 15 #define _PI 3.14159265f
JJting 0:c23e915f255b 16 //***************************************************************
JJting 0:c23e915f255b 17
JJting 0:c23e915f255b 18 Serial uart(USBTX, USBRX);
JJting 0:c23e915f255b 19 //Serial uart(D10,D2); // TX : D10 RX : D2 // blueteeth
JJting 0:c23e915f255b 20 DigitalOut LED(A4); // check if the code is running
JJting 0:c23e915f255b 21 DigitalOut led2(A5); // check if the code is running interrupt
JJting 0:c23e915f255b 22 uint8_t led2f;
JJting 3:98cdee5d9b63 23 AnalogIn EMG(PC_4);
JJting 4:f19e7669d1b5 24 DigitalOut test(PC_8);
JJting 4:f19e7669d1b5 25 //AnalogOut test2(PA_5);
JJting 4:f19e7669d1b5 26 // IMU
JJting 4:f19e7669d1b5 27 LSM9DS1 imu(D14, D15); //SDA SCL
JJting 4:f19e7669d1b5 28 LSM9DS1 imu2(PC_9, D7); //SDA SCL
JJting 4:f19e7669d1b5 29 void init_IMU();
JJting 4:f19e7669d1b5 30 int16_t Gyro_axis_data[6] = {0}; // X, Y, Z axis
JJting 4:f19e7669d1b5 31 int16_t Acce_axis_data[6] = {0}; // X, Y, Z axis
JJting 4:f19e7669d1b5 32 float Acce_axis_data_f[6] = {0};
JJting 4:f19e7669d1b5 33 float Acce_axis_data_f_old[6] = {0};
JJting 4:f19e7669d1b5 34 float Gyro_axis_data_f[6] = {0};
JJting 4:f19e7669d1b5 35 float Gyro_axis_data_f_old[6] = {0};
JJting 4:f19e7669d1b5 36
JJting 0:c23e915f255b 37
JJting 0:c23e915f255b 38 // Timer
JJting 0:c23e915f255b 39 Ticker timer1;
JJting 4:f19e7669d1b5 40 float ITR_time1 = 6000.0; // unit:us
JJting 0:c23e915f255b 41 float Ts = ITR_time1/1000000;
JJting 0:c23e915f255b 42 uint8_t flag;
JJting 0:c23e915f255b 43
JJting 3:98cdee5d9b63 44 // EMG
JJting 3:98cdee5d9b63 45 float lpf(float input, float output_old, float frequency);
JJting 3:98cdee5d9b63 46 float emg_value;
JJting 3:98cdee5d9b63 47 float emg_value_f;
JJting 3:98cdee5d9b63 48 float emg_value_f_old;
JJting 4:f19e7669d1b5 49 float Tf = ITR_time1*0.000001f;
JJting 3:98cdee5d9b63 50
JJting 0:c23e915f255b 51 // uart_tx
JJting 0:c23e915f255b 52 union splitter {
JJting 0:c23e915f255b 53 short j;
JJting 0:c23e915f255b 54 char C[2];
JJting 0:c23e915f255b 55 // C[0] is lowbyte of j, C[1] is highbyte of j
JJting 0:c23e915f255b 56 };
JJting 0:c23e915f255b 57 char T[16] = {255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
JJting 0:c23e915f255b 58 int i = 0;
JJting 0:c23e915f255b 59
JJting 0:c23e915f255b 60 // PID
JJting 6:f48c51662e27 61 PID motor_pid(100, 0, 0, Ts);// 6.4 0.13 7.2 0.13 4.8, 0.568, 0.142
JJting 0:c23e915f255b 62 float PIDout = 0.0f;
JJting 0:c23e915f255b 63
JJting 0:c23e915f255b 64 // Dynamixel
JJting 0:c23e915f255b 65 DynamixelClass dynamixelClass(SERVO_SET_Baudrate,SERVO_ControlPin,TxPin,RxPin);
JJting 0:c23e915f255b 66 int servo_cmd;
JJting 1:2823a39f70a9 67 int row_cmd;
JJting 0:c23e915f255b 68 int D_angle = 0;
JJting 0:c23e915f255b 69 int D_angle_dif = 0;
JJting 0:c23e915f255b 70 int D_Angle;
JJting 0:c23e915f255b 71 int D_angle_old;
JJting 0:c23e915f255b 72 unsigned short d = 0;
JJting 0:c23e915f255b 73 // Find Torque
JJting 4:f19e7669d1b5 74 double _angle_difference = 0.0;
JJting 4:f19e7669d1b5 75 double torque_measured = 0.0;
JJting 0:c23e915f255b 76 float ks = 2.6393*2; //spring constant
JJting 0:c23e915f255b 77 //int angle_dif = 0;
JJting 4:f19e7669d1b5 78 float torque_ref = 0;
JJting 1:2823a39f70a9 79 //float friction = 0.0f;
JJting 4:f19e7669d1b5 80 float friction = 0.0f;
JJting 4:f19e7669d1b5 81 float rate = 0.8;
JJting 0:c23e915f255b 82 //float friction = 0.0f;
JJting 0:c23e915f255b 83 //float check = 0.0f;
JJting 1:2823a39f70a9 84 float Angle_Dif;
JJting 5:4dbed091ec5a 85 short rotation_;
JJting 0:c23e915f255b 86 // function
JJting 0:c23e915f255b 87 void init_UART();
JJting 0:c23e915f255b 88 void init_TIMER();
JJting 0:c23e915f255b 89 void timer1_ITR();
JJting 0:c23e915f255b 90 void uart_tx();
JJting 0:c23e915f255b 91
JJting 0:c23e915f255b 92 void init_DYNAMIXEL();
JJting 0:c23e915f255b 93 void D_angle_measure();
JJting 0:c23e915f255b 94 void find_torque();
JJting 0:c23e915f255b 95
JJting 0:c23e915f255b 96 int main()
JJting 0:c23e915f255b 97 {
JJting 0:c23e915f255b 98 LED = 1; // darken
JJting 0:c23e915f255b 99 wait_ms(500);
JJting 0:c23e915f255b 100 // initial sensor
JJting 0:c23e915f255b 101 init_SPI_encoder();
JJting 0:c23e915f255b 102 init_encoder();
JJting 4:f19e7669d1b5 103 init_IMU();
JJting 0:c23e915f255b 104 init_DYNAMIXEL();
JJting 0:c23e915f255b 105 // initial uart
JJting 0:c23e915f255b 106 init_UART();
JJting 0:c23e915f255b 107
JJting 0:c23e915f255b 108 wait_ms(500);
JJting 0:c23e915f255b 109
JJting 0:c23e915f255b 110 led2 = 1;
JJting 1:2823a39f70a9 111 // led2f = 0;
JJting 0:c23e915f255b 112 LED = 0; // lighten
JJting 0:c23e915f255b 113
JJting 0:c23e915f255b 114 init_TIMER();
JJting 0:c23e915f255b 115
JJting 0:c23e915f255b 116 while(1) {
JJting 0:c23e915f255b 117
JJting 0:c23e915f255b 118 }
JJting 0:c23e915f255b 119 }
JJting 0:c23e915f255b 120
JJting 4:f19e7669d1b5 121 void init_IMU()
JJting 4:f19e7669d1b5 122 {
JJting 4:f19e7669d1b5 123 imu.begin();
JJting 4:f19e7669d1b5 124 imu2.begin();
JJting 4:f19e7669d1b5 125 }
JJting 4:f19e7669d1b5 126
JJting 0:c23e915f255b 127 void init_DYNAMIXEL()
JJting 0:c23e915f255b 128 {
JJting 5:4dbed091ec5a 129 // dynamixelClass.torqueMode(SERVO_ID, 0);
JJting 5:4dbed091ec5a 130 dynamixelClass.setMode(SERVO_ID, WHEEL, 0, 0);
JJting 5:4dbed091ec5a 131 // dynamixelClass.setPID(SERVO_ID, 1, 0, 0);
JJting 0:c23e915f255b 132 wait_ms(1);
JJting 0:c23e915f255b 133 }
JJting 0:c23e915f255b 134
JJting 0:c23e915f255b 135 void init_UART()
JJting 0:c23e915f255b 136 {
JJting 0:c23e915f255b 137 uart.baud(115200);
JJting 0:c23e915f255b 138 }
JJting 0:c23e915f255b 139
JJting 0:c23e915f255b 140 void init_TIMER()
JJting 0:c23e915f255b 141 {
JJting 0:c23e915f255b 142 timer1.attach_us(&timer1_ITR, ITR_time1);
JJting 0:c23e915f255b 143 }
JJting 0:c23e915f255b 144
JJting 0:c23e915f255b 145 void timer1_ITR()
JJting 0:c23e915f255b 146 {
JJting 5:4dbed091ec5a 147 test = 1;
JJting 5:4dbed091ec5a 148 led2 = !led2;
JJting 5:4dbed091ec5a 149 angle_measure();
JJting 5:4dbed091ec5a 150 D_angle_measure();
JJting 5:4dbed091ec5a 151 find_torque();
JJting 5:4dbed091ec5a 152 motor_pid.Compute(torque_ref, torque_measured);
JJting 5:4dbed091ec5a 153 PIDout = motor_pid.output;
JJting 6:f48c51662e27 154 servo_cmd = PIDout*22.73f; // 1023/45rpm = 22.73
JJting 5:4dbed091ec5a 155
JJting 5:4dbed091ec5a 156 if (servo_cmd > 0) {
JJting 5:4dbed091ec5a 157 // servo_cmd = servo_cmd + ((-torque_ref)*rate+friction)*22.73f;
JJting 5:4dbed091ec5a 158 servo_cmd = servo_cmd;
JJting 5:4dbed091ec5a 159 rotation_ = 0;// 0:Move Left
JJting 5:4dbed091ec5a 160 if (servo_cmd >= 1023)
JJting 5:4dbed091ec5a 161 servo_cmd = 1023;
JJting 5:4dbed091ec5a 162 } else {
JJting 5:4dbed091ec5a 163 // servo_cmd = -servo_cmd + 1024 + ((torque_ref)*rate+friction)*22.73f;
JJting 5:4dbed091ec5a 164 // servo_cmd = -servo_cmd+1024;
JJting 5:4dbed091ec5a 165 servo_cmd = -servo_cmd;
JJting 5:4dbed091ec5a 166 rotation_ = 1;// 1:Move Right
JJting 5:4dbed091ec5a 167 // if (servo_cmd >= 2047)
JJting 5:4dbed091ec5a 168 // servo_cmd = 2047;
JJting 5:4dbed091ec5a 169 if (servo_cmd >= 1023)
JJting 5:4dbed091ec5a 170 servo_cmd = 1023;
JJting 5:4dbed091ec5a 171 }
JJting 5:4dbed091ec5a 172
JJting 5:4dbed091ec5a 173 row_cmd = servo_cmd;
JJting 5:4dbed091ec5a 174
JJting 5:4dbed091ec5a 175 // if (servo_cmd > 1023) {
JJting 5:4dbed091ec5a 176 // row_cmd = -(servo_cmd-1023);
JJting 5:4dbed091ec5a 177 // } else {
JJting 5:4dbed091ec5a 178 // row_cmd = servo_cmd;
JJting 5:4dbed091ec5a 179 // }
JJting 5:4dbed091ec5a 180
JJting 5:4dbed091ec5a 181 // EMG
JJting 5:4dbed091ec5a 182 emg_value = EMG.read();
JJting 5:4dbed091ec5a 183 emg_value_f = lpf(emg_value,emg_value_f_old,15);
JJting 5:4dbed091ec5a 184 emg_value_f_old = emg_value_f;
JJting 5:4dbed091ec5a 185
JJting 5:4dbed091ec5a 186 // // AnalogOut
JJting 5:4dbed091ec5a 187 // if (torque_measured*10 > 3.3) {
JJting 5:4dbed091ec5a 188 // torque_measured = 0.33;
JJting 5:4dbed091ec5a 189 // } else {
JJting 5:4dbed091ec5a 190 // test2 = torque_measured*10;
JJting 5:4dbed091ec5a 191 // }
JJting 5:4dbed091ec5a 192 // IMU
JJting 5:4dbed091ec5a 193 // imu.readAccel();
JJting 5:4dbed091ec5a 194 // imu.readGyro();
JJting 5:4dbed091ec5a 195 // imu2.readAccel();
JJting 5:4dbed091ec5a 196 // imu2.readGyro();
JJting 5:4dbed091ec5a 197 /*
JJting 5:4dbed091ec5a 198 Acce_axis_data[0] = imu.ax*Acce_gain_x;
JJting 5:4dbed091ec5a 199 Acce_axis_data[1] = imu.ay*Acce_gain_y;
JJting 5:4dbed091ec5a 200 Acce_axis_data[2] = imu.az*Acce_gain_z;
JJting 5:4dbed091ec5a 201 Acce_axis_data[3] = -imu2.ax*Acce_gain_x_2;
JJting 5:4dbed091ec5a 202 Acce_axis_data[4] = imu2.az*Acce_gain_y_2;
JJting 5:4dbed091ec5a 203 Acce_axis_data[5] = imu2.ay*Acce_gain_z_2;
JJting 5:4dbed091ec5a 204
JJting 5:4dbed091ec5a 205 Gyro_axis_data[0] = imu.gx*Gyro_gain_x;
JJting 5:4dbed091ec5a 206 Gyro_axis_data[1] = imu.gy*Gyro_gain_y;
JJting 5:4dbed091ec5a 207 Gyro_axis_data[2] = imu.gz*Gyro_gain_z;
JJting 5:4dbed091ec5a 208 Gyro_axis_data[3] = -imu2.gx*Gyro_gain_x_2;
JJting 5:4dbed091ec5a 209 Gyro_axis_data[4] = imu2.gz*Gyro_gain_y_2;
JJting 5:4dbed091ec5a 210 Gyro_axis_data[5] = imu2.gy*Gyro_gain_z_2;
JJting 5:4dbed091ec5a 211
JJting 5:4dbed091ec5a 212 for(i=0; i<6; i++) {
JJting 5:4dbed091ec5a 213 Acce_axis_data_f[i] = lpf(Acce_axis_data[i],Acce_axis_data_f_old[i],15);
JJting 5:4dbed091ec5a 214 Acce_axis_data_f_old[i] = Acce_axis_data_f[i];
JJting 5:4dbed091ec5a 215 Gyro_axis_data_f[i] = lpf(Gyro_axis_data[i],Gyro_axis_data_f_old[i],15);
JJting 5:4dbed091ec5a 216 Gyro_axis_data_f_old[i] = Gyro_axis_data_f[i];
JJting 5:4dbed091ec5a 217 }
JJting 5:4dbed091ec5a 218
JJting 5:4dbed091ec5a 219 */
JJting 5:4dbed091ec5a 220 // dynamixelClass.torque(SERVO_ID, servo_cmd);
JJting 5:4dbed091ec5a 221 dynamixelClass.wheel(SERVO_ID, rotation_, servo_cmd); //0~1023
JJting 5:4dbed091ec5a 222 wait_ms(1);
JJting 5:4dbed091ec5a 223 uart_tx();
JJting 5:4dbed091ec5a 224 flag = 0;
JJting 5:4dbed091ec5a 225 wait_ms(1);
JJting 5:4dbed091ec5a 226 test = 0;
JJting 0:c23e915f255b 227 }
JJting 0:c23e915f255b 228
JJting 0:c23e915f255b 229 void uart_tx()
JJting 0:c23e915f255b 230 {
JJting 0:c23e915f255b 231 splitter s1;
JJting 0:c23e915f255b 232 splitter s2;
JJting 0:c23e915f255b 233 splitter s3;
JJting 0:c23e915f255b 234 splitter s4;
JJting 0:c23e915f255b 235 splitter s5;
JJting 0:c23e915f255b 236 splitter s6;
JJting 0:c23e915f255b 237 splitter s7;
JJting 0:c23e915f255b 238
JJting 6:f48c51662e27 239 s1.j = _angle_difference*100;
JJting 5:4dbed091ec5a 240 s2.j = row_cmd;
JJting 4:f19e7669d1b5 241 // s2.j = 1;
JJting 5:4dbed091ec5a 242 s3.j = servo_cmd;
JJting 4:f19e7669d1b5 243 s4.j = D_Angle;
JJting 5:4dbed091ec5a 244 s5.j = D_angle;
JJting 5:4dbed091ec5a 245 s6.j = Angle;
JJting 1:2823a39f70a9 246 s7.j = 1;
JJting 0:c23e915f255b 247
JJting 0:c23e915f255b 248 T[2] = s1.C[0];
JJting 0:c23e915f255b 249 T[3] = s1.C[1];
JJting 0:c23e915f255b 250 T[4] = s2.C[0];
JJting 0:c23e915f255b 251 T[5] = s2.C[1];
JJting 0:c23e915f255b 252 T[6] = s3.C[0];
JJting 0:c23e915f255b 253 T[7] = s3.C[1];
JJting 0:c23e915f255b 254 T[8] = s4.C[0];
JJting 0:c23e915f255b 255 T[9] = s4.C[1];
JJting 0:c23e915f255b 256 T[10] = s5.C[0];
JJting 0:c23e915f255b 257 T[11] = s5.C[1];
JJting 0:c23e915f255b 258 T[12] = s6.C[0];
JJting 0:c23e915f255b 259 T[13] = s6.C[1];
JJting 0:c23e915f255b 260 T[14] = s7.C[0];
JJting 0:c23e915f255b 261 T[15] = s7.C[1];
JJting 0:c23e915f255b 262
JJting 0:c23e915f255b 263 while(1) {
JJting 0:c23e915f255b 264 if (uart.writeable() == 1) {
JJting 0:c23e915f255b 265 uart.putc(T[i]);
JJting 0:c23e915f255b 266 i++;
JJting 0:c23e915f255b 267 }
JJting 1:2823a39f70a9 268 if (i >= sizeof(T)) {
JJting 0:c23e915f255b 269 i = 0;
JJting 0:c23e915f255b 270 break;
JJting 0:c23e915f255b 271 }
JJting 0:c23e915f255b 272 }
JJting 0:c23e915f255b 273 }
JJting 0:c23e915f255b 274
JJting 0:c23e915f255b 275 void D_angle_measure()
JJting 0:c23e915f255b 276 {
JJting 0:c23e915f255b 277 D_angle = dynamixelClass.readPosition(SERVO_ID);
JJting 0:c23e915f255b 278
JJting 0:c23e915f255b 279 if (d == 0) {
JJting 0:c23e915f255b 280 D_Angle = 0;
JJting 0:c23e915f255b 281 D_angle_old = D_angle;
JJting 0:c23e915f255b 282 d++;
JJting 0:c23e915f255b 283 } else {
JJting 0:c23e915f255b 284 D_angle_dif = D_angle - D_angle_old;
JJting 0:c23e915f255b 285 D_Angle = D_Angle + D_angle_dif;
JJting 0:c23e915f255b 286 D_angle_old = D_angle;
JJting 0:c23e915f255b 287 }
JJting 0:c23e915f255b 288 }
JJting 0:c23e915f255b 289
JJting 0:c23e915f255b 290 void find_torque()
JJting 0:c23e915f255b 291 {
JJting 1:2823a39f70a9 292
JJting 4:f19e7669d1b5 293 Angle_Dif = (-Angle*3+D_Angle);
JJting 4:f19e7669d1b5 294 // _angle_difference = (Angle*3-D_Angle)/4096.0f*2*_PI;
JJting 1:2823a39f70a9 295
JJting 4:f19e7669d1b5 296 _angle_difference = Angle_Dif/4096*2*_PI;
JJting 4:f19e7669d1b5 297 // if ((_angle_difference < 0) && (D_angle < 0)) {
JJting 6:f48c51662e27 298 // if (_angle_difference < -99) {
JJting 6:f48c51662e27 299 // _angle_difference = _angle_difference-100.54;
JJting 6:f48c51662e27 300 // }
JJting 6:f48c51662e27 301 // if (_angle_difference > 99) {
JJting 6:f48c51662e27 302 // _angle_difference = _angle_difference-100.54;
JJting 6:f48c51662e27 303 // }
JJting 6:f48c51662e27 304 if (_angle_difference > 6) {
JJting 6:f48c51662e27 305 _angle_difference = _angle_difference-6.4;
JJting 4:f19e7669d1b5 306 }
JJting 6:f48c51662e27 307 if (_angle_difference < -6) {
JJting 6:f48c51662e27 308 _angle_difference = _angle_difference-6.4;
JJting 4:f19e7669d1b5 309 }
JJting 4:f19e7669d1b5 310 torque_measured = _angle_difference*ks;
JJting 4:f19e7669d1b5 311 // torque_measured = Angle_Dif;
JJting 1:2823a39f70a9 312 }
JJting 3:98cdee5d9b63 313
JJting 3:98cdee5d9b63 314 float lpf(float input, float output_old, float frequency)
JJting 3:98cdee5d9b63 315 {
JJting 3:98cdee5d9b63 316 float output = 0;
JJting 3:98cdee5d9b63 317
JJting 3:98cdee5d9b63 318 output = (output_old + frequency*Tf*input) / (1 + frequency*Tf);
JJting 3:98cdee5d9b63 319
JJting 3:98cdee5d9b63 320 return output;
JJting 3:98cdee5d9b63 321 }