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: mbed
Control/drivecontrol.cpp@15:151e59899221, 2017-05-20 (annotated)
- Committer:
- kolanery
- Date:
- Sat May 20 05:17:47 2017 +0000
- Revision:
- 15:151e59899221
- Parent:
- 14:a646667ac9ea
- Child:
- 16:c26d8e007df5
update working version
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| kolanery | 0:cb667de3a336 | 1 | #include "drivecontrol.h" | 
| kolanery | 0:cb667de3a336 | 2 | #include "Cell.h" | 
| kolanery | 0:cb667de3a336 | 3 | #include "ir_sensor.h" | 
| kolanery | 2:619b02232144 | 4 | #include "left_motor.h" | 
| kolanery | 2:619b02232144 | 5 | #include "right_motor.h" | 
| szh66 | 6:1bcfda49e146 | 6 | #include "pin_assignment.h" | 
| kolanery | 0:cb667de3a336 | 7 | |
| szh66 | 6:1bcfda49e146 | 8 | IRSensor leftIR(PA_8, PC_5); | 
| szh66 | 6:1bcfda49e146 | 9 | IRSensor rightIR(PB_0, PA_4); | 
| szh66 | 8:4a32fc9ee939 | 10 | //Encoder rightEncoder(PA_1, PA_0); | 
| szh66 | 8:4a32fc9ee939 | 11 | //Encoder leftEncoder(PC_9, PC_8); | 
| kolanery | 2:619b02232144 | 12 | LeftMotor * leftMotor; | 
| kolanery | 2:619b02232144 | 13 | RightMotor * rightMotor; | 
| kolanery | 0:cb667de3a336 | 14 | Cell * curr_cell; | 
| szh66 | 6:1bcfda49e146 | 15 | Serial pc(PA_9, PA_10); | 
| szh66 | 6:1bcfda49e146 | 16 | |
| kolanery | 13:a1a3418c07f3 | 17 | // Sensor offsets | 
| kolanery | 15:151e59899221 | 18 | float FRONT_SENSOR_THRES = 7.0f, SENSOR_ERROR_OFFSET = 0.0f; | 
| kolanery | 14:a646667ac9ea | 19 | float LEFT_WALL_THRES = 0.552f, RIGHT_WALL_THRES = 0.198f; | 
| kolanery | 15:151e59899221 | 20 | float RIGHT_SIDE_WALL_THRES = 0.3f, LEFT_SIDE_WALL_THRES = 0.3f; | 
| kolanery | 13:a1a3418c07f3 | 21 | |
| kolanery | 13:a1a3418c07f3 | 22 | // Motor speed offsets | 
| kolanery | 13:a1a3418c07f3 | 23 | float left_speed, right_speed, motor_speed; | 
| kolanery | 14:a646667ac9ea | 24 | float MOTOR_BASE_SPEED = 10.0f; | 
| kolanery | 14:a646667ac9ea | 25 | float cool_down_offset = 0.0f; | 
| kolanery | 7:7215adbae3da | 26 | |
| kolanery | 13:a1a3418c07f3 | 27 | namespace pid_controller { | 
| kolanery | 13:a1a3418c07f3 | 28 | // PID Constants | 
| kolanery | 13:a1a3418c07f3 | 29 | float error_p = 0.0f, old_error_p = 0.0f, old_error_d = 0.0f, error_d = 0.0f; | 
| kolanery | 13:a1a3418c07f3 | 30 | float total_error = 0.0f; | 
| kolanery | 15:151e59899221 | 31 | float P = 18.0f, D = 5.0f; | 
| kolanery | 13:a1a3418c07f3 | 32 | |
| kolanery | 7:7215adbae3da | 33 | void navigate() { | 
| kolanery | 7:7215adbae3da | 34 | bool has_left_wall = leftDiagonalIR.readIR() > LEFT_WALL_THRES; | 
| kolanery | 7:7215adbae3da | 35 | bool has_right_wall = rightDiagonalIR.readIR() > RIGHT_WALL_THRES; | 
| kolanery | 7:7215adbae3da | 36 | |
| kolanery | 7:7215adbae3da | 37 | if (has_left_wall && has_right_wall) { | 
| kolanery | 7:7215adbae3da | 38 | if (rightDiagonalIR - RIGHT_WALL_THRES < 0) { | 
| kolanery | 7:7215adbae3da | 39 | error_p = rightDiagonalIR - RIGHT_WALL_THRES; | 
| kolanery | 7:7215adbae3da | 40 | } | 
| kolanery | 7:7215adbae3da | 41 | else if (leftDiagonalIR - LEFT_WALL_THRES < 0) { | 
| kolanery | 7:7215adbae3da | 42 | error_p = leftDiagonalIR - LEFT_WALL_THRES; | 
| kolanery | 7:7215adbae3da | 43 | } | 
| kolanery | 7:7215adbae3da | 44 | else{ | 
| kolanery | 7:7215adbae3da | 45 | error_p = rightDiagonalIR - leftDiagonalIR; | 
| kolanery | 7:7215adbae3da | 46 | } | 
| kolanery | 7:7215adbae3da | 47 | error_d = error_p - old_error_p; | 
| kolanery | 7:7215adbae3da | 48 | } | 
| kolanery | 7:7215adbae3da | 49 | else if (has_left_wall) { | 
| kolanery | 7:7215adbae3da | 50 | error_p = 2 * (LEFT_WALL_THRES - leftDiagonalIR.readIR()); | 
| kolanery | 7:7215adbae3da | 51 | error_d = error_p - old_error_p; | 
| kolanery | 7:7215adbae3da | 52 | } | 
| kolanery | 7:7215adbae3da | 53 | else if (has_right_wall) { | 
| kolanery | 7:7215adbae3da | 54 | error_p = 2 * (rightDiagonalIR.readIR() - RIGHT_WALL_THRES); | 
| kolanery | 7:7215adbae3da | 55 | error_d = error_p - old_error_p; | 
| kolanery | 7:7215adbae3da | 56 | } | 
| kolanery | 7:7215adbae3da | 57 | else if (!has_left_wall && !has_right_wall) { | 
| kolanery | 7:7215adbae3da | 58 | error_p = 0; | 
| kolanery | 7:7215adbae3da | 59 | error_d = 0; | 
| kolanery | 7:7215adbae3da | 60 | } | 
| kolanery | 7:7215adbae3da | 61 | total_error = P * error_p + D * (error_d - old_error_d); | 
| kolanery | 7:7215adbae3da | 62 | old_error_p = error_p; | 
| kolanery | 7:7215adbae3da | 63 | old_error_d = error_d; | 
| kolanery | 7:7215adbae3da | 64 | |
| kolanery | 14:a646667ac9ea | 65 | //MOTOR_BASE_SPEED -= cool_down_offset; | 
| kolanery | 14:a646667ac9ea | 66 | if(total_error < 5.0f){ | 
| kolanery | 7:7215adbae3da | 67 | leftMotor -> speed(MOTOR_BASE_SPEED - total_error); | 
| kolanery | 7:7215adbae3da | 68 | rightMotor -> speed(MOTOR_BASE_SPEED + total_error); | 
| kolanery | 14:a646667ac9ea | 69 | |
| kolanery | 14:a646667ac9ea | 70 | //leftMotor -> speed(MOTOR_BASE_SPEED - total_error); | 
| kolanery | 14:a646667ac9ea | 71 | //rightMotor -> speed(MOTOR_BASE_SPEED + total_error); | 
| kolanery | 7:7215adbae3da | 72 | } | 
| kolanery | 7:7215adbae3da | 73 | else{ | 
| kolanery | 7:7215adbae3da | 74 | leftMotor->speed(MOTOR_BASE_SPEED); | 
| kolanery | 7:7215adbae3da | 75 | rightMotor->speed(MOTOR_BASE_SPEED); | 
| kolanery | 14:a646667ac9ea | 76 | //leftMotor->speed(MOTOR_BASE_SPEED); | 
| kolanery | 14:a646667ac9ea | 77 | //rightMotor->speed(MOTOR_BASE_SPEED); | 
| kolanery | 14:a646667ac9ea | 78 | } | 
| kolanery | 14:a646667ac9ea | 79 | |
| kolanery | 14:a646667ac9ea | 80 | |
| kolanery | 14:a646667ac9ea | 81 | } | 
| kolanery | 14:a646667ac9ea | 82 | |
| kolanery | 14:a646667ac9ea | 83 | void cool_down_speed() { | 
| kolanery | 14:a646667ac9ea | 84 | if (cool_down_offset < 5.0f) { | 
| kolanery | 14:a646667ac9ea | 85 | cool_down_offset += 2.0f; | 
| kolanery | 7:7215adbae3da | 86 | } | 
| ryan_whr | 12:6f48afe41cd9 | 87 | } | 
| ryan_whr | 12:6f48afe41cd9 | 88 | |
| kolanery | 13:a1a3418c07f3 | 89 | void one_cell_turned(){ | 
| ryan_whr | 12:6f48afe41cd9 | 90 | leftEncoder.reset(); | 
| ryan_whr | 12:6f48afe41cd9 | 91 | rightEncoder.reset(); | 
| ryan_whr | 12:6f48afe41cd9 | 92 | while(leftEncoder.getEncoderDistance(1)<-46000 & leftEncoder.getEncoderDistance(1)<46000){ | 
| ryan_whr | 12:6f48afe41cd9 | 93 | //Do nothing | 
| ryan_whr | 12:6f48afe41cd9 | 94 | } | 
| kolanery | 7:7215adbae3da | 95 | } | 
| kolanery | 7:7215adbae3da | 96 | |
| kolanery | 13:a1a3418c07f3 | 97 | // should use this method as the exit condition | 
| kolanery | 13:a1a3418c07f3 | 98 | // in the pid_controller::navigate() method | 
| kolanery | 13:a1a3418c07f3 | 99 | // resets the pid, encoders, etc. | 
| kolanery | 13:a1a3418c07f3 | 100 | void one_cell_traversed() { | 
| kolanery | 13:a1a3418c07f3 | 101 | leftEncoder.reset(); | 
| kolanery | 13:a1a3418c07f3 | 102 | rightEncoder.reset(); | 
| kolanery | 13:a1a3418c07f3 | 103 | old_error_p = old_error_d = total_error = 0.0f; | 
| kolanery | 13:a1a3418c07f3 | 104 | } | 
| kolanery | 13:a1a3418c07f3 | 105 | |
| kolanery | 13:a1a3418c07f3 | 106 | // TODO | 
| kolanery | 14:a646667ac9ea | 107 | void turn (bool turn_right) { | 
| kolanery | 15:151e59899221 | 108 | float MOTOR_TURN_SPEED = 10.0f; | 
| kolanery | 15:151e59899221 | 109 | |
| kolanery | 15:151e59899221 | 110 | if (turn_right) { | 
| kolanery | 14:a646667ac9ea | 111 | leftMotor -> speed(MOTOR_TURN_SPEED); | 
| kolanery | 15:151e59899221 | 112 | rightMotor -> speed(-MOTOR_TURN_SPEED); | 
| kolanery | 7:7215adbae3da | 113 | } | 
| kolanery | 14:a646667ac9ea | 114 | else { | 
| kolanery | 15:151e59899221 | 115 | leftMotor -> speed(-MOTOR_TURN_SPEED); | 
| kolanery | 14:a646667ac9ea | 116 | rightMotor -> speed(MOTOR_TURN_SPEED); | 
| kolanery | 7:7215adbae3da | 117 | } | 
| kolanery | 7:7215adbae3da | 118 | } | 
| kolanery | 7:7215adbae3da | 119 | } | 
| kolanery | 7:7215adbae3da | 120 | |
| kolanery | 0:cb667de3a336 | 121 | // Currently only have the x, y position fields for | 
| kolanery | 0:cb667de3a336 | 122 | // each cell. | 
| kolanery | 0:cb667de3a336 | 123 | DriveControl::DriveControl (int start_x, int start_y) { | 
| kolanery | 0:cb667de3a336 | 124 | curr_cell = new Cell (start_x, start_y); | 
| kolanery | 2:619b02232144 | 125 | leftMotor= new LeftMotor(); | 
| kolanery | 2:619b02232144 | 126 | rightMotor = new RightMotor(); | 
| kolanery | 0:cb667de3a336 | 127 | } | 
| kolanery | 0:cb667de3a336 | 128 | |
| kolanery | 0:cb667de3a336 | 129 | // Defines the next cell to traverse. | 
| kolanery | 0:cb667de3a336 | 130 | Cell * next_cell() { | 
| kolanery | 0:cb667de3a336 | 131 | return curr_cell; | 
| kolanery | 0:cb667de3a336 | 132 | } | 
| kolanery | 0:cb667de3a336 | 133 | |
| kolanery | 0:cb667de3a336 | 134 | void DriveControl::turn_left() { | 
| kolanery | 0:cb667de3a336 | 135 | // TODO: Add PID Control | 
| kolanery | 14:a646667ac9ea | 136 | pid_controller::turn(false); | 
| kolanery | 0:cb667de3a336 | 137 | } | 
| kolanery | 0:cb667de3a336 | 138 | |
| kolanery | 0:cb667de3a336 | 139 | int DriveControl::get_next_direction() { | 
| kolanery | 0:cb667de3a336 | 140 | // TODO: Define the direction based on heuristic eval. | 
| kolanery | 0:cb667de3a336 | 141 | return 1; | 
| kolanery | 0:cb667de3a336 | 142 | } | 
| kolanery | 0:cb667de3a336 | 143 | |
| kolanery | 0:cb667de3a336 | 144 | int DriveControl::get_next_state(int state) { | 
| kolanery | 2:619b02232144 | 145 | // Simply drives the mouse for testing | 
| kolanery | 15:151e59899221 | 146 | //return DRIVE; | 
| kolanery | 0:cb667de3a336 | 147 | } | 
| kolanery | 0:cb667de3a336 | 148 | |
| kolanery | 15:151e59899221 | 149 | void DriveControl::print_serial_ports(){ | 
| kolanery | 15:151e59899221 | 150 | pc.printf("LEFT Encoder Reading %d\n\r", leftEncoder.getEncoderDistance(1)); | 
| kolanery | 15:151e59899221 | 151 | pc.printf("RIGHT Encoder Reading %d\n\r", rightEncoder.getEncoderDistance(0)); | 
| kolanery | 15:151e59899221 | 152 | /* | 
| kolanery | 14:a646667ac9ea | 153 | pc.printf("FRONT TOP RIGHT IRSensor %f\n\r", rightFrontIR.readIR() * 1000); | 
| kolanery | 15:151e59899221 | 154 | pc.printf("FRONT TOP LEFT IRSensor %f\n\r", leftFrontIR.readIR() * 10); | 
| kolanery | 14:a646667ac9ea | 155 | pc.printf("LEFT Diagonal Sensor %f\n\r", leftDiagonalIR.readIR()); | 
| kolanery | 14:a646667ac9ea | 156 | pc.printf("RIGHT Diagonal Sensor %f\n\r", rightDiagonalIR.readIR()); | 
| kolanery | 14:a646667ac9ea | 157 | pc.printf("LEFT SIDE Sensor %f\n\r", leftIR.readIR()); | 
| kolanery | 14:a646667ac9ea | 158 | pc.printf("RIGHT SIDE Sensor %f\n\r", rightIR.readIR()); | 
| kolanery | 15:151e59899221 | 159 | */ | 
| szh66 | 8:4a32fc9ee939 | 160 | } | 
| szh66 | 8:4a32fc9ee939 | 161 | |
| kolanery | 0:cb667de3a336 | 162 | void DriveControl::turn_right() { | 
| kolanery | 4:73510c7fa316 | 163 | // TODO: Add PID Control | 
| kolanery | 14:a646667ac9ea | 164 | pid_controller::turn(true); | 
| kolanery | 7:7215adbae3da | 165 | } | 
| kolanery | 7:7215adbae3da | 166 | |
| kolanery | 7:7215adbae3da | 167 | void DriveControl::turn_around() { | 
| kolanery | 7:7215adbae3da | 168 | // TODO: Add PID Control | 
| kolanery | 15:151e59899221 | 169 | //pid_controller::turn(TURN_AROUND); | 
| kolanery | 0:cb667de3a336 | 170 | } | 
| kolanery | 0:cb667de3a336 | 171 | |
| kolanery | 0:cb667de3a336 | 172 | void DriveControl::stop() { | 
| kolanery | 2:619b02232144 | 173 | leftMotor->stop(); | 
| kolanery | 2:619b02232144 | 174 | rightMotor->stop(); | 
| kolanery | 0:cb667de3a336 | 175 | } | 
| kolanery | 0:cb667de3a336 | 176 | |
| kolanery | 14:a646667ac9ea | 177 | void DriveControl::resetEncoders() { | 
| kolanery | 14:a646667ac9ea | 178 | leftEncoder.resetEncoders(); | 
| kolanery | 14:a646667ac9ea | 179 | rightEncoder.resetEncoders(); | 
| kolanery | 14:a646667ac9ea | 180 | } | 
| kolanery | 14:a646667ac9ea | 181 | |
| kolanery | 7:7215adbae3da | 182 | void DriveControl::drive_forward() { | 
| kolanery | 14:a646667ac9ea | 183 | /* | 
| kolanery | 14:a646667ac9ea | 184 | float COOL_DOWN = 1.0f; | 
| kolanery | 14:a646667ac9ea | 185 | if ((rightFrontIR.readIR() * 1000) > COOL_DOWN) { | 
| kolanery | 14:a646667ac9ea | 186 | pid_controller::cool_down_speed(); | 
| kolanery | 14:a646667ac9ea | 187 | } | 
| kolanery | 14:a646667ac9ea | 188 | */ | 
| kolanery | 7:7215adbae3da | 189 | pid_controller::navigate(); | 
| kolanery | 14:a646667ac9ea | 190 | |
| kolanery | 14:a646667ac9ea | 191 | } | 
| kolanery | 14:a646667ac9ea | 192 | |
| kolanery | 14:a646667ac9ea | 193 | bool DriveControl::should_stop_drive_forward() { | 
| kolanery | 14:a646667ac9ea | 194 | float SHOULD_STOP = 7.0f; | 
| kolanery | 14:a646667ac9ea | 195 | /* | 
| kolanery | 14:a646667ac9ea | 196 | if ((rightFrontIR.readIR() * 1000) > SHOULD_STOP) { | 
| kolanery | 14:a646667ac9ea | 197 | stop(); | 
| kolanery | 14:a646667ac9ea | 198 | cool_down_offset = 0.0f; | 
| kolanery | 14:a646667ac9ea | 199 | }*/ | 
| kolanery | 14:a646667ac9ea | 200 | return (rightFrontIR.readIR() * 1000) > SHOULD_STOP; | 
| kolanery | 14:a646667ac9ea | 201 | } | 
| kolanery | 14:a646667ac9ea | 202 | |
| kolanery | 14:a646667ac9ea | 203 | bool DriveControl::should_finish_turn_right() { | 
| kolanery | 15:151e59899221 | 204 | // bool should_turn = (leftEncoder.getEncoderDistance(1) < -16000) || (rightEncoder.getEncoderDistance(0) < -16000); | 
| kolanery | 15:151e59899221 | 205 | int max = (leftEncoder.getEncoderDistance(1) < rightEncoder.getEncoderDistance(0)) | 
| kolanery | 15:151e59899221 | 206 | ? rightEncoder.getEncoderDistance(0) : leftEncoder.getEncoderDistance(1); | 
| kolanery | 15:151e59899221 | 207 | return max < -16000; | 
| kolanery | 15:151e59899221 | 208 | |
| kolanery | 15:151e59899221 | 209 | //return should_turn; | 
| kolanery | 14:a646667ac9ea | 210 | } | 
| kolanery | 14:a646667ac9ea | 211 | |
| kolanery | 14:a646667ac9ea | 212 | bool DriveControl::should_finish_turn_left() { | 
| kolanery | 15:151e59899221 | 213 | int min_two = (leftEncoder.getEncoderDistance(1) > rightEncoder.getEncoderDistance(0)) | 
| kolanery | 15:151e59899221 | 214 | ? rightEncoder.getEncoderDistance(0) : leftEncoder.getEncoderDistance(1); | 
| kolanery | 15:151e59899221 | 215 | //return leftEncoder.getEncoderDistance(1) > 15000 | 
| kolanery | 15:151e59899221 | 216 | // || rightEncoder.getEncoderDistance(0) > 15000; | 
| kolanery | 15:151e59899221 | 217 | return min_two > 16000; | 
| kolanery | 4:73510c7fa316 | 218 | } | 
| kolanery | 4:73510c7fa316 | 219 | |
| kolanery | 0:cb667de3a336 | 220 | bool DriveControl::has_front_wall() { | 
| kolanery | 15:151e59899221 | 221 | bool right_front_wall = (rightFrontIR.readIR() * 1000) > FRONT_SENSOR_THRES; | 
| kolanery | 15:151e59899221 | 222 | bool left_front_wall = (leftFrontIR.readIR() * 10) > FRONT_SENSOR_THRES; | 
| kolanery | 15:151e59899221 | 223 | return right_front_wall || left_front_wall; | 
| kolanery | 0:cb667de3a336 | 224 | } | 
| kolanery | 0:cb667de3a336 | 225 | |
| kolanery | 0:cb667de3a336 | 226 | bool DriveControl::has_left_wall() { | 
| kolanery | 15:151e59899221 | 227 | return leftIR.readIR() > LEFT_SIDE_WALL_THRES; | 
| kolanery | 0:cb667de3a336 | 228 | } | 
| kolanery | 0:cb667de3a336 | 229 | |
| kolanery | 0:cb667de3a336 | 230 | bool DriveControl::has_right_wall() { | 
| kolanery | 15:151e59899221 | 231 | return rightIR.readIR() > RIGHT_SIDE_WALL_THRES; | 
| kolanery | 0:cb667de3a336 | 232 | } |