1
0
forked from s425077/PotatoPlan

updated docs

This commit is contained in:
BOTLester 2020-05-04 01:56:37 +02:00
parent 73b078ec7a
commit e5a15185cb

View File

@ -1,28 +1,105 @@
# intelligent tractor environment implementation report # intelligent tractor route planning implementation report
The environment is a resizable two dimensional grid that has sprites for a farmhouse, crops and empty fields A* has been implemented. As of now, there are 4 types of fields wtih different costs:
Grass - 1
Dirt - 7
Crops - 15
4th type are obstacles (mountains) which are unpassable.
Apart from costs of each fields also cost or turning the agent has been implemented.
Turning once costs 2
Turning twice costs 9
Cost of turning twice is so high to encourage the agent to try different path rather that just turning back after reaching its destination point.
House: All costs can be changed and are not final values.
![](https://lh4.googleusercontent.com/tEGhmLT2PAgvXG313YaVewDrUhMYgvY1PPmPpISbcW2BRz4UPfDph3-86YDHjHl4YdyCYAx4qhzB2fTlmA2Gh5nyg6oLM92Nwg-UtV3tKw3nLBe3RZvr47efqYMElmaQASTr-xMt) Very rarely agent will make a little bump instead of going forward.
As of now we were not able to detect if it is a problem with A* algorithm or some other part of the program.
The tractor (in white) and crop (in red) on the field: Snippets of code:
![](https://lh4.googleusercontent.com/vd2n3rGPXDMLaaGBGBtjxVRftNryut-NYPstA4_CJwtRDrIVKVoAt-YrSZhcTysnk4cPXNEtssbVx02O9-DHUlV_JkY7nudSqanG7vCnMVMXQHSDnVjhDG8q98OelzNfxNXsMrbH) A* main loop:
The simulation can increase in speed or even be halted with the arrow keys, the current speed is displayed at the bottom left of the window The current environment spawns crops in randomly generated locations and the tractor tracks the location of crops and it will haul the target back to the house as well as fertilize newly planted crops. while (openList.GetSize() > 0)
{
current = openList.getMin();
closedList.Insert(current);
openList.removeMin();
direction = current.getDirection();
As a task is complete on a tile its stage level will increase by one all the way up to 4 depending when it is fully grown and can be harvested, if (current.getCords() == target.getCords())
break;
1. The soil will not support crops. var adjacentNodes = GetAdjacentNodes(current.getCords());
foreach (var adjacentNode in adjacentNodes)
2. Soil is ready for crops to be planted. {
if (closedList.Exists(adjacentNode.getCords())) // check if adjacent node is on closed list, if it is, skip it
3. Crops are planted and need fertilization. continue;
g = current.getG() + crops[(int)adjacentNode.getCords().X, (int)adjacentNode.getCords().Y].getCostOnMovement() + CalculateRotationCost(direction, adjacentNode.getDirection()); // calculate g - cost from start point
4. Crops are ready for harvest. if (!(openList.Exists(adjacentNode.getCords()))) // if adjacent node is not on open list, add it
{
After the crops have been harvested they will return to stage 2. adjacentNode.setG(g);
adjacentNode.setH(ComputeHScore(adjacentNode.getCords(), target.getCords()));
adjacentNode.calculateF();
adjacentNode.setParent(current);
openList.Insert(adjacentNode);
}
else
{
if (g + adjacentNode.getH() < adjacentNode.getF()) // check if adjacent node is a better path than the current one
{
adjacentNode.setG(g);
adjacentNode.calculateF();
adjacentNode.setParent(current);
}
}
A short video of how the project works:[video](https://uam-my.sharepoint.com/:v:/g/personal/domhof1_st_amu_edu_pl/Ec1ThqI2DSZNob2-6IrfPvYBe9_G2xfK8Ffn04dSklsWIQ?e=OrTqmy) }
}
// backtrack to create path
while (current != null)
{
path.AddNode(current);
current = current.getParent();
}
Successor function:
private List<Nodes> GetAdjacentNodes(Vector2 currentPos)
{
var adjacentNodes = new List<Nodes>()
{
new Nodes(new Vector2(currentPos.X, currentPos.Y+1), 0),
new Nodes(new Vector2(currentPos.X + 1, currentPos.Y), 1),
new Nodes(new Vector2(currentPos.X, currentPos.Y - 1), 2),
new Nodes(new Vector2(currentPos.X - 1, currentPos.Y), -1),
};
//check if out of range
for (int i = 3; i >= 0; i--)
{
if (adjacentNodes[i].getCords().X < 0 || adjacentNodes[i].getCords().Y < 0)
adjacentNodes.Remove(adjacentNodes[i]);
else
{
if (adjacentNodes[i].getCords().X > Size.X - 1 || adjacentNodes[i].getCords().Y > Size.Y - 1)
adjacentNodes.Remove(adjacentNodes[i]);
}
}
// return if not an obstacle
return adjacentNodes.Where(
item => crops[(int)item.getCords().X, (int)item.getCords().Y].Status != 0).ToList();
}
Heuristic function:
// Heuristic function, Manhattan method.
public int ComputeHScore(Vector2 currentNode, Vector2 endNote)
{
return (int)(Math.Abs(endNote.X - currentNode.X) + Math.Abs(endNote.Y - currentNode.Y));
}