Date: 16 01 2009
Duration of activity: 3 hours + (2 hours of homework)
Group members participating: all group members + (Anders B. of homework)
1. The Goal
The goal of this lab session is to make the robot to actually draw something decent.
2. The Plan
- Run drawing tests and make relevant conclusions.
- Make further adjustments to the software.
3. The Results
In this lab session we have run several trials of drawing. It was very important to establish how precisely our robot manages to follow the given instructions.
3.1. Drawing rounded square
The first attempt was to draw a square with round-shaped corners. This is the result that we got:
As it can be noticed at once---neither it is a square with round-shaped corners, nor it is smooth in any sense. At this particular moment there are two problems to be solved: Resolve the way operations are given to the robot (presently, we could appear to have a miscommunication) and make it draw things more precisely. The wavy lines appear because the correction of where-I-am and where-I-am-supposed-to-be is done in a relatively aggressive bang-bang fashion.
Also, in this picture the areas rounded with red circles indicate a mechanical problem that we have. As spindles on the axes are not tightened enough, lengthwise, they tend to open up gaps between the spindle parts, and this causes the robot ``skip over'' once in a while... and that clearly can be seen in the process of drawing!
3.2. Drawing square
Now in the second picture one can see that another attempt to draw a square (with non-rounded edges) ended up being more like a square. This time corners are at least in similar shapes. We still have problems with skipping spindles, we end up somewhat far from where we started, and the lines are somewhat shaky, but there is a definite improvement if to compare with the first attempt. All of these observations are backed by the way the robot behaved during plotting (the shakyness stemming from bang-bang-corrections, for example), and have a reasonable explanation.
3.3. Really drawing a square
The third attempt was really a success. The robot drew a rectangle with sharp corners and it was done with a big rate of precision. The error was (as predicted during the previous plot) that the robot was instructed to trace the shape too fast, and the rounded corners are a result of it not being able to keep up with where it was supposed to be at.
As it can be seen, the upper-most and the lower-most edges both are of 8,0 cm length. The difference between the right and the left edges is only one millimeter, so it is rather precise given the fact that we count tachos and later correlate them to millimeter values. One more issue was that we actually tried to draw a square, and not a rectangle. This problem requires further adjustments.
3.4. Drawing a triangle
As we were able to draw lines along x-axis and y-axis and do it rather precisely, it was time to try out how the robot handles diagonal lines. To fulfill this idea, we tried to draw a triangle. This was not that much of a success. The lines were of different lengths (compared to what they were supposed to be) and it did not shape the form it was supposed to shape. This may be due to the fact that we decided to hardwire the values that correspond to the length of x-axis and y-axis. Also, it cannot be excluded that some programmer error snook in, and the robot actually did as it was instructed to do.
3.5. Navigation layer
motorPowerFromFraction (float fraction)returns the power to supply to a motor in order to obtain the desired fraction of the maximal speed.
motorPowerFromDistance (float distance)returns the (signed!) motor powers that
NavigationLayerImpshould use to move towards a point that is ``distance'' away.
gotoCoordinates(float x, float y, float z)is now done in a more correct fashion. Inside the speed and direction of motors are set. Finds out in which direction the pointer is needing to go in the various axis.
halt ()stops the motors.
getCoordinates()retrieves coordinates with the help of calibration layer and puts into an array.
The new thing to this layer is general improvement of the corrective measures taken in order to go from actual position to desired position. This uses the
motorPowerFromDistance()helper method, that undergoes a transition from being a simple guesswork stepwise function to a nice linear mapping that is based on empirical knowledge.
3.6. Gradient interpreter layer
GradientInterpreterStandardhas had some changes from last time:
assureMaintainerRunning()the way operations are run is corrected.
interactivelyRunOperation(GradientGiver operation)is all about to be certain where to go. It allows to go (or to try to go) to the currently most correct coordinates.
The most important thing with a gradient interpreter layer at this point is the act of correction. At every moment we are trying to go to the most correct coordinates we are aware of, as determined from the time since the start of a movement.
3.7. Bogus handler layer
findOrigo ()finds the starting point, interactively (i.e. it's a blocking call).
drawRoundedSquare ()handles the way a square with rounded corners is being drawn.
drawSimpleSquare ()handles the way a square without rounded corners is being drawn.
drawTriangle ()handles the way a triangle is being drawn.
drawLinesegments (float array)handles the way some array of line segments is being drawn.
main (String args)handles sequence of actions.
This layer now contains descriptions of some more shapes. Therefore, now we should be able to draw a rounded square, a simple square, a triangle, and an ordinary line.
Drawing tests showed that we are actually able to draw lines along the axis with a lot of precision, whereas diagonal ones aren't at that level of precision yet. With regards to the drawing trials, necessary adjustments were made to the navigation layer, as well as to the gradient interpreter and bogus handler layers.