Using a wheeled robot Pioneer 3-DX. A display of BUG1 and BUG2 Algorithms showcase how the wee robot and reach itβs destination including whilst avoiding obstacles. No Fancy AIπ§ was used just simple mathsπ
Here is the equation for the bug algorithm distance
To follow a wall without crashing, I use a ProportionalβIntegralβDerivative (PID) controller, as while following the wall, I may travel closer or further than expected. PID controllers are a good way to correct but not overcorrect any error. To get the performance I currently have, I had to experiment with parameter values.
u(t)=Kpβe(t)+Kiββ«e(t)dt+Kdβdtde(t)β
Experimentation and Results
Bug 1 Results
Total Distance = 48.1m
Bug2 Results
Total Distance = 16.97m
Bug2 Results performed significantly better than Bug1's. Bug2 travelled much less distance as seen by the mini-map and total distance. Also not shown but calculated, Bug2 found the goal in a much faster time than Bug1.
In addition, Bug1, although simplistic in nature, was more complex to code due to more states being involved than Bug2.
Challenges and Reflections
Challenges:
PID controller
The controller took a long time to fine-tune to a stable state through experimenting with parameters. But by tuning P-D-I parameters in that order, I found a stable state. For future iterations, I wish this PID controller to perform better and smoother.
EventHandler
Turning the system from synchronous-based to asynchronous was challenging, especially considering Java is a strongly typed language. Creating custom definitions for the event handler was cumbersome.
Turning corners without over/under shooting
While experimenting with the bot, I over/undershot the corner many times, either hitting the incoming wall head-on or undershooting in open space. To fix this, I found using the back-side sensors (S15 & S8) to skew bot perception of side wall, so I turned those sensors off and only use S0 & S7.
Reflections:
Better turning
The robot will stop and turn. In the future, I wish it to arc on a smooth curve to desired position, without under/overshooting like my previous attempts.
More Efficient approach
Currently, I believe every timestep the bot is processing too many things at a given time, and the execution of the Bug1 and Bug2 Algorithm could be better. For example, with Bug1, I don't need to check every time if there is a new shortest exit pose. Solving these inefficiencies would allow for smaller embedded systems to run easier.
Conclusion
To conclude the assignment, I believe it went well, hitting many of the marks set: being able to have a successful wall-following algorithm, implement both Bug1 and Bug2 algorithms, and code and comment using best practices. The Bug2 algorithms outperform Bug1's, and there can only be a few specific layouts where Bug1 beats Bug2. However, I should mention that other algorithms and implementations can perform better than these bug algorithms; however, they do require additional data such as a map and greater sensor data.
CODE EXPLANATION
Event Handler
Is responsible for storing, manipulating, and initiating the robot actions/events like the action to wall follow or move straight. It stores events in a stack-like structure, executing events on top of the stack each iteration.
The EventHandler class is needed because of the asynchronous nature of the Bug1 and Bug2 algorithms. As the bot operates in an uncertain, unknown world, it needs to be able to react and adapt to the outside world in real time. Making an event handler that was purely synchronous/based on time thus would not be possible as the bot would need to know details of its local domain, which is impossible to do without mapping or hardcoding. Asynchronous behaviour is perfect for helping in executing the bug algorithms as it allows the robot's behavior to change according to the sensor reading/outside world. For example, commands like "Keep going straight until a wall is reached" is now doable. However, EventHandler can perform timed events if needed.
PioneerNav2
This class is wholly responsible for the bot's movement. Using differential drive logic and mathematics, this class manages to move the robot in all directions of the 2-D plane, including arching.
PioneerProxSensors1
This class is responsible for making and interpreting sonar sensor data, allowing the bot to know if an object is nearby, from which direction, and how far.
BaseDisplay & MapDisplay & DataDisplay & Obstacle
These classes deal with displaying information to the display. DataDisplay, MapDisplay, and PioneerProxSensors1 all extend from BaseDisplay. The Obstacle Class represents each obstacle and goal object on the mini-map.
BaseBugAlgorithm
Contains most of the logic that will be used for both classes. Both Bug1 and Bug2 contain many similarities in execution; for example, both algorithms:
Pivot to goal and move forward in a straight line to it, at the start.
Both will react when an obstacle is observed.
Wall follow
Need to pivot to goal several times.
Need to terminate execution once goal is reached.
Bug1 extends BaseBugAlgorithm
The Bug1 class makes the bot pivot to goal and move in a straight line towards it. If a wall is detected, it begins wall following and records the pose of entry point to wall following. While wall following, Bug1 at intervals will record current pose and current distance to goal and will continue to do so until the obstacle is circled/entry point is reached again. At this point, it will know the pose around the wall with the shortest exit point to goal. The bot will re-circle to that pose and exit the wall, pivoting in a straight line to the goal. These sets of actions repeat until the goal is reached.
Bug2 extends BaseBugAlgorithm
At instantiation, Bug2, using the Pythagorean theorem, will create a linear equation from current pose to goal pose using the LinearEquation class. From there, Bug2 will continue in parallel with the linear equation until an obstacle has been reached. Then it will wall follow around the obstacle until it has reached the location where the linear equation would lie. It does this by calculating Y given its current x pose. If the robot is on its <x,f(x)> coordinate, then it knows to exit the obstacle and continue in a straight line along the linear equation line to goal. This process is repeated until the goal is reached.