Advertisement
Cai_B

Computer Vision Approach to Line Following

Apr 21st, 2024 (edited)
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.42 KB | None | 0 0
  1.  
  2. // Include files for required libraries
  3. #include <stdio.h>
  4.  
  5.  
  6. #include "opencv_aee.hpp"
  7. #include "main.hpp"     // You can use this file for declaring defined values and functions
  8. #include "pi2c.h"
  9. using namespace std;
  10. using namespace cv;
  11. Pi2c car(0x22); // Configure the I2C interface to the Car as a global variable
  12. void setup(void)
  13. {
  14.     setupCamera(320, 240);  // Enable the camera for OpenCV
  15. }
  16.  
  17. int main( int argc, char** argv )
  18. {
  19.     setup();    // Call a setup function to prepare IO and devices
  20.  
  21.     namedWindow("Photo");   // Create a GUI window called photo
  22.    
  23.     //Intalises PID constants
  24.     float kp =70;
  25.     float ki =1.2;
  26.     float kd =1.3;
  27.  
  28.     float setpoint=0;
  29.     float error=0;
  30.     float previouserror=0;
  31.     float totalerror=0;
  32.     float u=0;
  33.  
  34.     int servoangle=90;
  35.     int centreangle=80;
  36.  
  37.     while(1)    // Main loop to perform image processing
  38.     {
  39.         Mat frame;
  40.         Mat frame_GREY;
  41.         Mat frame_HSV;
  42.         Mat hold;
  43.         int start;
  44.         int finish;
  45.         int16_t leftmotor =90;
  46.         int16_t rightmotor=90;
  47.         while(frame.empty())
  48.             frame = captureFrame(); // Capture a frame from the camera and store in a new matrix variable
  49.             cvtColor(frame, frame_HSV, COLOR_BGR2HSV); // Convert the image to HSV
  50.         inRange(frame_HSV, Scalar(0, 0, 0), Scalar(180, 102, 64), frame_GREY);//Isolates Black pixels in the frame
  51.         frame_GREY=frame_GREY(Rect(0,0,320,20));//Crops the frame to remove unnecessary noise
  52.         imshow("Photo", frame_GREY); //Display the image in the window
  53.  
  54.         hold=frame_GREY;// Stores a copy of the frame captured in the matrix 'hold' to be analysed
  55.         bool intial=true; //Bool flag
  56.         //First bit of for loop taken from manual to read a row
  57.         uchar* p = hold.ptr<uchar>(20); // Reads through each pixel on row 20 of the frame
  58.         for(int x = 0; x <hold.cols; x++)
  59.         {
  60.  
  61.             p[x]; // This is our B&W pixel data we can read it or write it
  62.             uchar pixel = p[x]; // read the data into pixel
  63.             if(pixel==255)
  64.             {
  65.                 if(intial)
  66.                 {
  67.                     start=x; //Stores the intial pixel number that reads the white line each time a while loop is run
  68.                     intial=false;// Sets boolean flag to false so for this frame this if statment can no longer be accessed
  69.                 }
  70.                 finish=x; // Stores the final pixel number all the way on the right that reads the line each time the while loop is run
  71.             }
  72.             else
  73.             {
  74.                 //cout<<" 0 ";
  75.             }
  76.         }
  77.         int center = (start + finish) / 2; // Calculates the pixel number that detects the centre of the line
  78.         int deviation = center - (hold.cols / 2); // Calculate deviation from the center of the frame
  79.         float controlSignal = static_cast<double>(deviation) / (hold.cols / 2); // Normalises deviation
  80.  
  81.         // Print the control signal
  82.      /*  cout << "Control Signal: " << controlSignal << endl;
  83.  
  84.        cout << start << " ";
  85.        cout << finish << " ";
  86.         cout << "Loop New" << endl;*/
  87.        
  88.         // Performs PID calculation
  89.         previouserror=error;
  90.         error=0.005-controlSignal;
  91.         totalerror=totalerror+error;
  92.  
  93.         u=(kp*error)+(ki*totalerror)+(kd*(error-previouserror));
  94.       //  cout<<" u "<<u<<endl;
  95.  
  96.         servoangle=centreangle+u;
  97.  
  98.  
  99.         // Stores the corrected Servo angle value and constant motor speeds in an Array
  100.         char data[6];
  101.         data[0] = (leftmotor >> 8)& 0xFF;   // leftMotor_speed16_9
  102.         data[1] = leftmotor & 0xFF;       // leftMotor_speed8_1
  103.         data[2] = (rightmotor >> 8)& 0xFF;  // rightMotor_speed16_9
  104.         data[3] = rightmotor & 0xFF;         // rightMotor_speed8_1
  105.         data[4] = (servoangle >> 8) & 0xFF;        // servoAngle16_9
  106.         data[5] = servoangle & 0xFF;               // servoAngle8_1
  107.  
  108.         car.i2cWrite(data, 6); // Sends the data to the Slave ESP32
  109.        // cout<<" I have passed through I2C"<<endl;
  110.  
  111.  
  112.         int key = cv::waitKey(1);   // Wait 1ms for a keypress (required to update windows)
  113.        // cout << "Servo angle: " << servoangle << endl;
  114.         key = (key==255) ? -1 : key;    // Check if the ESC key has been pressed
  115.         if (key == 27)
  116.             break;
  117.     }
  118.  
  119.     closeCV();  // Disable the camera and close any windows
  120.  
  121.     return 0;
  122. }
  123.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement