By pOOPOO

Dependencies:   MX28 mbed

Fork of LSM9DS1_project_5_zerotorque by Rong Syuan Lin

Committer:
JJting
Date:
Fri Aug 10 13:29:54 2018 +0000
Revision:
4:f19e7669d1b5
Parent:
3:98cdee5d9b63
Child:
5:4dbed091ec5a
still can't 0-torque control.

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 4:f19e7669d1b5 61 PID motor_pid(7.2, 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 0:c23e915f255b 85
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 if (flag==1) {
JJting 4:f19e7669d1b5 118 test = 1;
JJting 0:c23e915f255b 119 led2 = !led2;
JJting 0:c23e915f255b 120 angle_measure();
JJting 0:c23e915f255b 121 D_angle_measure();
JJting 0:c23e915f255b 122 find_torque();
JJting 0:c23e915f255b 123 motor_pid.Compute(torque_ref, torque_measured);
JJting 0:c23e915f255b 124 PIDout = motor_pid.output;
JJting 4:f19e7669d1b5 125 servo_cmd = PIDout*121.8f; // 1023/8.4Nm = 121.7857
JJting 0:c23e915f255b 126
JJting 0:c23e915f255b 127 if (servo_cmd > 0) {
JJting 4:f19e7669d1b5 128 // servo_cmd = servo_cmd + ((-torque_ref)*rate+friction)*121.8f;
JJting 4:f19e7669d1b5 129 servo_cmd = servo_cmd;
JJting 0:c23e915f255b 130 if (servo_cmd >= 1023)
JJting 0:c23e915f255b 131 servo_cmd = 1023;
JJting 0:c23e915f255b 132 } else {
JJting 4:f19e7669d1b5 133 // servo_cmd = -servo_cmd + 1024 + ((torque_ref)*rate+friction)*121.8f;
JJting 4:f19e7669d1b5 134 servo_cmd = -servo_cmd+1024;
JJting 0:c23e915f255b 135 if (servo_cmd >= 2047)
JJting 0:c23e915f255b 136 servo_cmd = 2047;
JJting 0:c23e915f255b 137 }
JJting 1:2823a39f70a9 138
JJting 4:f19e7669d1b5 139 if (servo_cmd > 1023) {
JJting 1:2823a39f70a9 140 row_cmd = -(servo_cmd-1023);
JJting 1:2823a39f70a9 141 } else {
JJting 1:2823a39f70a9 142 row_cmd = servo_cmd;
JJting 1:2823a39f70a9 143 }
JJting 1:2823a39f70a9 144
JJting 3:98cdee5d9b63 145 // EMG
JJting 3:98cdee5d9b63 146 emg_value = EMG.read();
JJting 3:98cdee5d9b63 147 emg_value_f = lpf(emg_value,emg_value_f_old,15);
JJting 3:98cdee5d9b63 148 emg_value_f_old = emg_value_f;
JJting 4:f19e7669d1b5 149
JJting 4:f19e7669d1b5 150 // // AnalogOut
JJting 4:f19e7669d1b5 151 // if (torque_measured*10 > 3.3) {
JJting 4:f19e7669d1b5 152 // torque_measured = 0.33;
JJting 4:f19e7669d1b5 153 // } else {
JJting 4:f19e7669d1b5 154 // test2 = torque_measured*10;
JJting 4:f19e7669d1b5 155 // }
JJting 4:f19e7669d1b5 156 // IMU
JJting 4:f19e7669d1b5 157 // imu.readAccel();
JJting 4:f19e7669d1b5 158 // imu.readGyro();
JJting 4:f19e7669d1b5 159 // imu2.readAccel();
JJting 4:f19e7669d1b5 160 // imu2.readGyro();
JJting 4:f19e7669d1b5 161 /*
JJting 4:f19e7669d1b5 162 Acce_axis_data[0] = imu.ax*Acce_gain_x;
JJting 4:f19e7669d1b5 163 Acce_axis_data[1] = imu.ay*Acce_gain_y;
JJting 4:f19e7669d1b5 164 Acce_axis_data[2] = imu.az*Acce_gain_z;
JJting 4:f19e7669d1b5 165 Acce_axis_data[3] = -imu2.ax*Acce_gain_x_2;
JJting 4:f19e7669d1b5 166 Acce_axis_data[4] = imu2.az*Acce_gain_y_2;
JJting 4:f19e7669d1b5 167 Acce_axis_data[5] = imu2.ay*Acce_gain_z_2;
JJting 4:f19e7669d1b5 168
JJting 4:f19e7669d1b5 169 Gyro_axis_data[0] = imu.gx*Gyro_gain_x;
JJting 4:f19e7669d1b5 170 Gyro_axis_data[1] = imu.gy*Gyro_gain_y;
JJting 4:f19e7669d1b5 171 Gyro_axis_data[2] = imu.gz*Gyro_gain_z;
JJting 4:f19e7669d1b5 172 Gyro_axis_data[3] = -imu2.gx*Gyro_gain_x_2;
JJting 4:f19e7669d1b5 173 Gyro_axis_data[4] = imu2.gz*Gyro_gain_y_2;
JJting 4:f19e7669d1b5 174 Gyro_axis_data[5] = imu2.gy*Gyro_gain_z_2;
JJting 4:f19e7669d1b5 175
JJting 4:f19e7669d1b5 176 for(i=0; i<6; i++) {
JJting 4:f19e7669d1b5 177 Acce_axis_data_f[i] = lpf(Acce_axis_data[i],Acce_axis_data_f_old[i],15);
JJting 4:f19e7669d1b5 178 Acce_axis_data_f_old[i] = Acce_axis_data_f[i];
JJting 4:f19e7669d1b5 179 Gyro_axis_data_f[i] = lpf(Gyro_axis_data[i],Gyro_axis_data_f_old[i],15);
JJting 4:f19e7669d1b5 180 Gyro_axis_data_f_old[i] = Gyro_axis_data_f[i];
JJting 4:f19e7669d1b5 181 }
JJting 4:f19e7669d1b5 182
JJting 4:f19e7669d1b5 183
JJting 4:f19e7669d1b5 184
JJting 4:f19e7669d1b5 185
JJting 4:f19e7669d1b5 186
JJting 4:f19e7669d1b5 187
JJting 4:f19e7669d1b5 188
JJting 4:f19e7669d1b5 189
JJting 4:f19e7669d1b5 190
JJting 4:f19e7669d1b5 191 */
JJting 4:f19e7669d1b5 192 dynamixelClass.torque(SERVO_ID, servo_cmd);
JJting 4:f19e7669d1b5 193 wait_ms(1);
JJting 0:c23e915f255b 194 uart_tx();
JJting 0:c23e915f255b 195 flag = 0;
JJting 4:f19e7669d1b5 196 wait_ms(1);
JJting 4:f19e7669d1b5 197 test = 0;
JJting 0:c23e915f255b 198 }
JJting 0:c23e915f255b 199 }
JJting 0:c23e915f255b 200 }
JJting 0:c23e915f255b 201
JJting 4:f19e7669d1b5 202 void init_IMU()
JJting 4:f19e7669d1b5 203 {
JJting 4:f19e7669d1b5 204 imu.begin();
JJting 4:f19e7669d1b5 205 imu2.begin();
JJting 4:f19e7669d1b5 206 }
JJting 4:f19e7669d1b5 207
JJting 0:c23e915f255b 208 void init_DYNAMIXEL()
JJting 0:c23e915f255b 209 {
JJting 0:c23e915f255b 210 dynamixelClass.torqueMode(SERVO_ID, 1);
JJting 0:c23e915f255b 211 wait_ms(1);
JJting 0:c23e915f255b 212 }
JJting 0:c23e915f255b 213
JJting 0:c23e915f255b 214 void init_UART()
JJting 0:c23e915f255b 215 {
JJting 0:c23e915f255b 216 uart.baud(115200);
JJting 0:c23e915f255b 217 }
JJting 0:c23e915f255b 218
JJting 0:c23e915f255b 219 void init_TIMER()
JJting 0:c23e915f255b 220 {
JJting 0:c23e915f255b 221 timer1.attach_us(&timer1_ITR, ITR_time1);
JJting 0:c23e915f255b 222 }
JJting 0:c23e915f255b 223
JJting 0:c23e915f255b 224 void timer1_ITR()
JJting 0:c23e915f255b 225 {
JJting 0:c23e915f255b 226 flag = 1;
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 4:f19e7669d1b5 239 s1.j = _angle_difference*100;
JJting 4:f19e7669d1b5 240 s2.j = D_angle;
JJting 4:f19e7669d1b5 241 // s2.j = 1;
JJting 4:f19e7669d1b5 242 s3.j = row_cmd;
JJting 4:f19e7669d1b5 243 s4.j = D_Angle;
JJting 4:f19e7669d1b5 244 s5.j = Angle;
JJting 4:f19e7669d1b5 245 s6.j = Angle_Dif;
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 4:f19e7669d1b5 298 if (_angle_difference < -99) {
JJting 4:f19e7669d1b5 299 _angle_difference = _angle_difference-100.54;
JJting 4:f19e7669d1b5 300 }
JJting 4:f19e7669d1b5 301 if (_angle_difference > 99) {
JJting 4:f19e7669d1b5 302 _angle_difference = _angle_difference-100.54;
JJting 4:f19e7669d1b5 303 }
JJting 4:f19e7669d1b5 304 torque_measured = _angle_difference*ks;
JJting 4:f19e7669d1b5 305 // torque_measured = Angle_Dif;
JJting 1:2823a39f70a9 306 }
JJting 3:98cdee5d9b63 307
JJting 3:98cdee5d9b63 308 float lpf(float input, float output_old, float frequency)
JJting 3:98cdee5d9b63 309 {
JJting 3:98cdee5d9b63 310 float output = 0;
JJting 3:98cdee5d9b63 311
JJting 3:98cdee5d9b63 312 output = (output_old + frequency*Tf*input) / (1 + frequency*Tf);
JJting 3:98cdee5d9b63 313
JJting 3:98cdee5d9b63 314 return output;
JJting 3:98cdee5d9b63 315 }