Added more code for side and angled sensor

Dependencies:   QEI2 PID Watchdog VL53L1X_Filter BNOWrapper ros_lib_kinetic

Committer:
t1jain
Date:
Tue Jul 02 16:40:41 2019 +0000
Revision:
33:f3585571f11e
Parent:
32:fb26baa75d44
Child:
34:b89967adc86c
Formatting updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryanlin97 0:fc0c4a184482 1 #include "wheelchair.h"
t1jain 30:c25b2556e84d 2
jvfausto 21:3489cffad196 3 bool manual_drive = false; // Variable changes between joystick and auto drive
jvfausto 21:3489cffad196 4 double encoder_distance; // Keeps distanse due to original position
jvfausto 21:3489cffad196 5
jvfausto 21:3489cffad196 6 volatile double Setpoint, Output, Input, Input2; // Variables for PID
jvfausto 21:3489cffad196 7 volatile double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2; // Variables for PID
jvfausto 21:3489cffad196 8 volatile double vIn, vOut, vDesired; // Variables for PID Velosity
jvfausto 21:3489cffad196 9 volatile double vInS, vOutS, vDesiredS; // Variables for PID Slave Wheel
jvfausto 21:3489cffad196 10 volatile double yIn, yOut, yDesired; // Variables for PID turn velosity
t1jain 30:c25b2556e84d 11 // int* ToFDataPointer1;
t1jain 30:c25b2556e84d 12 // int* ToFDataPointer2;
t1jain 30:c25b2556e84d 13
t1jain 31:06f2362caf12 14 int ledgeArrayLF[150];
t1jain 31:06f2362caf12 15 int ledgeArrayRF[150];
t1jain 30:c25b2556e84d 16 int* ToFDataPointer1 = ledgeArrayLF;
t1jain 30:c25b2556e84d 17 int* ToFDataPointer2 = ledgeArrayRF;
t1jain 31:06f2362caf12 18 statistics LFTStats(ToFDataPointer1, 149, 1);
t1jain 31:06f2362caf12 19 statistics RFTStats(ToFDataPointer2, 149, 1);
t1jain 30:c25b2556e84d 20 int k = 0;
ryanlin97 11:d14a1f7f1297 21
jvfausto 21:3489cffad196 22 double dist_old, curr_pos; // Variables for odometry position
t1jain 30:c25b2556e84d 23 double outlierToF[4];
jvfausto 19:71a6621ee5c3 24
jvfausto 21:3489cffad196 25
jvfausto 21:3489cffad196 26 PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT); // Angle PID object constructor
jvfausto 21:3489cffad196 27 PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.002, P_ON_E, DIRECT); // Distance PID object constructor
jvfausto 21:3489cffad196 28 PID PIDVelosity(&vIn, &vOut, &vDesired, 5.5, .00, .002, P_ON_E, DIRECT); // Velosity PID Constructor
jvfausto 21:3489cffad196 29 PID PIDSlaveV(&vInS, &vOutS, &vDesiredS, 5.5, .00, .002, P_ON_E, DIRECT); // Slave Velosity PID Constructor
jvfausto 21:3489cffad196 30 PID PIDAngularV(&yIn, &yOut, &yDesired, 5.5, .00, .002, P_ON_E, DIRECT); // Angular Velosity PID Constructor
jvfausto 21:3489cffad196 31
jvfausto 19:71a6621ee5c3 32
jvfausto 21:3489cffad196 33 /* Thread measures current angular position */
jvfausto 21:3489cffad196 34 void Wheelchair::compass_thread()
jvfausto 21:3489cffad196 35 {
ryanlin97 11:d14a1f7f1297 36 curr_yaw = imu->yaw();
jvfausto 21:3489cffad196 37 z_angular = curr_yaw;
jvfausto 21:3489cffad196 38 }
jvfausto 17:7f3b69300bb6 39
jvfausto 21:3489cffad196 40 /* Thread measures velocity of wheels and distance traveled */
jvfausto 21:3489cffad196 41 void Wheelchair::velocity_thread()
ryanlin97 1:c0beadca1617 42 {
jvfausto 21:3489cffad196 43 curr_vel = wheel->getVelocity();
jvfausto 21:3489cffad196 44 curr_velS = wheelS->getVelocity();
jvfausto 21:3489cffad196 45 curr_pos = wheel->getDistance(53.975);
ryanlin97 1:c0beadca1617 46 }
ryanlin97 6:0cd57bdd8fbc 47
t1jain 30:c25b2556e84d 48 void Wheelchair::ToFSafe_thread()
ryanlin97 1:c0beadca1617 49 {
jvfausto 21:3489cffad196 50 int ToFV[12];
jvfausto 26:662693bd7f31 51 for(int i = 0; i < 6; i++) // reads from the ToF Sensors
jvfausto 21:3489cffad196 52 {
jvfausto 21:3489cffad196 53 ToFV[i] = (*(ToF+i))->readFromOneSensor();
t1jain 32:fb26baa75d44 54 //out->printf("%d ", ToFV[i]);
jvfausto 27:da718b990837 55 }
jvfausto 27:da718b990837 56
t1jain 32:fb26baa75d44 57 //out->printf("\r\n");
t1jain 30:c25b2556e84d 58
t1jain 30:c25b2556e84d 59 k++;
t1jain 30:c25b2556e84d 60
t1jain 31:06f2362caf12 61 if (k == 150) {
t1jain 31:06f2362caf12 62 k = 0;
t1jain 30:c25b2556e84d 63 }
jvfausto 27:da718b990837 64
t1jain 30:c25b2556e84d 65 ledgeArrayLF[k] = (*(ToF+1))->readFromOneSensor();
t1jain 30:c25b2556e84d 66 ledgeArrayRF[k] = (*(ToF+4))->readFromOneSensor();
t1jain 31:06f2362caf12 67 /*for(int i = 0; i < 100; i++)
t1jain 31:06f2362caf12 68 {
t1jain 31:06f2362caf12 69 out->printf("%d, ",ledgeArrayRF[i]);
t1jain 31:06f2362caf12 70 }
t1jain 31:06f2362caf12 71 out->printf("\r\n");*/
t1jain 30:c25b2556e84d 72 // statistics LFTStats(ToFDataPointer1, 99, 1);
t1jain 30:c25b2556e84d 73 // statistics RFTStats(ToFDataPointer1, 99, 1);
t1jain 32:fb26baa75d44 74 //out->printf("Right Mean: %f ", RFTStats.mean());
t1jain 32:fb26baa75d44 75 //out->printf("Std Dev: % f", RFTStats.stdev());
t1jain 30:c25b2556e84d 76 outlierToF[0] = LFTStats.mean() + 2*LFTStats.stdev();
t1jain 32:fb26baa75d44 77 //out->printf("Left Mean: %f ", LFTStats.mean());
t1jain 32:fb26baa75d44 78 //out->printf("Std Dev: %f ", LFTStats.stdev());
t1jain 30:c25b2556e84d 79 outlierToF[1] = RFTStats.mean() + 2*RFTStats.stdev();
t1jain 32:fb26baa75d44 80 //out->printf("New outliers: %f, %f\n", outlierToF[0], outlierToF[1]);
t1jain 30:c25b2556e84d 81
t1jain 30:c25b2556e84d 82
jvfausto 27:da718b990837 83
jvfausto 27:da718b990837 84 for(int i = 0; i < 4; i++) { // Reads from the ToF Sensors
jvfausto 27:da718b990837 85 runningAverage[i] = ((runningAverage[i]*(4) + ToFV[(i*3)+1]) / 5);
t1jain 30:c25b2556e84d 86 }
jvfausto 27:da718b990837 87
jvfausto 27:da718b990837 88 int sensor1 = ToFV[0];
jvfausto 27:da718b990837 89 int sensor4 = ToFV[3];
t1jain 30:c25b2556e84d 90 //out->printf("%d, %d\r\n", ToFV[1], runningAverage[0]);
jvfausto 27:da718b990837 91 if(curr_vel < 1 &&((2 * maxDecelerationSlow*sensor1 < curr_vel*curr_vel*1000*1000 ||
jvfausto 26:662693bd7f31 92 2 * maxDecelerationSlow*sensor4 < curr_vel*curr_vel*1000*1000) &&
jvfausto 26:662693bd7f31 93 (sensor1 < 1500 || sensor4 < 1500)) ||
jvfausto 26:662693bd7f31 94 550 > sensor1 || 550 > sensor4)
jvfausto 26:662693bd7f31 95 {
jvfausto 26:662693bd7f31 96 //out->printf("i am in danger\r\n");
jvfausto 26:662693bd7f31 97 if(x->read() > def)
jvfausto 26:662693bd7f31 98 {
jvfausto 26:662693bd7f31 99 x->write(def);
t1jain 30:c25b2556e84d 100 forwardSafety = 1; // You cannot move forward
jvfausto 26:662693bd7f31 101 }
jvfausto 26:662693bd7f31 102 }
jvfausto 26:662693bd7f31 103 else if(curr_vel > 1 &&((2 * maxDecelerationFast*sensor1 < curr_vel*curr_vel*1000*1000 ||
jvfausto 26:662693bd7f31 104 2 * maxDecelerationFast*sensor4 < curr_vel*curr_vel*1000*1000) &&
jvfausto 21:3489cffad196 105 (sensor1 < 1500 || sensor4 < 1500)) ||
jvfausto 21:3489cffad196 106 550 > sensor1 || 550 > sensor4)
jvfausto 21:3489cffad196 107 {
jvfausto 21:3489cffad196 108 //out->printf("i am in danger\r\n");
jvfausto 21:3489cffad196 109 if(x->read() > def)
jvfausto 21:3489cffad196 110 {
jvfausto 21:3489cffad196 111 x->write(def);
jvfausto 21:3489cffad196 112 forwardSafety = 1;
jvfausto 21:3489cffad196 113 }
jvfausto 21:3489cffad196 114 }
t1jain 30:c25b2556e84d 115
t1jain 30:c25b2556e84d 116 else if ((runningAverage[0] > outlierToF[0]) || (runningAverage[1] > outlierToF[1])) {
t1jain 30:c25b2556e84d 117 forwardSafety = 1;
t1jain 31:06f2362caf12 118 out->printf("I'M STOPPING BECAUSE OF A LEDGE\r\n");
t1jain 30:c25b2556e84d 119 }
t1jain 30:c25b2556e84d 120
jvfausto 21:3489cffad196 121 else
jvfausto 21:3489cffad196 122 forwardSafety = 0;
jvfausto 21:3489cffad196 123 }
ryanlin97 6:0cd57bdd8fbc 124
jvfausto 21:3489cffad196 125 /* Constructor for Wheelchair class */
jvfausto 21:3489cffad196 126 Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time, QEI* qei, QEI* qeiS,
jvfausto 21:3489cffad196 127 VL53L1X** ToFT)
jvfausto 21:3489cffad196 128 {
jvfausto 21:3489cffad196 129 x_position = 0;
jvfausto 21:3489cffad196 130 y_position = 0;
jvfausto 21:3489cffad196 131 forwardSafety = 0;
jvfausto 21:3489cffad196 132 /* Initializes X and Y variables to Pins */
jvfausto 21:3489cffad196 133 x = new PwmOut(xPin);
jvfausto 21:3489cffad196 134 y = new PwmOut(yPin);
jvfausto 21:3489cffad196 135 /* Initializes IMU Library */
jvfausto 26:662693bd7f31 136 out = pc; // "out" is called for serial monitor
jvfausto 26:662693bd7f31 137 out->printf("on\r\n");
jvfausto 21:3489cffad196 138 imu = new chair_BNO055(pc, time);
jvfausto 21:3489cffad196 139 Wheelchair::stop(); // Wheelchair is initially stationary
jvfausto 21:3489cffad196 140 imu->setup(); // turns on the IMU
jvfausto 21:3489cffad196 141 wheelS = qeiS; // "wheel" is called for encoder
jvfausto 21:3489cffad196 142 wheel = qei;
jvfausto 21:3489cffad196 143 ToF = ToFT; // passes pointer with addresses of ToF sensors
jvfausto 21:3489cffad196 144
t1jain 33:f3585571f11e 145 for(int i = 0; i < 12; i++) // initializes the ToF Sensors
jvfausto 21:3489cffad196 146 {
jvfausto 21:3489cffad196 147 (*(ToF+i))->initReading(0x31+((0x02)*i), 50000);
jvfausto 21:3489cffad196 148 }
jvfausto 21:3489cffad196 149
jvfausto 21:3489cffad196 150 out->printf("wheelchair setup done \r\n"); // Make sure it initialized; prints in serial monitor
jvfausto 21:3489cffad196 151 ti = time;
t1jain 31:06f2362caf12 152 for(int i = 0; i < 10; i++)
t1jain 31:06f2362caf12 153 {
t1jain 31:06f2362caf12 154 (*(ToF+1))->readFromOneSensor();
t1jain 31:06f2362caf12 155 (*(ToF+1))->readFromOneSensor();
t1jain 31:06f2362caf12 156 }
t1jain 31:06f2362caf12 157 for(int i = 0; i < 150; i++)
jvfausto 27:da718b990837 158 {
jvfausto 27:da718b990837 159 ledgeArrayLF[i] = (*(ToF+1))->readFromOneSensor();
t1jain 30:c25b2556e84d 160 ledgeArrayRF[i] = (*(ToF+4))->readFromOneSensor();
jvfausto 27:da718b990837 161 }
t1jain 30:c25b2556e84d 162
t1jain 30:c25b2556e84d 163
t1jain 31:06f2362caf12 164 //statistics LFTStats(ToFDataPointer1, 99, 1);
t1jain 33:f3585571f11e 165 // //ToFDataPointer = ledgeArrayRF;
t1jain 31:06f2362caf12 166 //statistics RFTStats(ToFDataPointer2, 99, 1);
t1jain 31:06f2362caf12 167
t1jain 30:c25b2556e84d 168
t1jain 30:c25b2556e84d 169 outlierToF[0] = LFTStats.mean() + 2*LFTStats.stdev();
t1jain 30:c25b2556e84d 170 outlierToF[1] = RFTStats.mean() + 2*RFTStats.stdev();
t1jain 30:c25b2556e84d 171
t1jain 31:06f2362caf12 172 //out->printf("Left outlier = %f\n", outlierToF[0]);
t1jain 33:f3585571f11e 173 //out->printf("Right outlier = %f\n", outlierToF[1]);
t1jain 31:06f2362caf12 174 //out->printf("Left statistics = %f, %f\n", LFTStats.mean(), LFTStats.stdev());
t1jain 31:06f2362caf12 175 //out->printf("Right statistics = %f, %f\n", RFTStats.mean(), RFTStats.stdev());
jvfausto 21:3489cffad196 176 myPID.SetMode(AUTOMATIC); // PID mode: Automatic
jvfausto 21:3489cffad196 177 }
jvfausto 21:3489cffad196 178
jvfausto 21:3489cffad196 179 /* Move wheelchair with joystick on manual mode */
jvfausto 21:3489cffad196 180 void Wheelchair::move(float x_coor, float y_coor)
jvfausto 21:3489cffad196 181 {
jvfausto 21:3489cffad196 182 /* Scales one joystick measurement to the chair's joystick measurement */
ryanlin97 4:29a27953fe70 183 float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f;
ryanlin97 4:29a27953fe70 184 float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f;
jvfausto 21:3489cffad196 185
jvfausto 21:3489cffad196 186 /* Sends the scaled joystic values to the chair */
jvfausto 21:3489cffad196 187 x->write(scaled_x);
ryanlin97 4:29a27953fe70 188 y->write(scaled_y);
ryanlin97 5:e0ccaab3959a 189 }
jvfausto 21:3489cffad196 190
jvfausto 21:3489cffad196 191 /* Automatic mode: move forward and update x,y coordinate sent to chair */
jvfausto 21:3489cffad196 192 void Wheelchair::forward()
ryanlin97 1:c0beadca1617 193 {
jvfausto 26:662693bd7f31 194 //printf("current velosity; %f, curr vel S %f\r\n", curr_vel, curr_velS);
jvfausto 21:3489cffad196 195 if(forwardSafety == 0)
jvfausto 21:3489cffad196 196 {
ryanlin97 0:fc0c4a184482 197 x->write(high);
ryanlin97 3:a5e71bfdb492 198 y->write(def+offset);
jvfausto 21:3489cffad196 199 }
jvfausto 26:662693bd7f31 200 out->printf("%f, %f\r\n", curr_pos, wheelS->getDistance(53.975));
ryanlin97 0:fc0c4a184482 201 }
jvfausto 21:3489cffad196 202
jvfausto 21:3489cffad196 203 /* Automatic mode: move in reverse and update x,y coordinate sent to chair */
jvfausto 21:3489cffad196 204 void Wheelchair::backward()
ryanlin97 1:c0beadca1617 205 {
ryanlin97 0:fc0c4a184482 206 x->write(low);
ryanlin97 0:fc0c4a184482 207 y->write(def);
ryanlin97 0:fc0c4a184482 208 }
jvfausto 21:3489cffad196 209
jvfausto 21:3489cffad196 210 /* Automatic mode: move right and update x,y coordinate sent to chair */
jvfausto 21:3489cffad196 211 void Wheelchair::right()
ryanlin97 1:c0beadca1617 212 {
ryanlin97 0:fc0c4a184482 213 x->write(def);
ryanlin97 11:d14a1f7f1297 214 y->write(low);
ryanlin97 0:fc0c4a184482 215 }
ryanlin97 0:fc0c4a184482 216
jvfausto 21:3489cffad196 217 /* Automatic mode: move left and update x,y coordinate sent to chair */
jvfausto 21:3489cffad196 218 void Wheelchair::left()
ryanlin97 1:c0beadca1617 219 {
ryanlin97 0:fc0c4a184482 220 x->write(def);
ryanlin97 11:d14a1f7f1297 221 y->write(high);
ryanlin97 0:fc0c4a184482 222 }
jvfausto 21:3489cffad196 223
jvfausto 21:3489cffad196 224 /* Stop the wheelchair */
jvfausto 21:3489cffad196 225 void Wheelchair::stop()
ryanlin97 1:c0beadca1617 226 {
ryanlin97 0:fc0c4a184482 227 x->write(def);
ryanlin97 0:fc0c4a184482 228 y->write(def);
ryanlin97 6:0cd57bdd8fbc 229 }
jvfausto 21:3489cffad196 230
jvfausto 21:3489cffad196 231 /* Counter-clockwise is -
jvfausto 21:3489cffad196 232 * Clockwise is +
jvfausto 21:3489cffad196 233 * Range of deg: 0 to 360
jvfausto 21:3489cffad196 234 * This constructor takes in an angle from user and adjusts for turning right
jvfausto 21:3489cffad196 235 */
jvfausto 21:3489cffad196 236 void Wheelchair::pid_right(int deg)
ryanlin97 12:921488918749 237 {
t1jain 33:f3585571f11e 238 bool overturn = false; // Boolean if angle over 360˚
ryanlin97 12:921488918749 239
jvfausto 21:3489cffad196 240 out->printf("pid right\r\r\n");
jvfausto 21:3489cffad196 241 x->write(def); // Update x sent to chair to be stationary
jvfausto 21:3489cffad196 242 Setpoint = curr_yaw + deg; // Relative angle we want to turn
jvfausto 21:3489cffad196 243 pid_yaw = curr_yaw; // Sets pid_yaw to angle input from user
jvfausto 21:3489cffad196 244
jvfausto 21:3489cffad196 245 /* Turns on overturn boolean if setpoint over 360˚ */
jvfausto 21:3489cffad196 246 if(Setpoint > 360)
jvfausto 21:3489cffad196 247 {
ryanlin97 12:921488918749 248 overturn = true;
ryanlin97 12:921488918749 249 }
jvfausto 21:3489cffad196 250
jvfausto 21:3489cffad196 251 myPID.SetTunings(5.5,0, 0.0035); // Sets the constants for P and D
jvfausto 21:3489cffad196 252 myPID.SetOutputLimits(0, def-low-.15); // Limit is set to the differnce between def and low
jvfausto 21:3489cffad196 253 myPID.SetControllerDirection(DIRECT); // PID mode: Direct
jvfausto 21:3489cffad196 254
jvfausto 21:3489cffad196 255 /* PID stops when approaching a litte less than desired angle */
jvfausto 21:3489cffad196 256 while(pid_yaw < Setpoint - 3)
jvfausto 21:3489cffad196 257 {
jvfausto 21:3489cffad196 258 /* PID is set to correct angle range if angle greater than 360˚*/
jvfausto 17:7f3b69300bb6 259 if(overturn && curr_yaw < Setpoint-deg-1)
jvfausto 17:7f3b69300bb6 260 {
jvfausto 21:3489cffad196 261 pid_yaw = curr_yaw + 360;
jvfausto 21:3489cffad196 262 }
jvfausto 21:3489cffad196 263 else
jvfausto 21:3489cffad196 264 {
jvfausto 17:7f3b69300bb6 265 pid_yaw = curr_yaw;
ryanlin97 12:921488918749 266 }
jvfausto 21:3489cffad196 267
jvfausto 21:3489cffad196 268 myPID.Compute(); // Does PID calculations
jvfausto 21:3489cffad196 269 double tempor = -Output+def; // Temporary value with the voltage output
jvfausto 21:3489cffad196 270 y->write(tempor); // Update y sent to chair
jvfausto 21:3489cffad196 271
jvfausto 21:3489cffad196 272 /* Prints to serial monitor the current angle and setpoint */
jvfausto 21:3489cffad196 273 out->printf("curr_yaw %f\r\r\n", curr_yaw);
jvfausto 21:3489cffad196 274 out->printf("Setpoint = %f \r\n", Setpoint);
jvfausto 21:3489cffad196 275
jvfausto 21:3489cffad196 276 wait(.05); // Small delay (milliseconds)
ryanlin97 12:921488918749 277 }
jvfausto 21:3489cffad196 278
jvfausto 21:3489cffad196 279 /* Saftey stop for wheelchair */
jvfausto 21:3489cffad196 280 Wheelchair::stop();
jvfausto 21:3489cffad196 281 out->printf("done \r\n");
jvfausto 21:3489cffad196 282 }
jvfausto 21:3489cffad196 283
jvfausto 21:3489cffad196 284 /* Counter-clockwise is -
jvfausto 21:3489cffad196 285 * Clockwise is +
jvfausto 21:3489cffad196 286 * Range of deg: 0 to 360
jvfausto 21:3489cffad196 287 * This constructor takes in an angle from user and adjusts for turning left
jvfausto 21:3489cffad196 288 */
jvfausto 21:3489cffad196 289 void Wheelchair::pid_left(int deg)
ryanlin97 12:921488918749 290 {
jvfausto 21:3489cffad196 291 bool overturn = false; //Boolean if angle under 0˚
ryanlin97 12:921488918749 292
jvfausto 21:3489cffad196 293 out->printf("pid Left\r\r\n");
jvfausto 21:3489cffad196 294 x->write(def); // Update x sent to chair to be stationary
jvfausto 21:3489cffad196 295 Setpoint = curr_yaw - deg; // Relative angle we want to turn
jvfausto 21:3489cffad196 296 pid_yaw = curr_yaw; // Sets pid_yaw to angle input from user
jvfausto 21:3489cffad196 297
jvfausto 21:3489cffad196 298 /* Turns on overturn boolean if setpoint less than 0˚ */
jvfausto 21:3489cffad196 299 if(Setpoint < 0)
jvfausto 21:3489cffad196 300 {
ryanlin97 12:921488918749 301 overturn = true;
ryanlin97 12:921488918749 302 }
jvfausto 21:3489cffad196 303
jvfausto 21:3489cffad196 304 myPID.SetTunings(5,0, 0.004); // Sets the constants for P and D
t1jain 33:f3585571f11e 305 myPID.SetOutputLimits(0,high-def-.12); // Limit is set to the differnce between def and low
jvfausto 21:3489cffad196 306 myPID.SetControllerDirection(REVERSE); // PID mode: Reverse
jvfausto 21:3489cffad196 307
jvfausto 21:3489cffad196 308 /* PID stops when approaching a litte more than desired angle */
jvfausto 21:3489cffad196 309 while(pid_yaw > Setpoint+3)
jvfausto 21:3489cffad196 310 {
jvfausto 21:3489cffad196 311 /* PID is set to correct angle range if angle less than 0˚ */
jvfausto 21:3489cffad196 312 if(overturn && curr_yaw > Setpoint+deg+1)
jvfausto 17:7f3b69300bb6 313 {
jvfausto 17:7f3b69300bb6 314 pid_yaw = curr_yaw - 360;
jvfausto 21:3489cffad196 315 }
jvfausto 21:3489cffad196 316 else
jvfausto 21:3489cffad196 317 {
jvfausto 21:3489cffad196 318 pid_yaw = curr_yaw;
jvfausto 21:3489cffad196 319 }
jvfausto 21:3489cffad196 320
jvfausto 21:3489cffad196 321 myPID.Compute(); // Does PID calculations
jvfausto 21:3489cffad196 322 double tempor = Output+def; // Temporary value with the voltage output
jvfausto 21:3489cffad196 323 y->write(tempor); // Update y sent to chair
jvfausto 21:3489cffad196 324
jvfausto 21:3489cffad196 325 /* Prints to serial monitor the current angle and setpoint */
jvfausto 17:7f3b69300bb6 326 out->printf("curr_yaw %f\r\n", curr_yaw);
jvfausto 21:3489cffad196 327 out->printf("Setpoint = %f \r\n", Setpoint);
jvfausto 21:3489cffad196 328
jvfausto 21:3489cffad196 329 wait(.05); // Small delay (milliseconds)
ryanlin97 12:921488918749 330 }
jvfausto 21:3489cffad196 331
jvfausto 21:3489cffad196 332 /* Saftey stop for wheelchair */
jvfausto 21:3489cffad196 333 Wheelchair::stop();
jvfausto 21:3489cffad196 334 out->printf("done \r\n");
ryanlin97 12:921488918749 335
jvfausto 21:3489cffad196 336 }
jvfausto 21:3489cffad196 337
jvfausto 21:3489cffad196 338 /* This constructor determines whether to turn left or right */
jvfausto 21:3489cffad196 339 void Wheelchair::pid_turn(int deg)
jvfausto 21:3489cffad196 340 {
jvfausto 21:3489cffad196 341
jvfausto 21:3489cffad196 342 /* Sets angle to coterminal angle for left turn if deg > 180
jvfausto 21:3489cffad196 343 * Sets angle to coterminal angle for right turn if deg < -180
jvfausto 21:3489cffad196 344 */
jvfausto 21:3489cffad196 345 if(deg > 180)
jvfausto 21:3489cffad196 346 {
ryanlin97 12:921488918749 347 deg -= 360;
ryanlin97 12:921488918749 348 }
jvfausto 21:3489cffad196 349 else if(deg < -180)
jvfausto 21:3489cffad196 350 {
jvfausto 21:3489cffad196 351 deg +=360;
ryanlin97 12:921488918749 352 }
ryanlin97 12:921488918749 353
jvfausto 21:3489cffad196 354 /* Makes sure angle inputted to function is positive */
ryanlin97 12:921488918749 355 int turnAmt = abs(deg);
jvfausto 21:3489cffad196 356
jvfausto 21:3489cffad196 357 /* Calls PID_right if deg > 0, else calls PID_left if deg < 0 */
jvfausto 21:3489cffad196 358 if(deg >= 0)
jvfausto 21:3489cffad196 359 {
jvfausto 21:3489cffad196 360 Wheelchair::pid_right(turnAmt);
jvfausto 21:3489cffad196 361 }
jvfausto 21:3489cffad196 362 else
jvfausto 21:3489cffad196 363 {
jvfausto 21:3489cffad196 364 Wheelchair::pid_left(turnAmt);
jvfausto 21:3489cffad196 365 }
ryanlin97 12:921488918749 366
jvfausto 21:3489cffad196 367 }
jvfausto 21:3489cffad196 368
jvfausto 21:3489cffad196 369 /* This constructor takes in distance to travel and adjust to move forward */
jvfausto 19:71a6621ee5c3 370 void Wheelchair::pid_forward(double mm)
jvfausto 17:7f3b69300bb6 371 {
jvfausto 21:3489cffad196 372 mm -= 20; // Makes sure distance does not overshoot
jvfausto 21:3489cffad196 373 Input = 0; // Initializes input to zero: Test latter w/o
jvfausto 21:3489cffad196 374 wheel->reset(); // Resets encoders so that they start at 0
jvfausto 21:3489cffad196 375
jvfausto 17:7f3b69300bb6 376 out->printf("pid foward\r\n");
jvfausto 21:3489cffad196 377
jvfausto 21:3489cffad196 378 double tempor; // Initializes Temporary variable for x input
jvfausto 21:3489cffad196 379 Setpoint = mm; // Initializes the setpoint to desired value
jvfausto 21:3489cffad196 380
jvfausto 21:3489cffad196 381 myPIDDistance.SetTunings(5.5,0, 0.0015); // Sets constants for P and D
jvfausto 21:3489cffad196 382 myPIDDistance.SetOutputLimits(0,high-def-.15); // Limit set to difference between high and def
jvfausto 21:3489cffad196 383 myPIDDistance.SetControllerDirection(DIRECT); // PID mode: Direct
jvfausto 21:3489cffad196 384
jvfausto 21:3489cffad196 385 y->write(def+offset); // Update y to make chair stationary
jvfausto 21:3489cffad196 386
jvfausto 21:3489cffad196 387 /* Chair stops moving when Setpoint is reached */
jvfausto 21:3489cffad196 388 while(Input < Setpoint){
jvfausto 21:3489cffad196 389
jvfausto 21:3489cffad196 390 if(out->readable()) // Emergency Break
jvfausto 21:3489cffad196 391 {
jvfausto 21:3489cffad196 392 break;
jvfausto 21:3489cffad196 393 }
jvfausto 17:7f3b69300bb6 394
jvfausto 21:3489cffad196 395 Input = wheel->getDistance(53.975); // Gets distance from Encoder into PID
jvfausto 21:3489cffad196 396 wait(.05); // Slight Delay: *****Test without
jvfausto 21:3489cffad196 397 myPIDDistance.Compute(); // Compute distance traveled by chair
jvfausto 21:3489cffad196 398
jvfausto 21:3489cffad196 399 tempor = Output + def; // Temporary output variable
jvfausto 21:3489cffad196 400 x->write(tempor); // Update x sent to chair
jvfausto 17:7f3b69300bb6 401
jvfausto 21:3489cffad196 402 /* Prints to serial monitor the distance traveled by chair */
jvfausto 19:71a6621ee5c3 403 out->printf("distance %f\r\n", Input);
jvfausto 17:7f3b69300bb6 404 }
ryanlin97 12:921488918749 405
jvfausto 17:7f3b69300bb6 406 }
jvfausto 21:3489cffad196 407
jvfausto 21:3489cffad196 408 /* This constructor returns the relative angular position of chair */
jvfausto 21:3489cffad196 409 double Wheelchair::getTwistZ()
jvfausto 17:7f3b69300bb6 410 {
jvfausto 21:3489cffad196 411 return imu->gyro_z();
jvfausto 21:3489cffad196 412 }
jvfausto 18:663b6d693252 413
jvfausto 21:3489cffad196 414 /* This constructor computes the relative angle for Twist message in ROS */
jvfausto 21:3489cffad196 415 void Wheelchair::pid_twistA()
jvfausto 21:3489cffad196 416 {
jvfausto 21:3489cffad196 417 /* Initialize variables for angle and update x,y sent to chair */
jvfausto 21:3489cffad196 418 char c;
jvfausto 21:3489cffad196 419 double temporA = def;
jvfausto 21:3489cffad196 420 y->write(def);
jvfausto 21:3489cffad196 421 x->write(def);
jvfausto 21:3489cffad196 422
jvfausto 21:3489cffad196 423 PIDAngularV.SetTunings(.00015,0, 0.00); // Sets the constants for P and D
jvfausto 21:3489cffad196 424 PIDAngularV.SetOutputLimits(-.1, .1); // Limit set to be in range specified
jvfausto 21:3489cffad196 425 PIDAngularV.SetControllerDirection(DIRECT); // PID mode: Direct
jvfausto 21:3489cffad196 426
jvfausto 21:3489cffad196 427 /* Computes angular position of wheelchair while turning */
jvfausto 21:3489cffad196 428 while(1)
jvfausto 21:3489cffad196 429 {
jvfausto 21:3489cffad196 430 yDesired = angularV;
jvfausto 21:3489cffad196 431
jvfausto 21:3489cffad196 432 /* Update and set all variable so that the chair is stationary
jvfausto 21:3489cffad196 433 * if the desired angle is zero
jvfausto 21:3489cffad196 434 */
jvfausto 21:3489cffad196 435 if(yDesired == 0)
jvfausto 18:663b6d693252 436 {
jvfausto 21:3489cffad196 437 x->write(def);
jvfausto 21:3489cffad196 438 y->write(def);
jvfausto 21:3489cffad196 439 yDesired = 0;
ryanlin97 8:381a4ec3fef8 440 return;
ryanlin97 7:5e38d43fbce3 441 }
jvfausto 21:3489cffad196 442
jvfausto 21:3489cffad196 443 /* Continuously updates with current angle measured by IMU */
jvfausto 21:3489cffad196 444 yIn = imu->gyro_z();
jvfausto 21:3489cffad196 445 PIDAngularV.Compute();
jvfausto 21:3489cffad196 446 temporA += yOut; // Temporary value with the voltage output
jvfausto 21:3489cffad196 447 y->write(temporA); // Update y sent to chair
jvfausto 21:3489cffad196 448
jvfausto 21:3489cffad196 449 //out->printf("temporA: %f, yDesired %f, angle: %f\r\n", temporA, yDesired, imu->gyro_z());
jvfausto 21:3489cffad196 450 wait(.05); // Small delay (milliseconds)
ryanlin97 6:0cd57bdd8fbc 451 }
jvfausto 21:3489cffad196 452
jvfausto 21:3489cffad196 453 }
ryanlin97 6:0cd57bdd8fbc 454
jvfausto 21:3489cffad196 455 /* This constructor computes the relative velocity for Twist message in ROS */
jvfausto 21:3489cffad196 456 void Wheelchair::pid_twistV()
ryanlin97 6:0cd57bdd8fbc 457 {
jvfausto 21:3489cffad196 458 /* Initializes variables as default */
jvfausto 21:3489cffad196 459 double temporV = def;
jvfausto 26:662693bd7f31 460 double temporS = def+offset;
jvfausto 21:3489cffad196 461 vDesiredS = 0;
jvfausto 21:3489cffad196 462 x->write(def);
jvfausto 21:3489cffad196 463 y->write(def);
jvfausto 21:3489cffad196 464 wheel->reset(); // Resets the encoders
jvfausto 21:3489cffad196 465 /* Sets the constants for P and D */
jvfausto 21:3489cffad196 466 PIDVelosity.SetTunings(.0005,0, 0.00);
jvfausto 26:662693bd7f31 467 PIDSlaveV.SetTunings(.005,0.000001, 0.000001);
jvfausto 21:3489cffad196 468
jvfausto 21:3489cffad196 469 /* Limits to the range specified */
jvfausto 21:3489cffad196 470 PIDVelosity.SetOutputLimits(-.005, .005);
jvfausto 21:3489cffad196 471 PIDSlaveV.SetOutputLimits(-.002, .002);
jvfausto 21:3489cffad196 472
jvfausto 21:3489cffad196 473 /* PID mode: Direct */
jvfausto 21:3489cffad196 474 PIDVelosity.SetControllerDirection(DIRECT);
jvfausto 21:3489cffad196 475 PIDSlaveV.SetControllerDirection(DIRECT);
jvfausto 21:3489cffad196 476
jvfausto 21:3489cffad196 477 while(1)
jvfausto 21:3489cffad196 478 {
jvfausto 21:3489cffad196 479 linearV = .7;
jvfausto 21:3489cffad196 480 test1 = linearV*100;
jvfausto 21:3489cffad196 481 vel = curr_vel;
jvfausto 21:3489cffad196 482 vDesired = linearV*100;
jvfausto 21:3489cffad196 483 if(out->readable())
jvfausto 21:3489cffad196 484 return;
jvfausto 21:3489cffad196 485 /* Update and set all variable so that the chair is stationary
jvfausto 21:3489cffad196 486 * if the velocity is zero
jvfausto 21:3489cffad196 487 */
jvfausto 21:3489cffad196 488 if(linearV == 0)
jvfausto 21:3489cffad196 489 {
jvfausto 21:3489cffad196 490 x->write(def);
jvfausto 21:3489cffad196 491 y->write(def);
ryanlin97 8:381a4ec3fef8 492
jvfausto 21:3489cffad196 493 vel = 0;
jvfausto 21:3489cffad196 494 vDesired = 0;
jvfausto 21:3489cffad196 495 dist_old = 0;
ryanlin97 8:381a4ec3fef8 496 return;
ryanlin97 8:381a4ec3fef8 497 }
jvfausto 21:3489cffad196 498
jvfausto 21:3489cffad196 499 if(vDesired >= 0)
jvfausto 21:3489cffad196 500 {
jvfausto 21:3489cffad196 501 PIDVelosity.SetTunings(.000004,0, 0.00); // Sets the constants for P and D
jvfausto 21:3489cffad196 502 PIDVelosity.SetOutputLimits(-.002, .002); // Limits to the range specified
jvfausto 21:3489cffad196 503 }
jvfausto 21:3489cffad196 504 else
jvfausto 21:3489cffad196 505 {
jvfausto 21:3489cffad196 506 PIDVelosity.SetTunings(.000015,0, 0.00); // Sets the constants for P and D
jvfausto 21:3489cffad196 507 PIDVelosity.SetOutputLimits(-.0005, .0005); // Limits to range specified
jvfausto 21:3489cffad196 508 }
jvfausto 21:3489cffad196 509
jvfausto 21:3489cffad196 510 /* Sets maximum value of variable to 1 */
jvfausto 21:3489cffad196 511 if(temporV >= 1.5)
jvfausto 21:3489cffad196 512 {
jvfausto 21:3489cffad196 513 temporV = 1.5;
ryanlin97 8:381a4ec3fef8 514 }
jvfausto 21:3489cffad196 515 /* Scales and makes some adjustments to velocity */
jvfausto 21:3489cffad196 516 vIn = curr_vel*100;
jvfausto 21:3489cffad196 517 vInS = curr_vel-curr_velS;
jvfausto 21:3489cffad196 518 PIDVelosity.Compute();
jvfausto 21:3489cffad196 519 PIDSlaveV.Compute();
jvfausto 21:3489cffad196 520 if(forwardSafety == 0)
jvfausto 21:3489cffad196 521 {
jvfausto 21:3489cffad196 522 temporV += vOut;
jvfausto 21:3489cffad196 523 temporS += vOutS;
jvfausto 21:3489cffad196 524
jvfausto 21:3489cffad196 525 /* Updates x,y sent to Wheelchair and for Odometry message in ROS */
jvfausto 21:3489cffad196 526 x->write(temporV);
jvfausto 21:3489cffad196 527 test2 = temporV;
jvfausto 21:3489cffad196 528 y->write(temporS);
jvfausto 21:3489cffad196 529 }
jvfausto 21:3489cffad196 530 else
jvfausto 21:3489cffad196 531 {
jvfausto 21:3489cffad196 532 x->write(def);
jvfausto 21:3489cffad196 533 y->write(def);
jvfausto 21:3489cffad196 534 }
jvfausto 21:3489cffad196 535 //out->printf("Velosity: %f, Velosity2: %f, temporV %f, temporS %f\r\n", curr_vel, curr_velS, temporV, temporS);
jvfausto 21:3489cffad196 536 Wheelchair::odomMsg();
jvfausto 21:3489cffad196 537 wait(.01); // Small delay (milliseconds)
ryanlin97 6:0cd57bdd8fbc 538 }
ryanlin97 11:d14a1f7f1297 539 }
ryanlin97 11:d14a1f7f1297 540
jvfausto 21:3489cffad196 541 /* This constructor calculates the relative position of the chair everytime the encoders reset
jvfausto 21:3489cffad196 542 * by setting its old position as the origin to calculate the new position
jvfausto 21:3489cffad196 543 */
jvfausto 21:3489cffad196 544 void Wheelchair::odomMsg()
ryanlin97 11:d14a1f7f1297 545 {
jvfausto 21:3489cffad196 546 double dist_new = curr_pos;
jvfausto 21:3489cffad196 547 double dist = dist_new-dist_old;
jvfausto 21:3489cffad196 548 double temp_x = dist*sin(z_angular*3.14159/180);
jvfausto 21:3489cffad196 549 double temp_y = dist*cos(z_angular*3.14159/180);
jvfausto 21:3489cffad196 550
jvfausto 21:3489cffad196 551 x_position += temp_x;
jvfausto 21:3489cffad196 552 y_position += temp_y;
ryanlin97 11:d14a1f7f1297 553
jvfausto 21:3489cffad196 554 dist_old = dist_new;
jvfausto 21:3489cffad196 555 }
jvfausto 21:3489cffad196 556
jvfausto 21:3489cffad196 557 /* This constructor prints the Odometry message to the serial monitor */
jvfausto 21:3489cffad196 558 void Wheelchair::showOdom()
jvfausto 21:3489cffad196 559 {
jvfausto 21:3489cffad196 560 out->printf("x %f, y %f, angle %f", x_position, y_position, z_angular);
jvfausto 21:3489cffad196 561 }
jvfausto 21:3489cffad196 562
jvfausto 21:3489cffad196 563 /* This constructor returns the approximate distance based on the wheel diameter */
jvfausto 21:3489cffad196 564 float Wheelchair::getDistance()
jvfausto 21:3489cffad196 565 {
jvfausto 21:3489cffad196 566 return wheel->getDistance(Diameter);
ryanlin97 6:0cd57bdd8fbc 567 }
ryanlin97 8:381a4ec3fef8 568
jvfausto 21:3489cffad196 569 /* This constructor resets the wheel encoder's */
jvfausto 21:3489cffad196 570 void Wheelchair::resetDistance()
jvfausto 21:3489cffad196 571 {
ryanlin97 12:921488918749 572 wheel->reset();
jvfausto 21:3489cffad196 573 }
jvfausto 21:3489cffad196 574
jvfausto 21:3489cffad196 575
jvfausto 21:3489cffad196 576 /*Predetermined paths For Demmo*/
jvfausto 21:3489cffad196 577 void Wheelchair::desk()
jvfausto 21:3489cffad196 578 {
jvfausto 19:71a6621ee5c3 579 Wheelchair::pid_forward(5461);
jvfausto 19:71a6621ee5c3 580 Wheelchair::pid_right(87);
jvfausto 19:71a6621ee5c3 581 Wheelchair::pid_forward(3658);
jvfausto 19:71a6621ee5c3 582 Wheelchair::pid_right(87);
jvfausto 19:71a6621ee5c3 583 Wheelchair::pid_forward(3658);
jvfausto 21:3489cffad196 584 }
jvfausto 21:3489cffad196 585
jvfausto 21:3489cffad196 586 void Wheelchair::kitchen()
jvfausto 21:3489cffad196 587 {
jvfausto 19:71a6621ee5c3 588 Wheelchair::pid_forward(5461);
jvfausto 20:f42db4ae16f0 589 Wheelchair::pid_right(87);
jvfausto 19:71a6621ee5c3 590 Wheelchair::pid_forward(3658);
jvfausto 19:71a6621ee5c3 591 Wheelchair::pid_left(90);
jvfausto 19:71a6621ee5c3 592 Wheelchair::pid_forward(305);
jvfausto 21:3489cffad196 593 }
jvfausto 21:3489cffad196 594
jvfausto 21:3489cffad196 595 void Wheelchair::desk_to_kitchen()
jvfausto 21:3489cffad196 596 {
jvfausto 19:71a6621ee5c3 597 Wheelchair::pid_right(180);
jvfausto 19:71a6621ee5c3 598 Wheelchair::pid_forward(3700);
jvfausto 21:3489cffad196 599 }