Stap 7: Vereenvoudiging (optimaliseren) het pad
Laten we terugkeren naar ons voorbeeld. Op zoek naar de eerste groep van kruispunten, we realiseerden ons dat het de eerste links tak is in feite een "doodlopende weg" en dus, als de Robot in plaats van een "links-rug-Left" alleen bij die eerste kruispunt rechtdoor doorgegeven, veel energie en tijd zou worden bespaard! Met andere woorden, een reeks "LBL" in feite zou hetzelfde zijn als "S". Dat is precies hoe het volledige pad kan worden geoptimaliseerd. Als u analise alle mogelijkheden waar een "U-bocht" wordt gebruikt, de set van 3 kruispunten waar deze "ommekeer" ("B") wordt weergegeven ("xBx") kunnen worden teruggebracht tot slechts één.
Het bovenstaande is slechts een voorbeeld, balg vindt u de volledige lijst van mogelijkheden (proberen):
- LBR = B
- LBS = R
- RBL = B
- SBL = R
- SBS = B
- LBL = S
Het volledige pad of ons voorbeeld nemen, kunnen we het verminderen:
Path = [LBLLLBSBLLBSLL] == > LBL = S
Path = [SLLBSBLLBSLL] == > LBS = R
Path = [SLRBLLBSLL] == > RBL = B
Path = [SLBLBSLL] == > LBL = S
Path = [SSBSLL] == > SBS = B
Path = [SBLL] == > SBL = R
Path = [RL]
Verbazingwekkend! Kijkend naar het voorbeeld het is duidelijk dat als de robot recht op eerste kruising, en daarna een links neemt, het einde van de doolhof in het kortste pad zal bereiken!
De eerste pad van doolhof Oplosser totale code zullen worden geconsolideerd in de functie mazeSolve(). Deze functie is in feite de loop functie eerder gebruikt, maar op de integratie van alle die stappen van de optimalisering van het opslaan en het pad.
Toen het eerste pad afliep, zal de pad [] array de geoptimaliseerde pad hebben. Een nieuwe variabele wordt ingevoerd
unsigned int status = 0; oplossen van = 0; Doolhof einde bereikt = 1
Blaten de eerste pad-functie:
VOID mazeSolve(void)
{
terwijl (! status)
{
readLFSsensors();
schakelaar (modus)
{
Case NO_LINE:
motorStop();
goAndTurn (links), 180;
recIntersection('B');
breken;
Case CONT_LINE:
runExtraInch();
readLFSsensors();
Als (modus! = CONT_LINE) {goAndTurn (links, 90); recIntersection('L');}
anders mazeEnd();
breken;
Case RIGHT_TURN:
runExtraInch();
readLFSsensors();
Als (modus == NO_LINE) {goAndTurn (recht, 90); recIntersection('R');}
anders recIntersection('S');
breken;
Case LEFT_TURN:
goAndTurn (LEFT, 90);
recIntersection('L');
breken;
Case FOLLOWING_LINE:
followingLine();
breken;
}
}
}
Hier een nieuwe functie geïntroduceerd: recIntersection (richting)
Deze functie zal worden gebruikt voor winkel het snijpunt en ook Bel een andere functie simplifyPath(), die de groep 3 kruispunten met betrekking tot een "bocht", zoals we voordat zagen zal verminderen.
VOID recIntersection(char direction)
{
pad [pathLength] = richting; Het snijpunt in de path variabele opslaan.
pathLength ++;
simplifyPath(); Vereenvoudig het geleerde pad.
}
Het krediet voor de simplifyPath () functie is het Patrick McCabe voor het pad Solving Code (voor meer informatie, bezoek https://patrickmccabemakes.com! De strategie van vereenvoudiging van het pad is dat wanneer we een reeks xBx tegenkomen, kunnen we het vereenvoudigen door te snijden de doodlopende weg. Bijvoorbeeld, LBL == > S zoals we op het voorbeeld zagen.
VOID simplifyPath()
{
Als (pathLength < 3 || pad [pathLength-2]! = 'B') weer; alleen het vereenvoudigen van het pad als de tweede-na-laatste beurt was een 'B'
int totalAngle = 0;
int i;
voor (ik = 1; ik < = 3; i ++)
{
switch(path[pathLength-i])
{
Case 'R':
totalAngle += 90;
breken;
geval 'L':
totalAngle += 270;
breken;
Case "B":
totalAngle += 180;
breken;
}
}
totalAngle = totalAngle % 360; Krijgen de hoek als een getal tussen 0 en 360 graden.
switch(totalAngle) / / vervangen van al die bochten met één.
{
Case 0:
pad [pathLength - 3] = de ';
breken;
geval 90:
pad [pathLength - 3] = 'R';
breken;
Case 180:
pad [pathLength - 3] = 'B';
breken;
Case 270:
pad [pathLength - 3] = 'L';
breken;
}
pathLength-= 2; Het pad is nu twee stappen korter.
}