line_following
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
line_following [2025/02/20 12:20] – [Section02 - IR Sensor] arim | line_following [2025/02/20 12:44] (current) – [Special Section - Wall Following with PID Control] arim | ||
---|---|---|---|
Line 207: | Line 207: | ||
===== Special Section - Wall Following with PID Control | ===== Special Section - Wall Following with PID Control | ||
- | Code: | + | Code: {{ : |
\\ Video: [[https:// | \\ Video: [[https:// | ||
\\ {{ : | \\ {{ : | ||
+ | \\ | ||
+ | **- US sensor** | ||
+ | \\ Ultrasonic sensor is used to measure the distance to an object using ultrasound. The sensor emits an ultrasonic signal, which strikes the object and then returns to the sensor as a reflection. By measuring the time it takes for the signal to be transmitted and received, the distance to the object can be calculated. The range of the sensor values is from 0 to 255, where a smaller value indicates a closer distance. | ||
+ | \\ | ||
+ | |||
+ | \\ **- Save sensor data and display is as a graph** | ||
\\ {{ : | \\ {{ : | ||
+ | \\ The distance data measured by the sensor can be saved as a CSV file and visualized as a graph. This makes it easier to observe changes and helps determine how to adjust the PID gain values effectively. The graph above shows the distance from the wall while performing wall following at a target distance of 10 cm. By analyzing this data, the PID gain values can be adjusted to achieve more stable control. | ||
+ | |||
+ | // | ||
+ | fileName = " | ||
+ | result = CreateFile(fileName, | ||
+ | | ||
+ | //Overwrite existing file | ||
+ | while (result == LDR_FILEEXISTS) { //if the file already exists | ||
+ | CloseFile(fileHandle); | ||
+ | DeleteFile(fileName); | ||
+ | result = CreateFile(fileName, | ||
+ | } | ||
+ | | ||
+ | //Write column headers | ||
+ | fileHeader = " | ||
+ | WriteLnString(fileHandle, | ||
+ | | ||
+ | //Convert data to string and write to file | ||
+ | strIteration = FormatNum(" | ||
+ | strxWall = FormatNum(" | ||
+ | text = StrCat(strIteration, | ||
+ | | ||
+ | result = WriteLnString(fileHandle, | ||
+ | if(result == LDR_EOFEXPECTED) CloseFile(fileHandle); | ||
\\ | \\ | ||
+ | |||
+ | \\ **- Wall Following with PID** | ||
+ | \\ Refer to this example for the PID gain values, but adjust them to best suit your Domabot. | ||
+ | |||
+ | //Variable initializations --------------------------------------------------- | ||
+ | xWall = 0; // | ||
+ | dWall = 10; //Desired distance from wall [cm] | ||
+ | wKp = 1.25; //Wall P gain e.g. (PID) = [1.5, 0.005, 30.0] | ||
+ | wKi = 0.001; | ||
+ | wKd = 7.5; //Wall D gain | ||
+ | | ||
+ | // | ||
+ | wE = xWall - dWall; | ||
+ | wEInt +=wE; | ||
+ | wEDot = wE - wEPrev; | ||
+ | wCorr = (wKp * wE) + (wKi * wEInt) + (wKd * wEDot); | ||
+ | | ||
+ | //(1A) Check for motor staturation i.e. resulting wCorr forces | ||
+ | //motor getting > 2*speedBase (if speedBase > 50, this means >100) | ||
+ | if(wCorr > 0 && wCorr > speedBase) { | ||
+ | wCorr = speedBase; | ||
+ | //So Motor C speed min will be 0 | ||
+ | }; | ||
+ | if(wCorr < 0 && wCorr < -speedBase) { | ||
+ | wCorr = -speedBase; | ||
+ | //So Motor C speed min will be 0 | ||
+ | }; | ||
+ | //(1B) If PID gains all zero, then wCorr = 0 so do bang-bang | ||
+ | if(wCorr == 0 && xWall < dWall) { | ||
+ | wCorr = -speedBase; | ||
+ | }; | ||
+ | if(wCorr == 0 && xWall >= dWall) { | ||
+ | wCorr = speedBase; | ||
+ | }; | ||
+ | | ||
+ | // | ||
+ | speedA = speedBase + wCorr; | ||
+ | speedC = speedBase - wCorr; | ||
+ | OnFwd(OUT_C, | ||
+ | OnFwd(OUT_A, | ||
+ | | ||
+ | //(3) update wall errors for next derivative calculation | ||
+ | wEPrev = wE; |
line_following.1740082802.txt.gz · Last modified: by arim