
Endelig kildekode med rettelser.
Fork of EndeligKildekode by
robot.cpp@0:d3dbe632b1a9, 2016-10-31 (annotated)
- Committer:
- kimnielsen
- Date:
- Mon Oct 31 09:57:07 2016 +0000
- Revision:
- 0:d3dbe632b1a9
- Child:
- 1:396a582e8861
Hej
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kimnielsen | 0:d3dbe632b1a9 | 1 | /* |
kimnielsen | 0:d3dbe632b1a9 | 2 | ============================================================================ |
kimnielsen | 0:d3dbe632b1a9 | 3 | Name : robot.cpp |
kimnielsen | 0:d3dbe632b1a9 | 4 | Author : Henning Slavensky |
kimnielsen | 0:d3dbe632b1a9 | 5 | Version : 0.1 |
kimnielsen | 0:d3dbe632b1a9 | 6 | Date : 13102016 |
kimnielsen | 0:d3dbe632b1a9 | 7 | Copyright : Open for all |
kimnielsen | 0:d3dbe632b1a9 | 8 | Description : Program to serve af platform for Pro1 2016 |
kimnielsen | 0:d3dbe632b1a9 | 9 | ============================================================================ |
kimnielsen | 0:d3dbe632b1a9 | 10 | */ |
kimnielsen | 0:d3dbe632b1a9 | 11 | #include "mbed.h" |
kimnielsen | 0:d3dbe632b1a9 | 12 | #include "HCSR04.h" |
kimnielsen | 0:d3dbe632b1a9 | 13 | #include "nucleo_servo.h" |
kimnielsen | 0:d3dbe632b1a9 | 14 | #include "hack_motor.h" |
kimnielsen | 0:d3dbe632b1a9 | 15 | #include <math.h> // nice when you got to work with real geometry stuff |
kimnielsen | 0:d3dbe632b1a9 | 16 | |
kimnielsen | 0:d3dbe632b1a9 | 17 | #define PI 3.141592 // definition of PI |
kimnielsen | 0:d3dbe632b1a9 | 18 | |
kimnielsen | 0:d3dbe632b1a9 | 19 | // PID definitions |
kimnielsen | 0:d3dbe632b1a9 | 20 | #define P_TERM 0.1 |
kimnielsen | 0:d3dbe632b1a9 | 21 | #define I_TERM 0 |
kimnielsen | 0:d3dbe632b1a9 | 22 | #define D_TERM 0.0 |
kimnielsen | 0:d3dbe632b1a9 | 23 | #define MAX 1.0 |
kimnielsen | 0:d3dbe632b1a9 | 24 | #define MIN 0 |
kimnielsen | 0:d3dbe632b1a9 | 25 | |
kimnielsen | 0:d3dbe632b1a9 | 26 | |
kimnielsen | 0:d3dbe632b1a9 | 27 | /* ------------------------------ |
kimnielsen | 0:d3dbe632b1a9 | 28 | Definitions for robot |
kimnielsen | 0:d3dbe632b1a9 | 29 | note that N,R,L maybe not have the most meaningful name |
kimnielsen | 0:d3dbe632b1a9 | 30 | but they follow the names from the theory for our |
kimnielsen | 0:d3dbe632b1a9 | 31 | robot lectures, and can be used in youa application |
kimnielsen | 0:d3dbe632b1a9 | 32 | ------------------------------ |
kimnielsen | 0:d3dbe632b1a9 | 33 | */ |
kimnielsen | 0:d3dbe632b1a9 | 34 | |
kimnielsen | 0:d3dbe632b1a9 | 35 | #define N 20 // ticks on wheel |
kimnielsen | 0:d3dbe632b1a9 | 36 | #define R 32.5 // radius = 32.5 mm |
kimnielsen | 0:d3dbe632b1a9 | 37 | #define L 133 // 133 mm distance between wheels |
kimnielsen | 0:d3dbe632b1a9 | 38 | |
kimnielsen | 0:d3dbe632b1a9 | 39 | //Coordinates for Robot with x and y |
kimnielsen | 0:d3dbe632b1a9 | 40 | #define starting_x = 0 |
kimnielsen | 0:d3dbe632b1a9 | 41 | #define starting_y = 0 |
kimnielsen | 0:d3dbe632b1a9 | 42 | #define second_x = 5 |
kimnielsen | 0:d3dbe632b1a9 | 43 | #define second_y = 4 |
kimnielsen | 0:d3dbe632b1a9 | 44 | #define third_x = 7 |
kimnielsen | 0:d3dbe632b1a9 | 45 | #define third_y = 1 |
kimnielsen | 0:d3dbe632b1a9 | 46 | |
kimnielsen | 0:d3dbe632b1a9 | 47 | Timer t; // define a timer t |
kimnielsen | 0:d3dbe632b1a9 | 48 | Serial pc(USBTX, USBRX); // not used here because we only have one serial |
kimnielsen | 0:d3dbe632b1a9 | 49 | // connection |
kimnielsen | 0:d3dbe632b1a9 | 50 | InterruptIn tacho_left(PC_3); // Set PC_3 to be interupt in for tacho left |
kimnielsen | 0:d3dbe632b1a9 | 51 | InterruptIn tacho_right(PC_2);// Set PC_2 to be interupt in for tacho right |
kimnielsen | 0:d3dbe632b1a9 | 52 | |
kimnielsen | 0:d3dbe632b1a9 | 53 | Wheel robot(PB_2, PB_1, PB_15, PB_14); // create an object of robot H-bridge |
kimnielsen | 0:d3dbe632b1a9 | 54 | // (M1A, M1B, M2A, M2B) |
kimnielsen | 0:d3dbe632b1a9 | 55 | |
kimnielsen | 0:d3dbe632b1a9 | 56 | /* --------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 57 | definition for analog power |
kimnielsen | 0:d3dbe632b1a9 | 58 | --------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 59 | */ |
kimnielsen | 0:d3dbe632b1a9 | 60 | AnalogIn ain(PC_4); |
kimnielsen | 0:d3dbe632b1a9 | 61 | DigitalOut dout(PB_13); |
kimnielsen | 0:d3dbe632b1a9 | 62 | DigitalOut greenout(PB_12); |
kimnielsen | 0:d3dbe632b1a9 | 63 | |
kimnielsen | 0:d3dbe632b1a9 | 64 | int stop=0; |
kimnielsen | 0:d3dbe632b1a9 | 65 | |
kimnielsen | 0:d3dbe632b1a9 | 66 | /* --------------------- |
kimnielsen | 0:d3dbe632b1a9 | 67 | Global variables |
kimnielsen | 0:d3dbe632b1a9 | 68 | -------------------- |
kimnielsen | 0:d3dbe632b1a9 | 69 | */ |
kimnielsen | 0:d3dbe632b1a9 | 70 | double right,left; |
kimnielsen | 0:d3dbe632b1a9 | 71 | double speed=0.5; |
kimnielsen | 0:d3dbe632b1a9 | 72 | double e = 0; // angle error |
kimnielsen | 0:d3dbe632b1a9 | 73 | int tickL = 0; // tick on left wheel |
kimnielsen | 0:d3dbe632b1a9 | 74 | int tickR = 0; // tick on right wheel |
kimnielsen | 0:d3dbe632b1a9 | 75 | |
kimnielsen | 0:d3dbe632b1a9 | 76 | /* ----------- |
kimnielsen | 0:d3dbe632b1a9 | 77 | Prototypes |
kimnielsen | 0:d3dbe632b1a9 | 78 | ----------- |
kimnielsen | 0:d3dbe632b1a9 | 79 | */ |
kimnielsen | 0:d3dbe632b1a9 | 80 | void init(); |
kimnielsen | 0:d3dbe632b1a9 | 81 | void tickLeft(); // read tick left |
kimnielsen | 0:d3dbe632b1a9 | 82 | void tickRight(); // read tick right |
kimnielsen | 0:d3dbe632b1a9 | 83 | float Dleft(); // distance left wheel |
kimnielsen | 0:d3dbe632b1a9 | 84 | float Dright(); // distance right wheel |
kimnielsen | 0:d3dbe632b1a9 | 85 | float Dcenter(); // Distance for center |
kimnielsen | 0:d3dbe632b1a9 | 86 | void get_to_goal ( ); // function to get to goal |
kimnielsen | 0:d3dbe632b1a9 | 87 | void read_analog(); // comes here every second |
kimnielsen | 0:d3dbe632b1a9 | 88 | |
kimnielsen | 0:d3dbe632b1a9 | 89 | Ticker T1; // create an object T1 of Ticker |
kimnielsen | 0:d3dbe632b1a9 | 90 | |
kimnielsen | 0:d3dbe632b1a9 | 91 | int main() |
kimnielsen | 0:d3dbe632b1a9 | 92 | { |
kimnielsen | 0:d3dbe632b1a9 | 93 | |
kimnielsen | 0:d3dbe632b1a9 | 94 | T1.attach(&read_analog, 1.0); // attach the address of the read_analog |
kimnielsen | 0:d3dbe632b1a9 | 95 | //function to read analog in every second |
kimnielsen | 0:d3dbe632b1a9 | 96 | |
kimnielsen | 0:d3dbe632b1a9 | 97 | tacho_left.rise(&tickLeft); // attach the address of the count function |
kimnielsen | 0:d3dbe632b1a9 | 98 | //to the falling edge |
kimnielsen | 0:d3dbe632b1a9 | 99 | tacho_right.rise(&tickRight); // attach the address of the count function |
kimnielsen | 0:d3dbe632b1a9 | 100 | //to the falling edge |
kimnielsen | 0:d3dbe632b1a9 | 101 | |
kimnielsen | 0:d3dbe632b1a9 | 102 | HCSR04 sensor(PC_5,PC_6); // Create an object of HCSR04 ultrasonic with pin |
kimnielsen | 0:d3dbe632b1a9 | 103 | // (echo,trigger) on pin PC_5, PC6 |
kimnielsen | 0:d3dbe632b1a9 | 104 | Servo servo1(PC_8); //Create an object of Servo class on pin PC_8 |
kimnielsen | 0:d3dbe632b1a9 | 105 | |
kimnielsen | 0:d3dbe632b1a9 | 106 | sensor.setRanges(2, 400); // set the range for Ultrasonic |
kimnielsen | 0:d3dbe632b1a9 | 107 | |
kimnielsen | 0:d3dbe632b1a9 | 108 | /* ----------------------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 109 | Demo of the servor and ulta sonic sensor |
kimnielsen | 0:d3dbe632b1a9 | 110 | ----------------------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 111 | */ |
kimnielsen | 0:d3dbe632b1a9 | 112 | wait_ms(2000); // just get time for you to enable your screeen |
kimnielsen | 0:d3dbe632b1a9 | 113 | servo1.set_position(0); // Servo right position (angle = 0 degree) for servo |
kimnielsen | 0:d3dbe632b1a9 | 114 | wait_ms (500); |
kimnielsen | 0:d3dbe632b1a9 | 115 | printf("\r\nDistance: %5.1f mm", sensor.getDistance_mm()); // display the |
kimnielsen | 0:d3dbe632b1a9 | 116 | //readings from ultra sonic at this position |
kimnielsen | 0:d3dbe632b1a9 | 117 | servo1.set_position(180); // Servo left position (angle = 180 degree) |
kimnielsen | 0:d3dbe632b1a9 | 118 | //for servo |
kimnielsen | 0:d3dbe632b1a9 | 119 | wait_ms (500); |
kimnielsen | 0:d3dbe632b1a9 | 120 | printf("\r\nDistance: %5.1f mm", sensor.getDistance_mm()); |
kimnielsen | 0:d3dbe632b1a9 | 121 | servo1.set_position(90); // Straight ahead (angle = 90 degree) for servo |
kimnielsen | 0:d3dbe632b1a9 | 122 | wait_ms (500); |
kimnielsen | 0:d3dbe632b1a9 | 123 | printf("\r\nDistance: %5.1f mm", sensor.getDistance_mm()); |
kimnielsen | 0:d3dbe632b1a9 | 124 | |
kimnielsen | 0:d3dbe632b1a9 | 125 | init(); // initialise parameters (just for you to remember if you need to) |
kimnielsen | 0:d3dbe632b1a9 | 126 | |
kimnielsen | 0:d3dbe632b1a9 | 127 | wait_ms(1000); //wait 1 secs here before you go |
kimnielsen | 0:d3dbe632b1a9 | 128 | t.start(); // start timer (just demo of how you can use a timer) |
kimnielsen | 0:d3dbe632b1a9 | 129 | |
kimnielsen | 0:d3dbe632b1a9 | 130 | /* ------------------ |
kimnielsen | 0:d3dbe632b1a9 | 131 | with PID |
kimnielsen | 0:d3dbe632b1a9 | 132 | ----------------- |
kimnielsen | 0:d3dbe632b1a9 | 133 | -- delete get_to_goal(); when you use without pid |
kimnielsen | 0:d3dbe632b1a9 | 134 | get_to_goal (); |
kimnielsen | 0:d3dbe632b1a9 | 135 | */ |
kimnielsen | 0:d3dbe632b1a9 | 136 | |
kimnielsen | 0:d3dbe632b1a9 | 137 | /* --------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 138 | without pid |
kimnielsen | 0:d3dbe632b1a9 | 139 | ------------------------ |
kimnielsen | 0:d3dbe632b1a9 | 140 | */ |
kimnielsen | 0:d3dbe632b1a9 | 141 | // delete between --- when you use it with pid |
kimnielsen | 0:d3dbe632b1a9 | 142 | // ------------------------------------------------------------ |
kimnielsen | 0:d3dbe632b1a9 | 143 | while (Dcenter() <= CLOSE_ENOUGH) { // while distance traveled is less than |
kimnielsen | 0:d3dbe632b1a9 | 144 | //target |
kimnielsen | 0:d3dbe632b1a9 | 145 | |
kimnielsen | 0:d3dbe632b1a9 | 146 | robot.FW(0.5,0.5); // set new values half speed on both wheels |
kimnielsen | 0:d3dbe632b1a9 | 147 | wait_ms(20); |
kimnielsen | 0:d3dbe632b1a9 | 148 | } |
kimnielsen | 0:d3dbe632b1a9 | 149 | // -------------------------------------------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 150 | |
kimnielsen | 0:d3dbe632b1a9 | 151 | robot.stop(); // stop the robot again |
kimnielsen | 0:d3dbe632b1a9 | 152 | printf("\n\rtimeused = %4d tickL= %4d tickR = %4d ", t.read_ms(),tickL, |
kimnielsen | 0:d3dbe632b1a9 | 153 | tickR); |
kimnielsen | 0:d3dbe632b1a9 | 154 | |
kimnielsen | 0:d3dbe632b1a9 | 155 | } |
kimnielsen | 0:d3dbe632b1a9 | 156 | |
kimnielsen | 0:d3dbe632b1a9 | 157 | void tickLeft() // udtate left tick on tacho interrupt |
kimnielsen | 0:d3dbe632b1a9 | 158 | { |
kimnielsen | 0:d3dbe632b1a9 | 159 | tickL++; |
kimnielsen | 0:d3dbe632b1a9 | 160 | } |
kimnielsen | 0:d3dbe632b1a9 | 161 | void tickRight() // udtate right tick on tacho interrupt |
kimnielsen | 0:d3dbe632b1a9 | 162 | { |
kimnielsen | 0:d3dbe632b1a9 | 163 | tickR++; |
kimnielsen | 0:d3dbe632b1a9 | 164 | } |
kimnielsen | 0:d3dbe632b1a9 | 165 | float Dleft() // Distance for left wheel |
kimnielsen | 0:d3dbe632b1a9 | 166 | { |
kimnielsen | 0:d3dbe632b1a9 | 167 | |
kimnielsen | 0:d3dbe632b1a9 | 168 | return 2*PI*R*tickL/N; |
kimnielsen | 0:d3dbe632b1a9 | 169 | } |
kimnielsen | 0:d3dbe632b1a9 | 170 | |
kimnielsen | 0:d3dbe632b1a9 | 171 | float Dright() // Distance for right wheel |
kimnielsen | 0:d3dbe632b1a9 | 172 | { |
kimnielsen | 0:d3dbe632b1a9 | 173 | |
kimnielsen | 0:d3dbe632b1a9 | 174 | return 2*PI*R*tickR/N; |
kimnielsen | 0:d3dbe632b1a9 | 175 | } |
kimnielsen | 0:d3dbe632b1a9 | 176 | |
kimnielsen | 0:d3dbe632b1a9 | 177 | float Dcenter() // Distance for center |
kimnielsen | 0:d3dbe632b1a9 | 178 | { |
kimnielsen | 0:d3dbe632b1a9 | 179 | return (Dleft()+Dright())/2; |
kimnielsen | 0:d3dbe632b1a9 | 180 | } |
kimnielsen | 0:d3dbe632b1a9 | 181 | |
kimnielsen | 0:d3dbe632b1a9 | 182 | |
kimnielsen | 0:d3dbe632b1a9 | 183 | void get_to_goal ( ) // function to get to goal |
kimnielsen | 0:d3dbe632b1a9 | 184 | { |
kimnielsen | 0:d3dbe632b1a9 | 185 | |
kimnielsen | 0:d3dbe632b1a9 | 186 | // PID init |
kimnielsen | 0:d3dbe632b1a9 | 187 | double power, derivative, proportional, integral, e_old; |
kimnielsen | 0:d3dbe632b1a9 | 188 | power=derivative=proportional=integral=e_old=0; |
kimnielsen | 0:d3dbe632b1a9 | 189 | |
kimnielsen | 0:d3dbe632b1a9 | 190 | while (Dcenter() < CLOSE_ENOUGH) { |
kimnielsen | 0:d3dbe632b1a9 | 191 | |
kimnielsen | 0:d3dbe632b1a9 | 192 | e = tickR-tickL; // error is difference between right tick and left tick |
kimnielsen | 0:d3dbe632b1a9 | 193 | // should be ajusted to your context, angle for robot |
kimnielsen | 0:d3dbe632b1a9 | 194 | // and instead of test Dcenter() in your while loop, test |
kimnielsen | 0:d3dbe632b1a9 | 195 | // for distance_to_goal() |
kimnielsen | 0:d3dbe632b1a9 | 196 | |
kimnielsen | 0:d3dbe632b1a9 | 197 | /* -------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 198 | * PID regulator |
kimnielsen | 0:d3dbe632b1a9 | 199 | * -------------------------- |
kimnielsen | 0:d3dbe632b1a9 | 200 | */ |
kimnielsen | 0:d3dbe632b1a9 | 201 | |
kimnielsen | 0:d3dbe632b1a9 | 202 | // Compute the proportional |
kimnielsen | 0:d3dbe632b1a9 | 203 | proportional = e; // get the error |
kimnielsen | 0:d3dbe632b1a9 | 204 | |
kimnielsen | 0:d3dbe632b1a9 | 205 | // Compute the integral |
kimnielsen | 0:d3dbe632b1a9 | 206 | integral += proportional; |
kimnielsen | 0:d3dbe632b1a9 | 207 | |
kimnielsen | 0:d3dbe632b1a9 | 208 | // Compute the derivative |
kimnielsen | 0:d3dbe632b1a9 | 209 | derivative = e - e_old; |
kimnielsen | 0:d3dbe632b1a9 | 210 | |
kimnielsen | 0:d3dbe632b1a9 | 211 | // Remember the last error. |
kimnielsen | 0:d3dbe632b1a9 | 212 | e_old = e; |
kimnielsen | 0:d3dbe632b1a9 | 213 | |
kimnielsen | 0:d3dbe632b1a9 | 214 | // Compute the power |
kimnielsen | 0:d3dbe632b1a9 | 215 | power = (proportional * (P_TERM)) + (integral * (I_TERM)) |
kimnielsen | 0:d3dbe632b1a9 | 216 | + (derivative * (D_TERM)); |
kimnielsen | 0:d3dbe632b1a9 | 217 | |
kimnielsen | 0:d3dbe632b1a9 | 218 | // Compute new speeds |
kimnielsen | 0:d3dbe632b1a9 | 219 | |
kimnielsen | 0:d3dbe632b1a9 | 220 | right = speed - power;//if power is 0, no error and same speed on wheels |
kimnielsen | 0:d3dbe632b1a9 | 221 | left = speed + power; |
kimnielsen | 0:d3dbe632b1a9 | 222 | |
kimnielsen | 0:d3dbe632b1a9 | 223 | |
kimnielsen | 0:d3dbe632b1a9 | 224 | // limit checks |
kimnielsen | 0:d3dbe632b1a9 | 225 | if (right < MIN) |
kimnielsen | 0:d3dbe632b1a9 | 226 | right = MIN; |
kimnielsen | 0:d3dbe632b1a9 | 227 | else if (right > MAX) |
kimnielsen | 0:d3dbe632b1a9 | 228 | right = MAX; |
kimnielsen | 0:d3dbe632b1a9 | 229 | |
kimnielsen | 0:d3dbe632b1a9 | 230 | if (left < MIN) |
kimnielsen | 0:d3dbe632b1a9 | 231 | left = MIN; |
kimnielsen | 0:d3dbe632b1a9 | 232 | else if (left > MAX) |
kimnielsen | 0:d3dbe632b1a9 | 233 | left = MAX; |
kimnielsen | 0:d3dbe632b1a9 | 234 | |
kimnielsen | 0:d3dbe632b1a9 | 235 | robot.FW(right,left); // set new positions |
kimnielsen | 0:d3dbe632b1a9 | 236 | printf("\n\r Dcenter = %3.2f tickL= %4d tickR = %4d left %3.2f right %3.2f", |
kimnielsen | 0:d3dbe632b1a9 | 237 | Dcenter(),tickL,tickR,left,right); |
kimnielsen | 0:d3dbe632b1a9 | 238 | |
kimnielsen | 0:d3dbe632b1a9 | 239 | wait_ms(20); // should be adusted to your context. Give the motor time |
kimnielsen | 0:d3dbe632b1a9 | 240 | // to do something before you react |
kimnielsen | 0:d3dbe632b1a9 | 241 | |
kimnielsen | 0:d3dbe632b1a9 | 242 | } |
kimnielsen | 0:d3dbe632b1a9 | 243 | |
kimnielsen | 0:d3dbe632b1a9 | 244 | t.stop(); // stop timer |
kimnielsen | 0:d3dbe632b1a9 | 245 | |
kimnielsen | 0:d3dbe632b1a9 | 246 | } |
kimnielsen | 0:d3dbe632b1a9 | 247 | |
kimnielsen | 0:d3dbe632b1a9 | 248 | void read_analog() // comes here every second in this case |
kimnielsen | 0:d3dbe632b1a9 | 249 | // could be flagged with global variables like "stop" |
kimnielsen | 0:d3dbe632b1a9 | 250 | { |
kimnielsen | 0:d3dbe632b1a9 | 251 | if(ain > 0.6f) { // 60% power, time for recharge |
kimnielsen | 0:d3dbe632b1a9 | 252 | dout = 1; |
kimnielsen | 0:d3dbe632b1a9 | 253 | stop=0; |
kimnielsen | 0:d3dbe632b1a9 | 254 | } else { |
kimnielsen | 0:d3dbe632b1a9 | 255 | dout = not dout; |
kimnielsen | 0:d3dbe632b1a9 | 256 | stop=1; // flash red led |
kimnielsen | 0:d3dbe632b1a9 | 257 | } |
kimnielsen | 0:d3dbe632b1a9 | 258 | |
kimnielsen | 0:d3dbe632b1a9 | 259 | if (ain==1.0f) greenout = 1; // full power |
kimnielsen | 0:d3dbe632b1a9 | 260 | else greenout = 0; |
kimnielsen | 0:d3dbe632b1a9 | 261 | } |
kimnielsen | 0:d3dbe632b1a9 | 262 | void init() // init your parameters |
kimnielsen | 0:d3dbe632b1a9 | 263 | { |
kimnielsen | 0:d3dbe632b1a9 | 264 | tickL=0; |
kimnielsen | 0:d3dbe632b1a9 | 265 | tickR=0; |
kimnielsen | 0:d3dbe632b1a9 | 266 | } |