Code for our FYDP -only one IMU works right now -RTOS is working
Embed:
(wiki syntax)
Show/hide line numbers
ros_machine_interface.h
00001 #ifndef ROS_MACHINE_INTERFACE_H 00002 #define ROS_MACHINE_INTERFACE_H 00003 //THIS FILE IS INCOMPLETE/// 00004 00005 00006 /**This file contains the implementations for the controls through a python interface 00007 //The brain file uses ';' to separate lines 00008 Read IMU [acceleration and gyros] 00009 Read Gyro 00010 Read Angle 00011 Read Acceleration 00012 Read IR sensors 00013 Read Optical flow sensors 00014 Read current sensor 00015 Read voltage sensor 00016 00017 Drive to [x,y] (x,y) 00018 Drive fwd (speed, time) 00019 Run R motor (speed,time) 00020 Run L motor (speed,time) 00021 Set Direction (direction) 00022 Enable IMU control (bool) //if this is enabled, IMU will keep robot straight 00023 */ 00024 #include "keybindings.h" 00025 00026 00027 int ros_get_cmd(); //this reads from the bt connection 00028 int q_pow10(int n); //this calculates 10^n quickly (only up to 10^6) 00029 void print_all(); 00030 int ros_get_cmd(char s[16], int n); 00031 //char C; 00032 //char buffer[10]; 00033 int IR_mm(float x); 00034 00035 bool ros_shell_connection(char c) 00036 { 00037 char S[16]; 00038 float dum; 00039 float param[5]; 00040 int arg_in[10]; 00041 char run_time; 00042 int m_offset = 100; //use this so that the MATLAB can send motor values between 0 and 200 instead of -100 and 100 00043 //bt.printf("&%f;",t.read()); 00044 00045 switch (c) 00046 { 00047 case CONNECTION: //Return query if connection is ready 00048 bt.lock(); 00049 bt.printf("\nEBOTDEMO\n"); 00050 bt.unlock(); 00051 reckon.reset(); 00052 break; 00053 case ALL_SENSOR: //returns ALL sensor data //while robot is moving, send things every 50milliseconds 00054 print_all(); 00055 break; 00056 case CURRENT_SENSE: 00057 break; 00058 case IMU_READ: 00059 send_flag = 1; 00060 //bt.lock(); 00061 //bt.printf("i;%3.3f;%3.3f;%3.3f;%3.3f;%3.3f;%3.3f;",imu_data.acc[0],imu_data.acc[1],imu_data.acc[2],imu_data.ypr[0],imu_data.ypr[1],imu_data.ypr[2]); 00062 //bt.unlock(); 00063 break; 00064 case IMU_YAW: 00065 dum = imu_data.ypr[0]*180/PI; 00066 bt.lock(); 00067 bt.printf("y;%3.3f;",dum); 00068 bt.unlock(); 00069 break; 00070 //optical flow 00071 case OPT_READ: 00072 //return optical flow (pixels/second for left and right) 00073 //TODO: include second optical flow sensor 00074 //bt.printf("O;%3.3f;%3.3f;",opt_flow.dx_px,opt_flow.dy_px); 00075 bt.lock(); 00076 bt.printf("%c;%d;%d;%d;%d;",OPT_READ,reckon.flow_dx_L,reckon.flow_dy_L,reckon.flow_dx_R,reckon.flow_dy_R); 00077 bt.unlock(); 00078 reckon.reset(); 00079 break; 00080 case IR_READ: 00081 //return 5 IR sensors clockwise (Front, right_front, right_rear, left_rear, left_front) 00082 //ask Wen to fill out this function 00083 extern AnalogIn irL; 00084 extern AnalogIn irC; 00085 extern AnalogIn irR; 00086 extern DigitalOut irBack; 00087 if(irBack){ 00088 irBack = 0; //read from IR 00089 Thread::wait(50); 00090 } 00091 param[0] = irL.read(); 00092 Thread::wait(10); 00093 param[1] = irC.read(); 00094 Thread::wait(10); 00095 param[2] = irR.read(); 00096 param[3] = 0; 00097 param[4]=0; 00098 //irBack = 1; //read back IR 00099 /*Thread::wait(50); 00100 param[3] = irL.read(); 00101 Thread::wait(10); 00102 param[4] = irR.read(); 00103 irBack = 0;*/ 00104 //bt.printf("%f;%f;%f;%f;%f;",param[0],param[1],param[2],param[3],param[4]); 00105 for(int i = 0; i<5; i++) 00106 arg_in[i]=IR_mm(param[i]); 00107 bt.lock(); 00108 bt.printf("%d;%d;%d;%d;%d;",arg_in[0],arg_in[1],arg_in[2],arg_in[3],arg_in[4]); 00109 bt.unlock(); 00110 //Thread::wait(40); 00111 break; 00112 /*case IR_1: 00113 if(irBack){ 00114 irBack = 0; 00115 Thread::wait(50); 00116 } 00117 param[0] = irL.read(); 00118 bt.printf("%c;%f;",IR_1,param[0]); 00119 break; 00120 case IR_2: 00121 if(irBack){ 00122 irBack = 0; 00123 Thread::wait(50); 00124 } 00125 param[0] = irC.read(); 00126 bt.printf("%c;%f;",IR_2,param[0]); 00127 break; 00128 case IR_3: 00129 if(irBack){ 00130 irBack = 0; 00131 Thread::wait(50); 00132 } 00133 param[0] = irR.read(); 00134 bt.printf("%c;%f;",IR_3,param[0]); 00135 break; 00136 case IR_4: 00137 if(!irBack){ 00138 irBack = 1; 00139 Thread::wait(50); 00140 } 00141 param[0] = irR.read(); 00142 bt.printf("%c;%f;",IR_4,param[0]); 00143 break; 00144 case IR_5: 00145 if(!irBack){ 00146 irBack = 1; 00147 Thread::wait(50); 00148 } 00149 param[0] = irL.read(); 00150 bt.printf("%c;%f;",IR_5,param[0]); 00151 break;*/ 00152 case LOCATION: 00153 //return x,y,z,theta (maybe not z) 00154 break; 00155 00156 case MOTOR: //command: 'w[L_speed],[R_speed] //I should write an actual function to receive data from serial 00157 //Another argument should be included: time to run motors. 00158 arg_in[0] = ros_get_cmd(); 00159 arg_in[1] = ros_get_cmd(); 00160 arg_in[2] = ros_get_cmd(); 00161 if(arg_in[0] == arg_in[1] && arg_in[0] > 100){ 00162 if(IR_mm(irC.read()) < 260 && IR_mm(irC.read()) > 0) //if there is an obstacle, don't drive fwd 00163 { 00164 bt.lock(); 00165 bt.printf("&;OBSTACLE;"); 00166 bt.unlock(); 00167 break; 00168 } 00169 fwd_flag = 1; 00170 } 00171 moveMotors(arg_in[0]-m_offset,arg_in[1]-m_offset,arg_in[2]); 00172 bt.lock(); 00173 bt.printf("L=%d;R=%d;t=%d",arg_in[0],arg_in[1],arg_in[2]); //don't need to respond. Maybe have a confirmation? 00174 bt.unlock(); 00175 send_flag = 1; 00176 break; 00177 00178 case (MOTOR_STOP): 00179 *motors.Right = 0; 00180 *motors.Left = 0; 00181 send_flag = 0; // 00182 break; 00183 00184 00185 00186 00187 case (IMU_CALIBRATE): 00188 calibrate_flag = 1; 00189 break; 00190 case (OPT_CALIBRATE): 00191 calibrate_optFlow_flag=1; 00192 break; 00193 case END_CONNECTION: 00194 bt.lock(); 00195 bt.printf("End Connection\n"); 00196 bt.unlock(); 00197 return 0; 00198 ///break; 00199 default: 00200 bt.lock(); 00201 bt.putc(c); //echo command 00202 bt.unlock(); 00203 break; 00204 } 00205 bt.lock(); 00206 bt.printf("\n\r"); 00207 bt.unlock(); 00208 return 1; 00209 } 00210 int ros_get_cmd(char s[16], int n) 00211 { 00212 int i= 0, j = 0; 00213 char S[16]; 00214 int count = 0; 00215 while(count < n && i<13) 00216 { 00217 if(s[i] == ';') 00218 count++; 00219 i++; 00220 } 00221 count = 0; 00222 while(i<13) 00223 { 00224 if(s[i] == ';') 00225 break; 00226 S[j] = s[i]; 00227 j++; 00228 i++; 00229 } 00230 for(i=0;i<j;i++) 00231 { 00232 count += ((S[i])-48)* q_pow10(j-i-1); 00233 } 00234 return count; 00235 } 00236 void ros_interface_send_data() 00237 { 00238 //int mseconds = (int)time(NULL)+(int)t.read_ms(); 00239 bt.lock(); 00240 bt.printf("&%d;",t.read_ms());//indicate start of line, output system time 00241 bt.unlock(); 00242 //send all the requested data 00243 //if (x.list[0]){ //send all imu data 00244 //bt.printf("A%3.3f,%3.3f,%3.3f,G%3.3f,%3.3f,%3.3f",mpu.ax,mpu.ay,mpu.az,mpu.gx,mpu.gy,mpu.gz); 00245 //} 00246 00247 //0 - IMU_all 00248 //1 - IMU_acc 00249 //2 - IMU_gyr 00250 //3 - IMU_rotation 00251 //4 - IR_sensors 00252 //5 - Optical_flow_sensors 00253 //6 - Current_sensor 00254 //7 - Voltage_sensor 00255 00256 00257 } 00258 00259 int ros_get_cmd() //this requires a ',' or ';' or <enter> at the end of every command 00260 { 00261 char c = '0'; 00262 char C[10]; //stores the array of chars read 00263 int n=0; //counter 00264 int timeout = 0; //timeout counter 00265 int accum=0; //accumulates value of array 00266 00267 while(c != ',' && c != 13 && c !=';' && c!='x'){ //keep looping until a comma/semicolon is read (or enter is pressed) 00268 bt.lock(); 00269 while(! bt.readable()){ 00270 bt.unlock(); 00271 Thread::yield(); //wait for char input 00272 timeout++; 00273 if(timeout > 10000) //if one second has passed, give up on this command 00274 return -1; 00275 bt.lock(); 00276 } 00277 c= bt.getc(); //read the next char in the buffer 00278 bt.unlock(); 00279 00280 //bt.printf("%c",c); //REMOVE THIS. DEBUG ONLY 00281 //if(c == '.' || n >=9) break; //concatenate decimals. I'm not handling decimals. No reason. 00282 C[n]=c; 00283 n++; 00284 } 00285 00286 for(int i = 0; i<n-1; i++){ 00287 //need to subtract 2: 1 b/c n is incremented at the end of each iteration, 2 b/c comma is read. 00288 accum += ((C[i])-48)* q_pow10(n-i-2); 00289 } 00290 // memset(buffer, 0 , sizeof buffer); 00291 return accum; 00292 } 00293 00294 int q_pow10(int n){ //returns 10^n, up to 10^7 [8 sig figs] 00295 static int pow10[8] = {1,10,100,1000,10000,100000,1000000,10000000}; 00296 return pow10[n]; 00297 } 00298 void print_all(){ //call this function to print all sensor data 00299 float data[13]; 00300 data[0]= getTime(); 00301 data[1]= imu_data.ypr[0]; 00302 data[2]= imu_data.ypr[1]; 00303 data[3]= imu_data.ypr[2]; 00304 00305 data[4]= imu2_data.ypr[0]; 00306 data[5]= imu2_data.ypr[1]; 00307 data[6]= imu2_data.ypr[2]; 00308 00309 00310 bt.lock(); 00311 bt.printf("&;"); 00312 bt.printf("%f;",data[0]); //print time as an integer (milliseconds) 00313 for(int i = 1; i<=6; i++){ 00314 bt.printf("%.3f;",data[i]); 00315 } 00316 bt.printf("\n\r"); 00317 bt.unlock(); 00318 //commented out the below code because we want to ignore the rear IR sensors 00319 /*dt = t.read() - data[0]; 00320 irBack = 1; 00321 if(dt < 50) 00322 Thread::wait(50-dt); 00323 00324 data[6]= irR.read(); 00325 data[7]= irL.read(); 00326 data[8]= imu_data.ypr[0]*180/PI; 00327 irBack = 0; 00328 */ 00329 00330 } 00331 int IR_mm(float x) //converts IR sensor value to millimeters 00332 { 00333 //return 9462/(x*3.3/5*1024 - 16.92); 00334 if (x <= 0.24) 00335 return -1; 00336 return 170/x; 00337 } 00338 00339 #endif
Generated on Wed Jul 13 2022 10:32:23 by 1.7.2