*******************************************************************
Shows all the required output of the eebot Robot challenge on the
Liquid Crystal Display.
Bow bumper (*=not hit ,B=hit) _____E&F Sensors
\ / / (<,- = line is left )
---------------------- (-,> = line is right)
State name -----> |Right Turn * <L> | (|,| = line is center)
Voltage value --> |Knob= 9.7V S DLD |
----------------------
\_________/ | \_/
| | \
Display the battery | Light sensors (L=light, D=dark)
voltage if the frob |
knob is < 0.1 Volt Stern bumper (* not hit, S hit)
*******************************************************************
At first the entire project seemed like a large task which involved specialized routines to perform specific jobs at certain points on the obstacle course. If the entire process could be viewed in one frame, it can be seen that the robot needs to do only two things at any given time. Although the robot need to perform different specific tasks at different stages of the course, all these tasks fall into one of two classes; a state duty, and a state check. In every state that the robot is in, it is always doing two things:
performing some tangible duty,
sensing for certain criteria to be met.
The condition that the robot looks for changes from state to state but in all cases the satisfaction of this criteria results in a state change. In the mean time, the robot performs a duty while in that state; which in turn gave definition to the state by means of its behaviour.
As a means to keep the code size minimal it was vital to find this pattern. With the knowledge that every state can be generalized to fit a common loop, many of the specialized routines can be reused. These routines had to be called in a common way to make the main loop of the program identical for every state. Yet, they had to be flexible enough to call the proper routines for the current state of the robot. In addition to that, when the criteria of the state check is met, the program must know what the next state is.
All of these problems were resolved by using the indirect jump to subroutine instruction. The address of the next state, the state checker, and the state duty were all saved in pre-defined variables that were jumped to when the need arose. This method did not require a dispatcher to instruct the program where the go next because this matter was sorted out the moment the robot entered a new state. Essentially the robot always did the same thing by jumping to the address in the "STATEDUTY" variable, and the address in the state check variable, "LOOKFOR". If the condition was satisfied in the state checker, the robot changed its behavior by jumping to a state initializing routine which had its address stored in the variable appropriately called "NEXTSTATE".
The routine that was addressed in the NEXTSTATE variable was responsible for a few things that were only done once at the entry of a new state. It was responsible for marking the address of the string that described the robots current state, the starting motor controls at the beginning of the current state and the size of a software delay value if need be. The most important things that it did was save the addresses of, the next state initializing routine, the criteria checking routine, and the current state duty routine.
The criteria checking routines that were responsible for conditionally taking the robot to the next state included routines that checked for the bumper, the light sensors, and even a routine that looked for the software delay alarm. These same routines were used at different point on the course at only selected time as defined by the "LOOKFOR" variable. The heart of these routines were the compare instruction that branched the program into one of the state initializing routines as defined by the variable "NEXTSTATE". If the conditions were not met these state checking routines simple ended.
While in the main loop the program always jumped to the subroutine in the "STATEDUTY" variable. These duties included either tracking the line, decrementing the delay alarm counter, and even a void routine that just did nothing by only containing that RTS instruction. The "do nothing" routine or "DONUTN" as it was called was needed for instances when the robot was in a turn and needed to do nothing while in that turn because the motors were already set.
The track line routine was the most impressive of all the robots abilities. It tracked the line by using the E and F line sensors to determine whether the robot was steering left or right of the line. Using that data the robot corrected itself by switching off the appropriate motor to initiate a turn. The last routine was responsible for decrementing a delay variable that the alarm checker looked at. This decrementing process occurred once per main loop, so essentially the program didn't stall during any of the delays. The waiting process was part of the main loop, and not a subroutine that stalled the entire program.
The major problems in this program was in getting the threshold values for the light sensors correct. The line sensor thresholds posed the greatest problems if they were not calculated properly. At first only one threshold value was used for the tracking. If the sensor value was greater the robot would go right, else it would go left. The problem with this is when both sensors are of equal value, as in the instance when it is crossing an intersection or on the line perfectly, the robot should go straight. This doesn't work with only one threshold. The robot always ends up in a turn whether left or right, and this is how it always rolls along. When it reaches an intersection, it wants to turn because the value at that point is on one side of the threshold.
This problem was fixed by having two thresholds. They were calculated by having both sensors on light and both on dark. The lower of the two was the low threshold, and the higher one was the high threshold. It didn't matter which produced the higher one because in theory they were both supposed to be the same. As long as the sensor value was lower than the lowest the robot turned left and if it was higher than the highest it turned right. In the event that it fell between the two thresholds, it would go straight.
The tracking of the line was further improved by building on top of the exiting routine. The existing routine would only be used if the bow sensor of the robot was off the line. If it was on the line the robot would just go straight. As soon as the bow went off the line the robot would track. In essence the robot will go straight in two cases. The first case is when the bow is on the line. The second is if the bow is off the line and both line sensors have equal value. The only time the latter is possible is when the robot is off course and all the sensors are dark. This occurs at the beginning of the course when the robot has to find the line. This feature of the track line routine allows it to be recycled for the initial find line routine, which was the intention all along. As a result the robot tracked more smoothly.
In addition to just running the course I also had the robot make full use of the on board liquid crystal display. In addition to displaying the state name, the robot also displayed the bumper switches, the light sensors, the battery voltage, and the frob knob voltage. The bumper switches were display as "B", or "S" if hit, and "*" if not. The light sensors were displayed as "D" if dark, and "L" if light. In the case of the line sensors, a "<" indicated the line was more to the left, and a ">" indicated the line was more to the right. A pair of "|" indicated that the robot has to go straight because the sensors were either on both dark or both light. Since there was no room on the LCD to show both the battery voltage and the knob voltage, I only showed the battery voltage when the knob was turned off and had a voltage less than 0.1 volt. To differentiate what voltage was being displayed, the voltage was properly labeled, and it was changed as the knob was switched on and off.
*******************************************************************
Shows all the required output of the eebot Robot challenge on the
Liquid Crystal Display.
Bow bumper (*=not hit ,B=hit) _____E&F Sensors
\ / / (<,- = line is left )
---------------------- (-,> = line is right)
State name -----> |Right Turn * <L> | (|,| = line is center)
Voltage value --> |Knob= 9.7V S DLD |
----------------------
\_________/ | \_/
| | \
Display the battery | Light sensors (L=light, D=dark)
voltage if the frob |
knob is < 0.1 Volt Stern bumper (* not hit, S hit)
*******************************************************************
In addition to that the turns of the robot were improved by having different styles of turning in different states. The alive indicator was also used to show that the robot had not crashed. Please see the attached assembly language code for more details about all these features of the robot.