Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: QEI2 PID IMU6050Ver11 Watchdog VL53L1X_Filter ros_lib_kinetic
Dependents: Version1-6 Version1-7
wheelchair.cpp
00001 /************************************************************************* 00002 * Importing header into wheelchair.cpp * 00003 **************************************************************************/ 00004 #include "wheelchair.h" 00005 00006 /************************************************************************* 00007 * Defining global variables * 00008 **************************************************************************/ 00009 bool manual_drive = false; // Variable changes between joystick and auto drive 00010 double encoder_distance; // Keeps distanse due to original position 00011 00012 volatile double Setpoint, Output, Input, Input2; // Variables for PID 00013 volatile double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2; // Variables for PID 00014 volatile double vIn, vOut, vDesired; // Variables for PID Velosity 00015 volatile double vInS, vOutS, vDesiredS; // Variables for PID Slave Wheel 00016 volatile double yIn, yOut, yDesired; // Variables for PID turn velosity 00017 // int* ToFDataPointer1; 00018 // int* ToFDataPointer2; 00019 00020 int ledgeArrayLF[150]; 00021 int ledgeArrayRF[150]; 00022 int* ToFDataPointer1 = ledgeArrayLF; 00023 int* ToFDataPointer2 = ledgeArrayRF; 00024 Statistics LFTStats(ToFDataPointer1, 149, 1); 00025 Statistics RFTStats(ToFDataPointer2, 149, 1); 00026 int k = 0; 00027 00028 int ledgeArrayLB[150]; 00029 int ledgeArrayRB[150]; 00030 int* ToFDataPointer3 = ledgeArrayLB; 00031 int* ToFDataPointer4 = ledgeArrayRB; 00032 Statistics LBTStats(ToFDataPointer3, 149, 1); 00033 Statistics RBTStats(ToFDataPointer4, 149, 1); 00034 00035 double dist_old, curr_pos; // Variables for odometry position 00036 double outlierToF[4]; 00037 00038 /************************************************************************* 00039 * Creating PID objects * 00040 **************************************************************************/ 00041 PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT); // Angle PID object constructor 00042 PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.002, P_ON_E, DIRECT); // Distance PID object constructor 00043 PID PIDVelosity(&vIn, &vOut, &vDesired, 5.5, .00, .002, P_ON_E, DIRECT); // Velosity PID Constructor 00044 PID PIDSlaveV(&vInS, &vOutS, &vDesiredS, 5.5, .00, .002, P_ON_E, DIRECT); // Slave Velosity PID Constructor 00045 PID PIDAngularV(&yIn, &yOut, &yDesired, 5.5, .00, .002, P_ON_E, DIRECT); // Angular Velosity PID Constructor 00046 00047 00048 /************************************************************************* 00049 * Thread measures current angular position * 00050 **************************************************************************/ 00051 void Wheelchair::compass_thread() 00052 { 00053 curr_yaw = imu->yaw(); 00054 z_angular = curr_yaw; 00055 } 00056 00057 /************************************************************************* 00058 * Thread measures velocity of wheels and distance traveled * 00059 **************************************************************************/ 00060 void Wheelchair::velocity_thread() 00061 { 00062 curr_vel = wheel->getVelocity(); 00063 curr_velS = wheelS->getVelocity(); 00064 curr_pos = wheel->getDistance(53.975); 00065 } 00066 00067 void Wheelchair::emergencyButton_thread () 00068 { 00069 while(1) { 00070 while(!e_button) { 00071 00072 //Stop wheelchair 00073 Wheelchair::stop(); 00074 printf("E-button has been pressed\r\n"); 00075 off->write(high); // Turn off PCB 00076 on->write(0); // Make sure PCB not on 00077 //Reset Board 00078 NVIC_SystemReset(); 00079 00080 } 00081 00082 } 00083 } 00084 00085 /************************************************************************* 00086 * Thread checks ToF sensors for safety of wheelchair movement * 00087 **************************************************************************/ 00088 void Wheelchair::ToFSafe_thread() 00089 { 00090 int ToFV[12]; 00091 for(int i = 0; i < 6; i++) { // Reads from the ToF Sensors 00092 ToFV[i] = (*(ToF+i))->readFromOneSensor(); 00093 //out->printf("%d ", ToFV[i]); 00094 } 00095 00096 //out->printf("\r\n"); 00097 00098 k++; 00099 00100 if (k == 150) { 00101 k = 1; 00102 } 00103 00104 ledgeArrayLF[k] = (*(ToF+1))->readFromOneSensor(); 00105 ledgeArrayRF[k] = (*(ToF+4))->readFromOneSensor(); 00106 00107 /* for(int i = 0; i < 100; i++) 00108 { 00109 out->printf("%d, ",ledgeArrayRF[i]); 00110 } 00111 out->printf("\r\n"); */ 00112 00113 outlierToF[0] = LFTStats.mean() + 2*LFTStats.stdev(); 00114 outlierToF[1] = RFTStats.mean() + 2*RFTStats.stdev(); 00115 00116 for(int i = 0; i < 2; i++) { // Reads from the ToF Sensors 00117 runningAverage[i] = ((runningAverage[i]*(4) + ToFV[(i*3)+1]) / 5); 00118 } 00119 00120 int sensor1 = ToFV[0]; 00121 int sensor4 = ToFV[3]; 00122 if(curr_vel < 1 &&((2 * maxDecelerationSlow*sensor1 < curr_vel*curr_vel*1000*1000 || 00123 2 * maxDecelerationSlow*sensor4 < curr_vel*curr_vel*1000*1000) && 00124 (sensor1 < 1500 || sensor4 < 1500)) || 00125 550 > sensor1 || 550 > sensor4) { 00126 if(x->read() > def) { 00127 x->write(def); 00128 forwardSafety = 1; // You cannot move forward 00129 } 00130 } 00131 00132 else if(curr_vel > 1 &&((2 * maxDecelerationFast*sensor1 < curr_vel*curr_vel*1000*1000 || 00133 2 * maxDecelerationFast*sensor4 < curr_vel*curr_vel*1000*1000) && 00134 (sensor1 < 1500 || sensor4 < 1500)) || 00135 550 > sensor1 || 550 > sensor4) { 00136 if(x->read() > def) { 00137 x->write(def); 00138 forwardSafety = 1; // You cannot move forward 00139 } 00140 } 00141 00142 else if ((runningAverage[0] > outlierToF[0]) || (runningAverage[1] > outlierToF[1])) { 00143 forwardSafety = 1; 00144 out->printf("I'M STOPPING BECAUSE OF A FRONT LEDGE\r\n"); 00145 } 00146 00147 else 00148 forwardSafety = 0; 00149 00150 //////////////////////////////////////////////////////////////////////////// 00151 00152 ledgeArrayLB[k] = (*(ToF+1))->readFromOneSensor(); 00153 ledgeArrayRB[k] = (*(ToF+4))->readFromOneSensor(); 00154 00155 outlierToF[2] = LBTStats.mean() + 2*LBTStats.stdev(); 00156 outlierToF[3] = RBTStats.mean() + 2*RBTStats.stdev(); 00157 00158 for(int i = 2; i < 4; i++) { // Reads from the ToF Sensors 00159 runningAverage[i] = ((runningAverage[i]*(4) + ToFV[(i*3)+1]) / 5); 00160 } 00161 00162 int sensor7 = ToFV[6]; 00163 int sensor10 = ToFV[9]; 00164 if(curr_vel < 1 &&((2 * maxDecelerationSlow*sensor7 < curr_vel*curr_vel*1000*1000 || 00165 2 * maxDecelerationSlow*sensor10 < curr_vel*curr_vel*1000*1000) && 00166 (sensor7 < 1500 || sensor10 < 1500)) || 00167 550 > sensor7 || 550 > sensor10) { 00168 if(x->read() > def) { 00169 x->write(def); 00170 backwardSafety = 1; // You cannot move backwards 00171 } 00172 } 00173 00174 else if(curr_vel > 1 &&((2 * maxDecelerationFast*sensor1 < curr_vel*curr_vel*1000*1000 || 00175 2 * maxDecelerationFast*sensor4 < curr_vel*curr_vel*1000*1000) && 00176 (sensor7 < 1500 || sensor10 < 1500)) || 00177 550 > sensor7 || 550 > sensor10) { 00178 if(x->read() > def) { 00179 x->write(def); 00180 backwardSafety = 1; // You cannot move backwards 00181 } 00182 } 00183 00184 else if ((runningAverage[2] > outlierToF[2]) || (runningAverage[3] > outlierToF[3])) { 00185 backwardSafety = 1; 00186 out->printf("I'M STOPPING BECAUSE OF A BACK LEDGE\r\n"); 00187 } 00188 00189 else 00190 backwardSafety = 0; 00191 00192 //////////////////////////////////////////////////////////////////////////// 00193 00194 /*Side Tof begin*/ 00195 int sensor3 = ToFV[2]; //front left 00196 int sensor6 = ToFV[5]; //front right 00197 int sensor9 = ToFV[8]; //back 00198 int sensor12 = ToFV[11]; //back 00199 00200 double currAngularVelocity = imu->gyro_x(); //Current angular velocity from IMU 00201 double angle = imu->yaw() * 3.14159 / 180; //from IMU, in rads 00202 double arcLength = WheelchairRadius * currAngularVelocity * 00203 currAngularVelocity / (2 * maxAngularDeceleration); //S = r*Ө, in cm 00204 00205 /* Clear the front side first, else continue going straight or can't turn 00206 After clearing the front sideand movinf forward, check if can clear the back 00207 when turning */ 00208 00209 //When either sensors too close to the wall, can't turn 00210 if(sensor3 <= minWallLength) { 00211 leftSafety = 1; 00212 out-> printf("Detecting wall to the left!\n"); 00213 } 00214 else{ 00215 leftSafety = 0; 00216 } 00217 00218 if(sensor6 <= minWallLength) { 00219 rightSafety = 1; 00220 out-> printf("Detecting wall to the right!\n"); 00221 } 00222 else { 00223 rightSafety = 0; 00224 } 00225 00226 /*Check whether safe to keep turning 00227 Know the exact moment you can stop the chair going at a certain speed before 00228 its too late*/ 00229 if((currAngularVelocity * currAngularVelocity > 2 * 00230 maxAngularDeceleration * angle) && (sensor3/10 <= arcLength + 10)) { 00231 leftSafety = 1; //Not safe to turn left 00232 out-> printf("Too fast to the left!\n"); 00233 } 00234 else{ 00235 leftSafety = 0; 00236 } 00237 if((currAngularVelocity * currAngularVelocity > 2 * 00238 maxAngularDeceleration * angle) && (sensor6/10 <= arcLength + 10)) { 00239 rightSafety = 1; //Not safe to turn right 00240 out-> printf("Too fast to the right!\n"); 00241 } 00242 else{ 00243 rightSafety = 0; 00244 } 00245 00246 //Safe to continue turning 00247 //Check if can turn left and back side sensors 00248 // Staring t road and frequenctly checking 00249 //Check the back sensor 00250 /*int sensor7 = ToFV[0]; //back sensor NOTTT SURE 00251 int sensor8 = ToFV[3]; //back sensor 00252 00253 if(curr_vel < 1 &&((2 * maxDecelerationSlow*sensor7 < curr_vel*curr_vel*1000*1000 || 00254 2 * maxDecelerationSlow*sensor8 < curr_vel*curr_vel*1000*1000) && 00255 (sensor7 < 1500 || sensor8 < 1500)) || 00256 550 > sensor7 || 550 > sensor8) 00257 { 00258 //out->printf("i am in danger\r\n"); 00259 if(x->read() > def) 00260 { 00261 x->write(def); 00262 backwardSafety = 1;// You cannot move backward 00263 } 00264 } 00265 //When going to fast to stop from wall 00266 else if(curr_vel > 1 &&((2 * maxDecelerationFast*sensor7 < curr_vel*curr_vel*1000*1000 || 00267 2 * maxDecelerationFast*sensor8 < curr_vel*curr_vel*1000*1000) && 00268 (sensor7 < 1500 || sensor8 < 1500)) || 00269 550 > sensor7 || 550 > sensor8) 00270 { 00271 //out->printf("i am in danger\r\n"); 00272 if(x->read() > def) 00273 { 00274 x->write(def); 00275 backwardSafety = 1; 00276 } 00277 }*/ 00278 00279 /*Side Tof end*/ 00280 00281 } 00282 00283 /************************************************************************* 00284 * Constructor for Wheelchair class * 00285 **************************************************************************/ 00286 Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time, QEI* qei, QEI* qeiS, 00287 VL53L1X** ToFT) 00288 { 00289 x_position = 0; 00290 y_position = 0; 00291 forwardSafety = 0; 00292 backwardSafety = 0; 00293 00294 /* Initializes X and Y variables to Pins */ 00295 x = new PwmOut(xPin); 00296 y = new PwmOut(yPin); 00297 00298 /* Initializes IMU Library */ 00299 out = pc; // "out" is called for serial monitor 00300 out->printf("on\r\n"); 00301 imu = new IMUWheelchair(pc, time); 00302 Wheelchair::stop(); // Wheelchair is initially stationary 00303 imu->setup(); // turns on the IMU 00304 wheelS = qeiS; // "wheel" is called for encoder 00305 wheel = qei; 00306 ToF = ToFT; // passes pointer with addresses of ToF sensors 00307 00308 for(int i = 0; i < 12; i++) { // initializes the ToF Sensors 00309 (*(ToF+i))->initReading(0x31+((0x02)*i), 50000); 00310 } 00311 00312 out->printf("wheelchair setup done \r\n"); // Make sure it initialized; prints in serial monitor 00313 ti = time; 00314 for(int i = 0; i < 10; i++) { 00315 (*(ToF+1))->readFromOneSensor(); 00316 (*(ToF+1))->readFromOneSensor(); 00317 } 00318 for(int i = 0; i < 150; i++) { 00319 ledgeArrayLF[i] = (*(ToF+1))->readFromOneSensor(); 00320 ledgeArrayRF[i] = (*(ToF+4))->readFromOneSensor(); 00321 } 00322 00323 outlierToF[0] = LFTStats.mean() + 2*LFTStats.stdev(); 00324 outlierToF[1] = RFTStats.mean() + 2*RFTStats.stdev(); 00325 00326 myPID.SetMode(AUTOMATIC); // PID mode: Automatic 00327 } 00328 00329 /************************************************************************* 00330 * Move wheelchair with joystick on manual mode * 00331 **************************************************************************/ 00332 void Wheelchair::move(float x_coor, float y_coor) 00333 { 00334 /* Scales one joystick measurement to the chair's joystick measurement */ 00335 float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f; 00336 float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f; 00337 00338 /* Sends the scaled joystic values to the chair */ 00339 x->write(scaled_x); 00340 y->write(scaled_y); 00341 } 00342 00343 00344 /************************************************************************* 00345 * Automatic mode: move forward and update x,y coordinate sent to chair * 00346 **************************************************************************/ 00347 void Wheelchair::forward() 00348 { 00349 //printf("current velosity; %f, curr vel S %f\r\n", curr_vel, curr_velS); 00350 if(forwardSafety == 0) { 00351 x->write(high); 00352 y->write(def+offset); 00353 } 00354 out->printf("%f, %f\r\n", curr_pos, wheelS->getDistance(53.975)); 00355 } 00356 00357 /************************************************************************* 00358 * Automatic mode: move in reverse and update x,y coordinate sent to chair* 00359 **************************************************************************/ 00360 void Wheelchair::backward() 00361 { 00362 if (backwardSafety == 0) { 00363 x->write(low); 00364 y->write(def); 00365 } 00366 } 00367 /************************************************************************* 00368 * Automatic mode: move right and update x,y coordinate sent to chair * 00369 **************************************************************************/ 00370 void Wheelchair::right() 00371 { 00372 //if safe to move, from ToFSafety 00373 if(rightSafety == 0) { 00374 x->write(def); 00375 y->write(low); 00376 } 00377 } 00378 /************************************************************************* 00379 * Automatic mode: move left and update x,y coordinate sent to chair * 00380 **************************************************************************/ 00381 void Wheelchair::left() 00382 { 00383 //if safe to move, from ToFSafety 00384 if(leftSafety == 0) { 00385 x->write(def); 00386 y->write(high); 00387 } 00388 } 00389 /************************************************************************* 00390 * Stop the wheelchair * 00391 **************************************************************************/ 00392 void Wheelchair::stop() 00393 { 00394 x->write(def); 00395 y->write(def); 00396 } 00397 /************************************************************************* 00398 * Counter-clockwise is ( - ) * 00399 * Clockwise is ( + ) * 00400 * Range of deg: 0 to 360 * 00401 * This method takes in an angle from user and adjusts for turning right * 00402 **************************************************************************/ 00403 void Wheelchair::pid_right(int deg) 00404 { 00405 bool overturn = false; // Boolean if angle over 360˚ 00406 00407 out->printf("pid right\r\r\n"); 00408 x->write(def); // Update x sent to chair to be stationary 00409 Setpoint = curr_yaw + deg; // Relative angle we want to turn 00410 pid_yaw = curr_yaw; // Sets pid_yaw to angle input from user 00411 00412 /* Turns on overturn boolean if setpoint over 360˚ */ 00413 if(Setpoint > 360) { 00414 overturn = true; 00415 } 00416 00417 myPID.SetTunings(5.5,0, 0.0035); // Sets the constants for P and D 00418 myPID.SetOutputLimits(0, def-low-.15); // Limit is set to the differnce between def and low 00419 myPID.SetControllerDirection(DIRECT); // PID mode: Direct 00420 00421 /* PID stops when approaching a litte less than desired angle */ 00422 while(pid_yaw < Setpoint - 3) { 00423 /* PID is set to correct angle range if angle greater than 360˚*/ 00424 if(overturn && curr_yaw < Setpoint-deg-1) { 00425 pid_yaw = curr_yaw + 360; 00426 } else { 00427 pid_yaw = curr_yaw; 00428 } 00429 00430 myPID.Compute(); // Does PID calculations 00431 double tempor = -Output+def; // Temporary value with the voltage output 00432 y->write(tempor); // Update y sent to chair 00433 00434 /* Prints to serial monitor the current angle and setpoint */ 00435 out->printf("curr_yaw %f\r\r\n", curr_yaw); 00436 out->printf("Setpoint = %f \r\n", Setpoint); 00437 00438 wait(.05); // Small delay (milliseconds) 00439 } 00440 00441 /* Saftey stop for wheelchair */ 00442 Wheelchair::stop(); 00443 out->printf("done \r\n"); 00444 } 00445 /************************************************************************* 00446 * Counter-clockwise is ( - ) * 00447 * Clockwise is ( + ) * 00448 * Range of deg: 0 to 360 * 00449 * This method takes in an angle from user and adjusts for turning left * 00450 **************************************************************************/ 00451 void Wheelchair::pid_left(int deg) 00452 { 00453 bool overturn = false; //Boolean if angle under 0˚ 00454 00455 out->printf("pid Left\r\r\n"); 00456 x->write(def); // Update x sent to chair to be stationary 00457 Setpoint = curr_yaw - deg; // Relative angle we want to turn 00458 pid_yaw = curr_yaw; // Sets pid_yaw to angle input from user 00459 00460 /* Turns on overturn boolean if setpoint less than 0˚ */ 00461 if(Setpoint < 0) { 00462 overturn = true; 00463 } 00464 00465 myPID.SetTunings(5,0, 0.004); // Sets the constants for P and D 00466 myPID.SetOutputLimits(0,high-def-.12); // Limit is set to the differnce between def and low 00467 myPID.SetControllerDirection(REVERSE); // PID mode: Reverse 00468 00469 /* PID stops when approaching a litte more than desired angle */ 00470 while(pid_yaw > Setpoint+3) { 00471 /* PID is set to correct angle range if angle less than 0˚ */ 00472 if(overturn && curr_yaw > Setpoint+deg+1) { 00473 pid_yaw = curr_yaw - 360; 00474 } else { 00475 pid_yaw = curr_yaw; 00476 } 00477 00478 myPID.Compute(); // Does PID calculations 00479 double tempor = Output+def; // Temporary value with the voltage output 00480 y->write(tempor); // Update y sent to chair 00481 00482 /* Prints to serial monitor the current angle and setpoint */ 00483 out->printf("curr_yaw %f\r\n", curr_yaw); 00484 out->printf("Setpoint = %f \r\n", Setpoint); 00485 00486 wait(.05); // Small delay (milliseconds) 00487 } 00488 00489 /* Saftey stop for wheelchair */ 00490 Wheelchair::stop(); 00491 out->printf("done \r\n"); 00492 00493 } 00494 00495 /************************************************************************* 00496 * This method determines whether to turn left or right * 00497 **************************************************************************/ 00498 void Wheelchair::pid_turn(int deg) 00499 { 00500 00501 /***************************************************************** 00502 * Sets angle to coterminal angle for left turn if deg > 180 * 00503 * Sets angle to coterminal angle for right turn if deg < -180 * 00504 *****************************************************************/ 00505 if(deg > 180) { 00506 deg -= 360; 00507 } else if(deg < -180) { 00508 deg +=360; 00509 } 00510 00511 /* Makes sure angle inputted to function is positive */ 00512 int turnAmt = abs(deg); 00513 00514 /* Calls PID_right if deg > 0, else calls PID_left if deg < 0 */ 00515 if(deg >= 0) { 00516 Wheelchair::pid_right(turnAmt); 00517 } else { 00518 Wheelchair::pid_left(turnAmt); 00519 } 00520 00521 } 00522 00523 /************************************************************************* 00524 * This method takes in distance to travel and adjust to move forward * 00525 **************************************************************************/ 00526 void Wheelchair::pid_forward(double mm) 00527 { 00528 mm -= 20; // Makes sure distance does not overshoot 00529 Input = 0; // Initializes input to zero: Test latter w/o 00530 wheel->reset(); // Resets encoders so that they start at 0 00531 00532 out->printf("pid foward\r\n"); 00533 00534 double tempor; // Initializes Temporary variable for x input 00535 Setpoint = mm; // Initializes the setpoint to desired value 00536 00537 myPIDDistance.SetTunings(5.5,0, 0.0015); // Sets constants for P and D 00538 myPIDDistance.SetOutputLimits(0,high-def-.15); // Limit set to difference between high and def 00539 myPIDDistance.SetControllerDirection(DIRECT); // PID mode: Direct 00540 00541 y->write(def+offset); // Update y to make chair stationary 00542 00543 /* Chair stops moving when Setpoint is reached */ 00544 while(Input < Setpoint) { 00545 00546 if(out->readable()) { // Emergency Break 00547 break; 00548 } 00549 00550 Input = wheel->getDistance(53.975); // Gets distance from Encoder into PID 00551 wait(.05); // Slight Delay: *****Test without 00552 myPIDDistance.Compute(); // Compute distance traveled by chair 00553 00554 tempor = Output + def; // Temporary output variable 00555 x->write(tempor); // Update x sent to chair 00556 00557 /* Prints to serial monitor the distance traveled by chair */ 00558 out->printf("distance %f\r\n", Input); 00559 } 00560 00561 } 00562 00563 /************************************************************************* 00564 * This method returns the relative angular position of chair * 00565 **************************************************************************/ 00566 double Wheelchair::getTwistZ() 00567 { 00568 return imu->gyro_z(); 00569 } 00570 00571 /************************************************************************* 00572 * This method computes the relative angle for Twist message in ROS * 00573 **************************************************************************/ 00574 void Wheelchair::pid_twistA() 00575 { 00576 /* Initialize variables for angle and update x,y sent to chair */ 00577 char c; 00578 double temporA = def; 00579 y->write(def); 00580 x->write(def); 00581 00582 PIDAngularV.SetTunings(.00015,0, 0.00); // Sets the constants for P and D 00583 PIDAngularV.SetOutputLimits(-.1, .1); // Limit set to be in range specified 00584 PIDAngularV.SetControllerDirection(DIRECT); // PID mode: Direct 00585 00586 /* Computes angular position of wheelchair while turning */ 00587 while(1) { 00588 yDesired = angularV; 00589 00590 /* Update and set all variable so that the chair is stationary 00591 * if the desired angle is zero 00592 */ 00593 if(yDesired == 0) { 00594 x->write(def); 00595 y->write(def); 00596 yDesired = 0; 00597 return; 00598 } 00599 00600 /* Continuously updates with current angle measured by IMU */ 00601 yIn = imu->gyro_z(); 00602 PIDAngularV.Compute(); 00603 temporA += yOut; // Temporary value with the voltage output 00604 y->write(temporA); // Update y sent to chair 00605 00606 //out->printf("temporA: %f, yDesired %f, angle: %f\r\n", temporA, yDesired, imu->gyro_z()); 00607 wait(.05); // Small delay (milliseconds) 00608 } 00609 00610 } 00611 00612 /************************************************************************* 00613 * This method computes the relative velocity for Twist message in ROS * 00614 **************************************************************************/ 00615 void Wheelchair::pid_twistV() 00616 { 00617 /* Initializes variables as default */ 00618 double temporV = def; 00619 double temporS = def+offset; 00620 vDesiredS = 0; 00621 x->write(def); 00622 y->write(def); 00623 wheel->reset(); // Resets the encoders 00624 /* Sets the constants for P and D */ 00625 PIDVelosity.SetTunings(.0005,0, 0.00); 00626 PIDSlaveV.SetTunings(.005,0.000001, 0.000001); 00627 00628 /* Limits to the range specified */ 00629 PIDVelosity.SetOutputLimits(-.005, .005); 00630 PIDSlaveV.SetOutputLimits(-.002, .002); 00631 00632 /* PID mode: Direct */ 00633 PIDVelosity.SetControllerDirection(DIRECT); 00634 PIDSlaveV.SetControllerDirection(DIRECT); 00635 00636 while(1) { 00637 linearV = .7; 00638 test1 = linearV*100; 00639 vel = curr_vel; 00640 vDesired = linearV*100; 00641 if(out->readable()) 00642 return; 00643 /* Update and set all variable so that the chair is stationary 00644 * if the velocity is zero 00645 */ 00646 if(linearV == 0) { 00647 x->write(def); 00648 y->write(def); 00649 00650 vel = 0; 00651 vDesired = 0; 00652 dist_old = 0; 00653 return; 00654 } 00655 00656 if(vDesired >= 0) { 00657 PIDVelosity.SetTunings(.000004,0, 0.00); // Sets the constants for P and D 00658 PIDVelosity.SetOutputLimits(-.002, .002); // Limits to the range specified 00659 } else { 00660 PIDVelosity.SetTunings(.000015,0, 0.00); // Sets the constants for P and D 00661 PIDVelosity.SetOutputLimits(-.0005, .0005); // Limits to range specified 00662 } 00663 00664 /* Sets maximum value of variable to 1 */ 00665 if(temporV >= 1.5) { 00666 temporV = 1.5; 00667 } 00668 /* Scales and makes some adjustments to velocity */ 00669 vIn = curr_vel*100; 00670 vInS = curr_vel-curr_velS; 00671 PIDVelosity.Compute(); 00672 PIDSlaveV.Compute(); 00673 if(forwardSafety == 0) { 00674 temporV += vOut; 00675 temporS += vOutS; 00676 00677 /* Updates x,y sent to Wheelchair and for Odometry message in ROS */ 00678 x->write(temporV); 00679 test2 = temporV; 00680 y->write(temporS); 00681 } else { 00682 x->write(def); 00683 y->write(def); 00684 } 00685 //out->printf("Velosity: %f, Velosity2: %f, temporV %f, temporS %f\r\n", curr_vel, curr_velS, temporV, temporS); 00686 Wheelchair::odomMsg(); 00687 wait(.01); // Small delay (milliseconds) 00688 } 00689 } 00690 00691 /************************************************************************* 00692 * This method calculates the relative position of the chair everytime the* 00693 * encoders reset by setting its old position as the origin to calculate * 00694 * the new position * 00695 **************************************************************************/ 00696 void Wheelchair::odomMsg() 00697 { 00698 double dist_new = curr_pos; 00699 double dist = dist_new-dist_old; 00700 double temp_x = dist*sin(z_angular*3.14159/180); 00701 double temp_y = dist*cos(z_angular*3.14159/180); 00702 00703 x_position += temp_x; 00704 y_position += temp_y; 00705 00706 dist_old = dist_new; 00707 } 00708 00709 /************************************************************************** 00710 * This method prints the Odometry message to the serial monitor * 00711 ***************************************************************************/ 00712 void Wheelchair::showOdom() 00713 { 00714 out->printf("x %f, y %f, angle %f", x_position, y_position, z_angular); 00715 } 00716 00717 /************************************************************************** 00718 * This method returns the approximate distance based on the wheel diameter* 00719 ***************************************************************************/ 00720 float Wheelchair::getDistance() 00721 { 00722 return wheel->getDistance(Diameter); 00723 } 00724 00725 /************************************************************************** 00726 * This method resets the Encoder's * 00727 ***************************************************************************/ 00728 void Wheelchair::resetDistance() 00729 { 00730 wheel->reset(); 00731 } 00732 00733 /*---------------------------------------------------------------------------------------------------*/ 00734 /*---------------------------------------------------------------------------------------------------*/ 00735 /*---------------------------------------------------------------------------------------------------*/ 00736 /*---------------------------------------------------------------------------------------------------*/ 00737 /*---------------------------------------------------------------------------------------------------*/ 00738 00739 /*Predetermined paths For Demmo*/ 00740 void Wheelchair::desk() 00741 { 00742 Wheelchair::pid_forward(5461); 00743 Wheelchair::pid_right(87); 00744 Wheelchair::pid_forward(3658); 00745 Wheelchair::pid_right(87); 00746 Wheelchair::pid_forward(3658); 00747 } 00748 00749 void Wheelchair::kitchen() 00750 { 00751 Wheelchair::pid_forward(5461); 00752 Wheelchair::pid_right(87); 00753 Wheelchair::pid_forward(3658); 00754 Wheelchair::pid_left(90); 00755 Wheelchair::pid_forward(305); 00756 } 00757 00758 void Wheelchair::desk_to_kitchen() 00759 { 00760 Wheelchair::pid_right(180); 00761 Wheelchair::pid_forward(3700); 00762 }
Generated on Thu Jul 21 2022 09:14:49 by
1.7.2